initial commit
This commit is contained in:
commit
f50ba452df
13 changed files with 757 additions and 0 deletions
169
.gitignore
vendored
Executable file
169
.gitignore
vendored
Executable file
|
@ -0,0 +1,169 @@
|
||||||
|
config.json
|
||||||
|
|
||||||
|
# Deployment Unix socket
|
||||||
|
*.sock
|
||||||
|
|
||||||
|
# Temp files
|
||||||
|
*~
|
||||||
|
*swp
|
||||||
|
*swo
|
||||||
|
|
||||||
|
# web
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
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/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# 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
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .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
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__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/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# Mastodon secrets
|
||||||
|
**/*.secret
|
61
README.md
Normal file
61
README.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# Python Template
|
||||||
|
|
||||||
|
An opinionated starter project for flask python projects. It contains code for a new [Flask Blueprint]https://flask.palletsprojects.com/en/stable/blueprints/).
|
||||||
|
|
||||||
|
**DO NOT PUSH PROJECT-SPECIFIC CHANGES**
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
|
||||||
|
1. Set up your **Debian** (for other environments, search for counterpart instructions)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# update repositories
|
||||||
|
$ sudo apt update
|
||||||
|
|
||||||
|
# install python stuff
|
||||||
|
$ sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools python3-venv
|
||||||
|
```
|
||||||
|
|
||||||
|
> For MacOS: https://docs.python.org/3/using/mac.html
|
||||||
|
|
||||||
|
2. Install dependencies and set up the project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# clone the project
|
||||||
|
$ git clone git@git.sr.ht:~ayoayco/python-template [project-name]
|
||||||
|
|
||||||
|
# go into the directory
|
||||||
|
$ cd [project-name]
|
||||||
|
|
||||||
|
# remove template .git stuff
|
||||||
|
$ rm -rf .git
|
||||||
|
|
||||||
|
# initialize git
|
||||||
|
$ git init .
|
||||||
|
|
||||||
|
# create python environment:
|
||||||
|
$ python3 -m venv .venv
|
||||||
|
|
||||||
|
# activate python env:
|
||||||
|
$ . .venv/bin/activate
|
||||||
|
|
||||||
|
# install dependencies
|
||||||
|
(.venv)$ python -m pip install -r requirements.txt
|
||||||
|
|
||||||
|
# create configuration from example config file
|
||||||
|
(.venv)$ cp ./example_config.json ./config.json
|
||||||
|
|
||||||
|
# rejoice!
|
||||||
|
```
|
||||||
|
|
||||||
|
3. To start development, run the following:
|
||||||
|
```bash
|
||||||
|
(.venv)$ flask --debug run
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note: On a Mac, the default port 5000 is used by AirDrop & Handoff; you may have to turn those off
|
||||||
|
|
||||||
|
4. After development session, deactivate the python env
|
||||||
|
``bash
|
||||||
|
` (.venv)$ deactivate
|
||||||
|
```
|
0
__init__.py
Normal file
0
__init__.py
Normal file
14
app.py
Executable file
14
app.py
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
from flask import Flask
|
||||||
|
import json
|
||||||
|
from .blueprintname import blueprintname
|
||||||
|
from .cache import cache
|
||||||
|
|
||||||
|
# TODO: Update blueprintname
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
cache.init_app(app, config={'CACHE_TYPE': 'SimpleCache'})
|
||||||
|
app.register_blueprint(blueprintname, url_prefix='/')
|
||||||
|
app.config.from_file("config.json", load=json.load)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0')
|
20
blueprintname.py
Executable file
20
blueprintname.py
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
from flask import Blueprint, render_template, current_app
|
||||||
|
from .cache import cache
|
||||||
|
|
||||||
|
blueprintname = Blueprint("blueprintname", __name__, template_folder="templates", static_folder="static")
|
||||||
|
|
||||||
|
|
||||||
|
def get_attribution():
|
||||||
|
return current_app.config['ATTRIBUTION']
|
||||||
|
|
||||||
|
def get_app_config():
|
||||||
|
return current_app.config['APPS']['blueprintname']
|
||||||
|
|
||||||
|
|
||||||
|
@blueprintname.route("/")
|
||||||
|
@cache.cached(timeout=300)
|
||||||
|
async def home():
|
||||||
|
|
||||||
|
# DO STUFF...
|
||||||
|
|
||||||
|
return render_template("_home.html", app=get_app_config(), attribution=get_attribution())
|
2
cache.py
Normal file
2
cache.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
from flask_caching import Cache
|
||||||
|
cache = Cache()
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
flask[async]
|
||||||
|
Flask-Caching
|
29
static/button.css
Normal file
29
static/button.css
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
.btn {
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid;
|
||||||
|
color: var(--text-color-dark);
|
||||||
|
border-color: var(--border-color-light);
|
||||||
|
background-color: var(--bg-light);
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-brand-blue-3);
|
||||||
|
border-color: var(--color-brand-blue-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.btn {
|
||||||
|
color: var(--text-color-light);
|
||||||
|
border-color: var(--border-color-dark);
|
||||||
|
background-color: var(--bg-dark);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-brand-complement);
|
||||||
|
border-color: var(--color-brand-complement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
175
static/card.css
Normal file
175
static/card.css
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
.card_content {
|
||||||
|
& .invisible {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .emoji {
|
||||||
|
display: inline;
|
||||||
|
height: calc(1rem + 6px);
|
||||||
|
margin-bottom: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .ellipsis::after {
|
||||||
|
content: "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
& .body {
|
||||||
|
.hashtag:not(.pill),
|
||||||
|
.mention:not(.pill) {
|
||||||
|
color: var(--text-color-dark-faded);
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& code {
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
background: rgb(245, 242, 240);
|
||||||
|
padding: 0.25em 0.3em;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-wrap: initial;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& a:has(.link-card) {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .media,
|
||||||
|
& .link-card {
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: var(--border-color-light);
|
||||||
|
color: var(--text-color-dark-faded);
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 5px 25px 10px -25px rgba(34, 34, 34, 0.15);
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 15px 0 1em;
|
||||||
|
object-fit: contain;
|
||||||
|
height: auto;
|
||||||
|
text-decoration: none;
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .media:hover,
|
||||||
|
& .link-card:hover {
|
||||||
|
color: var(--color-brand-blue-3);
|
||||||
|
border: 1px solid var(--color-brand-blue-3);
|
||||||
|
text-decoration-color: var(--color-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
& p {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .heading {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto;
|
||||||
|
gap: 5px;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
& .author {
|
||||||
|
font-size: var(--font-size-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
& .right_menu {
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
& a,
|
||||||
|
& span {
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& a {
|
||||||
|
color: var(--text-color-dark-faded);
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-link);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .link-card {
|
||||||
|
color: var(--text-color-dark-faded);
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: var(--text-color-light-faded);
|
||||||
|
|
||||||
|
& strong,
|
||||||
|
& small {
|
||||||
|
text-decoration-thickness: 1px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
article.card {
|
||||||
|
/* border-bottom: 1px solid;
|
||||||
|
border-color: var(--border-color-light);
|
||||||
|
*/
|
||||||
|
|
||||||
|
& .bottom-menu {
|
||||||
|
padding: 0.25em 0 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.card_content {
|
||||||
|
& .action {
|
||||||
|
color: var(--color-brand-complement);
|
||||||
|
}
|
||||||
|
|
||||||
|
& .heading .right_menu a {
|
||||||
|
color: var(--text-color-light-faded);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-brand-complement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .body {
|
||||||
|
.hashtag:not(.pill),
|
||||||
|
.mention:not(.pill) {
|
||||||
|
color: var(--text-color-light-faded);
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: rgb(45, 51, 59);
|
||||||
|
color: rgb(197, 209, 222);
|
||||||
|
}
|
||||||
|
|
||||||
|
& .media,
|
||||||
|
& .link-card {
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: var(--border-color-dark);
|
||||||
|
color: var(--text-color-light-faded);
|
||||||
|
background-color: var(--bg-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
& .media:hover,
|
||||||
|
& .link-card:hover {
|
||||||
|
color: var(--color-brand-complement);
|
||||||
|
border: 1px solid var(--color-brand-complement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* article.card {
|
||||||
|
border-color: var(--border-color-dark);
|
||||||
|
} */
|
||||||
|
}
|
78
static/reset.css
Normal file
78
static/reset.css
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
THANKS TO JOSH COMEAU FOR HIS CUSTOM CSS RESET
|
||||||
|
👉 https://www.joshwcomeau.com/css/custom-css-reset/
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Use a more-intuitive box-sizing model.
|
||||||
|
*/
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
2. Remove default margin
|
||||||
|
*/
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
3. Allow percentage-based heights in the application
|
||||||
|
*/
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Typographic tweaks!
|
||||||
|
4. Add accessible line-height
|
||||||
|
5. Improve text rendering
|
||||||
|
*/
|
||||||
|
body {
|
||||||
|
line-height: 1.5;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
6. Improve media defaults
|
||||||
|
*/
|
||||||
|
img,
|
||||||
|
picture,
|
||||||
|
video,
|
||||||
|
canvas,
|
||||||
|
svg,
|
||||||
|
iframe {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
7. Remove built-in form typography styles
|
||||||
|
*/
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
8. Avoid text overflows
|
||||||
|
*/
|
||||||
|
p,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
9. Create a root stacking context
|
||||||
|
*/
|
||||||
|
#root,
|
||||||
|
#__next {
|
||||||
|
isolation: isolate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
31
static/variables.css
Normal file
31
static/variables.css
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
:root {
|
||||||
|
--content-width: 700px;
|
||||||
|
--font-size-sm: clamp(0.75rem, 0.2vw + 0.66rem, 0.8rem);
|
||||||
|
--font-size-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
|
||||||
|
--font-size-lg: clamp(1.2rem, 0.7vw + 1.2rem, 1.5rem);
|
||||||
|
--font-size-xl: clamp(2.44rem, 2.38vw + 1.85rem, 3.75rem);
|
||||||
|
|
||||||
|
--color-border: hsl(17, 24%, 90%);
|
||||||
|
--color-link: var(--color-brand-blue-5);
|
||||||
|
|
||||||
|
--color-brand-blue-1: #3054bf;
|
||||||
|
--color-brand-blue-2: #203880;
|
||||||
|
--color-brand-blue-3: #416fff;
|
||||||
|
--color-brand-blue-4: #101c40;
|
||||||
|
--color-brand-blue-5: #3964e6;
|
||||||
|
|
||||||
|
--color-brand-complement: orange;
|
||||||
|
|
||||||
|
--ayo-gradient: linear-gradient(45deg, #3054bf, #416fff);
|
||||||
|
--text-color-dark: #232323;
|
||||||
|
--text-color-dark-faded: #555;
|
||||||
|
--text-color-light: #f8f9fa;
|
||||||
|
--text-color-light-faded: #999;
|
||||||
|
|
||||||
|
--border-color-light: rgba(197, 209, 222, 0.7);
|
||||||
|
--bg-light: rgba(197, 209, 222, 0.15);
|
||||||
|
--border-color-dark: rgba(0, 0, 0, 0.25);
|
||||||
|
--bg-dark: #343a40;
|
||||||
|
--bg-darker: #212529;
|
||||||
|
--bg-darkest: #000;
|
||||||
|
}
|
175
templates/_home.html
Normal file
175
templates/_home.html
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>{{ app.title }}</title>
|
||||||
|
<meta name="theme-color" content="#3054bf">
|
||||||
|
<meta name="description" content="{{ app.description }}" />
|
||||||
|
<meta property="og:description" content="{{ app.description }}" />
|
||||||
|
<meta name="author" content="{{ attribution.owner }}" />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:site_name" content="{{ app.site_name }}" />
|
||||||
|
<meta property="og:title" content="{{ app.title }}" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: var(--text-color-dark);
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
display: grid;
|
||||||
|
gap: 1em;
|
||||||
|
padding: 0 1em;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
& a.app-title {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer {
|
||||||
|
background: var(--ayo-gradient);
|
||||||
|
color: var(--text-color-light);
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 1em;
|
||||||
|
text-wrap: balance;
|
||||||
|
|
||||||
|
& a {
|
||||||
|
color: var(--text-color-light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
& ul.tags {
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
|
& li {
|
||||||
|
display: inline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
gap: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
main.home {
|
||||||
|
& .back {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main.thread {
|
||||||
|
& .card:not(:last-of-type) .card_avatar::after {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
border-right: 2px solid rgba(34, 34, 34, 0.15);
|
||||||
|
width: 26px;
|
||||||
|
margin-top: -8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card_avatar img {
|
||||||
|
border: 2px solid rgba(197, 209, 222, 0.15);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
grid-template-columns: 55px auto;
|
||||||
|
display: grid;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
background: var(--bg-darker);
|
||||||
|
color: var(--text-color-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
main a {
|
||||||
|
color: var(--color-brand-complement);
|
||||||
|
}
|
||||||
|
|
||||||
|
main.thread {
|
||||||
|
& .card:not(:last-of-type) .card_avatar::after {
|
||||||
|
border-right: 2px solid rgba(197, 209, 222, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Use parent app's variables & reset stylesheets -->
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='variables.css') }}" />
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='reset.css') }}" />
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<a id="top"></a>
|
||||||
|
<header>
|
||||||
|
{% include "nav.html" %}
|
||||||
|
<a class="app-title" href="{{url_for('blueprintname.home')}}">
|
||||||
|
<h1>{{ app.title }}</h1>
|
||||||
|
</a>
|
||||||
|
<p>{{ app.description }}</p>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<p>CONTENT GOES HERE</p>
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<p>
|
||||||
|
Copyright ©
|
||||||
|
{% if attribution.current_year %}
|
||||||
|
{{ attribution.year}}-{{ attribution.current_year }}
|
||||||
|
{% else %}
|
||||||
|
{{ attribution.year}}
|
||||||
|
{% endif %}
|
||||||
|
{{ attribution.owner }}
|
||||||
|
</p>
|
||||||
|
<p>Rendered on {{ render_date }} in Europe/Amsterdam</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import TimeAgo from "https://esm.sh/v135/@github/relative-time-element@4.4.0/es2022/relative-time.js"
|
||||||
|
customElements.define('relative-time', TimeAgo)
|
||||||
|
</script>
|
||||||
|
<script type="module" src="{{ url_for('blueprintname.static', filename='enhance-content.js') }}">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
1
templates/nav.html
Normal file
1
templates/nav.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<nav><a href="/">Go home</a></nav>
|
Loading…
Reference in a new issue