Browse Source

included posts

master
Chris 4 years ago
parent
commit
e30bbe24b2
  1. 150
      .gitignore
  2. 82
      README.md
  3. 6
      archetypes/default.md
  4. 35
      config.toml
  5. 13
      data/banner.yml
  6. 77
      data/gallery.yml
  7. 65
      data/items.yml
  8. 62
      data/post/20211210.yml
  9. 30
      data/spot/20220120.yml
  10. 90
      data/spot/20220129.yml
  11. 2412
      design/Zeichnung-1.svg
  12. BIN
      design/apple-touch-icon.png
  13. BIN
      design/favicon-16x16.png
  14. BIN
      design/favicon-32x32.png
  15. BIN
      design/icon.png
  16. 64
      design/icon.svg
  17. 23
      layouts/_default/baseof.html
  18. 21
      layouts/index.html
  19. 14
      layouts/partials/banner.html
  20. 11
      layouts/partials/gallery.html
  21. 10
      layouts/partials/header.html
  22. 13
      layouts/partials/picture.html
  23. 10
      layouts/partials/post.html
  24. 26
      layouts/partials/template/footer.html
  25. 17
      layouts/partials/template/head.html
  26. 160
      redaktion/generate.sh
  27. 958
      redaktion/generate_content.py
  28. 4
      redaktion/resources.txt
  29. 22
      redaktion/test.sh
  30. 10
      redaktion/test.svg
  31. 68
      redaktion/upload.sh
  32. BIN
      static/images/instagram.png
  33. BIN
      static/images/pic_rss.gif
  34. BIN
      static/rss/rss-1.jpg
  35. BIN
      static/rss/rss-1.png
  36. 22
      static/rss/rss.xml
  37. 3
      themes/hugo-story/LICENSE
  38. 98
      themes/hugo-story/README.md
  39. 5
      themes/hugo-story/assets/css/fontawesome-all.min.css
  40. 1
      themes/hugo-story/assets/css/main.css
  41. 314
      themes/hugo-story/assets/css/noscript.css
  42. 2
      themes/hugo-story/assets/js/breakpoints.min.js
  43. 2
      themes/hugo-story/assets/js/browser.min.js
  44. 562
      themes/hugo-story/assets/js/demo.js
  45. 2
      themes/hugo-story/assets/js/jquery.min.js
  46. 2
      themes/hugo-story/assets/js/jquery.scrollex.min.js
  47. 2
      themes/hugo-story/assets/js/jquery.scrolly.min.js
  48. 342
      themes/hugo-story/assets/js/main.js
  49. 587
      themes/hugo-story/assets/js/util.js
  50. 48
      themes/hugo-story/assets/sass/base/_page.scss
  51. 77
      themes/hugo-story/assets/sass/base/_reset.scss
  52. 237
      themes/hugo-story/assets/sass/base/_typography.scss
  53. 102
      themes/hugo-story/assets/sass/components/_actions.scss
  54. 991
      themes/hugo-story/assets/sass/components/_banner.scss
  55. 35
      themes/hugo-story/assets/sass/components/_box.scss
  56. 113
      themes/hugo-story/assets/sass/components/_button.scss
  57. 287
      themes/hugo-story/assets/sass/components/_form.scss
  58. 617
      themes/hugo-story/assets/sass/components/_gallery.scss
  59. 97
      themes/hugo-story/assets/sass/components/_icon.scss
  60. 23
      themes/hugo-story/assets/sass/components/_icons.scss
  61. 62
      themes/hugo-story/assets/sass/components/_image.scss
  62. 67
      themes/hugo-story/assets/sass/components/_index.scss
  63. 339
      themes/hugo-story/assets/sass/components/_items.scss
  64. 87
      themes/hugo-story/assets/sass/components/_list.scss
  65. 36
      themes/hugo-story/assets/sass/components/_row.scss
  66. 50
      themes/hugo-story/assets/sass/components/_section.scss
  67. 1013
      themes/hugo-story/assets/sass/components/_spotlight.scss
  68. 138
      themes/hugo-story/assets/sass/components/_table.scss
  69. 121
      themes/hugo-story/assets/sass/components/_wrapper.scss
  70. 50
      themes/hugo-story/assets/sass/layout/_wrapper.scss
  71. 223
      themes/hugo-story/assets/sass/libs/_breakpoints.scss
  72. 90
      themes/hugo-story/assets/sass/libs/_functions.scss
  73. 149
      themes/hugo-story/assets/sass/libs/_html-grid.scss
  74. 78
      themes/hugo-story/assets/sass/libs/_mixins.scss
  75. 80
      themes/hugo-story/assets/sass/libs/_vars.scss
  76. 376
      themes/hugo-story/assets/sass/libs/_vendor.scss
  77. 186
      themes/hugo-story/assets/sass/main.scss
  78. 208
      themes/hugo-story/assets/sass/noscript.scss
  79. BIN
      themes/hugo-story/images/device-screenshots.png
  80. BIN
      themes/hugo-story/images/screenshot.png
  81. BIN
      themes/hugo-story/images/tn.png
  82. 24
      themes/hugo-story/layouts/_default/baseof.html
  83. 13
      themes/hugo-story/layouts/index.html
  84. 14
      themes/hugo-story/layouts/partials/banner.html
  85. 472
      themes/hugo-story/layouts/partials/elements.html
  86. 2009
      themes/hugo-story/layouts/partials/elements_reference.html
  87. 14
      themes/hugo-story/layouts/partials/gallery.html
  88. 5
      themes/hugo-story/layouts/partials/item.html
  89. 12
      themes/hugo-story/layouts/partials/items.html
  90. 1663
      themes/hugo-story/layouts/partials/modifiers.html
  91. 12
      themes/hugo-story/layouts/partials/picture.html
  92. 13
      themes/hugo-story/layouts/partials/spotlight-01-left.html
  93. 13
      themes/hugo-story/layouts/partials/spotlight-02-right.html
  94. 13
      themes/hugo-story/layouts/partials/spotlight-03-left.html
  95. 13
      themes/hugo-story/layouts/partials/spotlight.html
  96. 7
      themes/hugo-story/layouts/partials/template/favicon.html
  97. 14
      themes/hugo-story/layouts/partials/template/footer.html
  98. 18
      themes/hugo-story/layouts/partials/template/head.html
  99. 8
      themes/hugo-story/layouts/partials/template/head_css.html
  100. 10
      themes/hugo-story/layouts/partials/template/head_sass.html
  101. Some files were not shown because too many files have changed in this diff Show More

150
.gitignore vendored

@ -1,15 +1,143 @@
# ---> Hugo /themes/hugo-story/exampleSite/
# Generated files by hugo /themes/hugo-story/assets/.sass-cache/
/assets/
/content/
/static/images/gallery/
/public/ /public/
/resources/_gen/ /redaktion/work/
/assets/jsconfig.json /images*
hugo_stats.json /redaktion/venv/
/dropin/
/archive/
_gen/
/hugo/
.hugo_build.lock
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# Executable may be added to repository # C extensions
hugo.exe *.so
hugo.darwin
hugo.linux
# Temporary lock file while building # Distribution / packaging
/.hugo_build.lock .Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

82
README.md

@ -1,24 +1,25 @@
## dierundestunde ## dierundestunde
Hugo-Projekt mit Bilder von _Die Runde Stunde_. Hugo-Projekt mit Bilder von _Die Runde Stunde_.
Das Hugo-Projekt liegt auf github. Die erstellen Blog-Beiträge liegen im separaten gitea-Bereich [dierundestunde](https://kollegen.uber.space/gitea/dierundestunde/). Der Bild-Content wird dageben nicht versioniert, sondern immer generiert. Das Projekt liegt komplett hier auf gitea. Der Bild-Content wird dageben nicht versioniert, sondern immer generiert.
Es muss folgende Verzeichnisstruktur vorliegen: Es muss folgende Verzeichnisstruktur vorliegen:
```bash ```bash
~/ ~/
.ssh/ # SSH-Konfiguration .ssh/ # SSH-Konfiguration
dierundestundegen/ dierundestundegen/
dierundestunde/ # GitHub-Projekt drs/ # Gitea-Projekt
data # Blog-Beiträge
... # Hugo-Website
redaktion/ redaktion/
generate_content.py # Hugo-Content neu erzeugen generate_content.py # Hugo-Content neu erzeugen
dropin/ # neue Bilder hier hinein legen dropin/ # neue Bilder hier hinein legen
images/ # verabeitete Bilder, nicht manuell ändern images/ # verabeitete Bilder, nicht manuell ändern
generate.sh # Zum Neuaufbau des Web-Contents generate.sh # Zum Neuaufbau des Web-Contents
drs-posts/ # Gitea-Projekt hugo-extended/hugo # Die extended Version (für css-Anpassungen)
data # Beiträge
html/ # User-Web-Content html/ # User-Web-Content
/dierundestunde # Wird von generate.py neu aufgebaut /dierundestunde # Wird von generate.py neu aufgebaut
usr/bin # Hier liegt hugo usr/bin # Hier liegt hugo in der gleichen Version, wie auf dem Server
``` ```
### Initiales Setup des lokalen Rechners ### Initiales Setup des lokalen Rechners
@ -27,7 +28,7 @@ Mit dem lokalen Rechner wird zum Einen bei Bedarf das Hugo-Projekt angepasst. F
#### Setup um Hugo-Projekt pflegen #### Setup um Hugo-Projekt pflegen
Um am Projekt etwas ändern zu k̨önnen, sind die git-Repositories am besten in die oben beschriebenen Verzeichnisstruktur wie clonen. Lokal kann die extended Version von Hugo genutzt werden, falls am Template bzw. Styling etwas geändert wird. Wo hugo extended installiert wird is frei wählbar, z.B. in dierundestundegen/hugo. Soll allerdings hugo wie auf Uberspace ausgeführt werden (nicht die extended Version), ist hugo nach ~/usr/bin zu installieren, damit das generation-Skript hugo findet und keine Anpassen vorgenommen werden müssen. Um am Projekt etwas ändern zu k̨önnen, ist das git-Repository in die oben beschriebenen Verzeichnisstruktur zu clonen. Lokal kann die extended Version von Hugo genutzt werden, falls am Template bzw. Styling etwas geändert wird. Hugo-extended wird unter dierundestundegen/hugo-extended installiert. Um hugo wie auf Uberspace auszuführen (nicht die extended Version), ist hugo nach ~/usr/bin zu installieren, damit das generation-Skript hugo findet und keine Anpassen vorgenommen werden müssen.
#### Setup um Bilder hochladen zu k̨önnen #### Setup um Bilder hochladen zu k̨önnen
Um neue Bilder der Hugo website hinzuzufügen wird am einfachsten das Bash-Skript upload.sh verwendet. Weiter unten ist aber auch der manuelle Weg beschrieben. Jedenfalls muss das JPG verkleinert und anschlißend nach dropin hochgelanden werden und zu guter letzt das generate-Skript auf dem Host ausgeführt werden, welches dann Hugo neu generiert und in das web-Verzeichnis kopiert. Um neue Bilder der Hugo website hinzuzufügen wird am einfachsten das Bash-Skript upload.sh verwendet. Weiter unten ist aber auch der manuelle Weg beschrieben. Jedenfalls muss das JPG verkleinert und anschlißend nach dropin hochgelanden werden und zu guter letzt das generate-Skript auf dem Host ausgeführt werden, welches dann Hugo neu generiert und in das web-Verzeichnis kopiert.
@ -38,7 +39,7 @@ Sind alle Voraussetzungen für das Script erfüllt (s. nächstes Kapitel), ist d
```bash ```bash
# <pfad/zum/script/upload.sh> <pfad/zu/den/original/bildern> # <pfad/zum/script/upload.sh> <pfad/zu/den/original/bildern>
local$ ~/dierundestundegen/dierundestunde/redaktion/uplod.sh ~/photo/f/02_Progress/drs/20220119/final/ local$ ~/dierundestundegen/drs/redaktion/uplod.sh ~/photo/f/02_Progress/drs/20220119/final/
``` ```
##### Setup bzw. der manuelle Weg ##### Setup bzw. der manuelle Weg
@ -58,7 +59,7 @@ Der Command __convert__ ist Teil von imagemagick:
``` ```
__SSH__ __SSH__
Wird für Zugriff auf uberspace als auch auf gitHub verwendet. Dazu muss ein Schlüsselpaar generiert und in ~/.ssh abgelegt sein. Die dabei zu definierende Passphrase (das Passwort), ist in keepass sicher abzulegen. Der so erzeugte SSH-Schlüssel wird für alle Zugänge verwendet. Wird für Zugriff auf uberspace und auf gitea verwendet. Dazu muss ein Schlüsselpaar generiert und in /home/mylocaluser/.ssh abgelegt sein. Die dabei zu definierende Passphrase (das Passwort), ist in keepass sicher abzulegen. Der so erzeugte SSH-Schlüssel wird für alle Zugänge verwendet.
```bash ```bash
~/ ~/
@ -68,27 +69,14 @@ Wird für Zugriff auf uberspace als auch auf gitHub verwendet. Dazu muss ein Sch
config # Konfiguration für ssh-Forwarding config # Konfiguration für ssh-Forwarding
``` ```
Wie in den beiden Dokumentationen (uberspace-Manual [SSH](https://manual.uberspace.de/basics-ssh/) bzw. github-Dokumentation [Connecting to GitHub via SSH](https://docs.github.com/en/authentication/connecting-to-github-with-ssh)) beschrieben, ist der Public Key auf uberspace und auf GutHub abzulegen. Wie in der Uberspace-Dokumentationen (uberspace-Manual [SSH](https://manual.uberspace.de/basics-ssh/)) beschrieben, ist der Public Key auf uberspace abzulegen.
Wichtig ist, dass der __ssh-agent__ funktioniert und die Passphrase speichert. Wichtig ist, dass lokal der __ssh-agent__ funktioniert und die Passphrase speichert.
```unformatted ```unformatted
local$ ssh-add ~/.ssh/id_ed25519 local$ ssh-add /home/localuser/.ssh/id_ed25519
Enter passphrase for /home/chris/.ssh/id_ed25519: Enter passphrase for /home/localuser/.ssh/id_ed25519:
Identity added: /home/chris/.ssh/id_ed25519 (chris@debian-egh) Identity added: /home/localuser/.ssh/id_ed25519 (localuser@localhost)
```
Das generate-Script, welches per SSH auf uberspace ausgeführt wird, benötigt das für den GitHub-Zugriff. Dazu muss in der Config-Datei folgender Eintrag stehen:
> __*~/.ssh/config*__
>
> ForwardAgent yes
So eingerichtet, kann der Zugriff auf GitHub von uberspace heraus erfolgen. Test:
```unformatted
local$ ssh kollegen@despina.uberspace.de "cd ~/tmp && rm -f -r dierundestunde && git clone git@github.com:chs8691/dierundestunde.git"
Cloning into 'dierundestunde'...
``` ```
### Initiales Setup von Uberspace ### Initiales Setup von Uberspace
@ -121,16 +109,15 @@ Verzeichnisse anlegen:
Git-Repositories holen: Git-Repositories holen:
```unformatted ```unformatted
host$ git clone https://kollegen.uber.space/gitea/dierundestunde/drs-posts.git host$ git clone https://kollegen.uber.space/gitea/drs/drs-posts.git
host$ git clone https://github.com/chs8691/dierundestunde.git host$ cd drs
host$ cd dierundestunde
``` ```
Venv für Python 3 anlegen. Dafür sorgen, dass pip auf dem neusten Stand ist. Besonderheit auf dem Server: Venv für Python 3 anlegen. Dafür sorgen, dass pip auf dem neusten Stand ist. Besonderheit auf dem Server:
pip immer mit --user ausführen! pip immer mit --user ausführen!
```unformatted ```unformatted
host$ cd ~/dierundestundegen/dierundestunde/redaktion host$ cd ~/dierundestundegen/drs/redaktion
host$ python3.9 -m venv venv host$ python3.9 -m venv venv
host$ venv/bin/python -m pip install --upgrade --no-cache-dir pip host$ venv/bin/python -m pip install --upgrade --no-cache-dir pip
host$ venv/bin/python -m pip install -r resources.txt host$ venv/bin/python -m pip install -r resources.txt
@ -146,10 +133,10 @@ Da noch keine Bilder vorhanden sind, wird eine erste Generierung nur eine Info a
Skript für Web-Generierung ins Hauptverzeichnis kopieren (muss wiederholt werden, wenn das Script geändert wurde): Skript für Web-Generierung ins Hauptverzeichnis kopieren (muss wiederholt werden, wenn das Script geändert wurde):
```unformatted ```unformatted
host$ cp ~/dierundestundegen/dierundestunde/redaktion/generate.py ~/dierundestundegen/ host$ cp ~/dierundestundegen/drs/redaktion/generate.py ~/dierundestundegen/
``` ```
Das Skript pulled die git-Repros und startet die hugo-Generierung. Anschließend wird die Hugo-Site nach ~/html kopiert. Das Skript pulled das git-Repro und startet die hugo-Generierung. Anschließend wird die Hugo-Site nach ~/html kopiert.
Damit ist das (leere) Hugo-Projekt einsatzbereit. Damit ist das (leere) Hugo-Projekt einsatzbereit.
@ -175,7 +162,7 @@ Nun noch das neue Bild in _dropin_ ablegen und anschließend den Hugo Content ge
Hugo Content daraus generieren und in Webspace befördern. Dazu muss nur das Script auf dem Host ausgeführt werden: Hugo Content daraus generieren und in Webspace befördern. Dazu muss nur das Script auf dem Host ausgeführt werden:
```unformatted ```unformatted
local$ ssh kollegen@despina.uberspace.de 'cd dierundestundegen/dierundestunde/redaktion; venv/bin/python ~/dierundestundegen/dierundestunde/redaktion/generate_content.py && ~/dierundestundegen/dierundestunde/redaktion/generate.sh' local$ ssh kollegen@despina.uberspace.de 'cd dierundestundegen/drs/redaktion; venv/bin/python ~/dierundestundegen/drs/redaktion/generate_content.py && ~/dierundestundegen/drs/redaktion/generate.sh'
local$ ... local$ ...
local$ Congratulations! Generation done. local$ Congratulations! Generation done.
``` ```
@ -205,10 +192,10 @@ Auf dem lokalen Rechner ist dann einmalig die SASS-Konvertierung durchzuführen.
Dann mit dem aktuellen Release von hugo extended den SASS-Präprozessor durchführen: Dann mit dem aktuellen Release von hugo extended den SASS-Präprozessor durchführen:
```unformatted ```unformatted
local$ cd ~/dierundestundegen/dierundestunde local$ cd ~/dierundestundegen/drs
local$ ~/hugo-extended/hugo local$ ~/hugo-extended/hugo
local$ rm ~/dierundestundegen/dierundestunde/themes/hugo-story/assets/css/*.css local$ rm ~/dierundestundegen/drs/themes/hugo-story/assets/css/*.css
local$ cp ~/dierundestundegen/dierundestunde/public/assets/css/*.css ~/dierundestundegen/dierundestunde/themes/hugo-story/assets/css/ local$ cp ~/dierundestundegen/drs/public/assets/css/*.css ~/dierundestundegen/drs/themes/hugo-story/assets/css/
``` ```
Nun wieder auf die Verwendung der css-Dateien switchen. Nun wieder auf die Verwendung der css-Dateien switchen.
@ -225,19 +212,17 @@ Das ist nicht sehr bequem, es werden aber auch nicht sensationell viele Beiträg
#### Post erstellen oder bearbeiten (lokal) #### Post erstellen oder bearbeiten (lokal)
Lokal bearbeitet man Posts, indem das Post-Verzeichnis aus dem drs-post nach data kopiert wird, der Post dort bearbeitet getestet wird. Am Ende den Inhalt zurückkopieren und pushen. Auf dem Server dann Hugo neu generieren und aktiv setzen. Posts liegen in unter drs/data/post. Wird dort geändert, ist nach dem pushen auf den Server die Generierung anzuschmeißen. Auf dem Server dann Hugo neu generieren und aktiv setzen.
Post erstellen oder bearbeiten: Post erstellen oder bearbeiten:
```unformatted ```unformatted
local$ cd ~/dierundestundegen/dierundestunde local$ cd ~/dierundestundegen/drs
local$ mv ../drs-posts/data/post data/ local$ vi data/post/20211210.yml # Post erstellen
local$ vi post/20211210.yml # Post erstellen
``` ```
Nach dem lokalen Test mit hugo server, pushen: Nach dem lokalen Test mit hugo server, pushen:
```unformatted ```unformatted
local$ mv data/post/ ../drs-posts/data/
local$ git add . && git commit -m 'new post' local$ git add . && git commit -m 'new post'
local$ git push local$ git push
``` ```
@ -245,10 +230,11 @@ Nach dem lokalen Test mit hugo server, pushen:
Jetzt generieren und aktivieren: Jetzt generieren und aktivieren:
```unformatted ```unformatted
local$ ssh kollegen@despina.uberspace.de '~/dierundestundegen/dierundestunde/redaktion/generate.sh' local$ ssh kollegen@despina.uberspace.de '~/dierundestundegen/drs/redaktion/generate.sh'
``` ```
> __*Hinweis*__
Generate funktioniert nur, wenn die Repos auf dem Server keine lokalen Änderungen haben. >
> Generate funktioniert nur, wenn die Repos auf dem Server keine lokalen Änderungen haben.
#### Kleine Korrekturen (Server) #### Kleine Korrekturen (Server)
@ -257,15 +243,13 @@ Das gleiche Prozedere, nur auf dem Server und ohne Test.
Post erstellen oder bearbeiten: Post erstellen oder bearbeiten:
```unformatted ```unformatted
host$ cd ~/dierundestundegen/dierundestunde host$ cd ~/dierundestundegen/drs
host$ mv ../drs-posts/data/post data/ host$ vi data/post/20211210.yml # Post erstellen
host$ vi post/20211210.yml # Post erstellen
``` ```
Nach dem lokalen Test mit hugo server, pushen: Nach dem lokalen Test mit hugo server, pushen:
```unformatted ```unformatted
host$ mv data/post/ ../drs-posts/data/
host$ git add . && git commit -m 'new post' host$ git add . && git commit -m 'new post'
host$ git push host$ git push
``` ```
@ -273,5 +257,5 @@ Nach dem lokalen Test mit hugo server, pushen:
Jetzt generieren und aktivieren: Jetzt generieren und aktivieren:
```unformatted ```unformatted
host$ ~/dierundestundegen/dierundestunde/redaktion/generate.sh host$ ~/dierundestundegen/drs/redaktion/generate.sh
``` ```

6
archetypes/default.md

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

35
config.toml

@ -0,0 +1,35 @@
## -----------------------------------------------
## Basic Configuration
## -----------------------------------------------
title = "Die Runde Stunde"
theme = "hugo-story"
# Defining the namespace. This is a must for generating resources
# with the correct permalink (e.g. css)
baseURL = "https://kollegen.uber.space/dierundestunde"
## -----------------------------------------------
## Hugo Built-in Features
## -----------------------------------------------
disableKinds = ["taxonomy", "taxonomyTerm"]
# disableKinds = ["taxonomy", "taxonomyTerm", "section"]
# googleAnalytics = "your-google-analytics-id"
## -----------------------------------------------
## Site Parameters
## -----------------------------------------------
[Params]
description = "Bilder aus dem Radius"
logo = "images/banner.jpg"
favicon = true
[Params.social]
github = "https://github.com/chs8691/"
email = "chs8691@mailbox.org"
instagram = "https://www.instagram.com/christianschulzendorff/"
flickr = "https://www.flickr.com/photos/christian_schulzendorff/"
uberspace = "https://kollegen.uber.space/"

13
data/banner.yml

@ -0,0 +1,13 @@
####################### Banner #########################
style: "style1 orient-left content-align-left image-position-right fullscreen onload-image-fade-in onload-content-fade-right"
title : "Die Runde Stunde"
subtitle: |
Bilder aus dem Radius
content : |
Entsprungen aus <a target="_blank" href="https://www.instagram.com/explore/tags/dierundestunde/">#dierundestunde</a>.
button:
label : "Info"
link : "#first"
image : "images/gallery/svgs/banner.svg"

77
data/gallery.yml

@ -0,0 +1,77 @@
title: "Gallery"
style: "style2 medium lightbox onscroll-fade-in"
content: |
This is a <strong>Gallery</strong> element. It can behave as a lightbox (when given the <code>lightbox</code> class), and you can customize its <span class="demo-controls">appearance with a number of modifiers</span>, as well as assign it an optional <code>onload</code> or <code>onscroll</code> transition modifier (<a href="#reference-gallery">details</a>).
pictures:
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/01.jpg"
thumb: "images/gallery/thumbs/01.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/02.jpg"
thumb: "images/gallery/thumbs/02.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/03.jpg"
thumb: "images/gallery/thumbs/03.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/04.jpg"
thumb: "images/gallery/thumbs/04.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/05.jpg"
thumb: "images/gallery/thumbs/05.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/06.jpg"
thumb: "images/gallery/thumbs/06.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/07.jpg"
thumb: "images/gallery/thumbs/07.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/08.jpg"
thumb: "images/gallery/thumbs/08.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/09.jpg"
thumb: "images/gallery/thumbs/09.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/10.jpg"
thumb: "images/gallery/thumbs/10.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/11.jpg"
thumb: "images/gallery/thumbs/11.jpg"
button: "Details"
- title: "Title"
content: "Lorem ipsum dolor amet, consectetur magna etiam elit. Etiam sed ultrices."
image: "images/gallery/fulls/12.jpg"
thumb: "images/gallery/thumbs/12.jpg"
button: "Details"

65
data/items.yml

@ -0,0 +1,65 @@
title : "Items"
content: |
This is an <strong>Items</strong> element, and it's basically just a grid for organizing items of various types. You can customize its <span class="demo-controls">appearance with a number of modifiers</span>, as well as assign it an optional <code>onload</code> or <code>onscroll</code> transition modifier (<a href="#reference-items">details</a>).
style: "style1 medium onscroll-fade-in"
items:
# feature item loop
- name : "One"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "style2 major fa-gem"
# feature item loop
- name : "Two"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-save"
# feature item loop
- name : "Three"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-chart-bar"
# feature item loop
- name : "Four"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-wifi"
# feature item loop
- name : "Five"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-cog"
# feature item loop
- name : "Six"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "style2 major fa-paper-plane"
# feature item loop
- name : "Seven"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-desktop"
# feature item loop
- name : "Eight"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-sync-alt"
# feature item loop
- name : "Nine"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-hashtag"
# feature item loop
- name : "Ten"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-bolt"
# feature item loop
- name : "Eleven"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "style2 major fa-envelope"
# feature item loop
- name : "Twelve"
content : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui turpis, cursus eget orci amet aliquam congue semper. Etiam eget ultrices risus nec tempor elit."
style : "solid style2 major fa-leaf"

62
data/post/20211210.yml

@ -0,0 +1,62 @@
####################### Post #########################
id: "first"
title : "Zu guter Erst"
date : 20220205
content: |
<h3>Was sieht man hier?</h3>
<p>Dies ist die generierte Webseite meiner Fotos aus dem Format <i>Die Runde Stunde</i>, eine Art sich
selbst veränderndes Foto-Album. Mit jedem Hochladen eines neuen Bildes wird die Website neu erzeugt und
die Bilder werden neu gruppiert.</p>
<br>
<h3>Motivation</h3>
<p>Das Sport-Format <i>Die Runden Stunde</i> entstand durch das vermehrte Arbeiten im Home Office und der damit
verbundenen extremen Bewegungsarmut (Schrittzähler lügen nicht). Es besteht aus einer morgendlichen Stunde
Workout auf dem Rad bzw. mit den Laufschuhen. Im ersten Corona-Lockdown 2020 kam die Einschränkung auf 15
km-Bewegungsradius hinzu. Das entspricht so ziemlich genau dem maximalen Radius beim Radfahren. Das
bedeutete für mich also keine Einschränkung, sondern machte mir im Gegenteil klar, wie wertvoll diese
kleine Fläche Heimat ist. Und dass es galt, diese zu entdecken und dieses zu teilen.</p>
<br>
<h3>Regeln der Bilder</h3>
<p>Beim morgendlichen Laufen oder einer Radfahrt von ca. 1 Stunde Dauer. Mit Handy-Kamera oder der guten Fuji.
GPS einschalten. Spontane Wahl von genau einem Spot oder auch vorher überlegt den Spot ansteuern. Bild(er) machen.
Nach Hause ohne weiteren Halt. Nachbearbeitung erlaubt.</p>
<br>
<h3>Funktionsweise des Blogs</h3>
<p>Der Inhalt wird aus den Bildern generiert. Dazu werden Aufnahmedatum und GPS-Position ausgelesen und jeweils
neun Bilder zu einem Spot zusammengefasst (denn 9 ist eine gute Zahl für einen Spot). Der erste Spot besteht aus
dem neusten Bild, was den Mittelpunkt des Spots bestimmt. Dann werden acht weiteren Bildern aus dessen Nähe
gesucht. Das am weitest entfernte Bild bestimmt den Radius des Spots. Zum Spot wird noch eine Header-Grafik
generiert: Jedes Bild wird als Punkt dargestellt und es wird eine Kreisfläche um das erste Bild mit dem
ermittelten Radius gezeichnet. Je älter das Bild, desto verblasster sein Punkt.
Der nächste Spot wird mit den verbleibenden Bildern genauso erzeugt.</p>
<p>Die Header-Grafik besteht aus dem 15 km-Kreis meiner Heimat und den Spot-Kreisen. Auch hier gilt:
Ältere Spots verblassen...</p>
<br>
<h3>Technik </h3>
Der Blog besteht aus der einen statischen Seite, welche mit dem Hugo-Framework generiert wird.
Ein neues Bild, mit GPS-Koordinaten und ggf. einem Titel getaggt, wird mit einem lokalen
Upload-Skript erst verkleinert und dann auf dem Webhost hochgeladen. Auf dem Server werden
dann noch zwei weitere Skripte bemüht und die Bilder und Blog-Beiträge zu generieren: die
Bilder werden neu in Beiträge (Spots) aufgeteilt und pro Spot je eine Yml-Datei mit dem
dazugehörigen SVG-Bild neu generiert. Auch wird das Header-SVG neu erzeugt. Dann wird Hugo
angeschmissen und der so erzeugte Content auf den Webspace kopiert. Eine genauere Anleitung
und auch den Quellcode findet man über das Kollegen-eigene
<a href="https://kollegen.uber.space/gitea/website/website/src/branch/master/dierundestunde.md">Gitea</a>.
<br>
<h3>Reflektion </h3>
Hiermit liegen die Bilder nun an ihrem dritten Ort im Netz, neben Instagram und Strava.
Das macht sie nicht besser. Ganz im Gegenteil, es fühlt sich etwas 'too much' an. Auch wegen des
Ressourcenverbrauchs für Uberspace-Server und Plattenplatz und so. Außerdem muss ich das ganze ja
am Laufen halten, was trotz der Helferskripte Lebenszeit benötigt. Aber so ist das mit einem
Experiment: Es ist erstmal nicht schonend, und man weiß nicht unbedingt, wozu die Erfahrung noch gut sein wird.

30
data/spot/20220120.yml

@ -0,0 +1,30 @@
title: 20220120
headerstyle: "style1 orient-left content-align-left image-position-center onscroll-image-fade-in"
style: "style2 medium lightbox onscroll-fade-in"
header: "images/gallery/svgs/20220120.svg"
content: |
&#10137; Entenhausen<br>
R = 1326 m<br>
&Delta; = 30 Tage
circle:
- pos: "(-6340, -4530)"
radius: "1326"
pictures:
- title: "Die Turmuhr schlägt acht, Hüttengesäß"
subtitle: "20220120"
content: "distance=0 m"
distance: "0"
geo: "9.041409166666666, 50.21767861111111"
pos: "(-7239, -3556)"
image: "images/gallery/fulls/20220119-075556-DSCF0809_1.jpg"
thumb: "images/gallery/thumbs/20220119-075556-DSCF0809_1.jpg"
button: "Ansehen"
- title: "Die Grenzstele, Ronneburg"
subtitle: "20211221"
content: "distance=2651 m"
distance: "2651"
geo: "9.06654111111111, 50.235193333333335"
pos: "(-5442, -5505)"
image: "images/gallery/fulls/20211215-082428-DSCF0776a.JPG"
thumb: "images/gallery/thumbs/20211215-082428-DSCF0776a.JPG"
button: "Ansehen"

90
data/spot/20220129.yml

@ -0,0 +1,90 @@
title: 20220129
headerstyle: "style1 orient-right content-align-left image-position-center onscroll-image-fade-in"
style: "style2 medium lightbox onscroll-fade-in"
header: "images/gallery/svgs/20220129.svg"
content: |
&#10137; Entenhausen<br>
R = 8555 m<br>
&Delta; = 77 Tage
circle:
- pos: "(-2054, 4180)"
radius: "8555"
pictures:
- title: "20220129"
content: "distance=0 m"
distance: "0"
geo: "9.1235447, 50.103113316666665"
pos: "(-1366, 9195)"
image: "images/gallery/fulls/20220128-074450-DSCF0842_01.jpg"
thumb: "images/gallery/thumbs/20220128-074450-DSCF0842_01.jpg"
button: "Ansehen"
- title: "20220126"
content: "distance=8516 m"
distance: "8516"
geo: "9.231804166666667, 50.13499861111111"
pos: "(6375, 5646)"
image: "images/gallery/fulls/20220126-080239-DSCF0820_5.jpg"
thumb: "images/gallery/thumbs/20220126-080239-DSCF0820_5.jpg"
button: "Ansehen"
- title: "Das Tor zum Feld"
subtitle: "20220115"
content: "distance=13637 m"
distance: "13637"
geo: "9.064321944444444, 50.21958361111111"
pos: "(-5600, -3768)"
image: "images/gallery/fulls/20220114-080743-DSCF0800-1.jpg"
thumb: "images/gallery/thumbs/20220114-080743-DSCF0800-1.jpg"
button: "Ansehen"
- title: "Pfaffenhütchen"
subtitle: "20211212"
content: "distance=11185 m"
distance: "11185"
geo: "8.996051111111111, 50.161345555555556"
pos: "(-10482, 2714)"
image: "images/gallery/fulls/20211210-080028-DSCF0750-1.jpg"
thumb: "images/gallery/thumbs/20211210-080028-DSCF0750-1.jpg"
button: "Ansehen"
- title: "20211128"
content: "distance=12144 m"
distance: "12144"
geo: "9.197558033333333, 50.201320833333334"
pos: "(3926, -1735)"
image: "images/gallery/fulls/20211126-072935-DSCF0722.jpg"
thumb: "images/gallery/thumbs/20211126-072935-DSCF0722.jpg"
button: "Ansehen"
- title: "Grenzweg Roth/Gelnhausen"
subtitle: "20211120"
content: "distance=13129 m"
distance: "13129"
geo: "9.161694722222222, 50.21849805555556"
pos: "(1362, -3647)"
image: "images/gallery/fulls/20211119-082307-DSCF0703_1.JPG"
thumb: "images/gallery/thumbs/20211119-082307-DSCF0703_1.JPG"
button: "Ansehen"
- title: "Abgespannte Situation, Hof Geiisberg"
subtitle: "20211118"
content: "distance=11012 m"
distance: "11012"
geo: "9.227687777777778, 50.17601194444445"
pos: "(6080, 1082)"
image: "images/gallery/fulls/20211117-081220-DSCF0691.JPG"
thumb: "images/gallery/thumbs/20211117-081220-DSCF0691.JPG"
button: "Ansehen"
- title: "Weit geReist, Gelnhausen"
subtitle: "20211116"
content: "distance=11625 m"
distance: "11625"
geo: "9.190425, 50.19831666666666"
pos: "(3416, -1401)"
image: "images/gallery/fulls/20211115-074420-PXL_20211115_064420839-01.jpeg"
thumb: "images/gallery/thumbs/20211115-074420-PXL_20211115_064420839-01.jpeg"
button: "Ansehen"
- title: "An der Birkenhainer, Freigericht"
subtitle: "20211113"
content: "distance=2155 m"
distance: "2155"
geo: "9.142690555555555, 50.11806388888889"
pos: "(3, 7531)"
image: "images/gallery/fulls/20211112-080147-DSCF0677.JPG"
thumb: "images/gallery/thumbs/20211112-080147-DSCF0677.JPG"
button: "Ansehen"

2412
design/Zeichnung-1.svg

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 121 KiB

BIN
design/apple-touch-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
design/favicon-16x16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

BIN
design/favicon-32x32.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
design/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

64
design/icon.svg

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="500"
height="500"
viewBox="0 0 132.29166 132.29167"
version="1.1"
id="svg5"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/chris/drs/story/design/icon.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
units="px"
width="500px"
inkscape:snap-page="true"
inkscape:snap-bbox="true"
inkscape:snap-grids="false"
inkscape:snap-to-guides="false"
inkscape:snap-center="true"
inkscape:snap-object-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:zoom="0.70710678"
inkscape:cx="445.47727"
inkscape:cy="269.40768"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path6061"
style="fill:#d3b5b5;fill-opacity:1;stroke-width:0.340802"
d="m 0,72.638448 a 105.64881,105.64881 0 0 0 -1e-6,149.409832 105.64881,105.64881 0 0 0 149.409831,1e-5 105.64881,105.64881 0 0 0 27.68818,-48.86742 A 105.64881,105.64881 0 0 1 76.555594,145.49269 105.64881,105.64881 0 0 1 48.878252,44.902742 105.64881,105.64881 0 0 0 0,72.638448 Z M 48.878252,44.902742 a 105.64881,105.64881 0 0 1 100.531578,27.73571 105.64881,105.64881 0 0 1 27.68818,100.542418 105.64881,105.64881 0 0 0 48.86742,-27.68818 105.64881,105.64881 0 0 0 -1e-5,-149.4098348 105.64881,105.64881 0 0 0 -149.409826,-1e-6 105.64881,105.64881 0 0 0 -27.677342,48.8198878 z" />
<circle
style="fill:#d3b5b5;fill-opacity:1;stroke-width:0.264583"
id="path6263"
cx="68.176376"
cy="67.085167"
r="9.8510265" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

23
layouts/_default/baseof.html

@ -0,0 +1,23 @@
<!DOCTYPE HTML>
<!--
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
-->
<html>
{{ partial "template/head" . }}
<body class="is-preload">
<!-- Wrapper -->
<div id="wrapper" class="divided">
{{- block "main" . }}{{- end }}
<!-- Wrapper -->
</div>
{{ partial "template/scripts" . }}
</body>
</html>

21
layouts/index.html

@ -0,0 +1,21 @@
{{ define "main" }}
{{ partial "banner" site.Data.banner }}
{{ if site.Data.spot }}
{{ range sort site.Data.spot "title" "desc" }}
{{ partial "header" . }}
{{ partial "gallery" . }}
{{ end }}
{{ end }}
{{ if site.Data.post }}
{{ range sort site.Data.post "date" "asc" }}
{{ partial "post" . }}
{{ end }}
{{ end }}
{{ partial "template/footer" . }}
{{ end }}

14
layouts/partials/banner.html

@ -0,0 +1,14 @@
<!-- Banner -->
<section class="banner {{ .style }}">
<div class="content">
{{ with .title }}<h1>{{ . }}</h1>{{ end }}
{{ with .subtitle }}<p class="major">{{ . | safeHTML }}</p>{{ end }}
{{ with .content }}<p>{{ . | safeHTML }}</p>{{ end }}
{{ with .button }}<ul class="actions stacked">
<li><a href="{{ .link }}" class="button primary large wide smooth-scroll-middle">{{ .label }}</a></li>
</ul>{{ end }}
</div>
{{ with .image }}<div class="image">
<img src="{{.}}" alt="R15" />
</div>{{end}}
</section>

11
layouts/partials/gallery.html

@ -0,0 +1,11 @@
<!-- Gallery -->
<section class="wrapper style1 align-center">
<!-- Gallery -->
<div class="gallery {{ .style }}">
{{ range .pictures }}
{{ partial "picture" . }}
{{ end }}
</div>
</section>

10
layouts/partials/header.html

@ -0,0 +1,10 @@
<!-- Spotlight -->
<section class="spotlight {{ .headerstyle }}"{{ with .id }} id="{{ . }}"{{ end }}>
<div class="content">
{{ with .title }}<h2>{{ . }}</h2>{{ end }}
{{ with .content }}<p>{{ . | safeHTML }}</p>{{ end }}
</div>
{{ with .header }}<div class="image">
<img src="{{ . }}" alt="" />
</div>{{ end }}
</section>

13
layouts/partials/picture.html

@ -0,0 +1,13 @@
<article>
<a href="{{ .image }}" class="image">
<img src="{{ .thumb }}" alt="" />
</a>
<div class="caption">
<h3>{{ .title }}</h3>
<h4>{{ .subtitle }}</h4>
<p>&longleftrightarrow; {{ .distance }} m</p>
<ul class="actions fixed">
<li><span class="button small">{{ .button }}</span></li>
</ul>
</div>
</article>

10
layouts/partials/post.html

@ -0,0 +1,10 @@
<!-- Spotlight -->
<section class="spotlight style1 orient-right content-align-left image-position-center" {{ with .id }} id="{{ . }}"{{ end }}>
<div class="content">
{{ with .title }}<h2>{{ . }}</h2>{{ end }}
{{ with .content }}<p>{{ . | safeHTML }}</p>{{ end }}
{{ with .button }}<ul class="actions stacked">
<li><a href="{{ .link }}" class="button">{{ .label }}</a></li>
</ul>{{ end }}
</div>
</section>

26
layouts/partials/template/footer.html

@ -0,0 +1,26 @@
<!-- Footer -->
<footer class="wrapper style1 align-center">
<div class="inner">
<ul class="icons">
{{ with .Site.Params.social.github }}<li><a target="_blank" href="{{.}}" class="icon brands style2 fa-github"><span class="label">Github</span></a></li>{{end}}
{{ with .Site.Params.social.twitter }}<li><a target="_blank" href="{{.}}" class="icon brands style2 fa-twitter"><span class="label">Twitter</span></a></li>{{end}}
{{ with .Site.Params.social.instagram }}<li><a target="_blank" href="{{.}}" class="icon brands style2 fa-instagram"><span class="label">Instagram</span></a></li>{{end}}
{{ with .Site.Params.social.flickr }}<li><a target="_blank" href="{{.}}" class="icon brands style2 fa-flickr"><span class="label">Flickr</span></a></li>{{end}}
{{ with .Site.Params.social.email }}<li><a target="_blank" href="mailto:{{.}}" class="fav icon style2 fa-envelope"><span class="label">Email</span></a></li>{{end}}
</ul>
<p><a target="_blank" href="https://kollegen.uber.space/">Datenschutzerklärung und Impressum</a></p>
<p>
<span><a href="https://www.instagram.com/christianschulzendorff/">
<img src="images/instagram.png" width="30">
</a></span>
<span class="footerspacer icon fad fa-diamond"></span>
<span>Theme Base 'Hugo Story' by <a target="_blank" href="https://github.com/caressofsteel/">CaressOfSteel</a></span>
<span class="footerspacer icon fad fa-diamond"></span>
<span>Hosted on <a target="_blank" href="https://uberspace.de/de/">Uberspace</a></span>
<span class="footerspacer icon fad fa-diamond"></span>
<span><a href="rss/rss.xml">
<img src="images/pic_rss.gif" width="36" height="14">
</a></span>
</p>
</div>
</footer>

17
layouts/partials/template/head.html

@ -0,0 +1,17 @@
<head>
<title>{{ .Site.Title }}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="description" content="">
<meta name="author" content="">
{{ if .Site.Params.favicon }}
{{ partial "template/favicon" }}
{{ end }}
<!-- CSS: direct use the generated css or generate is new from the original sass. -->
<!-- The latter is only neede, if the template is updated from original hugo story -->
<!-- Take care of the extra space between the curly brackets when commenting out -->
{{ partial "template/head_css" . }}
<!-- {x{ partial "template/head_sass" . }x} -->
</head>

160
redaktion/generate.sh

@ -0,0 +1,160 @@
#!/bin/sh
# Execute Hugo website generation and log all output into log file
# In error case, existing blog content will not be touched
#
# Print all commands to console
set -x;
# Version nr of this script. Just for logging
VERSION=2
# Path to hugo executable on uberspace and local (for testing)
HUGO=~/bin/hugo
#HUGO=~/dierundestunde/hugo/hugo
# Path to output destination on uberspace and local (for testing). Folder must exists.
PUBLIC_WWW=~/html/dierundestunde
# PUBLIC_WWW=/var/www/virtual/$USER/html/dierundestunde
#PUBLIC_WWW=~/hugotest/html/dierundestunde
# Working dir: here is the script and git's working dir
GENDIR=~/dierundestundegen
# Destination dir where hugo will genereate the content into
TMPPUBLIC=$GENDIR/html
# Path to persisted log file, e.g. in web folder
LOG=$GENDIR/log.txt
# Path to a temp log file for hugo's stdout
TMPLOG=$GENDIR/tmplog.txt
# Path to a temp log file for hugo's errout
TMPERR=$GENDIR/tmperr.txt
# Tmp file with timestamp string
TMPDATE=$GENDIR/tmpdate.txt
# Paths to the local gits
TMPGIT_HUGO=$GENDIR/drs
# Path to our repositories
GIT_HUGO=https://kollegen.uber.space/gitea/webiste/drs.git
# Log a text file content
log_file () {
cat $1
cat $1 >> $LOG
}
# log a string argument
log () {
echo $1
echo $1 >> $LOG
}
# Always produce a log file in the destination folder
finish () {
if [ -f $LOG ]
then
echo "Moving log.txt file to $LOG $PUBLIC_WWW/"
mv -Z -v $LOG "$PUBLIC_WWW/"
fi
if [ -f $TMPLOG ]
then
rm $TMPLOG
fi
if [ -f $TMPERR ]
then
rm $TMPERR
fi
if [ -f $TMPDATE ]
then
rm $TMPDATE
fi
exit $1
}
### MAIN ###############################################
log "Version $VERSION"
if [ -d $TMPPUBLIC ]
then
rm -r -f $TMPPUBLIC
fi
if [ -f $LOG ]
then
rm -v $LOG
touch $LOG
fi
# Document actual time into log file
date > $TMPDATE
log_file $TMPDATE
log "Using tmp dir $GENDIR"
# For the very first time: create dir
if [ ! -d $TMPGIT_HUGO ]
then
mkdir -v $TMPGIT_HUGO 2>&1 | tee -a $LOG
fi
# Check, if there is really the repro inside
if [ ! -d $TMPGIT_HUGO/.git ]
then
# jetzt clonen wir das Repository in den temporären Ordner
git clone $GIT_HUGO $TMPGIT_HUGO 2>&1 | tee -a $LOG
else
# env -i git -C $TMPGIT_HUGO pull 2>&1 | tee -a $LOG
cd $TMPGIT_HUGO && git pull 2>&1 | tee -a $LOG
fi
# Hugo anschmeißen
log "Starting hugo"
cd $TMPGIT_HUGO && $HUGO --cacheDir=$HOME/tmp/hugo_cache --destination $TMPPUBLIC > $TMPLOG 2> $TMPERR
if [ -f $TMPLOG ]
then
log_file $TMPLOG
fi
if [ -f $TMPERR ]
then
if grep -Fq "Error" $TMPERR
then
log "Hugo failed"
log_file $TMPERR
log "Generation canceled. Check the error and try to fix it. Then push again."
finish 1
fi
fi
if [ -d $PUBLIC_WWW ]
then
log "Remove $PUBLIC_WWW"
rm -r -f $PUBLIC_WWW 2>&1 | tee -a $LOG
else
log "Create $PUBLIC_WWW"
mkdir -v $PUBLIC_WWW 2>&1 | tee -a $LOG
fi
# Publish now
log "Copy $TMPPUBLIC to $PUBLIC_WWW"
rm -r -f $PUBLIC_WWW
mv -Z -v $TMPPUBLIC $PUBLIC_WWW 2>&1 | tee -a $LOG
log "Ready, Blog created in $PUBLIC_WWW!"
finish 0

958
redaktion/generate_content.py

@ -0,0 +1,958 @@
import argparse
from geopy.geocoders import Nominatim
import math
import os
import re
import shutil
# from typing_extensions import TypeVarTuple
from PIL import Image, ImageOps
from datetime import datetime
from PIL.ExifTags import TAGS
WORK_DIR = 'work'
HUGO_ROOT = '..'
HUGO_STATIC_DIR = '../static'
IMAGE_ROOT_DIR = 'images/gallery'
DROPIN_DIR = '../../dropin'
FULLS_DIR = 'fulls'
SVGS_DIR = 'svgs'
THUMBS_DIR = 'thumbs'
IMAGES_DIR = '../../images'
SPOT_DIR = 'data/spot'
HOME_LAT = 50.18573
HOME_LON = 9.14265
COLOR_CIRCLE = "#cc9966"
COLOR_DOT = "#996600"
# Radius around Home in meters
RADIUS = 15000
# pixel = meter * scale
SCALE = 0.1
# Number oy images per spot
SPOTS_SIZE = 9
images = []
bundles = []
# program arguments
args = None
def create_banner_svg():
"""
Create banner SVG files based on the build bundles.
All things will be done in the locale work folder.
SVG has following coordinate system:
(0,0)
+---------------------> +x
|
| +--------------+ (2*homx)+margx
| | |
| | (homx,homy) |
| | + |
| | |
| | |
| +--------------+
| (2*homy)+margy
|
V
+y
"""
# print(f"Creating banner SVG file")
# Circle should not hit image edges
margin = int(round(RADIUS / 20.0))
# All calculations in a home centered coordinte system (not in a SVG coordinate system),
# unscaled and without margin
# Initialize
xmax = RADIUS
ymax = RADIUS
xmin = -xmax
ymin = -ymax
# find canvas size (without margin): all image points have to be on the canvas
# TODO Not useful as long the points will not be shown
for image in images:
if image['x'] > xmax:
xmax = image['x']
if image['x'] < xmin:
xmin = image['x']
if image['y'] > ymax:
ymax = image['y']
if image['y'] < ymin:
ymin = image['y']
radius15 = RADIUS
radiusCenter = int(round(RADIUS * 0.02))
offsetx = -xmin + margin
offsety = -ymin + margin
opacbundlemax = 0.4
opacbundlemin = 0.0001
opacbundlestep = round((opacbundlemax - opacbundlemin) / len(bundles),4)
# opacimagemax = 0.8
# opacimagemin = 0.2
radius_dot =int(round(RADIUS * 0.01))
print(f"Creating banner SVG, corners=({xmin},{ymin}),({xmax},{ymax})")
name = os.path.join(WORK_DIR, IMAGE_ROOT_DIR, SVGS_DIR, "banner.svg")
with open(name, 'w') as file:
file.write(f"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
file.write(f"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n")
file.write(f"<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n")
file.write(f"viewBox=\"0 0 {scale(offsetx + xmax + margin)} {scale(offsety + ymax + margin)}\" xml:space=\"preserve\">\n")
file.write(f"<circle cx=\"{scale(offsetx)}\" cy=\"{scale(offsety)}\" r=\"{scale(radius15)}\" fill=\"#eeeeee\"> \n ")
file.write(f"</circle>\n")
file.write(f"<circle cx=\"{scale(offsetx)}\" cy=\"{scale(offsety)}\" r=\"{scale(radiusCenter)}\" fill=\"#ffffff\"> \n ")
file.write(f"</circle>\n")
for i, bundle in enumerate(bundles):
log(f" bundle {i} with {len(bundle['images']) + 1} images")
file.write(f"<circle cx=\"{scale(offsetx + bundle['x'])}\" cy=\"{scale(offsety + bundle['y'])}\" " +
f"r=\"{scale(bundle['radius'] + radius_dot)}\" opacity=\"{opacbundlemax - (opacbundlestep * i)}\" fill=\"{COLOR_CIRCLE}\">\n")
file.write(f"</circle>")
file.write(f"</svg>")
def create_svgs():
"""
Create SVGs files based on the build bundles.
All things will be done in the locale work folder.
SVG has following coordinate system:
(0,0)
+---------------------> +x
|
| +--------------+ (2*homx)+margx
| | |
| | (homx,homy) |
| | + |
| | |
| | |
| +--------------+
| (2*homy)+margy
|
V
+y
"""
print(f"create_svgs()")
# Circle should not hit image edges
margin = int(round(RADIUS / 10.0))
# All calculations in a home centered coordinte system (not in a SVG coordinate system),
# unscaled and without margin
# Initialize
opacbundlemax = 0.4
opacbundlemin = 0.0001
opacbundlestep = round((opacbundlemax - opacbundlemin) / len(bundles),4)
opacimagemax = 0.8
opacimagemin = 0.2
opacmidmax = 0.9
opacmidmin = 0.4
radius_dot =int(round(RADIUS * 0.01))
for i, bundle in enumerate(bundles):
# log(f"create_svgs() bundle {bundle['x']} {bundle['y']} {bundle['radius']}")
# Always show center
xmax = max(bundle['x'] + bundle['radius'], 0)
ymax = max(bundle['y'] + bundle['radius'], 0)
xmin = min(bundle['x'] - bundle['radius'], 0)
ymin = min(bundle['y'] - bundle['radius'], 0)
log(f" bundle: {bundle['image']['date']}: ({xmin},{ymin},{xmax},{ymax})")
# log(f" ({xmax-xmin},{ymax-ymin}) - {round((xmax-xmin) / (ymax-ymin),1)}, ")
# All images incl. main bundle image
images = bundle['images'].copy()
images.append(bundle['image'])
# find canvas size (without margin): all image points have to be on the canvas
for image in images:
if image['x'] > xmax:
xmax = image['x']
if image['x'] < xmin:
xmin = image['x']
if image['y'] > ymax:
ymax = image['y']
if image['y'] < ymin:
ymin = image['y']
# log(f" now ({xmin},{ymin},{xmax},{ymax}) / ({xmax-xmin},{ymax-ymin}) - {round((xmax-xmin) / (ymax-ymin),1)}, ")
# Original aspect ratio: 16:10
ratio = 1.8
ytarget = ( xmax - xmin ) / ratio
# Expand y
if ( ymax - ymin ) < ytarget:
# log(f" Expanding y with ytarget={ytarget} ")
ymaxold = ymax
ymax = int(round(ymax + ((ytarget - ( ymax - ymin )) / 2)))
ymin = int(round(ymin - ((ytarget - ( ymaxold - ymin )) / 2)))
# Expand x
else:
xtarget = int(round(( ymax - ymin ) * ratio))
# log(f" Expanding x with xtarget={xtarget} ")
xmaxold = xmax
xmax = int(round(xmax + ((xtarget - ( xmax - xmin )) / 2)))
xmin = int(round(xmin - ((xtarget - ( xmaxold - xmin )) / 2)))
# log(f" -->({xmin},{ymin}),({xmax},{ymax}) ")
# log(f" ({xmax-xmin},{ymax-ymin}) - {round((xmax-xmin) / (ymax-ymin),1)}, ")
radius15 = RADIUS
home_radius_center = int(round(RADIUS * 0.02))
offsetx = -xmin + margin
offsety = -ymin + margin
name = os.path.join(WORK_DIR, IMAGE_ROOT_DIR, SVGS_DIR, f"{bundle['image']['date']}.svg")
log(f" --> Spot SVG, corners=({xmin},{ymin}),({xmax},{ymax}")
with open(name, 'w') as file:
file.write(f"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
file.write(f"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n")
file.write(f"<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n")
# file.write(f" width=\"1440\" heigth=\"900\" \n")
file.write(f"viewBox=\"0 0 {scale(offsetx + xmax + margin)} {scale(offsety + ymax + margin)}\" xml:space=\"preserve\">\n")
file.write(f"<circle cx=\"{scale(offsetx)}\" cy=\"{scale(offsety)}\" r=\"{scale(radius15)}\" fill=\"#eeeeee\"> \n ")
file.write(f"</circle>\n")
file.write(f"<circle cx=\"{scale(offsetx)}\" cy=\"{scale(offsety)}\" r=\"{scale(home_radius_center)}\" fill=\"#ffffff\"> \n ")
file.write(f"</circle>\n")
file.write(f"<circle cx=\"{scale(offsetx + bundle['x'])}\" cy=\"{scale(offsety + bundle['y'])}\" " +
f"r=\"{scale(bundle['radius'] + radius_dot)}\" opacity=\"{opacbundlemax - (opacbundlestep * i)}\" fill=\"{COLOR_CIRCLE}\">\n")
r_from = scale((bundle['radius'] + radius_dot) * 0.995)
r_to = scale((bundle['radius'] + radius_dot) * 1.005)
file.write(f"<animate id=\"step1\" \n")
file.write(f"begin=\"0s;step2.end\" dur=\"1s\" \n")
file.write(f"attributeName=\"r\" from=\"{r_from}\" to=\"{r_to}\" \n")
file.write(f"/>\n")
file.write(f"<animate id=\"step2\" \n")
file.write(f"begin=\"step1.end\" dur=\"1s\"\n")
file.write(f"attributeName=\"r\" from=\"{r_to}\" to=\"{r_from}\" \n")
file.write(f"/>\n")
file.write(f"</circle>")
# Center dot of bundle circle
file.write(f"<circle cx=\"{scale(offsetx + bundle['x'])}\" cy=\"{scale(offsety + bundle['y'])}\" " +
f"r=\"{scale(bundle['radius'] * 0.02 )}\" opacity=\"{opacmidmax - (opacbundlestep * i)}\" fill=\"#ffffff\">\n")
file.write(f"</circle>")
opacimagestep = round((opacimagemax - opacimagemin) / len(images),2)
for i, image in enumerate(images):
file.write(f"<circle cx=\"{scale(offsetx + image['x'])}\" cy=\"{scale(offsety + image['y'])}\" " +
f"r=\"{scale(radius_dot)}\" opacity=\"{opacimagemax - (opacimagestep * i)}\" fill=\"{COLOR_DOT}\">\n")
file.write(f"</circle>")
file.write(f"</svg>")
print("..done")
def scale(value):
return int(value * SCALE)
def get_exif(fn, warns):
"""
Return dictionary with EXIF data and the optinal title.
"""
ret = {}
with Image.open(fn) as i:
info = i._getexif()
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
xmp = i.getxmp()
title = False
try:
title = xmp['xmpmeta']['RDF']['Description'][0]['title']['Alt']['li']['text']
# log(f"Found title for {fn}: {ret['title']}")
except:
pass
if not title:
try:
title = xmp['xmpmeta']['RDF']['Description'][0]['title']
# log(f"Found title for {fn}: {ret['title']}")
except:
pass
if title:
# log(f"{fn} Title={title}")
ret['title'] = title
else:
if args.verbose:
warns.append(f"No title found: {fn}")
return ret
def get_geo(gpsInfo):
lat = 0
lon = 0
lat = (((gpsInfo[2][2] / 60.0) + gpsInfo[2][1]) / 60.0) + gpsInfo[2][0]
if gpsInfo[1] == 'S':
lat = -lat
lon = (((gpsInfo[4][2] / 60.0) + gpsInfo[4][1]) / 60.0) + gpsInfo[4][0]
if gpsInfo[3] == 'W':
lon = -lon
# log(f"get_geo: gpsInfo={gpsInfo[1]}, {gpsInfo[2]}, {gpsInfo[3]}, {gpsInfo[4]} --> lat={lat}, lon={lon}")
return lat, lon
def get_pos(lat, lon):
"""
Calculates the distance in meters between the given geo point and the HOME.
Calculation is based on https://www.kompf.de/gps/distcalc.html
Returns a tuple (x, y) with distance in integer meters, based on ths SVG cordinate system
| -y
|
|(0,0)
-x -------+------- +x
|
|
| +y
"""
x = int(round(71.5 * 1000.0 * (lon - HOME_LON)))
y = int(round(111.3 * 1000.0 * (HOME_LAT - lat)))
# log(f"get_pos: {lon} - {HOME_LON} --> x={x} ")
# log(f"get_pos: {lat} - {HOME_LAT} --> y={y} ")
return x, y
def resolve_pos(x, y):
"""
Reverse calculation for get_pos()
"""
lon = round((x / (71.5 * 1000)) + HOME_LON, 6)
lat = round(HOME_LAT - (y / (111.3 * 1000)), 6)
log(f"resolve_pos: ({x},{y}) --> {lat}, {lon} ")
return lat, lon
def create_image_item(dir, file, warns):
"""
Create image dictionary for the given image file in the given directory. Both must exists.
Returns dectionary with image item or, in error case, false.
"""
filename = os.path.join(dir, file)
target_filename = os.path.join(IMAGES_DIR, file)
tags = get_exif(filename, warns)
# Invalid items gpsInfo=, (nan, nan, nan), , (nan, nan, nan)
if 'GPSInfo' in tags and (tags['GPSInfo'][1] == 'N' or tags['GPSInfo'][1] == 'S'):
lat, lon = get_geo(tags['GPSInfo'])
else:
lat, lon = (HOME_LAT, HOME_LON)
warns.append(f"No GPS data: {file}")
return False
x, y = get_pos(lat, lon)
# log(f"{name}")
format = "%Y:%m:%d %H:%M:%S"
dt = datetime.strptime(tags['DateTime'], format)
image = dict(dt=dt, date=dt.strftime('%Y%m%d'),name=file, filename=target_filename, tags=tags, lat=lat, lon=lon, x=x, y=y)
return image
def format_image(name):
"""
Create full and thumb for one image from the dropin folder
All things will be done in the locale work folder.
Returns True in success case, otherwise False
"""
thumb_size = (360, 360)
full_width = 1900
filename = os.path.join(DROPIN_DIR, name)
try:
with Image.open(filename) as im:
# Must be rotated by exif Orientation, otherwise thumb and full will not be
# shown the image in the correct rotation
im = ImageOps.exif_transpose(im)
# Size of the image in pixels (size of original image)
# (This is not mandatory)
width, height = im.size
# Setting the points for cropped image
if width > height:
offset = int(round((width - height) / 2))
left = offset
top = 0
right = height + offset
bottom = height
else:
offset = int(round((height - width) / 2))
left = 0
top = offset
right = width
bottom = width + offset
# Cropped image of above dimension
# (It will not change original image)
thumb = im.crop((left, top, right, bottom))
thumb.thumbnail(thumb_size)
thumb.save(os.path.join(WORK_DIR, IMAGE_ROOT_DIR, THUMBS_DIR, name), "JPEG")
concat = full_width/float(im.size[0])
size = int((float(im.size[1])*float(concat)))
# print(f"concat,size={concat}, {size}")
out = im.resize((full_width,size), Image.ANTIALIAS)
out.save(os.path.join(WORK_DIR, IMAGE_ROOT_DIR, FULLS_DIR, name), "JPEG")
except OSError:
warn(f"\ncannot convert image {filename}! ")
return False
return True
def process_images():
"""
Process all images and create fulls and thumbnails from the dropin folder.
Move the processed images into /images and rebuild hugo content
All things will be done in the locale folder (work, dropin, images)
"""
log(f"Processing images from '{DROPIN_DIR}'")
global images
images = []
p = re.compile('\d{8}.*\.(jpg|jpeg)', re.IGNORECASE)
new_files = [f for f in os.listdir(DROPIN_DIR)
if os.path.isfile(os.path.join(DROPIN_DIR, f)) and
p.match(f)]
old_files = [f for f in os.listdir(IMAGES_DIR)
if os.path.isfile(os.path.join(IMAGES_DIR, f)) and
p.match(f)]
log(f"Found {len(new_files)} images in {DROPIN_DIR} and {len(old_files)} images in {IMAGES_DIR}")
if not new_files and not old_files:
exit_with_good_bye(f"No images found.")
cnt = 0
err = 0
warns =[]
for name in new_files:
cnt += 1
print(f".", end="", flush=True)
# Can print a warning
image = create_image_item(DROPIN_DIR, name, warns)
if not image is False:
# Can print a warning
formatted = format_image(name)
if image is False or formatted is False:
char = "x"
err += 1
else:
char = '.'
shutil.move( os.path.join(DROPIN_DIR, name), image['filename'])
images.append(image)
if cnt % 10 == 0:
print(f"\b{char} ({cnt})", end="\n", flush=True)
else:
print(f"\b{char}", end="", flush=True)
for name in old_files:
cnt += 1
image = create_image_item(IMAGES_DIR, name, warns)
# This should never happens
if image is False:
char = "X"
err += 1
else:
char = 'o'
images.append(image)
if cnt % 10 == 0:
print(f"\b{char} ({cnt})", end="\n", flush=True)
else:
print(f"\b{char}", end="", flush=True)
print("\n")
if warns:
for message in warns:
warn(message)
if not images:
exit_with_good_bye("No valid images.")
print(f"Total processed {len(new_files)} new and {len(old_files)} old images: {len(images)} OK, {err} ignored.")
def create_bundles():
"""
Bundle images to spots by global images list. Output
is a list of spots with tpe dict:
{
image=main_image,
images=list_of_satellite_images,
}
All things will be done in the locale work folder.
"""
print(f"Create bundle images")
global bundles
bundles = []
if len(images)==0:
exit_on_error("No images found to bundle")
end = False
left_images = images
while not end:
bundle = create_bundle(left_images)
if bundle is None:
end = True
break
bundles.append(bundle)
log(f"removing main image={bundle['image']['name']}")
left_images.remove(bundle['image'])
for image in bundle['images']:
log(f"removing bundle image={image['name']}")
left_images.remove(image)
# log(f"len={len(left_images)}")
print(f"Processed {len(bundles)} bundles.")
def calculate_circle(image, _images):
"""
Find the smallest circle for the images by finding the two point that are furhtermost from each other.
Returns dict with x, y as distance from HOME and radius, all in meters as integer.
"""
# circle dimension. Initialization for case of single image bundle
# 100.0 is no magic number, it's just a value to show something around the single image point
max_radius = 100.0
x = image['x']
y = image['y']
images = _images.copy()
images.append(image)
log(f"calculate_circle for {len(images)} images", end="")
for i, item1 in enumerate(images):
# log(f"image {i}: {item1['x'],item1['y']}")
for item2 in images[(i+1):]:
x_dist = item2['x'] - item1['x']
y_dist = item2['y'] - item1['y']
radius = int(round(math.sqrt(x_dist**2 + y_dist**2) / 2.0))
if max_radius >= radius:
continue
max_radius = radius
x = int(round(item1['x'] + (x_dist/2.0)))
y = int(round(item1['y'] + (y_dist/2.0)))
# log(f"image {i}: {item1['x'],item1['y']}")
ret = dict(x=x,y=y,radius=max_radius)
print(f"...done: {ret}")
return ret
def create_bundle(_images):
if len(_images) == 0:
return None
# Find newest
images.sort(key = lambda item: item.get("dt"))
# Work with copy to prevent from
newest = images[-1]
log(f"Create bundle for newest={newest['name']}")
# Add distance
for image in images:
image['dist'] = int(round(math.sqrt(((newest['x'] - image['x']) ** 2) + ((newest['y'] - image['y']) ** 2))))
# find nearbys. Be careful: newest must not be at first place, if there is a second image with dist == 0
images.sort(key = lambda item: item.get("dist"))
# for image in images:
# print(f"images: image={image['name']} dist={image['dist']}")
bundle_images = []
# Exclde newest from list (must not be at first place, see above)
for image in [i for i in images if i['name'] != newest['name']][:SPOTS_SIZE-1]:
log(f"image={image['name']}")
bundle_images.append(image)
circle = calculate_circle(newest, bundle_images)
bundle_images.sort(key = lambda item: item.get("date"), reverse=True)
ret = dict(image=newest, images=bundle_images, x=circle['x'], y=circle['y'], radius=circle['radius'])
log(f"Bundle created: x={ret['x']}, y={ret['y']}, radius={ret['radius']}")
# print(f"newest ={ret['image']['date']}")
# for i in ret['images']:
# print(f"image ={i['dist']} , {i['date']}")
return ret
def get_address(latitude, longitude, language="de"):
coordinates = f"{latitude}, {longitude}"
# Switch off for develop pursoses
if args.location_mockup:
return "Entenhausen"
try:
geolocator = Nominatim(user_agent="de.kollegen.dierundestunde")
location = geolocator.reverse(coordinates)
log(f"get_address() {location}")
parts = location.address.split(", ")
if len(parts) == 8:
return f"{parts[1]}, {parts[2]}"
elif len(parts) >= 2:
return f"{parts[0]}, {parts[1]}"
else:
return location.address
except:
print("geolocator failed")
return ""
def create_spots():
"""
Create all spots content based on the build bundles.
All things will be done in the locale work folder.
"""
print(f"Creating spots", end="")
i = 0
for bundle in bundles:
i += 1
filename = os.path.join(WORK_DIR, SPOT_DIR, f"{bundle['image']['date']}.yml")
if (i % 2) == 0:
orient = "orient-left"
else:
orient = "orient-right"
# Get time range
oldest = bundle['image']['date']
for image in bundle['images']:
if image['date'] < oldest:
oldest = image['date']
start = datetime.strptime(oldest, "%Y%m%d")
end = datetime.strptime(bundle['image']['date'], "%Y%m%d")
diff = end.date() - start.date()
# Center
lon, lat = resolve_pos(bundle['x'], bundle['y'])
address = get_address(lon, lat)
print(f"address={address}")
# print(f"creating {filename}")
with open(filename, 'w') as file:
file.write(f"title: {bundle['image']['date'] }\n")
file.write(f"headerstyle: \"style1 {orient} content-align-left image-position-center onscroll-image-fade-in\"\n")
file.write(f"style: \"style2 medium lightbox onscroll-fade-in\"\n")
file.write(f"header: \"{IMAGE_ROOT_DIR}/{SVGS_DIR}/{bundle['image']['date']}.svg\"\n")
file.write(f"content: |\n")
file.write(f" &#10137; {address}<br>\n")
file.write(f" R = {bundle['radius']} m<br>\n")
file.write(f" &Delta; = {diff.days} Tage\n")
file.write(f"circle:\n")
file.write(f" - pos: \"({bundle['x']}, {bundle['y']})\"\n")
file.write(f" radius: \"{bundle['radius']}\"\n")
file.write(f"pictures:\n")
write_picture_yaml(file, bundle['image'])
for image in bundle['images']:
write_picture_yaml(file, image)
print(f".", end="")
print(f" OK {len(bundles)} files created.")
def write_picture_yaml(file, image):
if 'title' in image['tags']:
log(f"write_picture_yaml {image['date']} title={image['tags']['title']}")
file.write(f" - title: \"{image['tags']['title']}\"\n")
file.write(f" subtitle: \"{image['date']}\"\n")
else:
file.write(f" - title: \"{image['date']}\"\n")
file.write(f" content: \"distance={image['dist']} m\"\n")
file.write(f" distance: \"{image['dist']}\"\n")
file.write(f" geo: \"{image['lon']}, {image['lat']}\"\n")
file.write(f" pos: \"({str(image['x'])}, {str(image['y'])})\"\n")
file.write(f" image: \"{os.path.join(IMAGE_ROOT_DIR, FULLS_DIR, image['name'])}\"\n")
file.write(f" thumb: \"{os.path.join(IMAGE_ROOT_DIR, THUMBS_DIR, image['name'])}\"\n")
file.write(f" button: \"Ansehen\"\n")
def activate():
"""
Active spots incl images from work folder to the hugo project.
Old spots will be removed.
This should only be processed in success case.
"""
print(f"Update hugo content", end="")
spot_dir = os.path.join(HUGO_ROOT, SPOT_DIR)
image_root_dir = os.path.join(HUGO_STATIC_DIR, IMAGE_ROOT_DIR)
thumbs_dir = os.path.join(image_root_dir, THUMBS_DIR)
fulls_dir = os.path.join(image_root_dir, FULLS_DIR)
svgs_dir = os.path.join(image_root_dir, SVGS_DIR)
if os.path.isdir(spot_dir):
shutil.rmtree(spot_dir)
shutil.copytree(os.path.join(WORK_DIR, SPOT_DIR), spot_dir)
if not os.path.isdir(image_root_dir):
os.makedirs(image_root_dir)
if os.path.isdir(svgs_dir):
shutil.rmtree(svgs_dir)
shutil.copytree(os.path.join(WORK_DIR, IMAGE_ROOT_DIR, SVGS_DIR), svgs_dir)
if os.path.isdir(thumbs_dir):
shutil.rmtree(thumbs_dir)
shutil.copytree(os.path.join(WORK_DIR, IMAGE_ROOT_DIR, THUMBS_DIR), thumbs_dir)
if os.path.isdir(fulls_dir):
shutil.rmtree(fulls_dir)
shutil.copytree(os.path.join(WORK_DIR, IMAGE_ROOT_DIR, FULLS_DIR), fulls_dir)
print("...done")
def log(message, end="\n", flush=False):
if args.verbose:
print(message, end=end, flush=flush)
def init_work():
"""
Setup working directory. This should be the very first step.
Fulls and thumbs directories will only be cleared with reset argument .
"""
log(f"Initialize directories")
# The very firs time
if not os.path.exists(DROPIN_DIR):
print(f"Creating missing directory '{DROPIN_DIR}'")
os.mkdir(DROPIN_DIR)
if not os.path.exists(IMAGES_DIR):
print(f"Creating missing directory '{IMAGES_DIR}'")
os.mkdir(IMAGES_DIR)
if not os.path.exists(WORK_DIR):
print(f"Creating missing directory structure '{WORK_DIR}'")
os.mkdir(WORK_DIR)
fulls = os.path.join(WORK_DIR, IMAGE_ROOT_DIR, FULLS_DIR)
if args.rebuild_all and os.path.exists(fulls):
print(f"Removing {fulls}")
shutil.rmtree(fulls)
# The very firs time or in case of a rebuild all
if not os.path.exists(fulls):
os.makedirs(fulls)
thumbs = os.path.join(WORK_DIR, IMAGE_ROOT_DIR, THUMBS_DIR)
if args.rebuild_all and os.path.exists(thumbs):
print(f"Removing {thumbs}")
shutil.rmtree(thumbs)
# The very first time or in case of a rebuild all
if not os.path.exists(thumbs):
log(f"Creating {thumbs}")
os.makedirs(thumbs)
# Reset always
svgs = os.path.join(WORK_DIR, IMAGE_ROOT_DIR, SVGS_DIR)
if os.path.isdir(svgs):
log(f"Clearing {svgs}")
shutil.rmtree(svgs)
os.makedirs(svgs)
# Reset always
spot = os.path.join(WORK_DIR, SPOT_DIR)
if os.path.isdir(spot):
log(f"Clearing {spot}")
shutil.rmtree(spot)
os.makedirs(spot)
# Rebuild all: move existing original images to dropin
if args.rebuild_all:
p = re.compile('\d{8}.*\.(jpg|jpeg)', re.IGNORECASE)
old_files = [f for f in os.listdir(IMAGES_DIR)
if os.path.isfile(os.path.join(IMAGES_DIR, f)) and
p.match(f)]
if len(old_files) == 0:
print(f"No files im {IMAGES_DIR}")
else:
print(f"Moving {len(old_files)} files from {IMAGES_DIR} to {DROPIN_DIR}", end="")
for file in old_files:
shutil.move(os.path.join(IMAGES_DIR, file), os.path.join(DROPIN_DIR, file))
log("..done")
log("Initialization done")
def exit_on_error(message):
print(f"ERROR {message}")
exit(1)
def exit_with_good_bye(message):
print(f"{message} --- Good bye ---")
exit(0)
def warn(message):
print(f"WARN {message}")
def do_it():
init_work()
process_images()
create_bundles()
create_svgs()
create_banner_svg()
create_spots()
activate()
print("Congratulations! Generation done.")
def parse_args():
global args
parser = argparse.ArgumentParser(description="Update drs by adding new images and create spot files. " +
"This script must be called from its directory 'redaktion'. Usage example: Add new images into ../../dropin directory and call without parameters. This images will be moved to ../../images. ")
parser.add_argument("-v", "--verbose", action="store_true",
help="Increase output verbosity.")
parser.add_argument("-a", "--rebuild_all", action="store_true",
help="Process images in /images in additional to the /dropin images")
parser.add_argument("-l", "--location_mockup", action="store_true",
help="Supress cost intensive location service. Mock all locations. Just for developer purposes.")
args = parser.parse_args()
if __name__ == '__main__':
parse_args()
do_it()

4
redaktion/resources.txt

@ -0,0 +1,4 @@
defusedxml==0.7.1
geographiclib==1.52
geopy==2.2.0
Pillow==8.4.0

22
redaktion/test.sh

@ -0,0 +1,22 @@
#!/bin/sh
set -x;
GENDIR=~/dierundestundegen
TMPGIT_POSTS=$GENDIR/drs-posts
GIT_POSTS=https://kollegen.uber.space/gitea/dierundestunde/drs-posts.git
# For the very first time: create dir
if [ ! -d $TMPGIT_POSTS ]
then
mkdir -v $TMPGIT_POSTS
fi
# Check, if there is really the repro inside
if [ ! -d $TMPGIT_POSTS/.git ]
then
# jetzt clonen wir das Repository in den temporären Ordner
git clone $GIT_POSTS $TMPGIT_POSTS 2>&1 | tee -a $LOG
else
env -i git -C $TMPGIT_POSTS pull 2>&1 | tee -a $LOG
fi

10
redaktion/test.svg

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1000 1000"
xml:space="preserve">
<circle cx="500" cy="500" r="400" fill="#eee0ee"> </circle>
<circle cx="500" cy="500" r="10" fill="#ffffff"> </circle>
<circle cx="241" cy="200" r="27" fill="#ff0fff"> </circle>
</svg>

After

Width:  |  Height:  |  Size: 483 B

68
redaktion/upload.sh

@ -0,0 +1,68 @@
#!/bin/bash
# Upload jpeg images from the give directory to the uberspace host.
# All images will be resized first, copied and then hugo generation will be started.
# Login will be done with ssh, so key must be installed for the
# executing system: See https://dashboard.uberspace.de/dashboard/authentication
# case in-sensitive matching
shopt -s nocaseglob
if [ -z "$1" ]
then
echo "Uploder for drs - Die Runde Stunde - to Uberspace"
echo "Usage:"
echo " upload <SORUCE_DIR>"
echo "SOURCE_DIR is a locale directory with jpg image file(s) (must end with case insensitive jpg or jpeg). All images will be resized and then copied to uberspace. Then the Hugo generation will be triggered."
exit 1
fi
if [[ ! -d "$1" ]]
then
echo "'$1' seems not to be an existing directory on your filesystem."
exit 1
fi
# We take all image files from the particular directory (no sub dir)...
count="$(find $1 -maxdepth 1 -iregex '.*\.jpe?g' | wc -l)"
if [[ $count == 0 ]]
then
echo "No jpg file found!"
exit 1
fi
echo "Found $count image(s) on $1"
# Create a temporary directory and store its name in a variable ...
TMPDIR=$(mktemp -d)
# Bail out if the temp directory wasn't created successfully.
if [ ! -e $TMPDIR ]; then
>&2 echo "Failed to create temp directory"
exit 1
fi
echo "Using temp dir: $TMPDIR"
# Make sure it gets removed even if the script exits abnormally.
trap "exit 1" HUP INT PIPE QUIT TERM
trap 'rm -rf "$TMPDIR"' EXIT
echo "Rezising image(s)"
# Copy and resize original images, we want to upload smaller files to uberspace
FILES=$(find "$1" -iregex '.*\.jpe?g')
for FILE in $FILES; do
convert "$FILE" -resize 1900x "$TMPDIR"/$(basename "$FILE")
done
HOST=kollegen@despina.uberspace.de
DESTDIR=/home/kollegen/dierundestundegen/dropin
echo "Uploading to $HOST/$DESTIDR"
rsync -v $TMPDIR/* $HOST:$DESTDIR
echo Generate content on uberspace
ssh kollegen@despina.uberspace.de 'cd dierundestundegen/dierundestunde/redaktion && venv/bin/python ~/dierundestundegen/dierundestunde/redaktion/generate_content.py && ~/dierundestundegen/dierundestunde/redaktion/generate.sh'
echo Done.

BIN
static/images/instagram.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
static/images/pic_rss.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
static/rss/rss-1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
static/rss/rss-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

22
static/rss/rss.xml

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>Die Runde Stunde</title>
<link>https://kollegen.uber.space/dierundestunde/</link>
<description>Die Runde Stunde. Bilder aus dem Radius.</description>
<image>
<url>https://kollegen.uber.space/dierundestunde/rss/rss-1.png</url>
<title>Die Runde Stunde</title>
<link>https://kollegen.uber.space/dierundestunde/</link>
</image>
<item>
<title>Zu guter Erst</title>
<link>https://kollegen.uber.space/dierundestunde/#first</link>
<description>Die Runde Stunde geht online. In dem Post wird erklärt,
warum man während des morgentlichen Workouts Fotos machen sollte und wie jedes Bild
das Album verändert. </description>
</item>
</channel>
</rss>

3
themes/hugo-story/LICENSE

@ -0,0 +1,3 @@
# License
The Hugo Story theme is licensed under the [Creative Commons Attribution 3.0 License](https://creativecommons.org/licenses/by/3.0/).

98
themes/hugo-story/README.md

@ -0,0 +1,98 @@
# Hugo Story
## A (modular, highly tweakable) responsive one-page theme for Hugo.
![](images/device-screenshots.png)
Hugo Story is a port of the static HTML template Story by HTML5 UP. It is designed to mirror the look and feel of the original template as closely as possible while incorporating some of the features Hugo has to offer.
This theme is designed for those who are comfortable editing HTML and integrating Hugo short codes and variables to customize the theme to their liking.
## Features
- Minimalist Design
- Fully Responsive
- Templates
- Header
- Footer
- FootScripts
- Favicon
- Partials for each element type
- Banner
- Spotlight
- Gallery
- Items
- Image gallery
- Short Codes
- Site Title
- Site Subtitle
- Site Logo
- Social Icons
- Favicon and Social icons
- FontAwesome Icon Support
- SASS and AutoMinify Support
- Google Analytics Support
## Demo
https://caressofsteel.github.io/demos/hugo/hugo-story/
## Using
### 1. Install Hugo
[Install Hugo (Extended Version)](https://gohugo.io/overview/installing/)
> _This theme uses Hugo Pipes to compile SCSS & Sass so you'll have to use the **extended** version of Hugo. See the official [Hugo Quick Start Guide](https://gohugo.io/getting-started/quick-start/) for more information._
### 2. Create a new site
```
hugo new site story-examplesite
```
### 3. Clone this Git repository
```
cd story-examplesite
git submodule add https://github.com/caressofsteel/hugo-story.git themes/hugo-story
```
> _Hint: See a note for non-Git users [here](https://gohugo.io/getting-started/quick-start/#step-3-add-a-theme)._
### 4. Copy `data` and `config.toml` with overwrite from `exampleSite`
```
cp -r themes/hugo-story/exampleSite/data ./
cp themes/hugo-story/exampleSite/config.toml ./
```
> _Hint: Using `config.toml` tells Hugo to use the theme and sets some basic theme parameters._
> _Hint: Using `data` provides default content for the site._
### 5. Start Hugo Server
```
hugo server
```
### 6. Open Hugo Server in your browser
```
http://localhost:1313/
```
Here you'll see the site running on the local Hugo server. You can now make changes to and Hugo will rebuild the site automatically.
> _Hint: A copy of the default generated site is located in the _`originalStorySite`_ folder should you need to reference it._
### 7. Further steps
- Change the contents of `YML` files in the `data` folder.
- _Altering `banner.yml` will change the top block on the site. See more details [here](https://gohugo.io/templates/data-templates/)._
- Create a custom site layout.
- Copy the default `index.html`.
```
cp themes/hugo-story/layouts/index.html layouts/
```
- By manipulating the the `{{ partial ... }}` tags within this file you can create a custom layout for the site. See more details [here](https://gohugo.io/templates/partials/).
- Continue exploring Hugo and the template!
## Credits
This theme was created using the _Story_ template by [HTML5 UP](https://html5up.net/uploads/demos/story/).
## License
<a rel="license" href="http://creativecommons.org/licenses/by/3.0/" class="license-button"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/3.0/88x31.png"></a>
This Hugo theme is licensed under the [Creative Commons Attribution 3.0 License](LICENSE).

5
themes/hugo-story/assets/css/fontawesome-all.min.css vendored

File diff suppressed because one or more lines are too long

1
themes/hugo-story/assets/css/main.css

File diff suppressed because one or more lines are too long

314
themes/hugo-story/assets/css/noscript.css

@ -0,0 +1,314 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Banner (transitions) */
.banner.onload-content-fade-up .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-content-fade-up .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onload-content-fade-down .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-content-fade-down .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onload-content-fade-left .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-content-fade-left .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onload-content-fade-right .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-content-fade-right .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onload-content-fade-in .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-content-fade-in .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onload-image-fade-up .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onload-image-fade-up .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-image-fade-up .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
body.is-preload .banner.onload-image-fade-up .image img {
opacity: 1; }
.banner.onload-image-fade-down .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onload-image-fade-down .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-image-fade-down .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
body.is-preload .banner.onload-image-fade-down .image img {
opacity: 1; }
.banner.onload-image-fade-left .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onload-image-fade-left .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-image-fade-left .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
body.is-preload .banner.onload-image-fade-left .image img {
opacity: 1; }
.banner.onload-image-fade-right .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onload-image-fade-right .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-image-fade-right .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
body.is-preload .banner.onload-image-fade-right .image img {
opacity: 1; }
.banner.onload-image-fade-in .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
body.is-preload .banner.onload-image-fade-in .image img {
opacity: 1; }
.banner.onscroll-content-fade-up .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-content-fade-up.is-inactive .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-content-fade-down .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-content-fade-down.is-inactive .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-content-fade-left .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-content-fade-left.is-inactive .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-content-fade-right .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-content-fade-right.is-inactive .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-content-fade-in .content {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-content-fade-in.is-inactive .content {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-image-fade-up .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-up .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-up.is-inactive .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-image-fade-up.is-inactive .image img {
opacity: 1; }
.banner.onscroll-image-fade-down .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-down .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-down.is-inactive .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-image-fade-down.is-inactive .image img {
opacity: 1; }
.banner.onscroll-image-fade-left .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-left .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-left.is-inactive .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-image-fade-left.is-inactive .image img {
opacity: 1; }
.banner.onscroll-image-fade-right .image {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-right .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-right.is-inactive .image {
-moz-transform: none;
-webkit-transform: none;
-ms-transform: none;
transform: none;
opacity: 1; }
.banner.onscroll-image-fade-right.is-inactive .image img {
opacity: 1; }
.banner.onscroll-image-fade-in .image img {
-moz-transition: none;
-webkit-transition: none;
-ms-transition: none;
transition: none; }
.banner.onscroll-image-fade-in.is-inactive .image img {
opacity: 1; }

2
themes/hugo-story/assets/js/breakpoints.min.js vendored

@ -0,0 +1,2 @@
/* breakpoints.js v1.0 | @ajlkn | MIT licensed */
var breakpoints=function(){"use strict";function e(e){t.init(e)}var t={list:null,media:{},events:[],init:function(e){t.list=e,window.addEventListener("resize",t.poll),window.addEventListener("orientationchange",t.poll),window.addEventListener("load",t.poll),window.addEventListener("fullscreenchange",t.poll)},active:function(e){var n,a,s,i,r,d,c;if(!(e in t.media)){if(">="==e.substr(0,2)?(a="gte",n=e.substr(2)):"<="==e.substr(0,2)?(a="lte",n=e.substr(2)):">"==e.substr(0,1)?(a="gt",n=e.substr(1)):"<"==e.substr(0,1)?(a="lt",n=e.substr(1)):"!"==e.substr(0,1)?(a="not",n=e.substr(1)):(a="eq",n=e),n&&n in t.list)if(i=t.list[n],Array.isArray(i)){if(r=parseInt(i[0]),d=parseInt(i[1]),isNaN(r)){if(isNaN(d))return;c=i[1].substr(String(d).length)}else c=i[0].substr(String(r).length);if(isNaN(r))switch(a){case"gte":s="screen";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: -1px)";break;case"not":s="screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (max-width: "+d+c+")"}else if(isNaN(d))switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen";break;case"gt":s="screen and (max-width: -1px)";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+")";break;default:s="screen and (min-width: "+r+c+")"}else switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+"), screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (min-width: "+r+c+") and (max-width: "+d+c+")"}}else s="("==i.charAt(0)?"screen and "+i:i;t.media[e]=!!s&&s}return t.media[e]!==!1&&window.matchMedia(t.media[e]).matches},on:function(e,n){t.events.push({query:e,handler:n,state:!1}),t.active(e)&&n()},poll:function(){var e,n;for(e=0;e<t.events.length;e++)n=t.events[e],t.active(n.query)?n.state||(n.state=!0,n.handler()):n.state&&(n.state=!1)}};return e._=t,e.on=function(e,n){t.on(e,n)},e.active=function(e){return t.active(e)},e}();!function(e,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?module.exports=t():e.breakpoints=t()}(this,function(){return breakpoints});

2
themes/hugo-story/assets/js/browser.min.js vendored

@ -0,0 +1,2 @@
/* browser.js v1.0 | @ajlkn | MIT licensed */
var browser=function(){"use strict";var e={name:null,version:null,os:null,osVersion:null,touch:null,mobile:null,_canUse:null,canUse:function(n){e._canUse||(e._canUse=document.createElement("div"));var o=e._canUse.style,r=n.charAt(0).toUpperCase()+n.slice(1);return n in o||"Moz"+r in o||"Webkit"+r in o||"O"+r in o||"ms"+r in o},init:function(){var n,o,r,i,t=navigator.userAgent;for(n="other",o=0,r=[["firefox",/Firefox\/([0-9\.]+)/],["bb",/BlackBerry.+Version\/([0-9\.]+)/],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/],["opera",/OPR\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)/],["edge",/Edge\/([0-9\.]+)/],["safari",/Version\/([0-9\.]+).+Safari/],["chrome",/Chrome\/([0-9\.]+)/],["ie",/MSIE ([0-9]+)/],["ie",/Trident\/.+rv:([0-9]+)/]],i=0;i<r.length;i++)if(t.match(r[i][1])){n=r[i][0],o=parseFloat(RegExp.$1);break}for(e.name=n,e.version=o,n="other",o=0,r=[["ios",/([0-9_]+) like Mac OS X/,function(e){return e.replace("_",".").replace("_","")}],["ios",/CPU like Mac OS X/,function(e){return 0}],["wp",/Windows Phone ([0-9\.]+)/,null],["android",/Android ([0-9\.]+)/,null],["mac",/Macintosh.+Mac OS X ([0-9_]+)/,function(e){return e.replace("_",".").replace("_","")}],["windows",/Windows NT ([0-9\.]+)/,null],["bb",/BlackBerry.+Version\/([0-9\.]+)/,null],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/,null],["linux",/Linux/,null],["bsd",/BSD/,null],["unix",/X11/,null]],i=0;i<r.length;i++)if(t.match(r[i][1])){n=r[i][0],o=parseFloat(r[i][2]?r[i][2](RegExp.$1):RegExp.$1);break}e.os=n,e.osVersion=o,e.touch="wp"==e.os?navigator.msMaxTouchPoints>0:!!("ontouchstart"in window),e.mobile="wp"==e.os||"android"==e.os||"ios"==e.os||"bb"==e.os}};return e.init(),e}();!function(e,n){"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?module.exports=n():e.browser=n()}(this,function(){return browser});

562
themes/hugo-story/assets/js/demo.js

@ -0,0 +1,562 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
(function($) {
var $window = $(window);
// Styles.
$(
'<style>' +
'.demo-animate-all:not(.gallery), .demo-animate-all:not(.gallery) *, .demo-animate-all:not(.gallery) *:before, .demo-animate-all:not(.gallery) *:after { transition: all 0.5s ease-in-out; }' +
'.demo-controls .property .classes { display: none; }' +
'.demo-controls .property[data-requires] { display: none; }' +
'.demo-controls .property[data-requires].active { display: inline; }' +
'.demo-controls .property .tooltip { position: relative; }' +
'.demo-controls .property .tooltip:before { content: \'Click to change!\'; font-size: 0.7rem; position: absolute; bottom: 100%; left: 0; background: #47D3E5; color: #ffffff; line-height: 1; white-space: nowrap; font-weight: bold; border-radius: 0.125rem; padding: 0.325rem 0.425rem; animation: demo-controls-tooltip 1.5s forwards; animation-delay: 1s; opacity: 0; }' +
'.demo-controls .property .tooltip:after { content: \'\'; position: absolute; bottom: calc(100% - 0.25rem); left: 0.5rem; border-left: solid 0.5rem transparent; border-right: solid 0.5rem transparent; border-top: solid 0.5rem #47D3E5; width: 0.5rem; height: 0.5rem; animation: demo-controls-tooltip 1.5s forwards; animation-delay: 1s; opacity: 0; }' +
'@keyframes demo-controls-tooltip {' +
'0% { opacity: 0; transform: translateY(0); }' +
'10% { opacity: 1; transform: translateY(0.125rem); }' +
'20% { opacity: 1; transform: translateY(-0.125rem); }' +
'30% { opacity: 1; transform: translateY(0.125rem); }' +
'40% { opacity: 1; transform: translateY(-0.125rem); }' +
'50% { opacity: 1; transform: translateY(0.125rem); }' +
'60% { opacity: 1; transform: translateY(0); }' +
'90% { opacity: 1; }' +
'100% { opacity: 0; }' +
'}' +
'</style>'
).appendTo($('head'));
// Functions.
$.fn.demo_controls = function(styles, userOptions) {
var $this = $(this),
$styleProperty, $stylePropertyClasses,
$controls, $x, $y, $z,
options,
current, i, j, k, s, n, count;
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).demo_controls(styles, userOptions);
return $this;
}
// Options.
options = $.extend({
target: null,
palette: true
}, userOptions);
// Controls.
if (styles) {
$controls = $(
'<span class="demo-controls">' +
'<span class="property" data-name="style">' +
'<a href="#" class="title tooltip">style</a>' +
'<span class="classes"></span>' + (options.palette ? ', ' : ' ') +
'</span>' +
(options.palette ?
'<span class="property active" data-name="scheme">' +
'<a href="#" class="title">scheme</a>' +
'<span class="classes">' +
'<span data-class="-" class="active">default</span>' +
'<span data-class="invert">invert</span>' +
'</span>, ' +
'</span>' +
'<span class="property active" data-name="color">' +
'<a href="#" class="title">color</a>' +
'<span class="classes">' +
'<span data-class="-" class="active">default</span>' +
'<span data-class="color1">color1</span>' +
'<span data-class="color2">color2</span>' +
'<span data-class="color3">color3</span>' +
'<span data-class="color4">color4</span>' +
'<span data-class="color5">color5</span>' +
'<span data-class="color6">color6</span>' +
'<span data-class="color7">color7</span>' +
'</span>, ' +
'</span>'
: '') +
'</span>'
);
}
else {
$controls = $(
'<span class="demo-controls">' +
(options.palette ?
'<span class="property active" data-name="scheme">' +
'<a href="#" class="title">scheme</a>' +
'<span class="classes">' +
'<span data-class="-" class="active">default</span>' +
'<span data-class="invert">invert</span>' +
'</span> and ' +
'</span>' +
'<span class="property active" data-name="color">' +
'<a href="#" class="title">color</a>' +
'<span class="classes">' +
'<span data-class="-" class="active">default</span>' +
'<span data-class="color1">color1</span>' +
'<span data-class="color2">color2</span>' +
'<span data-class="color3">color3</span>' +
'<span data-class="color4">color4</span>' +
'<span data-class="color5">color5</span>' +
'<span data-class="color6">color6</span>' +
'<span data-class="color7">color7</span>' +
'</span>' +
'</span>'
: '') +
'</span>'
);
}
// Target.
switch (options.target) {
case 'previous':
$this.prev().find('.demo-controls').replaceWith($controls);
break;
default:
$this.find('.demo-controls').replaceWith($controls);
break;
}
// Styles.
if (styles) {
$styleProperty = $controls.find('.property[data-name="style"]');
$stylePropertyClasses = $styleProperty.children('.classes');
for (i in styles) {
current = false;
count = Object.keys(styles[i]).length;
n = 1;
// Add to style property.
$x = $('<span data-class="' + i + '">, ' + i + '</span>')
.appendTo($stylePropertyClasses);
if ($this.hasClass(i)) {
$x.addClass('active');
current = true;
}
// Step through properties.
for (j in styles[i]) {
$x = $(
'<span class="property" data-name="' + j + '" data-requires="' + i + '">' +
(n == count ? '<span>and </span>' : '') +
'<a href="#" class="title">' + j + '</a>' +
'<span class="classes">' +
'</span>' + (n < count ? ', ' : '') +
'</span>'
).appendTo($controls);
$y = $x.children('.classes');
if (current)
$x.addClass('active');
for (k in styles[i][j]) {
$z = $('<span data-class="' + k + '">, ' + styles[i][j][k].replace('*', '') + '</span>')
.appendTo($y);
if (styles[i][j][k].substr(-1, 1) == '*')
$z.addClass('default');
if (current
&& $this.hasClass(k))
$z.addClass('active');
}
n++;
}
}
}
// Events.
$controls.on('click', 'a', function(event) {
event.preventDefault();
});
$controls.on('click', '.property.active', function(event) {
var $property = $(this);
var $classes = $property.find('.classes > *');
var $current = $classes.filter('.active');
var $next;
// Determine next.
if ($current.length == 0
|| $current.index() == $classes.length - 1)
$next = $classes.first();
else
$next = $current.next();
// Turn on animate all.
$this.addClass('demo-animate-all');
// Deactivate current.
$current.removeClass('active');
$this.removeClass($current.data('class'));
// Activate next.
$next.addClass('active');
$this.addClass($next.data('class'));
// Turn off animate all.
setTimeout(function() {
$this.removeClass('demo-animate-all');
}, 500);
});
$controls.on('click', '.property[data-name="style"]', function(event) {
var $property = $(this);
var $classes = $property.find('.classes > *');
var $current = $classes.filter('.active');
var $next;
// Determine next.
if ($current.length == 0
|| $current.index() == $classes.length - 1)
$next = $classes.first();
else
$next = $current.next();
// Turn on animate all.
$this.addClass('demo-animate-all');
// Deactivate current.
$current.removeClass('active');
$this.removeClass($current.data('class'));
$controls.find('.property[data-requires="' + $current.data('class') + '"]')
.removeClass('active');
$controls.find('.property[data-requires="' + $current.data('class') + '"] > .classes > .active').each(function() {
$(this).removeClass('active');
if ($(this).data('class') != '-')
$this.removeClass($(this).data('class'));
});
// Activate next.
$next.addClass('active');
$this.addClass($next.data('class'));
$controls.find('.property[data-requires="' + $next.data('class') + '"]')
.addClass('active');
$controls.find('.property[data-requires="' + $next.data('class') + '"] > .classes > .default').each(function() {
$(this).addClass('active');
if ($(this).data('class') != '-')
$this.addClass($(this).data('class'));
});
// Turn off animate all.
setTimeout(function() {
$this.removeClass('demo-animate-all');
}, 500);
});
};
// Elements.
// Wrappers.
$('.wrapper').demo_controls(null, {
palette: true
});
// Banner.
$('.banner').demo_controls({
style1: {
'size': {
'-': 'normal',
'fullscreen': 'fullscreen*'
},
'orientation': {
'orient-left': 'left*',
'orient-right': 'right'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
style2: {
'size': {
'-': 'normal',
'fullscreen': 'fullscreen*'
},
'orientation': {
'orient-left': 'left',
'orient-center': 'center*',
'orient-right': 'right'
},
'content alignment': {
'content-align-left': 'left',
'content-align-center': 'center*',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
style3: {
'size': {
'-': 'normal',
'fullscreen': 'fullscreen*'
},
'orientation': {
'orient-left': 'left',
'orient-right': 'right*'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
style4: {
'size': {
'-': 'normal',
'fullscreen': 'fullscreen*'
},
'phone type': {
'iphone': 'iphone*',
'android': 'android'
},
'orientation': {
'orient-left': 'left',
'orient-right': 'right*'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
style5: {
'size': {
'-': 'normal',
'fullscreen': 'fullscreen*'
},
'content alignment': {
'content-align-left': 'left',
'content-align-center': 'center*',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
}
});
// Spotlight.
$('.spotlight').demo_controls({
style1: {
'orientation': {
'orient-left': 'left',
'orient-right': 'right*'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left*',
'image-position-center': 'center',
'image-position-right': 'right'
}
},
style2: {
'orientation': {
'orient-left': 'left',
'orient-right': 'right*'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
style3: {
'phone type': {
'iphone': 'iphone*',
'android': 'android'
},
'orientation': {
'orient-left': 'left',
'orient-right': 'right*'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
style4: {
'size': {
'-size': 'normal',
'fullscreen': 'fullscreen*',
'halfscreen': 'halfscreen'
},
'orientation': {
'orient-left': 'left*',
'orient-center': 'center',
'orient-right': 'right'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
style5: {
'size': {
'-size': 'normal',
'fullscreen': 'fullscreen*',
'halfscreen': 'halfscreen'
},
'orientation': {
'orient-left': 'left*',
'orient-center': 'center',
'orient-right': 'right'
},
'content alignment': {
'content-align-left': 'left*',
'content-align-center': 'center',
'content-align-right': 'right'
},
'image position': {
'image-position-left': 'left',
'image-position-center': 'center*',
'image-position-right': 'right'
}
},
});
// Gallery.
$('.gallery').demo_controls({
style1: {
'size': {
'small': 'small',
'medium': 'medium*',
'big': 'big'
}
},
style2: {
'size': {
'small': 'small',
'medium': 'medium*',
'big': 'big'
}
},
}, {
target: 'previous',
palette: false
});
// Items.
$('.items').demo_controls({
style1: {
'size': {
'small': 'small',
'medium': 'medium*',
'big': 'big'
}
},
style2: {
'size': {
'small': 'small',
'medium': 'medium*',
'big': 'big'
}
},
style3: {
'size': {
'small': 'small',
'medium': 'medium*',
'big': 'big'
}
}
}, {
target: 'previous',
palette: false
});
})(jQuery);

2
themes/hugo-story/assets/js/jquery.min.js vendored

File diff suppressed because one or more lines are too long

2
themes/hugo-story/assets/js/jquery.scrollex.min.js vendored

@ -0,0 +1,2 @@
/* jquery.scrollex v0.2.1 | (c) @ajlkn | github.com/ajlkn/jquery.scrollex | MIT licensed */
!function(t){function e(t,e,n){return"string"==typeof t&&("%"==t.slice(-1)?t=parseInt(t.substring(0,t.length-1))/100*e:"vh"==t.slice(-2)?t=parseInt(t.substring(0,t.length-2))/100*n:"px"==t.slice(-2)&&(t=parseInt(t.substring(0,t.length-2)))),t}var n=t(window),i=1,o={};n.on("scroll",function(){var e=n.scrollTop();t.map(o,function(t){window.clearTimeout(t.timeoutId),t.timeoutId=window.setTimeout(function(){t.handler(e)},t.options.delay)})}).on("load",function(){n.trigger("scroll")}),jQuery.fn.scrollex=function(l){var s=t(this);if(0==this.length)return s;if(this.length>1){for(var r=0;r<this.length;r++)t(this[r]).scrollex(l);return s}if(s.data("_scrollexId"))return s;var a,u,h,c,p;switch(a=i++,u=jQuery.extend({top:0,bottom:0,delay:0,mode:"default",enter:null,leave:null,initialize:null,terminate:null,scroll:null},l),u.mode){case"top":h=function(t,e,n,i,o){return t>=i&&o>=t};break;case"bottom":h=function(t,e,n,i,o){return n>=i&&o>=n};break;case"middle":h=function(t,e,n,i,o){return e>=i&&o>=e};break;case"top-only":h=function(t,e,n,i,o){return i>=t&&n>=i};break;case"bottom-only":h=function(t,e,n,i,o){return n>=o&&o>=t};break;default:case"default":h=function(t,e,n,i,o){return n>=i&&o>=t}}return c=function(t){var i,o,l,s,r,a,u=this.state,h=!1,c=this.$element.offset();i=n.height(),o=t+i/2,l=t+i,s=this.$element.outerHeight(),r=c.top+e(this.options.top,s,i),a=c.top+s-e(this.options.bottom,s,i),h=this.test(t,o,l,r,a),h!=u&&(this.state=h,h?this.options.enter&&this.options.enter.apply(this.element):this.options.leave&&this.options.leave.apply(this.element)),this.options.scroll&&this.options.scroll.apply(this.element,[(o-r)/(a-r)])},p={id:a,options:u,test:h,handler:c,state:null,element:this,$element:s,timeoutId:null},o[a]=p,s.data("_scrollexId",p.id),p.options.initialize&&p.options.initialize.apply(this),s},jQuery.fn.unscrollex=function(){var e=t(this);if(0==this.length)return e;if(this.length>1){for(var n=0;n<this.length;n++)t(this[n]).unscrollex();return e}var i,l;return(i=e.data("_scrollexId"))?(l=o[i],window.clearTimeout(l.timeoutId),delete o[i],e.removeData("_scrollexId"),l.options.terminate&&l.options.terminate.apply(this),e):e}}(jQuery);

2
themes/hugo-story/assets/js/jquery.scrolly.min.js vendored

@ -0,0 +1,2 @@
/* jquery.scrolly v1.0.0-dev | (c) @ajlkn | MIT licensed */
(function(e){function u(s,o){var u,a,f;if((u=e(s))[t]==0)return n;a=u[i]()[r];switch(o.anchor){case"middle":f=a-(e(window).height()-u.outerHeight())/2;break;default:case r:f=Math.max(a,0)}return typeof o[i]=="function"?f-=o[i]():f-=o[i],f}var t="length",n=null,r="top",i="offset",s="click.scrolly",o=e(window);e.fn.scrolly=function(i){var o,a,f,l,c=e(this);if(this[t]==0)return c;if(this[t]>1){for(o=0;o<this[t];o++)e(this[o]).scrolly(i);return c}l=n,f=c.attr("href");if(f.charAt(0)!="#"||f[t]<2)return c;a=jQuery.extend({anchor:r,easing:"swing",offset:0,parent:e("body,html"),pollOnce:!1,speed:1e3},i),a.pollOnce&&(l=u(f,a)),c.off(s).on(s,function(e){var t=l!==n?l:u(f,a);t!==n&&(e.preventDefault(),a.parent.stop().animate({scrollTop:t},a.speed,a.easing))})}})(jQuery);

342
themes/hugo-story/assets/js/main.js

@ -0,0 +1,342 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
(function($) {
var $window = $(window),
$body = $('body'),
$wrapper = $('#wrapper');
// Breakpoints.
breakpoints({
xlarge: [ '1281px', '1680px' ],
large: [ '981px', '1280px' ],
medium: [ '737px', '980px' ],
small: [ '481px', '736px' ],
xsmall: [ '361px', '480px' ],
xxsmall: [ null, '360px' ]
});
// Play initial animations on page load.
$window.on('load', function() {
window.setTimeout(function() {
$body.removeClass('is-preload');
}, 100);
});
// Browser fixes.
// IE: Flexbox min-height bug.
if (browser.name == 'ie')
(function() {
var flexboxFixTimeoutId;
$window.on('resize.flexbox-fix', function() {
var $x = $('.fullscreen');
clearTimeout(flexboxFixTimeoutId);
flexboxFixTimeoutId = setTimeout(function() {
if ($x.prop('scrollHeight') > $window.height())
$x.css('height', 'auto');
else
$x.css('height', '100vh');
}, 250);
}).triggerHandler('resize.flexbox-fix');
})();
// Object fit workaround.
if (!browser.canUse('object-fit'))
(function() {
$('.banner .image, .spotlight .image').each(function() {
var $this = $(this),
$img = $this.children('img'),
positionClass = $this.parent().attr('class').match(/image-position-([a-z]+)/);
// Set image.
$this
.css('background-image', 'url("' + $img.attr('src') + '")')
.css('background-repeat', 'no-repeat')
.css('background-size', 'cover');
// Set position.
switch (positionClass.length > 1 ? positionClass[1] : '') {
case 'left':
$this.css('background-position', 'left');
break;
case 'right':
$this.css('background-position', 'right');
break;
default:
case 'center':
$this.css('background-position', 'center');
break;
}
// Hide original.
$img.css('opacity', '0');
});
})();
// Smooth scroll.
$('.smooth-scroll').scrolly();
$('.smooth-scroll-middle').scrolly({ anchor: 'middle' });
// Wrapper.
$wrapper.children()
.scrollex({
top: '30vh',
bottom: '30vh',
initialize: function() {
$(this).addClass('is-inactive');
},
terminate: function() {
$(this).removeClass('is-inactive');
},
enter: function() {
$(this).removeClass('is-inactive');
},
leave: function() {
var $this = $(this);
if ($this.hasClass('onscroll-bidirectional'))
$this.addClass('is-inactive');
}
});
// Items.
$('.items')
.scrollex({
top: '30vh',
bottom: '30vh',
delay: 50,
initialize: function() {
$(this).addClass('is-inactive');
},
terminate: function() {
$(this).removeClass('is-inactive');
},
enter: function() {
$(this).removeClass('is-inactive');
},
leave: function() {
var $this = $(this);
if ($this.hasClass('onscroll-bidirectional'))
$this.addClass('is-inactive');
}
})
.children()
.wrapInner('<div class="inner"></div>');
// Gallery.
$('.gallery')
.wrapInner('<div class="inner"></div>')
.prepend(browser.mobile ? '' : '<div class="forward"></div><div class="backward"></div>')
.scrollex({
top: '30vh',
bottom: '30vh',
delay: 50,
initialize: function() {
$(this).addClass('is-inactive');
},
terminate: function() {
$(this).removeClass('is-inactive');
},
enter: function() {
$(this).removeClass('is-inactive');
},
leave: function() {
var $this = $(this);
if ($this.hasClass('onscroll-bidirectional'))
$this.addClass('is-inactive');
}
})
.children('.inner')
//.css('overflow', 'hidden')
.css('overflow-y', browser.mobile ? 'visible' : 'hidden')
.css('overflow-x', browser.mobile ? 'scroll' : 'hidden')
.scrollLeft(0);
// Style #1.
// ...
// Style #2.
$('.gallery')
.on('wheel', '.inner', function(event) {
var $this = $(this),
delta = (event.originalEvent.deltaX * 10);
// Cap delta.
if (delta > 0)
delta = Math.min(25, delta);
else if (delta < 0)
delta = Math.max(-25, delta);
// Scroll.
$this.scrollLeft( $this.scrollLeft() + delta );
})
.on('mouseenter', '.forward, .backward', function(event) {
var $this = $(this),
$inner = $this.siblings('.inner'),
direction = ($this.hasClass('forward') ? 1 : -1);
// Clear move interval.
clearInterval(this._gallery_moveIntervalId);
// Start interval.
this._gallery_moveIntervalId = setInterval(function() {
$inner.scrollLeft( $inner.scrollLeft() + (5 * direction) );
}, 10);
})
.on('mouseleave', '.forward, .backward', function(event) {
// Clear move interval.
clearInterval(this._gallery_moveIntervalId);
});
// Lightbox.
$('.gallery.lightbox')
.on('click', 'a', function(event) {
var $a = $(this),
$gallery = $a.parents('.gallery'),
$modal = $gallery.children('.modal'),
$modalImg = $modal.find('img'),
href = $a.attr('href');
// Not an image? Bail.
if (!href.match(/\.(jpg|gif|png|mp4)$/))
return;
// Prevent default.
event.preventDefault();
event.stopPropagation();
// Locked? Bail.
if ($modal[0]._locked)
return;
// Lock.
$modal[0]._locked = true;
// Set src.
$modalImg.attr('src', href);
// Set visible.
$modal.addClass('visible');
// Focus.
$modal.focus();
// Delay.
setTimeout(function() {
// Unlock.
$modal[0]._locked = false;
}, 600);
})
.on('click', '.modal', function(event) {
var $modal = $(this),
$modalImg = $modal.find('img');
// Locked? Bail.
if ($modal[0]._locked)
return;
// Already hidden? Bail.
if (!$modal.hasClass('visible'))
return;
// Lock.
$modal[0]._locked = true;
// Clear visible, loaded.
$modal
.removeClass('loaded')
// Delay.
setTimeout(function() {
$modal
.removeClass('visible')
setTimeout(function() {
// Clear src.
$modalImg.attr('src', '');
// Unlock.
$modal[0]._locked = false;
// Focus.
$body.focus();
}, 475);
}, 125);
})
.on('keypress', '.modal', function(event) {
var $modal = $(this);
// Escape? Hide modal.
if (event.keyCode == 27)
$modal.trigger('click');
})
.prepend('<div class="modal" tabIndex="-1"><div class="inner"><img src="" /></div></div>')
.find('img')
.on('load', function(event) {
var $modalImg = $(this),
$modal = $modalImg.parents('.modal');
setTimeout(function() {
// No longer visible? Bail.
if (!$modal.hasClass('visible'))
return;
// Set loaded.
$modal.addClass('loaded');
}, 275);
});
})(jQuery);

587
themes/hugo-story/assets/js/util.js

@ -0,0 +1,587 @@
(function($) {
/**
* Generate an indented list of links from a nav. Meant for use with panel().
* @return {jQuery} jQuery object.
*/
$.fn.navList = function() {
var $this = $(this);
$a = $this.find('a'),
b = [];
$a.each(function() {
var $this = $(this),
indent = Math.max(0, $this.parents('li').length - 1),
href = $this.attr('href'),
target = $this.attr('target');
b.push(
'<a ' +
'class="link depth-' + indent + '"' +
( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
'>' +
'<span class="indent-' + indent + '"></span>' +
$this.text() +
'</a>'
);
});
return b.join('');
};
/**
* Panel-ify an element.
* @param {object} userConfig User config.
* @return {jQuery} jQuery object.
*/
$.fn.panel = function(userConfig) {
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).panel(userConfig);
return $this;
}
// Vars.
var $this = $(this),
$body = $('body'),
$window = $(window),
id = $this.attr('id'),
config;
// Config.
config = $.extend({
// Delay.
delay: 0,
// Hide panel on link click.
hideOnClick: false,
// Hide panel on escape keypress.
hideOnEscape: false,
// Hide panel on swipe.
hideOnSwipe: false,
// Reset scroll position on hide.
resetScroll: false,
// Reset forms on hide.
resetForms: false,
// Side of viewport the panel will appear.
side: null,
// Target element for "class".
target: $this,
// Class to toggle.
visibleClass: 'visible'
}, userConfig);
// Expand "target" if it's not a jQuery object already.
if (typeof config.target != 'jQuery')
config.target = $(config.target);
// Panel.
// Methods.
$this._hide = function(event) {
// Already hidden? Bail.
if (!config.target.hasClass(config.visibleClass))
return;
// If an event was provided, cancel it.
if (event) {
event.preventDefault();
event.stopPropagation();
}
// Hide.
config.target.removeClass(config.visibleClass);
// Post-hide stuff.
window.setTimeout(function() {
// Reset scroll position.
if (config.resetScroll)
$this.scrollTop(0);
// Reset forms.
if (config.resetForms)
$this.find('form').each(function() {
this.reset();
});
}, config.delay);
};
// Vendor fixes.
$this
.css('-ms-overflow-style', '-ms-autohiding-scrollbar')
.css('-webkit-overflow-scrolling', 'touch');
// Hide on click.
if (config.hideOnClick) {
$this.find('a')
.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
$this
.on('click', 'a', function(event) {
var $a = $(this),
href = $a.attr('href'),
target = $a.attr('target');
if (!href || href == '#' || href == '' || href == '#' + id)
return;
// Cancel original event.
event.preventDefault();
event.stopPropagation();
// Hide panel.
$this._hide();
// Redirect to href.
window.setTimeout(function() {
if (target == '_blank')
window.open(href);
else
window.location.href = href;
}, config.delay + 10);
});
}
// Event: Touch stuff.
$this.on('touchstart', function(event) {
$this.touchPosX = event.originalEvent.touches[0].pageX;
$this.touchPosY = event.originalEvent.touches[0].pageY;
})
$this.on('touchmove', function(event) {
if ($this.touchPosX === null
|| $this.touchPosY === null)
return;
var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
th = $this.outerHeight(),
ts = ($this.get(0).scrollHeight - $this.scrollTop());
// Hide on swipe?
if (config.hideOnSwipe) {
var result = false,
boundary = 20,
delta = 50;
switch (config.side) {
case 'left':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
break;
case 'right':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
break;
case 'top':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
break;
case 'bottom':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
break;
default:
break;
}
if (result) {
$this.touchPosX = null;
$this.touchPosY = null;
$this._hide();
return false;
}
}
// Prevent vertical scrolling past the top or bottom.
if (($this.scrollTop() < 0 && diffY < 0)
|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
event.preventDefault();
event.stopPropagation();
}
});
// Event: Prevent certain events inside the panel from bubbling.
$this.on('click touchend touchstart touchmove', function(event) {
event.stopPropagation();
});
// Event: Hide panel if a child anchor tag pointing to its ID is clicked.
$this.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.removeClass(config.visibleClass);
});
// Body.
// Event: Hide panel on body click/tap.
$body.on('click touchend', function(event) {
$this._hide(event);
});
// Event: Toggle.
$body.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.toggleClass(config.visibleClass);
});
// Window.
// Event: Hide on ESC.
if (config.hideOnEscape)
$window.on('keydown', function(event) {
if (event.keyCode == 27)
$this._hide(event);
});
return $this;
};
/**
* Apply "placeholder" attribute polyfill to one or more forms.
* @return {jQuery} jQuery object.
*/
$.fn.placeholder = function() {
// Browser natively supports placeholders? Bail.
if (typeof (document.createElement('input')).placeholder != 'undefined')
return $(this);
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).placeholder();
return $this;
}
// Vars.
var $this = $(this);
// Text, TextArea.
$this.find('input[type=text],textarea')
.each(function() {
var i = $(this);
if (i.val() == ''
|| i.val() == i.attr('placeholder'))
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('blur', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == '')
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('focus', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == i.attr('placeholder'))
i
.removeClass('polyfill-placeholder')
.val('');
});
// Password.
$this.find('input[type=password]')
.each(function() {
var i = $(this);
var x = $(
$('<div>')
.append(i.clone())
.remove()
.html()
.replace(/type="password"/i, 'type="text"')
.replace(/type=password/i, 'type=text')
);
if (i.attr('id') != '')
x.attr('id', i.attr('id') + '-polyfill-field');
if (i.attr('name') != '')
x.attr('name', i.attr('name') + '-polyfill-field');
x.addClass('polyfill-placeholder')
.val(x.attr('placeholder')).insertAfter(i);
if (i.val() == '')
i.hide();
else
x.hide();
i
.on('blur', function(event) {
event.preventDefault();
var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
}
});
x
.on('focus', function(event) {
event.preventDefault();
var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
x.hide();
i
.show()
.focus();
})
.on('keypress', function(event) {
event.preventDefault();
x.val('');
});
});
// Events.
$this
.on('submit', function() {
$this.find('input[type=text],input[type=password],textarea')
.each(function(event) {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
i.attr('name', '');
if (i.val() == i.attr('placeholder')) {
i.removeClass('polyfill-placeholder');
i.val('');
}
});
})
.on('reset', function(event) {
event.preventDefault();
$this.find('select')
.val($('option:first').val());
$this.find('input,textarea')
.each(function() {
var i = $(this),
x;
i.removeClass('polyfill-placeholder');
switch (this.type) {
case 'submit':
case 'reset':
break;
case 'password':
i.val(i.attr('defaultValue'));
x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
}
else {
i.show();
x.hide();
}
break;
case 'checkbox':
case 'radio':
i.attr('checked', i.attr('defaultValue'));
break;
case 'text':
case 'textarea':
i.val(i.attr('defaultValue'));
if (i.val() == '') {
i.addClass('polyfill-placeholder');
i.val(i.attr('placeholder'));
}
break;
default:
i.val(i.attr('defaultValue'));
break;
}
});
});
return $this;
};
/**
* Moves elements to/from the first positions of their respective parents.
* @param {jQuery} $elements Elements (or selector) to move.
* @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
*/
$.prioritize = function($elements, condition) {
var key = '__prioritize';
// Expand $elements if it's not already a jQuery object.
if (typeof $elements != 'jQuery')
$elements = $($elements);
// Step through elements.
$elements.each(function() {
var $e = $(this), $p,
$parent = $e.parent();
// No parent? Bail.
if ($parent.length == 0)
return;
// Not moved? Move it.
if (!$e.data(key)) {
// Condition is false? Bail.
if (!condition)
return;
// Get placeholder (which will serve as our point of reference for when this element needs to move back).
$p = $e.prev();
// Couldn't find anything? Means this element's already at the top, so bail.
if ($p.length == 0)
return;
// Move element to top of parent.
$e.prependTo($parent);
// Mark element as moved.
$e.data(key, $p);
}
// Moved already?
else {
// Condition is true? Bail.
if (condition)
return;
$p = $e.data(key);
// Move element back to its original location (using our placeholder).
$e.insertAfter($p);
// Unmark element as moved.
$e.removeData(key);
}
});
};
})(jQuery);

48
themes/hugo-story/assets/sass/base/_page.scss

@ -0,0 +1,48 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Basic */
// MSIE: Required for IEMobile.
@-ms-viewport {
width: device-width;
}
// MSIE: Prevents scrollbar from overlapping content.
body {
-ms-overflow-style: scrollbar;
}
// Ensures page width is always >=320px.
@include breakpoint('<=xsmall') {
html, body {
min-width: 320px;
}
}
// Set box model to border-box.
// Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
background: _palette(bg);
// Stops initial animations until page loads.
&.is-preload {
*, *:before, *:after {
@include vendor('animation', 'none !important');
@include vendor('transition', 'none !important');
}
}
}

77
themes/hugo-story/assets/sass/base/_reset.scss

@ -0,0 +1,77 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
// Reset.
// Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain)
html, body, div, span, applet, object,
iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
pre, a, abbr, acronym, address, big, cite,
code, del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var, b,
u, i, center, dl, dt, dd, ol, ul, li, fieldset,
form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td, article, aside,
canvas, details, embed, figure, figcaption,
footer, header, hgroup, menu, nav, output, ruby,
section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style:none;
}
blockquote, q {
quotes: none;
&:before,
&:after {
content: '';
content: none;
}
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body {
-webkit-text-size-adjust: none;
}
mark {
background-color: transparent;
color: inherit;
}
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input, select, textarea {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
}

237
themes/hugo-story/assets/sass/base/_typography.scss

@ -0,0 +1,237 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Type */
html {
font-size: 18pt;
@include breakpoint('<=xlarge') {
font-size: 14pt;
}
@include breakpoint('<=large') {
font-size: 12pt;
}
@include breakpoint('<=small') {
font-size: 11pt;
}
@include breakpoint('<=xxsmall') {
font-size: 10pt;
}
}
body {
background-color: _palette(bg);
color: _palette(fg);
}
body, input, select, textarea {
font-family: _font(family);
font-size: 1rem;
font-weight: _font(weight);
line-height: 1.65;
}
a {
@include vendor('transition', 'color #{_duration(transition)} ease-in-out');
text-decoration: underline;
&:hover {
text-decoration: none;
}
}
strong, b {
font-weight: _font(weight-bold);
}
em, i {
font-style: italic;
}
p {
margin: 0 0 _size(element-margin) 0;
&.major {
font-size: 1.25rem;
}
}
h1, h2, h3, h4, h5, h6 {
font-weight: _font(weight);
line-height: 1.375;
letter-spacing: _font(kerning);
margin: 0 0 (_size(element-margin) * 0.5) 0;
a {
color: inherit;
text-decoration: none;
}
}
h1 {
font-size: 3.5rem;
line-height: 1.2;
}
h2 {
font-size: 2.25rem;
}
h3 {
font-size: 1.5rem;
}
h4 {
font-size: 1.1rem;
}
h5 {
font-size: 0.9rem;
}
h6 {
font-size: 0.7rem;
}
sub {
font-size: 0.8rem;
position: relative;
top: 0.5rem;
}
sup {
font-size: 0.8rem;
position: relative;
top: -0.5rem;
}
blockquote {
border-left: solid (_size(border-width) * 4);
font-style: italic;
margin: 0 0 _size(element-margin) 0;
padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin);
}
code {
border-radius: _size(border-radius);
font-family: _font(family-fixed);
font-size: 0.9em;
margin: 0 0.25rem;
padding: 0.25rem 0.325rem;
}
pre {
-webkit-overflow-scrolling: touch;
font-family: _font(family-fixed);
font-size: 0.9em;
margin: 0 0 _size(element-margin) 0;
code {
display: block;
line-height: 1.5;
padding: 0.75rem 1rem;
overflow-x: auto;
}
}
hr {
border: 0;
border-bottom: solid _size(border-width);
margin: (_size(element-margin) * 1.25) 0;
&.major {
margin: (_size(element-margin) * 1.75) 0;
}
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
.footerspacer {
padding-left: 15px;
padding-right: 15px;
}
@include breakpoint('<=small') {
p {
&.major {
font-size: 1.1rem;
}
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.25rem;
}
h4 {
font-size: 1rem;
}
}
@mixin color-typography($p: null) {
@if $p != null {
background-color: _palette($p, bg);
color: _palette($p, fg);
}
input, select, textarea {
color: _palette($p, fg-bold);
}
a {
color: _palette($p, fg-bold);
&:hover {
color: _palette($p, accent);
}
}
strong, b {
color: _palette($p, fg-bold);
}
h1, h2, h3, h4, h5, h6 {
color: _palette($p, fg-bold);
}
blockquote {
border-left-color: _palette($p, border);
}
code {
background: _palette($p, border-bg);
border-color: _palette($p, border);
}
hr {
border-bottom-color: _palette($p, border);
}
}
@include color-typography;

102
themes/hugo-story/assets/sass/components/_actions.scss

@ -0,0 +1,102 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Actions */
ul.actions {
@include vendor('display', 'flex');
cursor: default;
list-style: none;
margin-left: (_size(element-margin) * -0.5);
padding-left: 0;
li {
padding: 0 0 0 (_size(element-margin) * 0.5);
vertical-align: middle;
}
&.special {
@include vendor('justify-content', 'center');
width: 100%;
margin-left: 0;
li {
&:first-child {
padding-left: 0;
}
}
}
&.stacked {
@include vendor('flex-direction', 'column');
margin-left: 0;
li {
padding: (_size(element-margin) * 0.65) 0 0 0;
&:first-child {
padding-top: 0;
}
}
}
&.fit {
width: calc(100% + #{_size(element-margin) * 0.5});
li {
@include vendor('flex-grow', '1');
@include vendor('flex-shrink', '1');
width: 100%;
> * {
width: 100%;
}
}
&.stacked {
width: 100%;
}
}
@include breakpoint('<=xsmall') {
&:not(.fixed) {
@include vendor('flex-direction', 'column');
margin-left: 0;
width: 100% !important;
li {
@include vendor('flex-grow', '1');
@include vendor('flex-shrink', '1');
padding: (_size(element-margin) * 0.5) 0 0 0;
text-align: center;
width: 100%;
> * {
width: 100%;
}
&:first-child {
padding-top: 0;
}
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
width: 100%;
&.icon {
&:before {
margin-left: -0.5rem;
}
}
}
}
}
}
}

991
themes/hugo-story/assets/sass/components/_banner.scss

@ -0,0 +1,991 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Banner (transitions) */
.banner {
// Mixin.
@mixin transition-banner($event) {
$x: null;
$y: null;
@if ($event == 'load') {
$x: 'body.is-preload &';
$y: _duration(on-load);
}
@else if ($event == 'scroll') {
$x: '&.is-inactive';
$y: _duration(on-scroll);
}
// Content.
&.on#{$event}-content-fade-up {
.content {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
}
#{$x} {
.content {
@include vendor('transform', 'translateY(1rem)');
opacity: 0;
}
}
}
&.on#{$event}-content-fade-down {
.content {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
}
#{$x} {
.content {
@include vendor('transform', 'translateY(-1rem)');
opacity: 0;
}
}
}
&.on#{$event}-content-fade-left {
.content {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
}
#{$x} {
.content {
@include vendor('transform', 'translateX(1rem)');
opacity: 0;
}
}
}
&.on#{$event}-content-fade-right {
.content {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
}
#{$x} {
.content {
@include vendor('transform', 'translateX(-1rem)');
opacity: 0;
}
}
}
&.on#{$event}-content-fade-in {
.content {
@include vendor('transition', 'opacity #{$y} ease-in-out');
}
#{$x} {
.content {
opacity: 0;
}
}
}
// Image.
&.on#{$event}-image-fade-up {
.image {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
img {
@include vendor('transition', 'opacity #{$y} ease-in-out');
@include vendor('transition-delay', '#{$y * 0.75}');
}
}
#{$x} {
.image {
@include vendor('transform', 'translateY(1rem)');
opacity: 0;
img {
opacity: 0;
}
}
}
}
&.on#{$event}-image-fade-down {
.image {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
img {
@include vendor('transition', 'opacity #{$y} ease-in-out');
@include vendor('transition-delay', '#{$y * 0.75}');
}
}
#{$x} {
.image {
@include vendor('transform', 'translateY(-1rem)');
opacity: 0;
img {
opacity: 0;
}
}
}
}
&.on#{$event}-image-fade-left {
.image {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
img {
@include vendor('transition', 'opacity #{$y} ease-in-out');
@include vendor('transition-delay', '#{$y * 0.75}');
}
}
#{$x} {
.image {
@include vendor('transform', 'translateX(1rem)');
opacity: 0;
img {
opacity: 0;
}
}
}
}
&.on#{$event}-image-fade-right {
.image {
@include vendor('transition', (
'opacity #{$y} ease-in-out',
'transform #{$y} ease-in-out'
));
img {
@include vendor('transition', 'opacity #{$y} ease-in-out');
@include vendor('transition-delay', '#{$y * 0.75}');
}
}
#{$x} {
.image {
@include vendor('transform', 'translateX(-1rem)');
opacity: 0;
img {
opacity: 0;
}
}
}
}
&.on#{$event}-image-fade-in {
.image {
img {
@include vendor('transition', 'opacity #{$y} ease-in-out');
}
}
#{$x} {
.image {
img {
opacity: 0;
}
}
}
}
}
// On Load.
@include transition-banner('load');
// On Scroll.
@include transition-banner('scroll');
}
/* Banner (style1) */
.banner.style1 {
@include vendor('align-items', 'stretch');
@include vendor('display', 'flex');
@include vendor('flex-direction', 'row');
@include vendor('justify-content', 'flex-end');
position: relative;
text-align: left;
overflow-x: hidden;
.content {
@include padding(_size(padding, default), _size(padding, default));
@include vendor('align-self', 'center');
@include vendor('flex-grow', '1');
@include vendor('flex-shrink', '1');
width: 50%;
max-width: (_size(inner) * 0.75);
margin: 0 auto;
}
.image {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
border-radius: 0;
width: 50%;
img {
@include vendor('object-fit', 'cover');
@include vendor('object-position', 'center');
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 0;
}
}
@include breakpoint('<=xlarge') {
.content {
@include padding(_size(padding, xlarge), _size(padding, xlarge));
}
}
@include breakpoint('<=large') {
.content {
@include padding(_size(padding, large), _size(padding, large));
}
}
@include breakpoint('<=medium') {
.content {
@include padding(_size(padding, medium) * 1.25, _size(padding, medium));
}
}
@include breakpoint('<=small') {
.content {
@include padding(_size(padding, small) * 1.25, _size(padding, small));
}
}
@include orientation(portrait) {
@include vendor('flex-direction', 'column-reverse');
text-align: center;
.content {
@include vendor('display', 'flex');
@include vendor('flex-direction', 'column');
@include vendor('justify-content', 'center');
width: 100%;
max-width: 100%;
}
.image {
width: 100%;
max-width: 100%;
height: 45vh;
}
}
// Modifiers.
// Size.
&.fullscreen {
min-height: 100vh;
@include orientation(portrait) {
.content {
min-height: 50vh;
}
.image {
height: 50vh;
}
}
}
// Orientation.
&.orient-left {
// ...
}
&.orient-right {
@include vendor('flex-direction', 'row-reverse');
@include orientation(portrait) {
@include vendor('flex-direction', 'column-reverse');
}
}
// Content Alignment.
&.content-align-left {
// ...
}
&.content-align-center {
text-align: center;
}
&.content-align-right {
text-align: right;
@include orientation(portrait) {
text-align: center;
}
}
// Image Position.
&.image-position-left {
.image {
img {
@include vendor('object-position', 'left');
}
}
}
&.image-position-center {
.image {
img {
// ...
}
}
}
&.image-position-right {
.image {
img {
@include vendor('object-position', 'right');
}
}
}
}
/* Banner (style2) */
.banner.style2 {
@include padding(_size(padding, default) * 0.75, _size(padding, default) * 0.75);
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('justify-content', 'center');
background-color: inherit;
position: relative;
text-align: center;
overflow-x: hidden;
.content {
@include padding(_size(padding, default) * 0.75, _size(padding, default) * 0.75);
position: relative;
width: (_size(inner) * 0.625);
max-width: 100%;
background-color: inherit;
border-radius: _size(border-radius-alt);
margin-bottom: _size(element-margin);
z-index: 1;
}
.image {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border-radius: 0;
img {
@include vendor('object-fit', 'cover');
@include vendor('object-position', 'center');
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 0;
}
}
@include breakpoint('<=xlarge') {
@include padding(_size(padding, xlarge) * 0.75, _size(padding, xlarge) * 0.75);
.content {
@include padding(_size(padding, xlarge) * 0.75, _size(padding, xlarge) * 0.75);
}
}
@include breakpoint('<=large') {
@include padding(_size(padding, large), _size(padding, large) * 0.75);
.content {
@include padding(_size(padding, large), _size(padding, large) * 0.75);
}
}
@include breakpoint('<=medium') {
@include padding(_size(padding, medium), _size(padding, medium));
.content {
@include padding(_size(padding, medium) * 1.25, _size(padding, medium) * 0.75);
}
}
@include breakpoint('<=small') {
@include padding(_size(padding, small), _size(padding, small));
.content {
@include padding(_size(padding, small) * 1.25, _size(padding, small) * 0.75);
}
}
// Modifiers.
// Size.
&.fullscreen {
min-height: 100vh;
}
// Orientation.
&.orient-left {
@include vendor('justify-content', 'flex-start');
padding-left: 0;
.content {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
&.orient-center {
// ...
}
&.orient-right {
@include vendor('justify-content', 'flex-end');
padding-right: 0;
.content {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
// Content Alignment.
&.content-align-left {
text-align: left;
}
&.content-align-center {
// ...
}
&.content-align-right {
text-align: right;
}
// Image Position.
&.image-position-left {
.image {
img {
@include vendor('object-position', 'left');
}
}
}
&.image-position-center {
.image {
img {
// ...
}
}
}
&.image-position-right {
.image {
img {
@include vendor('object-position', 'right');
}
}
}
}
/* Banner (style3) */
.banner.style3 {
$image-size: 21rem;
$content-size: (_size(inner) * 0.875) - $image-size - (_size(element-margin) * 1.75);
@include padding(_size(padding, default), _size(padding, default));
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('flex-direction', 'row-reverse');
@include vendor('justify-content', 'center');
position: relative;
text-align: left;
overflow-x: hidden;
.content {
width: $content-size;
max-width: 100%;
}
.image {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
width: $image-size;
height: $image-size;
border-radius: 100%;
margin: 0 (_size(element-margin) * 1.75) _size(element-margin) 0;
img {
@include vendor('object-fit', 'cover');
@include vendor('object-position', 'center');
display: block;
width: 100%;
height: 100%;
border-radius: 100%;
}
}
@include breakpoint('<=xlarge') {
@include padding(_size(padding, xlarge), _size(padding, xlarge));
}
@include breakpoint('<=large') {
@include padding(_size(padding, large), _size(padding, large));
}
@include breakpoint('<=medium') {
@include padding(_size(padding, medium) * 1.25, _size(padding, medium));
.image {
width: ($image-size * 0.875);
height: ($image-size * 0.875);
}
}
@include breakpoint('<=small') {
@include padding(_size(padding, small) * 1.25, _size(padding, small));
@include vendor('align-items', 'flex-start');
.image {
width: ($image-size * 0.75);
height: ($image-size * 0.75);
margin: 0 (_size(element-margin) * 1) _size(element-margin) 0;
}
}
@include orientation(portrait) {
@include vendor('align-items', 'center');
@include vendor('flex-direction', 'column-reverse');
text-align: center;
.content {
width: 34rem;
max-width: 100%;
}
.image {
margin-right: 0;
}
}
// Modifiers.
// Size.
&.fullscreen {
min-height: 100vh;
}
// Orientation.
&.orient-left {
@include vendor('flex-direction', 'row');
.image {
margin: 0 0 _size(element-margin) (_size(element-margin) * 1.75);
}
@include breakpoint('<=small') {
.image {
margin: 0 0 _size(element-margin) (_size(element-margin) * 1);
}
}
@include orientation(portrait) {
@include vendor('flex-direction', 'column-reverse');
.image {
margin-left: 0;
}
}
}
&.orient-right {
// ...
}
// Content Alignment.
&.content-align-left {
// ...
}
&.content-align-center {
text-align: center;
}
&.content-align-right {
text-align: right;
}
// Image Position.
&.image-position-left {
.image {
img {
@include vendor('object-position', 'left');
}
}
}
&.image-position-center {
// ...
}
&.image-position-right {
.image {
img {
@include vendor('object-position', 'right');
}
}
}
}
/* Banner (style4) */
.banner.style4 {
$image-width: 13rem;
$content-size: (_size(inner) * 0.75) - $image-width - (_size(element-margin) * 1.75);
@include padding(_size(padding, default), _size(padding, default));
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('flex-direction', 'row-reverse');
@include vendor('justify-content', 'center');
position: relative;
text-align: left;
overflow-x: hidden;
.content {
width: $content-size;
max-width: 100%;
}
.image {
@include phone($image-width);
margin-right: (_size(element-margin) * 1.75);
}
@include breakpoint('<=xlarge') {
@include padding(_size(padding, xlarge), _size(padding, xlarge));
}
@include breakpoint('<=large') {
@include padding(_size(padding, large), _size(padding, large));
}
@include breakpoint('<=medium') {
@include padding(_size(padding, medium) * 1.25, _size(padding, medium));
.image {
@include resize-phone($image-width, 0.875);
}
}
@include breakpoint('<=small') {
@include padding(_size(padding, small) * 1.25, _size(padding, small));
@include vendor('align-items', 'flex-start');
.image {
@include resize-phone($image-width, 0.625);
}
}
@include orientation(portrait) {
@include vendor('align-items', 'center');
@include vendor('flex-direction', 'column-reverse');
text-align: center;
.content {
width: 34rem;
max-width: 100%;
}
.image {
margin-right: 0;
margin-left: 0;
}
}
// Modifiers.
// Size.
&.fullscreen {
min-height: 100vh;
}
// Variant.
&.iphone {
// ...
}
&.android {
// ...
}
// Orientation.
&.orient-left {
@include vendor('flex-direction', 'row');
.image {
margin-right: 0;
margin-left: (_size(element-margin) * 1.75);
}
@include orientation(portrait) {
@include vendor('flex-direction', 'column-reverse');
.image {
margin-right: 0;
margin-left: 0;
}
}
}
&.orient-right {
// ...
}
// Content Alignment.
&.content-align-left {
// ...
}
&.content-align-center {
text-align: center;
}
&.content-align-right {
text-align: right;
}
// Image Position.
&.image-position-left {
.image {
img {
@include vendor('object-position', 'left');
}
}
}
&.image-position-center {
// ...
}
&.image-position-right {
.image {
img {
@include vendor('object-position', 'right');
}
}
}
}
/* Banner (style5) */
.banner.style5 {
@include padding(_size(padding, default), _size(padding, default));
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('justify-content', 'center');
background-color: inherit;
position: relative;
text-align: center;
overflow-x: hidden;
.content {
position: relative;
width: (_size(inner) * 0.625);
max-width: 100%;
margin-bottom: _size(element-margin);
z-index: 1;
}
.image {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border-radius: 0;
opacity: _misc(overlay-opacity);
img {
@include vendor('object-fit', 'cover');
@include vendor('object-position', 'center');
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 0;
}
}
@include breakpoint('<=xlarge') {
@include padding(_size(padding, xlarge), _size(padding, xlarge));
}
@include breakpoint('<=large') {
@include padding(_size(padding, large), _size(padding, large));
}
@include breakpoint('<=medium') {
@include padding(_size(padding, medium) * 1.25, _size(padding, medium));
}
@include breakpoint('<=small') {
@include padding(_size(padding, small) * 1.25, _size(padding, small));
}
// Modifiers.
// Size.
&.fullscreen {
min-height: 100vh;
}
// Content Alignment.
&.content-align-left {
text-align: left;
}
&.content-align-center {
// ...
}
&.content-align-right {
text-align: right;
}
// Image Position.
&.image-position-left {
.image {
img {
@include vendor('object-position', 'left');
}
}
}
&.image-position-center {
// ...
}
&.image-position-right {
.image {
img {
@include vendor('object-position', 'right');
}
}
}
}
// Mixin
@mixin color-banner($p: null) {
.banner {
.image {
background-color: transparentize(_palette($p, fg-bold), 0.875);
}
@if ($p != 'invert') {
&.invert {
.image {
background-color: transparentize(_palette(invert, fg-bold), 0.875);
}
}
}
}
.banner.style4 {
.image {
@include color-phone($p);
}
// Variant.
&.iphone {
.image {
@include color-phone-variant('iphone', $p);
}
}
&.android {
.image {
@include color-phone-variant('android', $p);
}
}
@if ($p != 'invert') {
&.invert {
.image {
@include color-phone(invert);
}
// Variant.
&.iphone {
.image {
@include color-phone-variant('iphone', invert);
}
}
&.android {
.image {
@include color-phone-variant('android', invert);
}
}
}
}
}
}
@include color-banner;

35
themes/hugo-story/assets/sass/components/_box.scss

@ -0,0 +1,35 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Box */
.box {
border-radius: _size(border-radius);
border: solid _size(border-width);
margin-bottom: _size(element-margin);
padding: 1.5rem;
> :last-child,
> :last-child > :last-child,
> :last-child > :last-child > :last-child {
margin-bottom: 0;
}
&.alt {
border: 0;
border-radius: 0;
padding: 0;
}
}
@mixin color-box($p: null) {
.box {
border-color: _palette($p, border);
}
}
@include color-box;

113
themes/hugo-story/assets/sass/components/_button.scss

@ -0,0 +1,113 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Button */
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
@include vendor('appearance', 'none');
@include vendor('transition', (
'background-color #{_duration(transition)} ease-in-out',
'box-shadow #{_duration(transition)} ease-in-out',
'color #{_duration(transition)} ease-in-out'
));
border: 0;
cursor: pointer;
display: inline-block;
font-weight: _font(weight-bold);
letter-spacing: _font(kerning-alt);
text-align: center;
text-decoration: none;
text-transform: uppercase;
white-space: nowrap;
font-size: 0.75rem;
max-width: 20rem;
height: 3.75em;
line-height: 3.75em;
border-radius: 3.75em;
padding: 0 2.5em;
text-overflow: ellipsis;
overflow: hidden;
&.icon {
&:before {
margin-right: 0.5rem;
}
}
&.fit {
width: 100%;
}
&.small {
font-size: 0.6rem;
height: 3.325em;
line-height: 3.325em;
border-radius: 3.325em;
padding: 0 2em;
}
&.large {
font-size: 0.8rem;
height: 4em;
line-height: 4em;
border-radius: 4em;
padding: 0 3em;
}
&.wide {
min-width: 14em;
}
&.disabled,
&:disabled {
@include vendor('pointer-events', 'none');
opacity: 0.25;
}
}
@mixin color-button($p: null) {
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
background-color: transparent;
box-shadow: inset 0 0 0 _size(border-width) _palette($p, border);
color: _palette($p, fg-bold) !important;
&:hover {
box-shadow: inset 0 0 0 _size(border-width) _palette($p, accent);
color: _palette($p, accent) !important;
}
&:active {
background-color: transparentize(_palette($p, accent), 0.8);
box-shadow: inset 0 0 0 _size(border-width) _palette($p, accent);
color: _palette($p, accent) !important;
}
&.primary {
background-color: _palette($p, fg-bold);
box-shadow: none;
color: _palette($p, bg) !important;
&:hover {
background-color: _palette($p, accent);
}
&:active {
background-color: darken(_palette($p, accent), 12);
}
}
}
}
@include color-button;

287
themes/hugo-story/assets/sass/components/_form.scss

@ -0,0 +1,287 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Form */
form {
margin: 0 0 _size(element-margin) 0;
> :last-child {
margin-bottom: 0;
}
> .fields {
$gutter: (_size(element-margin) * 0.75);
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
width: calc(100% + #{$gutter * 2});
margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1);
> .field {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
padding: $gutter 0 0 $gutter;
width: calc(100% - #{$gutter * 1});
&.half {
width: calc(50% - #{$gutter * 0.5});
}
&.third {
width: calc(#{100% / 3} - #{$gutter * (1 / 3)});
}
&.quarter {
width: calc(25% - #{$gutter * 0.25});
}
}
}
@include breakpoint('<=xsmall') {
> .fields {
$gutter: (_size(element-margin) * 0.75);
width: calc(100% + #{$gutter * 2});
margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1);
> .field {
padding: $gutter 0 0 $gutter;
width: calc(100% - #{$gutter * 1});
&.half {
width: calc(100% - #{$gutter * 1});
}
&.third {
width: calc(100% - #{$gutter * 1});
}
&.quarter {
width: calc(100% - #{$gutter * 1});
}
}
}
}
}
label {
display: block;
font-size: 0.9rem;
font-weight: _font(weight-bold);
margin: 0 0 (_size(element-margin) * 0.5) 0;
}
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
input[type="search"],
input[type="url"],
select,
textarea {
@include vendor('appearance', 'none');
background-color: transparent;
border-radius: _size(border-radius);
border: none;
border: solid _size(border-width);
color: inherit;
display: block;
outline: 0;
padding: 0 0.825rem;
text-decoration: none;
width: 100%;
&:invalid {
box-shadow: none;
}
}
select {
background-size: 1.25rem;
background-repeat: no-repeat;
background-position: calc(100% - 1rem) center;
height: _size(element-height);
padding-right: _size(element-height);
text-overflow: ellipsis;
&:focus {
&::-ms-value {
background-color: transparent;
}
}
&::-ms-expand {
display: none;
}
}
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
input[type="search"],
input[type="url"],
select {
height: _size(element-height);
}
textarea {
padding: 0.75rem 1rem;
}
input[type="checkbox"],
input[type="radio"], {
@include vendor('appearance', 'none');
display: block;
float: left;
margin-right: -2rem;
opacity: 0;
width: 1rem;
z-index: -1;
& + label {
@include icon(false, solid);
@include vendor('user-select', 'none');
cursor: pointer;
display: inline-block;
font-size: 1rem;
font-weight: _font(weight);
padding-left: (_size(element-height) * 0.6) + 0.75rem;
padding-right: 0.75rem;
position: relative;
margin-bottom: 0;
&:before {
border-radius: _size(border-radius);
border: solid _size(border-width);
content: '';
display: inline-block;
font-size: 0.8rem;
height: (_size(element-height) * 0.6);
left: 0;
line-height: (_size(element-height) * 0.6);
position: absolute;
text-align: center;
top: 0;
width: (_size(element-height) * 0.6);
}
}
&:checked + label {
&:before {
content: '\f00c';
}
}
}
input[type="checkbox"] {
& + label {
&:before {
border-radius: _size(border-radius);
}
}
}
input[type="radio"] {
& + label {
&:before {
border-radius: 100%;
}
}
}
::-webkit-input-placeholder {
opacity: 1.0;
}
:-moz-placeholder {
opacity: 1.0;
}
::-moz-placeholder {
opacity: 1.0;
}
:-ms-input-placeholder {
opacity: 1.0;
}
@mixin color-form($p: null) {
label {
color: _palette($p, fg-bold);
}
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
input[type="search"],
input[type="url"],
select,
textarea {
border-color: _palette($p, border);
&:focus {
border-color: _palette($p, accent);
box-shadow: 0 0 0 _size(border-width) _palette($p, accent);
}
}
select {
background-image: svg-url("<svg xmlns='http://www.w3.org/2000/svg' width='40' height='40' preserveAspectRatio='none' viewBox='0 0 40 40'><path d='M9.4,12.3l10.4,10.4l10.4-10.4c0.2-0.2,0.5-0.4,0.9-0.4c0.3,0,0.6,0.1,0.9,0.4l3.3,3.3c0.2,0.2,0.4,0.5,0.4,0.9 c0,0.4-0.1,0.6-0.4,0.9L20.7,31.9c-0.2,0.2-0.5,0.4-0.9,0.4c-0.3,0-0.6-0.1-0.9-0.4L4.3,17.3c-0.2-0.2-0.4-0.5-0.4-0.9 c0-0.4,0.1-0.6,0.4-0.9l3.3-3.3c0.2-0.2,0.5-0.4,0.9-0.4S9.1,12.1,9.4,12.3z' fill='#{_palette(border)}' /></svg>");
option {
color: _palette(fg-bold);
background: _palette(bg);
}
}
input[type="checkbox"],
input[type="radio"], {
& + label {
color: _palette($p, fg);
&:before {
border-color: _palette($p, border);
}
}
&:checked + label {
&:before {
background-color: _palette($p, fg-bold);
border-color: _palette($p, fg-bold);
color: _palette($p, bg);
}
}
&:focus + label {
&:before {
border-color: _palette($p, accent);
box-shadow: 0 0 0 _size(border-width) _palette($p, accent);
}
}
}
::-webkit-input-placeholder {
color: _palette($p, fg-light) !important;
}
:-moz-placeholder {
color: _palette($p, fg-light) !important;
}
::-moz-placeholder {
color: _palette($p, fg-light) !important;
}
:-ms-input-placeholder {
color: _palette($p, fg-light) !important;
}
}
@include color-form;

617
themes/hugo-story/assets/sass/components/_gallery.scss

@ -0,0 +1,617 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Gallery (transitions) */
.gallery {
// Mixin.
@mixin transition-gallery($event) {
$x: null;
$y: null;
@if ($event == 'load') {
$x: 'body.is-preload &';
$y: _duration(on-load);
}
@else if ($event == 'scroll') {
$x: '&.is-inactive';
$y: _duration(on-scroll);
}
&.on#{$event}-fade-in {
article {
.image {
img {
@include vendor('transition', 'opacity #{$y} ease-in-out');
@include vendor('transition-delay', '#{_misc(gallery-limit) * _duration(gallery-delay)}');
}
}
@for $i from 0 through _misc(gallery-limit) {
&:nth-child(#{$i + 1}) {
.image {
img {
@include vendor('transition-delay', '#{$i * _duration(gallery-delay)}');
}
}
}
}
}
#{$x} {
article {
.image {
img {
opacity: 0;
}
}
}
}
}
}
// On Load.
@include transition-gallery('load');
// On Scroll.
@include transition-gallery('scroll');
}
/* Gallery (style1) */
.gallery.style1 {
@include color-typography(invert);
@include color-button(invert);
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
@include vendor('justify-content', 'center');
position: relative;
width: 100%;
background-color: transparent;
> .forward, >.backward {
display: none;
}
> .inner {
@include vendor('align-items', 'inherit');
@include vendor('display', 'inherit');
@include vendor('flex-wrap', 'inherit');
@include vendor('justify-content', 'inherit');
}
article {
overflow: hidden;
position: relative;
width: 25%;
.image {
@include vendor('transition', 'opacity #{_duration(transition)} ease-in-out');
display: block;
width: 100%;
border-radius: 0;
img {
display: block;
width: 100%;
border-radius: 0;
}
}
.caption {
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('flex-direction', 'column');
@include vendor('justify-content', 'center');
@include vendor('pointer-events', 'none');
@include vendor('transition', 'opacity #{_duration(transition)} ease-in-out');
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparentize(_palette(invert, bg), 1 - _misc(overlay-opacity));
opacity: 0;
padding: 2rem;
z-index: 1;
font-size: 0.8rem;
a {
@include vendor('pointer-events', 'auto');
}
h2, h3, h4, h5, h6 {
font-size: 1.25rem;
margin-bottom: 0.25rem;
}
> * {
max-width: 100%;
margin-bottom: 1rem;
}
> :last-child {
margin-bottom: 0;
}
}
&:hover {
.caption {
opacity: 1;
}
}
}
@include breakpoint('<=large') {
article {
width: (100% / 3);
.caption {
padding: 1rem;
}
}
}
@include breakpoint('<=medium') {
article {
width: 50%;
.caption {
padding: 1rem;
}
}
}
@include breakpoint('<=xsmall') {
article {
width: 100%;
.caption {
padding: 1rem;
}
}
}
// Modifiers.
// size
&.small {
article {
width: 20%;
.caption {
padding: 1rem;
}
}
@include breakpoint('<=large') {
article {
width: 25%;
.caption {
padding: 1rem;
}
}
}
@include breakpoint('<=medium') {
article {
width: (100% / 3);
.caption {
padding: 1rem;
}
}
}
@include breakpoint('<=xsmall') {
article {
width: 50%;
.caption {
padding: 1rem;
}
}
}
}
&.medium {
// ...
}
&.big {
article {
width: (100% / 3);
.caption {
padding: 3rem;
}
}
@include breakpoint('<=large') {
article {
width: 50%;
.caption {
padding: 2rem;
}
}
}
@include breakpoint('<=medium') {
article {
width: 50%;
.caption {
padding: 2rem;
}
}
}
@include breakpoint('<=xsmall') {
article {
width: 100%;
.caption {
padding: 1rem;
}
}
}
}
}
/* Gallery (style2) */
.gallery.style2 {
@include color-typography(invert);
@include color-button(invert);
@include vendor('display', 'flex');
-webkit-overflow-scrolling: touch;
position: relative;
background-color: transparent;
> .forward, >.backward {
@include icon(false, solid);
@include vendor('transition', 'opacity #{_duration(transition)} ease-in-out');
position: absolute;
top: 0;
width: 5rem;
height: 100%;
cursor: pointer;
opacity: 0;
z-index: 2;
&:before {
display: block;
top: calc(50% - 1.5rem);
width: 4rem;
height: 3rem;
line-height: 1em;
font-size: 3rem;
position: absolute;
text-align: center;
}
}
&:hover {
> .forward, > .backward {
opacity: 1;
}
}
> .forward {
right: 0;
background-image: linear-gradient(to left, rgba(0,0,0,0.25) 15%, rgba(0,0,0,0));
&:before {
content: '\232A';
right: 0;
}
}
> .backward {
left: 0;
background-image: linear-gradient(to right, rgba(0,0,0,0.25) 15%, rgba(0,0,0,0));
&:before {
content: '\2329';
left: 0;
}
}
> .inner {
@include vendor('display', 'inherit');
overflow-x: auto;
overflow-y: hidden;
position: relative;
width: 100%;
}
article {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
display: block;
position: relative;
overflow: hidden;
width: 22.5rem;
max-width: 75vw;
.image {
display: block;
width: 100%;
border-radius: 0;
img {
display: block;
width: 100%;
border-radius: 0;
}
}
.caption {
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('flex-direction', 'column');
@include vendor('justify-content', 'center');
@include vendor('pointer-events', 'none');
@include vendor('transition', 'opacity #{_duration(transition)} ease-in-out');
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparentize(_palette(invert, bg), 1 - _misc(overlay-opacity));
opacity: 0;
padding: 3rem;
z-index: 1;
font-size: 0.8rem;
a {
@include vendor('pointer-events', 'auto');
}
h2, h3, h4, h5, h6 {
font-size: 1.25rem;
margin-bottom: 0.25rem;
}
> * {
max-width: 100%;
margin-bottom: 1rem;
}
> :last-child {
margin-bottom: 0;
}
}
&:hover {
.caption {
opacity: 1;
}
}
}
@include breakpoint('<=medium') {
article {
.caption {
padding: 2rem;
}
}
}
@include breakpoint('<=small') {
article {
.caption {
padding: 2rem;
}
}
}
// Modifiers.
// size
&.small {
article {
width: 17.5rem;
.caption {
padding: 2rem;
}
}
@include breakpoint('<=medium') {
article {
.caption {
padding: 2rem;
}
}
}
@include breakpoint('<=small') {
article {
.caption {
padding: 2rem;
}
}
}
}
&.medium {
// ...
}
&.big {
article {
width: 30rem;
.caption {
padding: 4rem;
}
}
@include breakpoint('<=medium') {
article {
.caption {
padding: 3rem;
}
}
}
@include breakpoint('<=small') {
article {
.caption {
padding: 2rem;
}
}
}
}
}
/* Gallery (lightbox) */
@include keyframes('gallery-modal-spinner') {
0% {
@include vendor('transform', 'rotate(0deg)');
}
100% {
@include vendor('transform', 'rotate(360deg)');
}
}
.gallery.lightbox {
.modal {
@include vendor('display', 'flex');
@include vendor('align-items', 'center');
@include vendor('justify-content', 'center');
@include vendor('pointer-events', 'none');
@include vendor('user-select', 'none');
@include vendor('transition', (
'opacity #{_duration(gallery-lightbox)} ease',
'visibility #{_duration(gallery-lightbox)}',
'z-index #{_duration(gallery-lightbox)}'
));
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: 0;
background-color: transparentize(_palette(invert, bg), 1 - _misc(lightbox-opacity));
visibility: none;
opacity: 0;
z-index: 0;
&:before {
@include vendor('animation', 'gallery-modal-spinner 1s infinite linear');
@include vendor('transition', 'opacity #{_duration(gallery-lightbox) * 0.5} ease');
@include vendor('transition-delay', '#{_duration(gallery-lightbox)}');
content: '';
display: block;
position: absolute;
top: 50%;
left: 50%;
width: 4rem;
height: 4rem;
margin: -2rem 0 0 -2rem;
background-image: svg-url('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="96px" height="96px" viewBox="0 0 96 96" zoomAndPan="disable"><style>circle {fill: transparent; stroke: #{_palette(invert, fg-bold)}; stroke-width: 1.5px; }</style><defs><clipPath id="corner"><polygon points="0,0 48,0 48,48 96,48 96,96 0,96" /></clipPath></defs><g clip-path="url(#corner)"><circle cx="48" cy="48" r="32"/></g></svg>');
background-position: center;
background-repeat: no-repeat;
background-size: 4rem;
opacity: 0;
}
&:after {
content: '';
display: block;
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 4rem;
height: 4rem;
cursor: pointer;
background-image: svg-url('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="64px" viewBox="0 0 64 64" zoomAndPan="disable"><style>line {stroke: #{_palette(invert, fg-bold)};stroke-width: 1.5px;}</style><line x1="20" y1="20" x2="44" y2="44" /><line x1="20" y1="44" x2="44" y2="20" /></svg>');
background-position: center;
background-repeat: no-repeat;
background-size: 3rem;
}
.inner {
@include vendor('transform', 'translateY(0.75rem)');
@include vendor('transition', (
'opacity #{_duration(gallery-lightbox) * 0.5} ease',
'transform #{_duration(gallery-lightbox) * 0.5} ease'
));
opacity: 0;
img {
display: block;
max-width: 90vw;
max-height: 85vh;
box-shadow: 0 1rem 3rem 0 rgba(0, 0, 0, 0.35);
}
}
&.visible {
@include vendor('pointer-events', 'auto');
visibility: visible;
opacity: 1;
z-index: _misc(z-index-base) + 1;
&:before {
opacity: 1;
}
}
&.loaded {
.inner {
@include vendor('transform', 'translateY(0)');
@include vendor('transition', (
'opacity #{_duration(gallery-lightbox)} ease',
'transform #{_duration(gallery-lightbox)} ease'
));
opacity: 1;
}
&:before {
@include vendor('transition-delay', '0s');
opacity: 0;
}
}
}
@include breakpoint('<=medium') {
.modal {
.inner {
img {
max-width: 100vw;
}
}
}
}
}
// Mixin
@mixin color-gallery($p: null) {
.gallery {
article {
.image {
background-color: transparentize(_palette($p, fg-bold), 0.875);
}
}
}
}
@include color-gallery;

97
themes/hugo-story/assets/sass/components/_icon.scss

@ -0,0 +1,97 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Icon */
.icon {
@include icon;
border-bottom: none;
position: relative;
text-align: center;
> .label {
display: none;
}
&:before {
line-height: inherit;
}
&.solid {
&:before {
font-weight: 900;
}
}
&.brands {
&:before {
font-family: 'Font Awesome 5 Brands';
}
}
&.style2 {
&:before {
border-radius: 2.75em;
display: inline-block;
height: 2.75em;
line-height: 2.75em;
width: 2.75em;
}
}
&.major {
display: block;
margin: 0 0 (_size(element-margin) * 0.5) 0;
&:before {
font-size: 1.25rem;
}
}
}
a.icon {
&.style2 {
&:before {
@include vendor('transition', (
'background-color #{_duration(transition)} ease-in-out',
'box-shadow #{_duration(transition)} ease-in-out',
'color #{_duration(transition)} ease-in-out'
));
}
}
}
@mixin color-icon($p: null) {
.icon {
&.style2 {
&:before {
box-shadow: inset 0 0 0 _size(border-width) _palette($p, border);
}
}
}
a.icon {
&.style2 {
&:hover {
&:before {
box-shadow: inset 0 0 0 _size(border-width) _palette($p, accent);
color: _palette($p, accent);
}
}
&:active {
&:before {
background-color: transparentize(_palette($p, accent), 0.9);
box-shadow: inset 0 0 0 _size(border-width) _palette($p, accent);
color: _palette($p, accent);
}
}
}
}
}
@include color-icon;

23
themes/hugo-story/assets/sass/components/_icons.scss

@ -0,0 +1,23 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Icons */
ul.icons {
cursor: default;
list-style: none;
padding-left: 0;
li {
display: inline-block;
padding: 0 0.75rem 0 0;
&:last-child {
padding-right: 0;
}
}
}

62
themes/hugo-story/assets/sass/components/_image.scss

@ -0,0 +1,62 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Image */
.image {
border: 0;
border-radius: _size(border-radius);
display: inline-block;
position: relative;
img {
display: block;
border-radius: _size(border-radius);
}
&.left,
&.right {
width: 40%;
max-width: 10rem;
img {
width: 100%;
}
}
&.left {
float: left;
margin: 0 1.5rem 1rem 0;
top: 0.25rem;
}
&.right {
float: right;
margin: 0 0 1rem 1.5rem;
top: 0.25rem;
}
&.fit {
display: block;
margin: 0 0 _size(element-margin) 0;
width: 100%;
img {
width: 100%;
}
}
&.main {
display: block;
margin: 0 0 (_size(element-margin) * 1.5) 0;
width: 100%;
img {
width: 100%;
}
}
}

67
themes/hugo-story/assets/sass/components/_index.scss

@ -0,0 +1,67 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Index */
.index {
> * {
@include padding(3rem, 0);
@include vendor('display', 'flex');
border-top: solid 1px;
> header {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
width: 15rem;
}
> .content {
@include vendor('flex-grow', '1');
@include vendor('flex-shrink', '1');
}
}
> :first-child {
border-top: 0;
}
@include breakpoint('<=medium') {
> * {
> header {
width: 11rem;
}
}
}
@include breakpoint('<=small') {
> * {
> header {
width: 10rem;
}
}
}
@include breakpoint('<=xsmall') {
> * {
@include vendor('flex-direction', 'column');
> header {
width: 100%;
}
}
}
}
@mixin color-index($p: null) {
.index {
> * {
border-top-color: _palette($p, border);
}
}
}
@include color-index;

339
themes/hugo-story/assets/sass/components/_items.scss

@ -0,0 +1,339 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Items (transitions) */
.items {
// Mixin.
@mixin transition-items($event) {
$x: null;
$y: null;
@if ($event == 'load') {
$x: 'body.is-preload &';
$y: _duration(on-load);
}
@else if ($event == 'scroll') {
$x: '&.is-inactive';
$y: _duration(on-scroll);
}
&.on#{$event}-fade-in {
> * {
> .inner {
@include vendor('transition', 'opacity #{$y} ease-in-out');
@include vendor('transition-delay', '#{_misc(items-limit) * _duration(items-delay)}');
}
@for $i from 0 through _misc(items-limit) {
&:nth-child(#{$i + 1}) {
> .inner {
@include vendor('transition-delay', '#{$i * _duration(items-delay)}');
}
}
}
}
#{$x} {
> * {
> .inner {
opacity: 0;
}
}
}
}
}
// On Load.
@include transition-items('load');
// On Scroll.
@include transition-items('scroll');
}
/* Items (style1) */
@mixin items-style1-size($name, $size, $padding) {
&.#{$name} {
> * {
@include padding($padding, $padding);
width: #{100% / $size};
&:nth-child(-n + #{$size}) {
border-top-width: 0;
}
&:nth-child(#{$size}n + 1) {
border-left-width: 0;
}
}
}
}
@mixin items-style1-size-reset($name, $size) {
&.#{$name} {
> * {
&:nth-child(-n + #{$size}) {
border-top-width: _size(border-width);
}
&:nth-child(#{$size}n + 1) {
border-left-width: _size(border-width);
}
}
}
}
.items.style1 {
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
@include vendor('justify-content', 'center');
margin: (_size(element-margin) * 1.5) 0;
position: relative;
> * {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
border-style: solid;
border-left-width: _size(border-width);
border-top-width: _size(border-width);
}
// Modifiers.
// Size.
@include items-style1-size(big, 2, _size(gutter));
@include items-style1-size(medium, 3, _size(gutter) * 0.625);
@include items-style1-size(small, 4, _size(gutter) * 0.375);
@include breakpoint('<=large') {
@include items-style1-size-reset(small, 4);
@include items-style1-size(small, 3, _size(gutter) * 0.625);
}
@include breakpoint('<=medium') {
@include items-style1-size-reset(medium, 3);
@include items-style1-size(medium, 2, _size(gutter));
@include items-style1-size-reset(small, 3);
@include items-style1-size(small, 2, _size(gutter));
}
@include breakpoint('<=xsmall') {
@include items-style1-size-reset(big, 2);
@include items-style1-size(big, 1, _size(gutter) * 0.75);
@include items-style1-size-reset(medium, 2);
@include items-style1-size(medium, 1, _size(gutter) * 0.75);
@include items-style1-size-reset(small, 2);
@include items-style1-size(small, 1, _size(gutter) * 0.75);
&.big,
&.medium,
&.small {
> * {
padding-left: 0;
padding-right: 0;
}
> :first-child {
padding-top: 0;
}
> :last-child {
padding-bottom: 0;
> .inner {
> :last-child {
margin-bottom: 0;
}
}
}
}
}
}
/* Items (style2) */
@mixin items-style2-size($name, $size, $padding) {
&.#{$name} {
> * {
@include padding($padding, $padding);
width: #{100% / $size};
&:nth-child(-n + #{$size}) {
border-top-width: 0;
}
&:nth-child(#{$size}n + 1) {
border-left-width: 0;
}
}
}
}
@mixin items-style2-size-reset($name, $size) {
&.#{$name} {
> * {
&:nth-child(-n + #{$size}) {
border-top-width: _size(border-width);
}
&:nth-child(#{$size}n + 1) {
border-left-width: _size(border-width);
}
}
}
}
.items.style2 {
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
@include vendor('justify-content', 'center');
margin: (_size(element-margin) * 1.5) 0;
position: relative;
border: solid _size(border-width);
border-radius: _size(border-radius);
> * {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
border-style: solid;
border-left-width: _size(border-width);
border-top-width: _size(border-width);
}
// Modifiers.
// Size.
@include items-style2-size(big, 2, _size(gutter));
@include items-style2-size(medium, 3, _size(gutter) * 0.625);
@include items-style2-size(small, 4, _size(gutter) * 0.375);
@include breakpoint('<=large') {
@include items-style2-size-reset(small, 4);
@include items-style2-size(small, 3, _size(gutter) * 0.625);
}
@include breakpoint('<=medium') {
@include items-style2-size-reset(medium, 3);
@include items-style2-size(medium, 2, _size(gutter));
@include items-style2-size-reset(small, 3);
@include items-style2-size(small, 2, _size(gutter));
}
@include breakpoint('<=xsmall') {
@include items-style2-size-reset(big, 2);
@include items-style2-size(big, 1, _size(gutter) * 0.75);
@include items-style2-size-reset(medium, 2);
@include items-style2-size(medium, 1, _size(gutter) * 0.75);
@include items-style2-size-reset(small, 2);
@include items-style2-size(small, 1, _size(gutter) * 0.75);
}
}
/* Items (style3) */
@mixin items-style3-size($name, $size, $padding) {
&.#{$name} {
> * {
@include padding($padding, $padding);
width: #{100% / $size};
}
}
}
.items.style3 {
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
@include vendor('justify-content', 'center');
margin: (_size(element-margin) * 1.5) 0;
position: relative;
> * {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
}
// Modifiers.
// Size.
@include items-style3-size(big, 2, _size(gutter) * 0.5);
@include items-style3-size(medium, 3, _size(gutter) * 0.5 * 0.625);
@include items-style3-size(small, 4, _size(gutter) * 0.5 * 0.375);
@include breakpoint('<=large') {
@include items-style3-size(small, 3, _size(gutter) * 0.5 * 0.625);
}
@include breakpoint('<=medium') {
@include items-style3-size(medium, 2, _size(gutter) * 0.5);
@include items-style3-size(small, 2, _size(gutter) * 0.5);
}
@include breakpoint('<=small') {
margin: _size(element-margin) 0;
}
@include breakpoint('<=xsmall') {
@include items-style3-size(big, 1, _size(gutter) * 0.5 * 0.75);
@include items-style3-size(medium, 1, _size(gutter) * 0.5 * 0.75);
@include items-style3-size(small, 1, _size(gutter) * 0.5 * 0.75);
&.big,
&.medium,
&.small {
> * {
padding-left: 0;
padding-right: 0;
}
> :first-child {
padding-top: 0;
}
> :last-child {
padding-bottom: 0;
> .inner {
> :last-child {
margin-bottom: 0;
}
}
}
}
}
}
// Mixin
@mixin color-items($p: null) {
.items.style1 {
> * {
border-color: _palette($p, border);
}
}
.items.style2 {
border-color: _palette($p, border);
> * {
border-color: _palette($p, border);
}
}
}
@include color-items;

87
themes/hugo-story/assets/sass/components/_list.scss

@ -0,0 +1,87 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* List */
ol {
list-style: decimal;
margin: 0 0 _size(element-margin) 0;
padding-left: 1.25rem;
li {
padding-left: 0.25rem;
}
}
ul {
list-style: disc;
margin: 0 0 _size(element-margin) 0;
padding-left: 1rem;
li {
padding-left: 0.5rem;
}
&.alt {
list-style: none;
padding-left: 0;
li {
border-top: solid _size(border-width);
padding: 0.5rem 0;
&:first-child {
border-top: 0;
padding-top: 0;
}
}
}
}
dl {
margin: 0 0 _size(element-margin) 0;
dt {
display: block;
font-weight: _font(weight-bold);
margin: 0 0 (_size(element-margin) * 0.5) 0;
}
dd {
margin-left: _size(element-margin);
}
&.style2 {
dt {
width: 25%;
float: left;
}
dd {
width: 70%;
float: left;
}
&:after {
content: '';
display: block;
clear: both;
}
}
}
@mixin color-list($p: null) {
ul {
&.alt {
li {
border-top-color: _palette($p, border);
}
}
}
}
@include color-list;

36
themes/hugo-story/assets/sass/components/_row.scss

@ -0,0 +1,36 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Row */
.row {
@include html-grid(2rem);
@include breakpoint('<=xlarge') {
@include html-grid(2rem, 'xlarge');
}
@include breakpoint('<=large') {
@include html-grid(2rem, 'large');
}
@include breakpoint('<=medium') {
@include html-grid(2rem, 'medium');
}
@include breakpoint('<=small') {
@include html-grid(2rem, 'small');
}
@include breakpoint('<=xsmall') {
@include html-grid(2rem, 'xsmall');
}
@include breakpoint('<=xxsmall') {
@include html-grid(2rem, 'xxsmall');
}
}

50
themes/hugo-story/assets/sass/components/_section.scss

@ -0,0 +1,50 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Section/Article */
section, article {
&.special {
text-align: center;
}
}
header {
p {
position: relative;
margin: (_size(element-margin) * -0.325) 0 (_size(element-margin) * 0.75) 0;
font-style: italic;
}
h1 + p {
font-size: 1.375rem;
}
h2 + p {
font-size: 1.25rem;
}
h3 + p {
font-size: 1.1rem;
}
h4 + p,
h5 + p,
h6 + p {
font-size: 0.9rem;
}
}
@mixin color-section($p: null) {
header {
p {
color: _palette($p, fg-light);
}
}
}
@include color-section;

1013
themes/hugo-story/assets/sass/components/_spotlight.scss

File diff suppressed because it is too large Load Diff

138
themes/hugo-story/assets/sass/components/_table.scss

@ -0,0 +1,138 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Table */
.table-wrapper {
-webkit-overflow-scrolling: touch;
margin: 0 0 _size(element-margin) 0;
overflow-x: auto;
> table {
margin-bottom: 0;
}
}
table {
margin: 0 0 _size(element-margin) 0;
width: 100%;
tbody {
tr {
border: solid _size(border-width);
border-left: 0;
border-right: 0;
}
}
td {
padding: 0.75rem 0.75rem;
}
th {
font-size: 0.9rem;
font-weight: _font(weight-bold);
padding: 0 0.75rem 0.75rem 0.75rem;
text-align: left;
}
thead {
border-bottom: solid (_size(border-width) * 2);
}
tfoot {
border-top: solid (_size(border-width) * 2);
}
&.alt {
border-collapse: separate;
tbody {
tr {
td {
border: solid _size(border-width);
border-left-width: 0;
border-top-width: 0;
&:first-child {
border-left-width: _size(border-width);
}
}
&:first-child {
td {
border-top-width: _size(border-width);
}
}
}
}
thead {
border-bottom: 0;
}
tfoot {
border-top: 0;
}
}
&.fixed {
table-layout: fixed;
}
}
@mixin color-table($p: null) {
table {
tbody {
tr {
border-color: _palette($p, border);
&:nth-child(2n + 1) {
background-color: _palette($p, border-bg);
}
&.alt {
background-color: _palette($p, border-bg) !important;
}
}
}
th {
color: _palette($p, fg-bold);
}
thead {
border-bottom-color: _palette($p, border);
}
tfoot {
border-top-color: _palette($p, border);
}
&.alt {
tbody {
tr {
td {
border-color: _palette($p, border);
}
}
}
}
&.uniform {
tbody {
tr {
&:nth-child(2n + 1) {
background-color: transparent;
}
}
}
}
}
}
@include color-table;

121
themes/hugo-story/assets/sass/components/_wrapper.scss

@ -0,0 +1,121 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Wrapper (style1) */
.wrapper.style1 {
> .inner {
@include padding(_size(padding, default), _size(padding, default) * 0.5);
margin: 0 auto;
max-width: 100%;
width: _size(inner);
&.medium {
width: _size(inner) * 0.75;
}
&.small {
width: _size(inner) * 0.5;
}
}
@include breakpoint('<=xlarge') {
> .inner {
@include padding(_size(padding, xlarge), _size(padding, xlarge) * 0.5);
}
}
@include breakpoint('<=large') {
> .inner {
@include padding(_size(padding, large), _size(padding, large));
}
}
@include breakpoint('<=medium') {
> .inner {
@include padding(_size(padding, medium) * 1.5, _size(padding, medium));
}
}
@include breakpoint('<=small') {
> .inner {
@include padding(_size(padding, small) * 1.5, _size(padding, small));
}
}
}
/* Wrapper (style2) */
.wrapper.style2 {
padding: _size(padding, default);
background-color: _palette(bg-alt);
> .inner {
@include padding(_size(padding, default) * 0.75, _size(padding, default) * 0.5);
background-color: _palette(bg);
border-radius: _size(border-radius-alt);
margin: 0 auto;
max-width: 100%;
position: relative;
width: _size(inner);
z-index: 1;
&.medium {
width: _size(inner) * 0.75;
}
&.small {
width: _size(inner) * 0.5;
}
}
@include breakpoint('<=xlarge') {
padding: _size(padding, xlarge);
> .inner {
@include padding(_size(padding, xlarge) * 0.75, _size(padding, xlarge) * 0.5);
}
}
@include breakpoint('<=large') {
padding: _size(padding, large);
> .inner {
@include padding(_size(padding, large) * 0.75, _size(padding, large) * 0.5);
}
}
@include breakpoint('<=medium') {
padding: _size(padding, medium) * 0.75;
> .inner {
@include padding(_size(padding, medium), _size(padding, medium) * 0.75);
}
}
@include breakpoint('<=small') {
padding: _size(padding, small) * 0.75;
> .inner {
@include padding(_size(padding, small), _size(padding, small) * 0.75);
}
}
}
#wrapper {
> .wrapper.style2 {
&.invert {
&:not(.color1):not(.color2):not(.color3):not(.color4):not(.color5):not(.color6):not(.color7) {
background-color: _palette(invert, bg-alt);
}
> .inner {
background-color: _palette(invert, bg);
}
}
}
}

50
themes/hugo-story/assets/sass/layout/_wrapper.scss

@ -0,0 +1,50 @@
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Wrapper */
@mixin wrapper-color($n) {
> .color#{$n} {
background-color: _palette(color#{$n});
}
}
#wrapper {
background-color: inherit;
width: 100%;
overflow-x: hidden;
> .invert {
@include color(invert);
}
@include wrapper-color(1);
@include wrapper-color(2);
@include wrapper-color(3);
@include wrapper-color(4);
@include wrapper-color(5);
@include wrapper-color(6);
@include wrapper-color(7);
&.divided {
> * {
box-shadow: inset 0 1px 0 0 _palette(border-alt);
&:first-child {
box-shadow: none !important;
}
}
> .invert {
box-shadow: inset 0 1px 0 0 _palette(invert, border-alt);
&:first-child {
box-shadow: none !important;
}
}
}
}

223
themes/hugo-story/assets/sass/libs/_breakpoints.scss

@ -0,0 +1,223 @@
// breakpoints.scss v1.0 | @ajlkn | MIT licensed */
// Vars.
/// Breakpoints.
/// @var {list}
$breakpoints: () !global;
// Mixins.
/// Sets breakpoints.
/// @param {map} $x Breakpoints.
@mixin breakpoints($x: ()) {
$breakpoints: $x !global;
}
/// Wraps @content in a @media block targeting a specific orientation.
/// @param {string} $orientation Orientation.
@mixin orientation($orientation) {
@media screen and (orientation: #{$orientation}) {
@content;
}
}
/// Wraps @content in a @media block using a given query.
/// @param {string} $query Query.
@mixin breakpoint($query: null) {
$breakpoint: null;
$op: null;
$media: null;
// Determine operator, breakpoint.
// Greater than or equal.
@if (str-slice($query, 0, 2) == '>=') {
$op: 'gte';
$breakpoint: str-slice($query, 3);
}
// Less than or equal.
@elseif (str-slice($query, 0, 2) == '<=') {
$op: 'lte';
$breakpoint: str-slice($query, 3);
}
// Greater than.
@elseif (str-slice($query, 0, 1) == '>') {
$op: 'gt';
$breakpoint: str-slice($query, 2);
}
// Less than.
@elseif (str-slice($query, 0, 1) == '<') {
$op: 'lt';
$breakpoint: str-slice($query, 2);
}
// Not.
@elseif (str-slice($query, 0, 1) == '!') {
$op: 'not';
$breakpoint: str-slice($query, 2);
}
// Equal.
@else {
$op: 'eq';
$breakpoint: $query;
}
// Build media.
@if ($breakpoint and map-has-key($breakpoints, $breakpoint)) {
$a: map-get($breakpoints, $breakpoint);
// Range.
@if (type-of($a) == 'list') {
$x: nth($a, 1);
$y: nth($a, 2);
// Max only.
@if ($x == null) {
// Greater than or equal (>= 0 / anything)
@if ($op == 'gte') {
$media: 'screen';
}
// Less than or equal (<= y)
@elseif ($op == 'lte') {
$media: 'screen and (max-width: ' + $y + ')';
}
// Greater than (> y)
@elseif ($op == 'gt') {
$media: 'screen and (min-width: ' + ($y + 1) + ')';
}
// Less than (< 0 / invalid)
@elseif ($op == 'lt') {
$media: 'screen and (max-width: -1px)';
}
// Not (> y)
@elseif ($op == 'not') {
$media: 'screen and (min-width: ' + ($y + 1) + ')';
}
// Equal (<= y)
@else {
$media: 'screen and (max-width: ' + $y + ')';
}
}
// Min only.
@else if ($y == null) {
// Greater than or equal (>= x)
@if ($op == 'gte') {
$media: 'screen and (min-width: ' + $x + ')';
}
// Less than or equal (<= inf / anything)
@elseif ($op == 'lte') {
$media: 'screen';
}
// Greater than (> inf / invalid)
@elseif ($op == 'gt') {
$media: 'screen and (max-width: -1px)';
}
// Less than (< x)
@elseif ($op == 'lt') {
$media: 'screen and (max-width: ' + ($x - 1) + ')';
}
// Not (< x)
@elseif ($op == 'not') {
$media: 'screen and (max-width: ' + ($x - 1) + ')';
}
// Equal (>= x)
@else {
$media: 'screen and (min-width: ' + $x + ')';
}
}
// Min and max.
@else {
// Greater than or equal (>= x)
@if ($op == 'gte') {
$media: 'screen and (min-width: ' + $x + ')';
}
// Less than or equal (<= y)
@elseif ($op == 'lte') {
$media: 'screen and (max-width: ' + $y + ')';
}
// Greater than (> y)
@elseif ($op == 'gt') {
$media: 'screen and (min-width: ' + ($y + 1) + ')';
}
// Less than (< x)
@elseif ($op == 'lt') {
$media: 'screen and (max-width: ' + ($x - 1) + ')';
}
// Not (< x and > y)
@elseif ($op == 'not') {
$media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')';
}
// Equal (>= x and <= y)
@else {
$media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')';
}
}
}
// String.
@else {
// Missing a media type? Prefix with "screen".
@if (str-slice($a, 0, 1) == '(') {
$media: 'screen and ' + $a;
}
// Otherwise, use as-is.
@else {
$media: $a;
}
}
}
// Output.
@media #{$media} {
@content;
}
}

90
themes/hugo-story/assets/sass/libs/_functions.scss

@ -0,0 +1,90 @@
/// Removes a specific item from a list.
/// @author Hugo Giraudel
/// @param {list} $list List.
/// @param {integer} $index Index.
/// @return {list} Updated list.
@function remove-nth($list, $index) {
$result: null;
@if type-of($index) != number {
@warn "$index: #{quote($index)} is not a number for `remove-nth`.";
}
@else if $index == 0 {
@warn "List index 0 must be a non-zero integer for `remove-nth`.";
}
@else if abs($index) > length($list) {
@warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
}
@else {
$result: ();
$index: if($index < 0, length($list) + $index + 1, $index);
@for $i from 1 through length($list) {
@if $i != $index {
$result: append($result, nth($list, $i));
}
}
}
@return $result;
}
/// Gets a value from a map.
/// @author Hugo Giraudel
/// @param {map} $map Map.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function val($map, $keys...) {
@if nth($keys, 1) == null {
$keys: remove-nth($keys, 1);
}
@each $key in $keys {
$map: map-get($map, $key);
}
@return $map;
}
/// Gets a duration value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _duration($keys...) {
@return val($duration, $keys...);
}
/// Gets a font value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _font($keys...) {
@return val($font, $keys...);
}
/// Gets a misc value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _misc($keys...) {
@return val($misc, $keys...);
}
/// Gets a palette value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _palette($keys...) {
@return val($palette, $keys...);
}
/// Gets a size value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _size($keys...) {
@return val($size, $keys...);
}

149
themes/hugo-story/assets/sass/libs/_html-grid.scss

@ -0,0 +1,149 @@
// html-grid.scss v1.0 | @ajlkn | MIT licensed */
// Mixins.
/// Initializes the current element as an HTML grid.
/// @param {mixed} $gutters Gutters (either a single number to set both column/row gutters, or a list to set them individually).
/// @param {mixed} $suffix Column class suffix (optional; either a single suffix or a list).
@mixin html-grid($gutters: 1.5em, $suffix: '') {
// Initialize.
$cols: 12;
$multipliers: 0, 0.25, 0.5, 1, 1.50, 2.00;
$unit: 100% / $cols;
// Suffixes.
$suffixes: null;
@if (type-of($suffix) == 'list') {
$suffixes: $suffix;
}
@else {
$suffixes: ($suffix);
}
// Gutters.
$guttersCols: null;
$guttersRows: null;
@if (type-of($gutters) == 'list') {
$guttersCols: nth($gutters, 1);
$guttersRows: nth($gutters, 2);
}
@else {
$guttersCols: $gutters;
$guttersRows: 0;
}
// Row.
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
// Columns.
> * {
box-sizing: border-box;
}
// Gutters.
&.gtr-uniform {
> * {
> :last-child {
margin-bottom: 0;
}
}
}
// Alignment.
&.aln-left {
justify-content: flex-start;
}
&.aln-center {
justify-content: center;
}
&.aln-right {
justify-content: flex-end;
}
&.aln-top {
align-items: flex-start;
}
&.aln-middle {
align-items: center;
}
&.aln-bottom {
align-items: flex-end;
}
// Step through suffixes.
@each $suffix in $suffixes {
// Suffix.
@if ($suffix != '') {
$suffix: '-' + $suffix;
}
@else {
$suffix: '';
}
// Row.
// Important.
> .imp#{$suffix} {
order: -1;
}
// Columns, offsets.
@for $i from 1 through $cols {
> .col-#{$i}#{$suffix} {
width: $unit * $i;
}
> .off-#{$i}#{$suffix} {
margin-left: $unit * $i;
}
}
// Step through multipliers.
@each $multiplier in $multipliers {
// Gutters.
$class: null;
@if ($multiplier != 1) {
$class: '.gtr-' + ($multiplier * 100);
}
&#{$class} {
margin-top: ($guttersRows * $multiplier * -1);
margin-left: ($guttersCols * $multiplier * -1);
> * {
padding: ($guttersRows * $multiplier) 0 0 ($guttersCols * $multiplier);
}
// Uniform.
&.gtr-uniform {
margin-top: $guttersCols * $multiplier * -1;
> * {
padding-top: $guttersCols * $multiplier;
}
}
}
}
}
}

78
themes/hugo-story/assets/sass/libs/_mixins.scss

@ -0,0 +1,78 @@
/// Makes an element's :before pseudoelement a FontAwesome icon.
/// @param {string} $content Optional content value to use.
/// @param {string} $category Optional category to use.
/// @param {string} $where Optional pseudoelement to target (before or after).
@mixin icon($content: false, $category: regular, $where: before) {
text-decoration: none;
&:#{$where} {
@if $content {
content: $content;
}
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
text-transform: none !important;
@if ($category == brands) {
font-family: 'Font Awesome 5 Brands';
}
@elseif ($category == solid) {
font-family: 'Font Awesome 5 Pro';
font-weight: 900;
}
@else {
font-family: 'Font Awesome 5 Pro';
font-weight: 400;
}
}
}
/// Applies padding to an element, taking the current element-margin value into account.
/// @param {mixed} $tb Top/bottom padding.
/// @param {mixed} $lr Left/right padding.
/// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left)
/// @param {bool} $important If true, adds !important.
@mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) {
@if $important {
$important: '!important';
}
$x: 0.1em;
@if unit(_size(element-margin)) == 'rem' {
$x: 0.1rem;
}
padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important};
}
/// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp).
/// @param {string} $svg SVG data URL.
/// @return {string} Encoded SVG data URL.
@function svg-url($svg) {
$svg: str-replace($svg, '"', '\'');
$svg: str-replace($svg, '%', '%25');
$svg: str-replace($svg, '<', '%3C');
$svg: str-replace($svg, '>', '%3E');
$svg: str-replace($svg, '&', '%26');
$svg: str-replace($svg, '#', '%23');
$svg: str-replace($svg, '{', '%7B');
$svg: str-replace($svg, '}', '%7D');
$svg: str-replace($svg, ';', '%3B');
@return url("data:image/svg+xml;charset=utf8,#{$svg}");
}

80
themes/hugo-story/assets/sass/libs/_vars.scss

@ -0,0 +1,80 @@
// Misc.
$misc: (
z-index-base: 10000,
overlay-opacity: 0.5,
lightbox-opacity: 0.75,
gallery-limit: 32,
items-limit: 16
);
// Duration.
$duration: (
menu: 0.5s,
transition: 0.2s,
gallery-lightbox: 0.5s,
gallery-delay: 0.15s,
items-delay: 0.15s,
on-load: 0.75s,
on-scroll: 0.75s
);
// Size.
$size: (
border-radius: 4px,
border-radius-alt: 0.5rem,
border-width: 1px,
element-height: 2.75rem,
element-margin: 2rem,
gutter: 3.5rem,
inner: 64rem,
padding: (
default: 7rem,
xlarge: 5rem,
large: 4rem,
medium: 3rem,
small: 2rem
)
);
// Font.
$font: (
family: ('Source Sans Pro', Helvetica, sans-serif),
family-fixed: ('Courier New', monospace),
weight: 300,
weight-bold: 400,
kerning: -0.05em,
kerning-alt: 0.125em
);
// Palette.
$palette: (
color1: #30363d,
color2: #db8992,
color3: #ab7aad,
color4: #897cad,
color5: #7794ce,
color6: #64abb4,
color7: #6ba78c,
bg: #ffffff,
bg-alt: #eeeeee,
fg: #000000,
fg-bold: #000000,
fg-light: rgba(0,0,0,0.75),
border: rgba(0,0,0,0.2),
border-alt: rgba(0,0,0,0.075),
border-bg: rgba(0,0,0,0.05),
accent: #837164,
invert: (
bg: #000000,
bg-alt: #222222,
fg: #ffffff,
fg-bold: #ffffff,
fg-light: #ffffff,
border: rgba(255,255,255,1.0),
border-alt: rgba(255,255,255,0.125),
border-bg: rgba(255,255,255,0.125),
accent: #837164
),
);

376
themes/hugo-story/assets/sass/libs/_vendor.scss

@ -0,0 +1,376 @@
// vendor.scss v1.0 | @ajlkn | MIT licensed */
// Vars.
/// Vendor prefixes.
/// @var {list}
$vendor-prefixes: (
'-moz-',
'-webkit-',
'-ms-',
''
);
/// Properties that should be vendorized.
/// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
/// @var {list}
$vendor-properties: (
// Animation.
'animation',
'animation-delay',
'animation-direction',
'animation-duration',
'animation-fill-mode',
'animation-iteration-count',
'animation-name',
'animation-play-state',
'animation-timing-function',
// Appearance.
'appearance',
// Backdrop filter.
'backdrop-filter',
// Background image options.
'background-clip',
'background-origin',
'background-size',
// Box sizing.
'box-sizing',
// Clip path.
'clip-path',
// Filter effects.
'filter',
// Flexbox.
'align-content',
'align-items',
'align-self',
'flex',
'flex-basis',
'flex-direction',
'flex-flow',
'flex-grow',
'flex-shrink',
'flex-wrap',
'justify-content',
'order',
// Font feature.
'font-feature-settings',
'font-language-override',
'font-variant-ligatures',
// Font kerning.
'font-kerning',
// Fragmented borders and backgrounds.
'box-decoration-break',
// Grid layout.
'grid-column',
'grid-column-align',
'grid-column-end',
'grid-column-start',
'grid-row',
'grid-row-align',
'grid-row-end',
'grid-row-start',
'grid-template-columns',
'grid-template-rows',
// Hyphens.
'hyphens',
'word-break',
// Masks.
'mask',
'mask-border',
'mask-border-outset',
'mask-border-repeat',
'mask-border-slice',
'mask-border-source',
'mask-border-width',
'mask-clip',
'mask-composite',
'mask-image',
'mask-origin',
'mask-position',
'mask-repeat',
'mask-size',
// Multicolumn.
'break-after',
'break-before',
'break-inside',
'column-count',
'column-fill',
'column-gap',
'column-rule',
'column-rule-color',
'column-rule-style',
'column-rule-width',
'column-span',
'column-width',
'columns',
// Object fit.
'object-fit',
'object-position',
// Regions.
'flow-from',
'flow-into',
'region-fragment',
// Scroll snap points.
'scroll-snap-coordinate',
'scroll-snap-destination',
'scroll-snap-points-x',
'scroll-snap-points-y',
'scroll-snap-type',
// Shapes.
'shape-image-threshold',
'shape-margin',
'shape-outside',
// Tab size.
'tab-size',
// Text align last.
'text-align-last',
// Text decoration.
'text-decoration-color',
'text-decoration-line',
'text-decoration-skip',
'text-decoration-style',
// Text emphasis.
'text-emphasis',
'text-emphasis-color',
'text-emphasis-position',
'text-emphasis-style',
// Text size adjust.
'text-size-adjust',
// Text spacing.
'text-spacing',
// Transform.
'transform',
'transform-origin',
// Transform 3D.
'backface-visibility',
'perspective',
'perspective-origin',
'transform-style',
// Transition.
'transition',
'transition-delay',
'transition-duration',
'transition-property',
'transition-timing-function',
// Unicode bidi.
'unicode-bidi',
// User select.
'user-select',
// Writing mode.
'writing-mode',
);
/// Values that should be vendorized.
/// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
/// @var {list}
$vendor-values: (
// Cross fade.
'cross-fade',
// Element function.
'element',
// Filter function.
'filter',
// Flexbox.
'flex',
'inline-flex',
// Grab cursors.
'grab',
'grabbing',
// Gradients.
'linear-gradient',
'repeating-linear-gradient',
'radial-gradient',
'repeating-radial-gradient',
// Grid layout.
'grid',
'inline-grid',
// Image set.
'image-set',
// Intrinsic width.
'max-content',
'min-content',
'fit-content',
'fill',
'fill-available',
'stretch',
// Sticky position.
'sticky',
// Transform.
'transform',
// Zoom cursors.
'zoom-in',
'zoom-out',
);
// Functions.
/// Removes a specific item from a list.
/// @author Hugo Giraudel
/// @param {list} $list List.
/// @param {integer} $index Index.
/// @return {list} Updated list.
@function remove-nth($list, $index) {
$result: null;
@if type-of($index) != number {
@warn "$index: #{quote($index)} is not a number for `remove-nth`.";
}
@else if $index == 0 {
@warn "List index 0 must be a non-zero integer for `remove-nth`.";
}
@else if abs($index) > length($list) {
@warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
}
@else {
$result: ();
$index: if($index < 0, length($list) + $index + 1, $index);
@for $i from 1 through length($list) {
@if $i != $index {
$result: append($result, nth($list, $i));
}
}
}
@return $result;
}
/// Replaces a substring within another string.
/// @author Hugo Giraudel
/// @param {string} $string String.
/// @param {string} $search Substring.
/// @param {string} $replace Replacement.
/// @return {string} Updated string.
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
/// Replaces a substring within each string in a list.
/// @param {list} $strings List of strings.
/// @param {string} $search Substring.
/// @param {string} $replace Replacement.
/// @return {list} Updated list of strings.
@function str-replace-all($strings, $search, $replace: '') {
@each $string in $strings {
$strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace));
}
@return $strings;
}
// Mixins.
/// Wraps @content in vendorized keyframe blocks.
/// @param {string} $name Name.
@mixin keyframes($name) {
@-moz-keyframes #{$name} { @content; }
@-webkit-keyframes #{$name} { @content; }
@-ms-keyframes #{$name} { @content; }
@keyframes #{$name} { @content; }
}
/// Vendorizes a declaration's property and/or value(s).
/// @param {string} $property Property.
/// @param {mixed} $value String/list of value(s).
@mixin vendor($property, $value) {
// Determine if property should expand.
$expandProperty: index($vendor-properties, $property);
// Determine if value should expand (and if so, add '-prefix-' placeholder).
$expandValue: false;
@each $x in $value {
@each $y in $vendor-values {
@if $y == str-slice($x, 1, str-length($y)) {
$value: set-nth($value, index($value, $x), '-prefix-' + $x);
$expandValue: true;
}
}
}
// Expand property?
@if $expandProperty {
@each $vendor in $vendor-prefixes {
#{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
}
}
// Expand just the value?
@elseif $expandValue {
@each $vendor in $vendor-prefixes {
#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
}
}
// Neither? Treat them as a normal declaration.
@else {
#{$property}: #{$value};
}
}

186
themes/hugo-story/assets/sass/main.scss

@ -0,0 +1,186 @@
@import 'libs/vars';
@import 'libs/functions';
@import 'libs/mixins';
@import 'libs/vendor';
@import 'libs/breakpoints';
@import 'libs/html-grid';
@import 'fontawesome-all.min.css';
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,400,400i');
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
// Breakpoints.
@include breakpoints((
xlarge: ( 1281px, 1680px ),
large: ( 981px, 1280px ),
medium: ( 737px, 980px ),
small: ( 481px, 736px ),
xsmall: ( 361px, 480px ),
xxsmall: ( null, 360px )
));
// Mixins.
@mixin color($p) {
@include color-typography($p);
@include color-box($p);
@include color-button($p);
@include color-form($p);
@include color-icon($p);
@include color-list($p);
@include color-section($p);
@include color-table($p);
@include color-banner($p);
@include color-spotlight($p);
@include color-gallery($p);
@include color-items($p);
@include color-index($p);
}
// Phone.
@mixin phone($image-width) {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
border-radius: 0;
border: solid _size(border-width);
img {
@include vendor('object-fit', 'cover');
@include vendor('object-position', 'center');
display: block;
width: 100%;
height: 100%;
border-radius: 0;
}
&:before {
content: '';
display: block;
background-position: center;
background-repeat: no-repeat;
border: solid _size(border-width);
border-bottom: 0;
}
&:after {
content: '';
display: block;
background-position: center;
background-repeat: no-repeat;
border: solid _size(border-width);
border-top: 0;
}
@include resize-phone($image-width, 1);
}
@mixin resize-phone($image-width, $image-factor) {
$image-pad-top: 2.5rem;
$image-pad-bottom: 3rem;
$image-height: ($image-width * (1920 / 1080));
width: ($image-width * $image-factor);
height: (($image-width * $image-factor) * (1920 / 1080));
margin-top: ($image-pad-top * $image-factor);
margin-bottom: (_size(element-margin) + ($image-pad-bottom * $image-factor));
&:before {
height: ($image-pad-top * $image-factor);
background-size: (64px * $image-factor) (32px * $image-factor);
margin-top: (($image-pad-top * $image-factor) * -1);
border-radius: (1rem * $image-factor) (1rem * $image-factor) 0 0;
}
&:after {
height: ($image-pad-bottom * $image-factor);
background-size: (64px * $image-factor) (32px * $image-factor);
margin-bottom: (($image-pad-bottom * $image-factor) * -1);
border-radius: 0 0 (1rem * $image-factor) (1rem * $image-factor);
}
}
@mixin color-phone($p) {
border-color: _palette($p, border);
background-color: _palette($p, border);
@if ($p != 'invert') {
border-width: 0;
}
@else {
border-width: _size(border-width);
}
&:before {
background-image: svg-url('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="32px" viewBox="0 0 64 32" zoomAndPan="disable"><style>rect {fill: transparent; stroke: #{_palette($p, border)}; stroke-width: #{_size(border-width)}; }</style><rect rx="4" ry="4" x="11" y="12" width="42" height="8" vector-effect="non-scaling-stroke" /></svg>');
border-color: _palette($p, border);
@if ($p == 'invert') {
width: calc(100% + #{_size(border-width) * 2});
margin-left: (_size(border-width) * -1);
}
@else {
width: 100%;
}
}
&:after {
background-image: svg-url('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="32px" viewBox="0 0 64 32" zoomAndPan="disable"><style>circle {fill: transparent; stroke: #{_palette($p, border)}; stroke-width: #{_size(border-width)}; }</style><circle cx="32" cy="16" r="14" vector-effect="non-scaling-stroke" /></svg>');
border-color: _palette($p, border);
@if ($p == 'invert') {
width: calc(100% + #{_size(border-width) * 2});
margin-left: (_size(border-width) * -1);
}
@else {
width: 100%;
}
}
}
@mixin color-phone-variant($v, $p) {
@if ($v == 'android') {
&:after {
background-image: svg-url('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="32px" viewBox="0 0 64 32" zoomAndPan="disable"><style>rect {fill: transparent; stroke: #{_palette($p, border)}; stroke-width: #{_size(border-width)}; }</style><rect rx="4" ry="4" x="6" y="4" width="52" height="24" vector-effect="non-scaling-stroke" /></svg>');
}
}
@else if ($p == 'iphone') {
// ...
}
}
// Base.
@import 'base/reset';
@import 'base/page';
@import 'base/typography';
// Component.
@import 'components/row';
@import 'components/box';
@import 'components/button';
@import 'components/form';
@import 'components/icon';
@import 'components/image';
@import 'components/list';
@import 'components/actions';
@import 'components/icons';
@import 'components/section';
@import 'components/table';
@import 'components/banner';
@import 'components/spotlight';
@import 'components/gallery';
@import 'components/wrapper';
@import 'components/items';
@import 'components/index';
// Layout.
@import 'layout/wrapper';

208
themes/hugo-story/assets/sass/noscript.scss

@ -0,0 +1,208 @@
@import 'libs/vars';
@import 'libs/functions';
@import 'libs/mixins';
@import 'libs/vendor';
@import 'libs/breakpoints';
@import 'libs/html-grid';
/*
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
*/
/* Banner (transitions) */
.banner {
// Mixin.
@mixin transition-banner($event) {
$x: null;
$y: null;
@if ($event == 'load') {
$x: 'body.is-preload &';
$y: _duration(on-load);
}
@else if ($event == 'scroll') {
$x: '&.is-inactive';
$y: _duration(on-scroll);
}
// Content.
&.on#{$event}-content-fade-up {
.content {
@include vendor('transition', 'none');
}
#{$x} {
.content {
@include vendor('transform', 'none');
opacity: 1;
}
}
}
&.on#{$event}-content-fade-down {
.content {
@include vendor('transition', 'none');
}
#{$x} {
.content {
@include vendor('transform', 'none');
opacity: 1;
}
}
}
&.on#{$event}-content-fade-left {
.content {
@include vendor('transition', 'none');
}
#{$x} {
.content {
@include vendor('transform', 'none');
opacity: 1;
}
}
}
&.on#{$event}-content-fade-right {
.content {
@include vendor('transition', 'none');
}
#{$x} {
.content {
@include vendor('transform', 'none');
opacity: 1;
}
}
}
&.on#{$event}-content-fade-in {
.content {
@include vendor('transition', 'none');
}
#{$x} {
.content {
@include vendor('transform', 'none');
opacity: 1;
}
}
}
// Image.
&.on#{$event}-image-fade-up {
.image {
@include vendor('transition', 'none');
img {
@include vendor('transition', 'none');
}
}
#{$x} {
.image {
@include vendor('transform', 'none');
opacity: 1;
img {
opacity: 1;
}
}
}
}
&.on#{$event}-image-fade-down {
.image {
@include vendor('transition', 'none');
img {
@include vendor('transition', 'none');
}
}
#{$x} {
.image {
@include vendor('transform', 'none');
opacity: 1;
img {
opacity: 1;
}
}
}
}
&.on#{$event}-image-fade-left {
.image {
@include vendor('transition', 'none');
img {
@include vendor('transition', 'none');
}
}
#{$x} {
.image {
@include vendor('transform', 'none');
opacity: 1;
img {
opacity: 1;
}
}
}
}
&.on#{$event}-image-fade-right {
.image {
@include vendor('transition', 'none');
img {
@include vendor('transition', 'none');
}
}
#{$x} {
.image {
@include vendor('transform', 'none');
opacity: 1;
img {
opacity: 1;
}
}
}
}
&.on#{$event}-image-fade-in {
.image {
img {
@include vendor('transition', 'none');
}
}
#{$x} {
.image {
img {
opacity: 1;
}
}
}
}
}
// On Load.
@include transition-banner('load');
// On Scroll.
@include transition-banner('scroll');
}

BIN
themes/hugo-story/images/device-screenshots.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

BIN
themes/hugo-story/images/screenshot.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
themes/hugo-story/images/tn.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

24
themes/hugo-story/layouts/_default/baseof.html

@ -0,0 +1,24 @@
<!DOCTYPE HTML>
<!--
Hugo Story by CaressOfSteel
A (modular, highly tweakable) responsive one-page theme for Hugo.
Ported from Story by HTML5UP.
This Hugo theme is licensed under the Creative Commons Attribution 3.0 License.
-->
<html>
{{ partial "template/head" . }}
<body class="is-preload">
<!-- Wrapper -->
<div id="wrapper" class="divided">
{{- block "main" . }}{{- end }}
<!-- Wrapper -->
</div>
<!-- {{ template "_internal/google_analytics.html" . }} -->
{{ partial "template/scripts" . }}
</body>
</html>

13
themes/hugo-story/layouts/index.html

@ -0,0 +1,13 @@
{{ define "main" }}
{{ partial "banner" site.Data.banner }}
{{ partial "spotlight" site.Data.spotlight1 }}
{{ partial "spotlight" site.Data.spotlight2 }}
{{ partial "spotlight" site.Data.spotlight3 }}
{{ partial "gallery" site.Data.gallery }}
{{ partial "items" site.Data.items }}
{{ partial "elements" . }}
{{ partial "elements_reference" . }}
{{ partial "template/footer" . }}
{{ end }}

14
themes/hugo-story/layouts/partials/banner.html

@ -0,0 +1,14 @@
<!-- Banner -->
<section class="banner {{ .style }}">
<div class="content">
{{ with .title }}<h1>{{ . }}</h1>{{ end }}
{{ with .subtitle }}<p class="major">{{ . | safeHTML }}</p>{{ end }}
{{ with .content }}<p>{{ . | safeHTML }}</p>{{ end }}
{{ with .button }}<ul class="actions stacked">
<li><a href="{{ .link }}" class="button primary large wide smooth-scroll-middle">{{ .label }}</a></li>
</ul>{{ end }}
</div>
{{ with .image }}<div class="image">
<img src="{{.}}" alt="Hugo Story" />
</div>{{end}}
</section>

472
themes/hugo-story/layouts/partials/elements.html

@ -0,0 +1,472 @@
<!-- Additional Elements -->
<section class="wrapper style1 align-center">
<div class="inner">
<h2>Additional Elements</h2>
<p>Finally, here are some additional elements you <em>might</em> find useful (and yup, they look fine with any <span class="demo-controls">appearance</span>).</p>
<div class="index align-left">
<!-- Text -->
<section>
<header>
<h3>Text</h3>
</header>
<div class="content">
<p>This is <b>bold</b> and this is <strong>strong</strong>. This is <i>italic</i> and this is <em>emphasized</em>.
This is <sup>superscript</sup> text and this is <sub>subscript</sub> text.
This is <u>underlined</u> and this is code: <code>for (;;) { ... }</code>.
Finally, this is a <a href="#">link</a>.</p>
</div>
</section>
<!-- Heading -->
<section>
<header>
<h3>Headings</h3>
</header>
<div class="content">
<h1>Heading Level 1</h1>
<h2>Heading Level 2</h2>
<h3>Heading Level 3</h3>
<h4>Heading Level 4</h4>
<h5>Heading Level 5</h5>
<h6>Heading Level 6</h6>
<hr />
<header>
<h1>Heading with a Subtitle</h1>
<p>Lorem ipsum dolor sit amet nullam id egestas urna aliquam</p>
</header>
<p>Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing blandit tempus accumsan.</p>
<hr />
<header>
<h2>Heading with a Subtitle</h2>
<p>Lorem ipsum dolor sit amet nullam id egestas urna aliquam</p>
</header>
<p>Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing blandit tempus accumsan.</p>
<hr />
<header>
<h3>Heading with a Subtitle</h3>
<p>Lorem ipsum dolor sit amet nullam id egestas urna aliquam</p>
</header>
<p>Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing blandit tempus accumsan.</p>
</div>
</section>
<!-- Unordered List -->
<section>
<header>
<h3>Unordered List</h3>
</header>
<div class="content">
<h4>Default</h4>
<ul>
<li>Lorem ipsum dolor sit amet</li>
<li>Interdum adipiscing gravida odio</li>
<li>Porttitor sem non integer</li>
<li>Non faucibus ornare mi ut ante</li>
<li>Sagittis adipiscing eleifend</li>
<li>Felis amet dolore viverra</li>
</ul>
<h4>Alternate</h4>
<ul class="alt">
<li>Lorem ipsum dolor sit amet</li>
<li>Interdum adipiscing gravida odio</li>
<li>Porttitor sem non integer</li>
<li>Non faucibus ornare mi ut ante</li>
<li>Sagittis adipiscing eleifend</li>
<li>Felis amet dolore viverra</li>
</ul>
</div>
</section>
<!-- Ordered List -->
<section>
<header>
<h3>Ordered List</h3>
</header>
<div class="content">
<ol>
<li>Lorem ipsum dolor sit amet</li>
<li>Interdum adipiscing gravida odio</li>
<li>Porttitor sem non integer</li>
<li>Non faucibus ornare mi ut ante</li>
<li>Sagittis adipiscing eleifend</li>
<li>Felis amet dolore viverra</li>
</ol>
</div>
</section>
<!-- Definition List -->
<section>
<header>
<h3>Definition List</h3>
</header>
<div class="content">
<dl>
<dt>Interdum adipiscing odio</dt>
<dd>
<p>Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent fringilla quis tincidunt felis sagittis eget tempus euismod. Ante ipsum primis vestibulum.</p>
</dd>
<dt>Non faucibus ornare mi ut ante</dt>
<dd>
<p>Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent fringilla quis tincidunt felis sagittis eget tempus euismod. Ante ipsum primis vestibulum.</p>
</dd>
<dt>Felis amet dolore viverra</dt>
<dd>
<p>Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent fringilla quis tincidunt felis sagittis eget tempus euismod. Ante ipsum primis vestibulum.</p>
</dd>
</dl>
</div>
</section>
<!-- Blockquote -->
<section>
<header>
<h3>Blockquote</h3>
</header>
<div class="content">
<blockquote>Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent fringilla quis tincidunt felis sagittis eget tempus euismod. Ante ipsum primis vestibulum.</blockquote>
</div>
</section>
<!-- Code -->
<section>
<header>
<h3>Code</h3>
</header>
<div class="content">
<pre><code>i = 0;
while (!deck.isInOrder()) {
print 'Iteration ' + i;
deck.shuffle();
i++;
}
print 'It took ' + i + ' iterations to sort the deck.';
</code></pre>
</div>
</section>
<!-- Icons -->
<section>
<header>
<h3>Icons</h3>
</header>
<div class="content">
<h4>Style #1</h4>
<ul class="icons">
<li><a href="#" class="icon brands style1 fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands style1 fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands style1 fa-instagram"><span class="label">Instagram</span></a></li>
<li><a href="#" class="icon brands style1 fa-github"><span class="label">Github</span></a></li>
<li><a href="#" class="icon brands style1 fa-dribbble"><span class="label">Dribbble</span></a></li>
</ul>
<h4>Style #2</h4>
<ul class="icons">
<li><a href="#" class="icon brands style2 fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands style2 fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands style2 fa-instagram"><span class="label">Instagram</span></a></li>
<li><a href="#" class="icon brands style2 fa-github"><span class="label">Github</span></a></li>
<li><a href="#" class="icon brands style2 fa-dribbble"><span class="label">Dribbble</span></a></li>
</ul>
</div>
</section>
<!-- Buttons -->
<section>
<header>
<h3>Buttons</h3>
</header>
<div class="content">
<ul class="actions">
<li><a href="#" class="button primary">Primary</a></li>
<li><a href="#" class="button">Default</a></li>
</ul>
<ul class="actions">
<li><a href="#" class="button primary large">Large</a></li>
<li><a href="#" class="button">Default</a></li>
<li><a href="#" class="button small">Small</a></li>
</ul>
<ul class="actions fit">
<li><a href="#" class="button primary fit">Fit</a></li>
<li><a href="#" class="button fit">Fit</a></li>
<li><a href="#" class="button primary fit">Fit</a></li>
<li><a href="#" class="button fit">Fit</a></li>
</ul>
<ul class="actions fit small">
<li><a href="#" class="button primary fit small">Fit + Small</a></li>
<li><a href="#" class="button fit small">Fit + Small</a></li>
<li><a href="#" class="button primary fit small">Fit + Small</a></li>
<li><a href="#" class="button fit small">Fit + Small</a></li>
</ul>
<ul class="actions">
<li><a href="#" class="button primary icon solid fa-search">Icon</a></li>
<li><a href="#" class="button icon solid fa-download">Icon</a></li>
</ul>
<ul class="actions">
<li><span class="button primary disabled">Primary</span></li>
<li><span class="button disabled">Default</span></li>
</ul>
</div>
</section>
<!-- Actions -->
<section>
<header>
<h3>Actions</h3>
</header>
<div class="content">
<h4>Default</h4>
<ul class="actions">
<li><a href="#" class="button primary">Default</a></li>
<li><a href="#" class="button">Default</a></li>
</ul>
<h4>Small</h4>
<ul class="actions small">
<li><a href="#" class="button primary small">Small</a></li>
<li><a href="#" class="button small">Small</a></li>
</ul>
<h4>Stacked</h4>
<ul class="actions stacked">
<li><a href="#" class="button primary">Default</a></li>
<li><a href="#" class="button">Default</a></li>
</ul>
<h4>Stacked + Fit</h4>
<ul class="actions stacked">
<li><a href="#" class="button primary fit">Default</a></li>
<li><a href="#" class="button fit">Default</a></li>
</ul>
</div>
</section>
<!-- Form -->
<section>
<header>
<h3>Form</h3>
</header>
<div class="content">
<form method="post" action="#">
<div class="fields">
<div class="field half">
<label for="name">Name</label>
<input type="text" name="name" id="name" value="" />
</div>
<div class="field half">
<label for="email">Email</label>
<input type="email" name="email" id="email" value="" />
</div>
<div class="field">
<label for="department">Department</label>
<select name="department" id="department">
<option value="">- Category -</option>
<option value="1">Manufacturing</option>
<option value="2">Shipping</option>
<option value="3">Administration</option>
<option value="4">Human Resources</option>
</select>
</div>
<div class="field third">
<input type="radio" id="priority-low" name="priority" checked />
<label for="priority-low">Low Priority</label>
</div>
<div class="field third">
<input type="radio" id="priority-normal" name="priority" />
<label for="priority-normal">Normal Priority</label>
</div>
<div class="field third">
<input type="radio" id="priority-high" name="priority" />
<label for="priority-high">High Priority</label>
</div>
<div class="field">
<label for="message">Message</label>
<textarea name="message" id="message" rows="6"></textarea>
</div>
<div class="field half">
<input type="checkbox" id="copy" name="copy" />
<label for="copy">Email me a copy of this message</label>
</div>
<div class="field half">
<input type="checkbox" id="human" name="human" checked />
<label for="human">I am a human and not a robot</label>
</div>
</div>
<ul class="actions">
<li><input type="submit" name="submit" id="submit" value="Send Message" /></li>
</ul>
</form>
</div>
</section>
<!-- Table -->
<section>
<header>
<h3>Table</h3>
</header>
<div class="content">
<h4>Default</h4>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>Ante turpis integer aliquet porttitor.</td>
<td>29.99</td>
</tr>
<tr>
<td>Item 2</td>
<td>Vis ac commodo adipiscing arcu aliquet.</td>
<td>19.99</td>
</tr>
<tr>
<td>Item 3</td>
<td> Morbi faucibus arcu accumsan lorem.</td>
<td>29.99</td>
</tr>
<tr>
<td>Item 4</td>
<td>Vitae integer tempus condimentum.</td>
<td>19.99</td>
</tr>
<tr>
<td>Item 5</td>
<td>Ante turpis integer aliquet porttitor.</td>
<td>29.99</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2"></td>
<td>100.00</td>
</tr>
</tfoot>
</table>
</div>
<h4>Alternate</h4>
<div class="table-wrapper">
<table class="alt">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>Ante turpis integer aliquet porttitor.</td>
<td>29.99</td>
</tr>
<tr>
<td>Item 2</td>
<td>Vis ac commodo adipiscing arcu aliquet.</td>
<td>19.99</td>
</tr>
<tr>
<td>Item 3</td>
<td> Morbi faucibus arcu accumsan lorem.</td>
<td>29.99</td>
</tr>
<tr>
<td>Item 4</td>
<td>Vitae integer tempus condimentum.</td>
<td>19.99</td>
</tr>
<tr>
<td>Item 5</td>
<td>Ante turpis integer aliquet porttitor.</td>
<td>29.99</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2"></td>
<td>100.00</td>
</tr>
</tfoot>
</table>
</div>
</div>
</section>
<!-- Images -->
<section>
<header>
<h3>Images</h3>
</header>
<div class="content">
<h4>Fit</h4>
<span class="image fit"><img src="images/banner.jpg" alt="" /></span>
<h4>Left</h4>
<p><span class="image left"><img src="images/pic01.jpg" alt="" /></span>Lorem ipsum dolor sit accumsan interdum nisi, quis tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent. Vestibulum ante ipsum primis in faucibus magna blandit adipiscing eu felis iaculis volutpat lorem ipsum dolor sit amet dolor consequat.</p>
<h4>Right</h4>
<p><span class="image right"><img src="images/pic02.jpg" alt="" /></span>Lorem ipsum dolor sit accumsan interdum nisi, quis tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent. Vestibulum ante ipsum primis in faucibus magna blandit adipiscing eu felis iaculis volutpat lorem ipsum dolor sit amet dolor consequat.</p>
</div>
</section>
<!-- Box -->
<section>
<header>
<h3>Box</h3>
</header>
<div class="content">
<div class="box">
<p>Felis sagittis eget tempus primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Magna sed etiam ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus lorem ipsum dolor sit amet nullam.</p>
</div>
</div>
</section>
</div>
</div>
</section>

2009
themes/hugo-story/layouts/partials/elements_reference.html

File diff suppressed because it is too large Load Diff

14
themes/hugo-story/layouts/partials/gallery.html

@ -0,0 +1,14 @@
<!-- Gallery -->
<section class="wrapper style1 align-center">
<div class="inner">
<h2>{{ .title }}</h2>
<p>{{ .content | safeHTML }}</p>
</div>
<!-- Gallery -->
<div class="gallery {{ .style }}">
{{ range .pictures }}
{{ partial "picture" . }}
{{ end }}
</div>
</section>

5
themes/hugo-story/layouts/partials/item.html

@ -0,0 +1,5 @@
<section>
<span class="icon {{ .style }}"></span>
<h3>{{ .name }}</h3>
<p>{{ .content }}</p>
</section>

12
themes/hugo-story/layouts/partials/items.html

@ -0,0 +1,12 @@
<!-- Items -->
<section class="wrapper style1 align-center">
<div class="inner">
{{ with .title }}<h2>{{ . }}</h2>{{ end }}
{{ with .content }}<p>{{ . | safeHTML }}</p>{{ end }}
<div class="items {{ .style }}">
{{ range .items }}
{{ partial "item" . }}
{{ end }}
</div>
</div>
</section>

1663
themes/hugo-story/layouts/partials/modifiers.html

File diff suppressed because it is too large Load Diff

12
themes/hugo-story/layouts/partials/picture.html

@ -0,0 +1,12 @@
<article>
<a href="{{ .image }}" class="image">
<img src="{{ .thumb }}" alt="" />
</a>
<div class="caption">
<h3>{{ .title }}</h3>
<p>{{ .content }}</p>
<ul class="actions fixed">
<li><span class="button small">{{ .button }}</span></li>
</ul>
</div>
</article>

13
themes/hugo-story/layouts/partials/spotlight-01-left.html

@ -0,0 +1,13 @@
<!-- Spotlight -->
<section class="spotlight style1 orient-right content-align-left image-position-center onscroll-image-fade-in" id="first">
<div class="content">
<h2>Spotlight</h2>
<p>This is a <strong>Spotlight</strong> element, and it's generally used &ndash; as its name implies &ndash; to spotlight a particular feature, subject, or pretty much whatever. You can customize its <span class="demo-controls">appearance with a number of modifiers</span>, as well as assign it an optional <code>onload</code> or <code>onscroll</code> transition modifier (<a href="#reference-spotlight">details</a>).</p>
<ul class="actions stacked">
<li><a href="#" class="button">Learn More</a></li>
</ul>
</div>
<div class="image">
<img src="images/spotlight01.jpg" alt="" />
</div>
</section>

13
themes/hugo-story/layouts/partials/spotlight-02-right.html

@ -0,0 +1,13 @@
<!-- Spotlight 02 Right -->
<section class="spotlight style1 orient-left content-align-left image-position-center onscroll-image-fade-in">
<div class="content">
<h2>Spotlight</h2>
<p>This is also a <strong>Spotlight</strong> element, and it's here because this demo would look a bit empty with just one spotlight. Like all spotlights, you can customize its <span class="demo-controls">appearance with a number of modifiers</span>, as well as assign it an optional <code>onload</code> or <code>onscroll</code> transition modifier (<a href="#reference-spotlight">details</a>).</p>
<ul class="actions stacked">
<li><a href="#" class="button">Learn More</a></li>
</ul>
</div>
<div class="image">
<img src="images/spotlight02.jpg" alt="" />
</div>
</section>

13
themes/hugo-story/layouts/partials/spotlight-03-left.html

@ -0,0 +1,13 @@
<!-- Spotlight 03 Left -->
<section class="spotlight style1 orient-right content-align-left image-position-center onscroll-image-fade-in">
<div class="content">
<h2>Spotlight</h2>
<p>And yes, this is another <strong>Spotlight</strong> element, and it's also here because I need to fill a bit of space. Naturally, like any other spotlight, you can customize its <span class="demo-controls">appearance with a number of modifiers</span>, as well as assign it an optional <code>onload</code> or <code>onscroll</code> transition modifier (<a href="#reference-spotlight">details</a>).</p>
<ul class="actions stacked">
<li><a href="#" class="button">Learn More</a></li>
</ul>
</div>
<div class="image">
<img src="images/spotlight03.jpg" alt="" />
</div>
</section>

13
themes/hugo-story/layouts/partials/spotlight.html

@ -0,0 +1,13 @@
<!-- Spotlight -->
<section class="spotlight {{ .style }}"{{ with .id }} id="{{ . }}"{{ end }}>
<div class="content">
{{ with .title }}<h2>{{ . }}</h2>{{ end }}
{{ with .content }}<p>{{ . | safeHTML }}</p>{{ end }}
{{ with .button }}<ul class="actions stacked">
<li><a href="{{ .link }}" class="button">{{ .label }}</a></li>
</ul>{{ end }}
</div>
{{ with .image }}<div class="image">
<img src="{{ . }}" alt="" />
</div>{{ end }}
</section>

7
themes/hugo-story/layouts/partials/template/favicon.html

@ -0,0 +1,7 @@
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<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">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">

14
themes/hugo-story/layouts/partials/template/footer.html

@ -0,0 +1,14 @@
<!-- Footer -->
<footer class="wrapper style1 align-center">
<div class="inner">
<ul class="icons">
{{ with .Site.Params.social.github }}<li><a target="_blank" href="{{.}}" class="icon brands style2 fa-github"><span class="label">Github</span></a></li>{{end}}
{{ with .Site.Params.social.instagram }}<li><a target="_blank" href="{{.}}" class="icon brands style2 fa-instagram"><span class="label">Instagram</span></a></li>{{end}}
{{ with .Site.Params.social.linkedin }}<li><a target="_blank" href="{{.}}" class="icon brands style2 fa-linkedin"><span class="label">LinkedIn</span></a></li>{{end}}
{{ with .Site.Params.social.email }}<li><a target="_blank" href="mailto:{{.}}" class="fav icon style2 fa-envelope"><span class="label">Email</span></a></li>{{end}}
</ul>
<p>Hugo Story &copy; 2020 <a target="_blank" href="https://github.com/caressofsteel/">CaressOfSteel</a><span class="footerspacer icon fad fa-diamond"></span>
Ported from <a target="_blank" href="https://html5up.net/uploads/demos/story/">Story</a> by HTML5UP<span class="footerspacer icon fad fa-diamond"></span>
Images courtesy of <a target="_blank" href="https://unsplash.com">Unsplash</a></p>
</div>
</footer>

18
themes/hugo-story/layouts/partials/template/head.html

@ -0,0 +1,18 @@
<head>
<title>{{ .Site.Title }}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="description" content="">
<meta name="author" content="">
<link rel="alternate" type="application/rss+xml" title="RSS" href="https://kollegen.uber.space/dierundestunde/rss.xml">
{{ if .Site.Params.favicon }}
{{ partial "template/favicon" }}
{{ end }}
<!-- CSS: direct use the generated css or generate is new from the original sass. -->
<!-- The latter is only neede, if the template is updated from original hugo story -->
<!-- Take care of the extra space between the curly brackets when commenting out -->
{{ partial "template/head_css" . }}
<!-- { { partial "template/head_sass" . } } -->
</head>

8
themes/hugo-story/layouts/partials/template/head_css.html

@ -0,0 +1,8 @@
<!-- CSS - direct use. Use this in head.html, if no hugo extended is available on the server.
CSS files must be genereated once with the head_sass template. -->
{{ $style := resources.Get "css/main.css" }}
<link rel="stylesheet" href="{{ $style.Permalink }}">
{{ $noscript := resources.Get "css/noscript.css" }}
<noscript><link rel="stylesheet" href="{{ $style.Permalink }}" /></noscript>

10
themes/hugo-story/layouts/partials/template/head_sass.html

@ -0,0 +1,10 @@
<!-- CSS generated from SASS files. Use this in head.html to genereate the CSS files once while developing.-->
{{ $style := resources.Get "sass/main.scss" | resources.ExecuteAsTemplate "scss/main.scss" .
| toCSS (dict "targetPath" "assets/css/main.css" "outputStyle" "compressed" "enableSourceMap" false) }}
<link rel="stylesheet" href="{{ ($style).RelPermalink }}">
{{ $noscript := resources.Get "sass/noscript.scss" | resources.ExecuteAsTemplate "noscript.scss" .
| toCSS (dict "targetPath" "assets/css/noscript.css" "enableSourceMap" false) }}
<noscript><link rel="stylesheet" href="{{ ($noscript).RelPermalink }}" /></noscript>

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

Loading…
Cancel
Save