diff --git a/.forgejo/workflows/cleanup.yaml b/.forgejo/workflows/cleanup.yaml
new file mode 100644
index 0000000..edb7bc4
--- /dev/null
+++ b/.forgejo/workflows/cleanup.yaml
@@ -0,0 +1,32 @@
+on:
+ pull_request:
+ types: [ closed, merged ]
+
+jobs:
+ cleanup:
+ runs-on: x86_64
+ container:
+ image: alpine:latest
+ steps:
+ - name: Environment setup
+ run: |
+ apk add git nodejs jq coreutils curl tree gawk grep
+ - name: Pages repo pull
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ ref: pages
+ - name: Render website
+ run: |
+ export GITHUB_PR_NAME=$(grep -l ${{ github.sha }} previews/*/git_sha.txt | awk -F '/' '{print $2}')
+ echo $GITHUB_PR_NAME >> $GITHUB_ENV
+ rm -rf previews/$GITHUB_PR_NAME || true
+ cd previews
+ tree -d -H '.' -L 1 --noreport --charset utf-8 -T "Versions" -o index.html
+ - name: Website upload
+ run: |
+ git config user.name "forgejo-actions[bot]"
+ git config user.email "dev@ayakael.net"
+ git add .
+ git commit -m "Clean-up $GITHUB_PR_NAME"
+ git push
diff --git a/.forgejo/workflows/pages.yaml b/.forgejo/workflows/pages.yaml
new file mode 100644
index 0000000..e37c097
--- /dev/null
+++ b/.forgejo/workflows/pages.yaml
@@ -0,0 +1,41 @@
+on:
+ push:
+ branches:
+ - 'main'
+
+jobs:
+ render:
+ runs-on: x86_64
+ container:
+ image: alpine:latest
+ steps:
+ - name: Environment setup
+ run: |
+ apk add git ikiwiki po4a perl-yaml-tiny tree nodejs imagemagick-perlmagick imagemagick imagemagick-jpeg findutils bash imagemagick-webp
+ - name: Repo pull
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+ - name: Pages repo pull
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ ref: pages
+ path: public
+ - name: Render website
+ run: ikiwiki --setup ikiwiki.setup
+ - name: Website upload
+ run: |
+ cp .pages-domains public/.domains
+ cp .pages-redirect public/_redirects
+ git log -1 --pretty=%B > commit.txt
+ cd public
+ find -name 'index.html' -type 'l' -delete
+ find -name 'index.fr.html' -exec bash -c 'ln -s "${0/.*\/}" "${0/.fr/}"' {} \;
+ date > generated.txt
+ # Note: the following account information will not work on GHES
+ git config user.name "forgejo-actions[bot]"
+ git config user.email "dev@ayakael.net"
+ git add .
+ git commit -F ../commit.txt
+ git push
diff --git a/.forgejo/workflows/preview.yaml b/.forgejo/workflows/preview.yaml
new file mode 100644
index 0000000..e8ec978
--- /dev/null
+++ b/.forgejo/workflows/preview.yaml
@@ -0,0 +1,47 @@
+on:
+ pull_request:
+ types: [ assigned, opened, synchronize, reopened ]
+
+jobs:
+ preview:
+ runs-on: x86_64
+ container:
+ image: alpine:latest
+ steps:
+ - name: Environment setup
+ run: |
+ apk add git ikiwiki po4a perl-yaml-tiny tree nodejs jq coreutils curl imagemagick-perlmagick imagemagick imagemagick-jpeg findutils bash imagemagick-webp
+ echo "GITHUB_PR_NAME=$(curl -Ls ${{ github.server_url }}/api/v1/repos/${{ github.repository }}/pulls/${{ github.ref_name }} -H 'accept: application/json' -H 'Authorization: token ${{ secrets.FORGEJO_TOKEN }}' | jq .title | tr ' ' '-' | tr -d ':' | tr -d '"' | tr '[:upper:]' '[:lower:]' | tr '/' '-' | tr -d ',')" >> $GITHUB_ENV
+ - name: Repo pull
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+ - name: Public repo pull
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ ref: pages
+ path: public
+ - name: Render website
+ run: |
+ rm -rf public/previews/$GITHUB_PR_NAME || true
+ mkdir -p public/previews/$GITHUB_PR_NAME
+ sed -i "s|destdir.*|destdir: ./public/previews/$GITHUB_PR_NAME|" ikiwiki.setup
+ ikiwiki --setup ikiwiki.setup
+ cd public/previews
+ tree -d -H '.' -L 1 --noreport --charset utf-8 -T "Versions" -o index.html
+ cd $GITHUB_PR_NAME
+ find -name 'index.html' -type 'l' -delete
+ find -name 'index.fr.html' -exec bash -c 'ln -s "${0/.*\/}" "${0/.fr/}"' {} \;
+ - name: Website upload
+ run: |
+ git log -1 --pretty=%B > commit.txt
+ cd public
+ date > previews/$GITHUB_PR_NAME/generated.txt
+ echo ${{ github.sha }} > previews/$GITHUB_PR_NAME/git_sha.txt
+ # Note: the following account information will not work on GHES
+ git config user.name "forgejo-actions[bot]"
+ git config user.email "dev@ayakael.net"
+ git add .
+ git commit -F ../commit.txt
+ git push
diff --git a/.gitignore b/.gitignore
index fca9333..13f4f82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
-content/.ikiwiki
+.ikiwiki
public/
-http-server/
-*.DS_Store
+tools/http-server/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index 1ad0ade..0000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,70 +0,0 @@
-workflow:
- rules: # disable tag pipelines and duplicate MR pipelines
- - if: $CI_COMMIT_BRANCH
-
-variables:
- MAIN_BRANCH_PATH: "."
- EPHEMERAL_BRANCHES_PATH: preview # subpath to ephemeral branches content for preview
-
-pages:
- stage: build
- cache:
- key: gitlab-pages
- paths: [public]
- before_script:
- - sudo apk add tree
- # CURRENT_CONTENT_PATH is defined in rules, different between main branch and ephemeral branches
- - mkdir -p public/$CURRENT_CONTENT_PATH && ls public/$CURRENT_CONTENT_PATH/..
- - | # create ephermetal branched path if not existent
- if [ ! -d "public/$EPHEMERAL_BRANCHES_PATH" ]; then
- mkdir -p public/$EPHEMERAL_BRANCHES_PATH
- fi
- - | # avoid deleting main branch content when cache has been erased
- if [ "$CI_COMMIT_BRANCH" != "$CI_DEFAULT_BRANCH" ] && [ ! -f public/$MAIN_BRANCH_PATH/index.html ]; then
- echo -e "đź’Ą\e[91;1m Unable to retrieve $CI_DEFAULT_BRANCH generated files from cache ; please regenerate $CI_DEFAULT_BRANCH files first\e[0m"
- exit 1
- fi
- - rm -rf public/$CURRENT_CONTENT_PATH || true # remove last version of current branch
- script:
- - mkdir -p public/$CURRENT_CONTENT_PATH
- - cp -R src/* public/$CURRENT_CONTENT_PATH/.
- - cd public/$EPHEMERAL_BRANCHES_PATH
- - tree -d -H '.' -L 1 --noreport --charset utf-8 -T "Versions" -o index.html # generate a root HTML listing all previews for easier access
- environment:
- name: pages/$CI_COMMIT_BRANCH
- action: start
- url: $CI_PAGES_URL/$CURRENT_CONTENT_PATH
- on_stop: pages-clean-preview
- rules:
- # 'main branch' is exposed at GitLab Pages root
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- variables:
- CURRENT_CONTENT_PATH: $MAIN_BRANCH_PATH
- # other (short-lived) branches generation are exposed in 'EPHEMERAL_BRANCHES_PATH/branch-name-sanitized' sub path
- - variables:
- CURRENT_CONTENT_PATH: $EPHEMERAL_BRANCHES_PATH/$CI_COMMIT_REF_SLUG
- artifacts:
- paths: [public]
- expire_in: 1h
- tags:
- - knit
-
-pages-clean-preview:
- stage: build
- cache:
- key: gitlab-pages
- paths: [public]
- variables:
- GIT_STRATEGY: none # git files not available after branch deletion
- FOLDER_TO_DELETE: $EPHEMERAL_BRANCHES_PATH/$CI_COMMIT_REF_SLUG # an indirection to allow arbitrary deletion when launching this job
- script:
- - rm -rf public/$FOLDER_TO_DELETE
- environment:
- name: pages/$CI_COMMIT_BRANCH
- action: stop
- rules:
- - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
- when: manual
- allow_failure: true
- tags:
- - knit
diff --git a/.pages-domains b/.pages-domains
new file mode 100644
index 0000000..fd7f80a
--- /dev/null
+++ b/.pages-domains
@@ -0,0 +1 @@
+www.ilot.io
diff --git a/.pages-redirect b/.pages-redirect
new file mode 100644
index 0000000..e69de29
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..daa5001
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+The Mastodon comments mechanism is by Carl Schwan CC-BY-SA:
+
+https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/
+
+The file in templates/, bootstrap.min.css, bootstrap.min.js, and local.css
+are derived from bootstrap. They and all remaining files are licensed under
+the MIT license:
+
+Copyright (c) 2011-2015 Twitter, Inc
+Copyright (c) 2009-2015 Julian Andres Klode
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.md b/README.md
index f6dd4e5..d969bd4 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,35 @@
# ilot.io
-Upstream: https://lab.ilot.io/ilot/ilot.io
+Upstream: https://forge.ilot.io/ilot/ilot.io
-
+
+
+## Forgejo Actions
-## Description
+This project's static Pages are built by Forgejo Actions, following the steps
+defined in [`.forgejo/workflows/pages.yaml`](.forgejo/workflows/pages.yaml).
+That builds this website using ikiwiki, and pushes the build artifacts to the
+`public` branch.
-This repository contains the source code to the [ilot.io](https://ilot.io)
-website.
+The `public` branch has its own workflow following steps defined in
+[`forgejo/workflows/deploy.yaml`](.forgejo/workflows/deploy.yaml)
+that uploads the artifacts to a remote HTTP server for deployment in
+production. This workflow is automatically updated from `main` so that `public`
+should never be manually modified.
-## GitLab CI
+The deployment is done by a simple remote git push via SSH to a non-bare repo
+where `git config receive.denyCurrentBranch` is set as `updateInstead`. This
+allows this repo to be checked out as `public`, allowing it to be a root for
+your favorite HTTP server.
-This project's static Pages are built by [GitLab CI][ci], following the steps
-defined in [`.gitlab-ci.yml`](.gitlab-ci.yml):
+The following secrets are expected to be set for operation:
+* PAGES_PRIVKEY: SSH private key that is used to push to the HTTP server's git
+repo
+* PAGES_TOKEN: Forgejo application token used to push to `public` branch.
-We are using a theme based on
-[Bootstrap 3](https://lab.ilot.io/ilot/ikiwiki-bootstrap-ilot) using submodules.
+The following variables are expected to be set for operation:
+* PAGES_TARGET: SSH target for HTTP server's git repo, following this format:
+user@example.net:/path/to/http/repo
## Building locally
@@ -26,9 +40,9 @@ To work locally with this project, you'll have to follow the steps below:
* [mac][]
* [linux][]
* [source][]
-1. Clone the submodules: `git submodule init && git submodule update`
1. Generate the website: `ikiwiki --setup ikiwiki.setup`
1. Start http-server: `./test-server.sh`
+1. Preview your project: open 127.0.0.1:8080 in your browser
Read more at ikiwiki's [documentation][].
@@ -38,7 +52,7 @@ Read more at ikiwiki's [documentation][].
2. Checkout the forked repository.
- - `git clone ssh://git@lab.ilot.io/$USER/ilot.io`
+ - `git clone ssh://git@forge.ilot.io/$USER/ilot.io`
- `cd ilot.io`
3. Make your changes.
@@ -61,11 +75,8 @@ Read more at ikiwiki's [documentation][].
8. Once the tests in the merge-request pass, and reviewers are happy, your changes
will be merged.
-[ci]: https://about.gitlab.com/gitlab-ci/
[ikiwiki]: https://ikiwiki.info/
[source]: https://ikiwiki.info/install/
[linux]: https://ikiwiki.info/setup/
[mac]: https://ikiwiki.info/tips/ikiwiki_on_mac_os_x/
[documentation]: https://ikiwiki.info/
-[userpages]: https://docs.gitlab.com/ce/user/project/pages/introduction.html#user-or-group-pages
-[projpages]: https://docs.gitlab.com/ce/user/project/pages/introduction.html#project-pages
diff --git a/android-chrome-192x192.png b/android-chrome-192x192.png
new file mode 100644
index 0000000..17467a4
Binary files /dev/null and b/android-chrome-192x192.png differ
diff --git a/android-chrome-512x512.png b/android-chrome-512x512.png
new file mode 100644
index 0000000..fbdfff2
Binary files /dev/null and b/android-chrome-512x512.png differ
diff --git a/apple-touch-icon.png b/apple-touch-icon.png
new file mode 100644
index 0000000..84b4fba
Binary files /dev/null and b/apple-touch-icon.png differ
diff --git a/browserconfig.xml b/browserconfig.xml
new file mode 100644
index 0000000..b3930d0
--- /dev/null
+++ b/browserconfig.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ #da532c
+
+
+
diff --git a/css/bootstrap.local.css b/css/bootstrap.local.css
new file mode 100644
index 0000000..f562351
--- /dev/null
+++ b/css/bootstrap.local.css
@@ -0,0 +1,496 @@
+/* Color palette */
+
+:root {
+ --bs-light-rgb: 248, 248, 248;
+}
+
+a {
+ --bs-link-color: #337ab7;
+}
+
+
+/* Custom page CSS
+-------------------------------------------------- */
+/* Not required for template or sticky footer method. */
+
+main > .container {
+ padding: 60px 15px 15px;
+}
+
+.pagedate {
+ font-size: 14px;
+}
+
+textarea {
+ width: 100%;
+}
+
+input[type='email'] {
+ width: 100%;
+}
+
+input[type='text'] {
+ width: 100%;
+}
+
+input[type='button'] {
+ width: 100%;
+}
+code {
+ font-size: 80%;
+}
+
+.actions ul {
+ margin: inherit;
+ padding: inherit;
+ height: inherit;
+ /* list-style-type: none; */
+}
+
+a {
+ text-decoration: none;
+}
+
+/* limit main content to ~90 chars per line */
+/* update: practical typography recommends 2-3 alphabets */
+#content {
+ max-width: 35em; /* this is 2.5 alphabets with Charter */
+ margin-top: 15px
+}
+
+/* limit header as well otherwise logo is out of whack without sidebar */
+.fixed-top .container-fluid {
+ max-width: 55em;
+}
+
+/* some hacking at typefaces to get some fresh zest in here
+ * fallbacks from:
+ * https://en.wikipedia.org/wiki/List_of_typefaces_included_with_Microsoft_Windows
+ * https://en.wikipedia.org/wiki/List_of_typefaces_included_with_macOS
+ *
+ * Font stacks from:
+ * https://modernfontstacks.com/#font-stacks
+ */
+.navbar, .footer {
+ /* according to modern font stacks, the following actually falls back to:
+ * San Francisco: MacOS 10.8+, iOS 3+
+ * Segoe UI: Windows 7+
+ * Roboto: Android
+ * Ubuntu: Linux
+ * Cantarell: Linux using GNOME
+ * Noto Sans: Linux using KDE
+ *
+ * So instead of letting "Linux" guess (because that's pretty
+ * chaotic), actually hardcode those two first, so we have a
+ * little better control over this. Noto sans is actually what I
+ * would fallback on in Firefox on my workstation before the
+ * change.
+ */
+ font-family: Ubuntu, "Noto sans", system-ui, sans-serif;
+}
+h1, h2, h3, h4, h5, body {
+ /* this is the "transitional" stack from modern stack fonts. it was
+ * picked because it sticks with the "Charter" font we were
+ * previously using. it runs the risk of falling back on bitmap
+ * fonts which look horrible on Linux, but in my tests it worked
+ * okay.
+ *
+ * Charter: MacOS 10.9+, iOS 9.3+
+ * Bitstream Charter: Linux
+ * Sitka Text: Windows 8.1+
+ * Cambreia: Windows 7+
+ * Noto Serif: Android
+ * Serif: fallback
+ */
+ font-family: Charter, 'Bitstream Charter', 'Sitka Text', Cambria, "Noto serif", serif;
+ /* Charter is Butterick's favorite, freely available, found on
+ * https://practicaltypography.com/free-fonts.html and available
+ * from https://practicaltypography.com/charter.html under the
+ * liberal Bitstream license. It used to be shipped alongside this
+ * site as a web font, but was disabled for the sake of simplicity
+ * and bandwidth saving. Now it is assumed that 'Bitstream
+ * Charter' will "just work" on Linux.
+ */
+}
+h1, h2, h3, h4, h5 {
+ font-style: italic;
+}
+/* for charter, we should inline this: */
+/* */
+/* we won't ship fira because it is too big and will hope some other font will kick in for headings, preferably Open sans */
+
+/* no idea why bootstrap makes quotes bigger, not what i want */
+blockquote {
+ font-size: 14px;
+ /* make blockquotes interesting */
+ font-style: italic;
+}
+
+/* enlarge body point size for charter for larger displays */
+@media (min-device-width: 750px) {
+ body {
+ font-size: 18px;
+ line-height: 1.3; /* default in FF is ~1.48, try seems a bit to sparse */
+ }
+ /* to match the other bootstrap workaround, below */
+ blockquote {
+ font-size: 18px;
+ }
+ /* UI elements should be a little less intrusive */
+ .navbar, .footer {
+ font-size: 16px;
+ }
+}
+
+pre, code {
+ font-family: "Fira Mono", Menlo, Monaco, Consolas, "Courier New", "Liberation mono", monospace;
+}
+
+/* don't word-wrap PRE blocks so they are scrolled*/
+pre {
+ -ms-word-wrap: normal;
+ word-wrap: normal;
+}
+pre code {
+ white-space: pre;
+}
+
+/* workaround multimarkdown bug:
+ * https://github.com/bobtfish/text-multimarkdown/issues/30 */
+a.footnote { vertical-align: super; font-size: xx-small; }
+div.footnotes { font-size: small; }
+
+/* scale down images so they are centered like the rest of the text */
+#content img { max-width: 100%; }
+/* except in the mastodon avatar, it squeezes them weirdly and messes with borders */
+#content .mastodon-comment .avatar img { max-width: inherit; }
+
+/* format HTML5 captions like ikiwiki's table-based captions
+ *
+ * those work, but basically need to be entered by hand.
+ *
+ * https://ikiwiki.info/todo/html5_image_captions/
+ */
+figure {
+ text-align: center;
+}
+figcaption {
+ text-align: center;
+ font-size: smaller;
+ color: #777;
+}
+
+/* right-aligned figures
+ *
+ * those need a "table" display so that the caption shows up alongside the
+ * figured. we also limit the size of the image so that it does not squeeze the
+ * text too mucha nd had judicious padding.
+ */
+figure.align-right {
+ float: right;
+ padding: 0em 1em;
+ display: table;
+ max-width: 60%;
+}
+figure.align-right figcaption {
+ display: table-caption;
+ caption-side: bottom;
+ padding: 0.5em 1em;
+}
+
+/* wrap long URLs so that we don't overflow layout
+ * this could apply to any element, but we often have to deal with long
+ * links so limit to that to avoid unexpected damage */
+#content a {
+ word-wrap: break-word;
+}
+
+/* make table scale out to avoid ugly word-wrapping
+ * bootstrap should deal with this, but ikiwiki doesn't assign the
+ * right style and anyways our width is smaller than necessary
+ *
+ * pages with tables that should be checked when this is changed:
+ *
+ * https://anarc.at/blog/2017-10-26-comparison-cryptographic-keycards/
+ * https://anarc.at/blog/2018-01-28-large-disk-price-review/
+ * https://anarc.at/services/backup/
+ * https://anarc.at/services/
+ * https://anarc.at/services/dns/registrars/
+ * https://anarc.at/services/welcome/
+ */
+table, table.table { width: 100%; }
+table { font-size: inherit; } /* why the heck does chrome override font-size for tables?! */
+
+/* this belongs in ikiwiki's style.css, but that needs the admonition
+ * patch to be merged: https://ikiwiki.info/todo/admonitions/ */
+
+/* admonition start */
+#content div.caution,
+#content div.important,
+#content div.note,
+#content div.tip,
+#content div.warning {
+ border: 1pt solid #aaa;
+ margin: 1em 3em 1em 3em;
+ background-repeat: no-repeat;
+ background-position: 8px 8px;
+ min-height: 48px; /*48=32+8+8 but doesn't work with IE*/
+ padding: 1em 1em 1em 48px;
+}
+#content div.tip { background-image: url("smileys/admon-tip.png"); }
+#content div.note { background-image: url("smileys/admon-note.png"); }
+#content div.important { background-image: url("smileys/admon-important.png"); }
+#content div.caution { background-image: url("smileys/admon-caution.png"); }
+#content div.warning { background-image: url("smileys/admon-warning.png"); }
+/* admonition end */
+
+.breadcrumb {
+ padding: 1px 0 0 0;
+ border-bottom: none;
+ padding-inline-start: 0px;
+}
+.breadcrumb li {
+ padding: 8px 0 8px 8px;
+}
+.breadcrumb li::before {
+ padding: 0 5px 0 0;
+}
+.page-header {
+ border-bottom: none;
+ margin: 40px 0 0;
+}
+
+/* more things to hide in printouts */
+@media print {
+ .footer { position: relative; }
+ .footer .powered-by { display: none; }
+ /* https://ikiwiki.info/todo/hide_add_comment_button_in_print/ */
+ .addcomment { display: none; }
+ /* remove link explosion in footer */
+ .pagedate a[href]::after { content: normal; }
+ .footer a[href]::after { content: normal; }
+ /* reset size constraints, paper takes care of that */
+ #content {
+ width: auto;
+ max-width: inherit;
+ padding: 0;
+ margin: 0;
+ }
+ body {
+ margin: 0;
+ }
+}
+
+
+/* hierarchical heading numbers */
+
+/* this uses CSS3 to show headings like:
+ *
+ * 1. one
+ * 2. two
+ * 2.1. two point one
+ * 3. three
+ *
+ * This is based on https://developer.mozilla.org/en-US/docs/Web/CSS/counter-reset
+ * ... and inspired by https://practicaltypography.com/hierarchical-headings.html
+ *
+ * This overrides the default in ikiwiki, which is *roman* numerals (!)
+ */
+/* make a counter for ordered lists in the table of contents */
+.toc ol {
+ /* this will break ikiwiki unless the following patch is applied: https://ikiwiki.info/todo/allow_toc_to_skip_entries/ */
+ counter-reset: section;
+ list-style-type: none;
+}
+/* override bootstrap */
+.toc li.L1, .toc li.L2, .toc li.L3, .toc li.L4, .toc li.L5, .toc li.L6 {
+ list-style-type: none;
+}
+.toc li::before {
+ /* increment the counter when we hit a new li */
+ counter-increment: section;
+ /* Combines the values of all instances of the section counter,
+ separated and followed by a period */
+ content: counters(section, ".") ". ";
+}
+/* except in notebox, we don't want to have numbers there. that is used
+ * in the blog archive, in blog.md */
+.notebox .toc ol {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ /* override LI's built-in padding */
+ padding-inline-start: 0px;
+}
+.notebox .toc li::before {
+ counter-increment: none;
+ content: "";
+}
+.notebox .toc li.L1, .notebox .toc li.L2, .notebox .toc li.L3, .notebox .toc li.L4, .notebox .toc li.L5, .notebox .toc li.L6 {
+ list-style-type: none;
+}
+
+/* another counter for headings, but one which should follow the one generated by the ikiwiki toc */
+
+/* this was taken from https://philarcher.org/diary/2013/headingnumbers/ */
+body {counter-reset: h1}
+h1 {counter-reset: h2}
+h2 {counter-reset: h3}
+h3 {counter-reset: h4}
+h4 {counter-reset: h5}
+h5 {counter-reset: h6}
+
+/* TODO: Fix counter
+h1:before {counter-increment: h1; content: counter(h1) ". "}
+h2:before {counter-increment: h2; content: counter(h1) "." counter(h2) ". "}
+h3:before {counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". "}
+h4:before {counter-increment: h4; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "}
+h5:before {counter-increment: h5; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
+h6:before {counter-increment: h6; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}
+*/
+
+h1.nocount:before, h2.nocount:before, h3.nocount:before, h4.nocount:before, h5.nocount:before, h6.nocount:before, div.nocount h1:before, div.nocount h2:before, div.nocount h3:before, div.nocount h4:before, div.nocount h5:before, div.nocount h6:before {
+ content: ""; counter-increment: none
+}
+
+/* ... except main title, we don't want a number there */
+header h1::before {
+ content: "";
+}
+
+/* Language switchers */
+
+.language-switcher {
+ font-size: 14px;
+ background: #f8f8f8;
+ color: #333;
+ border-color: #ccc;
+}
+
+.language-switcher:hover {
+ background: #e6e6e6;
+}
+
+/* Sign-in buttons */
+
+.sign-in:hover {
+ background: #e6e6e6;
+}
+
+/* Footer */
+
+.footer ul {
+ margin: inherit;
+ padding: 0;
+ height: inherit;
+ list-style-type: none;
+}
+
+.footer h5 {
+ font-weight: bold;
+}
+
+.footer li a {
+ color: #777;
+}
+
+.footer li {
+ color: #777;
+}
+
+.footer p {
+ color: #777;
+}
+
+/* Listmonk form */
+
+.listmonk-form {
+ display: table;
+}
+
+.listmonk-form .t {
+ display: table-cell;
+ width: 100%;
+}
+
+.listmonk-form a {
+ color: #777;
+ text-decoration-line: underline;
+}
+
+.listmonk-form .t > input {
+ width: 100%;
+ background: #f8f8f8;
+ color: #777;
+ text-align: left;
+ border-color: #ccc;
+}
+
+.listmonk-form button {
+ background: #f8f8f8;
+ color: #777;
+ border-color: #ccc;
+ margin-top: -2px;
+ margin-left: 12px;
+}
+
+.listmonk-form button:hover {
+ background: #e6e6e6;
+ color: #777;
+ border-color: #ccc;
+}
+
+/* NavBar */
+
+/* Navbar variables */
+.navbar {
+ --bs-navbar-padding-y: 0;
+ --bs-navbar-padding-x: 0;
+}
+
+.nav-link {
+ --bs-nav-link-padding-y: 5px;
+ --bs-nav-link-padding-x: 15px;
+}
+
+.dropdown-menu li a {
+ font-size: 14px;
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: 400;
+ line-height: 1.42857143;
+ color: #333;
+ border-color: #ccc;
+ white-space: nowrap;
+}
+
+.dropdown-menu li a:hover {
+ background: #e6e6e6;
+}
+
+/* Usually is set automatically by bootstrap, but do it manually to let ikiwiki handle links */
+.nav-link li a, .nav-link .selflink {
+ display: block;
+ padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);
+ font-size: var(--bs-nav-link-font-size);
+ font-weight: var(--bs-nav-link-font-weight);
+ color: var(--bs-nav-link-color);
+ text-decoration: none;
+ transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out;
+}
+
+.nav-link .selflink {
+ color: #393a35;
+}
+
+.nav-link li a:hover, .nav-link .selflink:hover {
+ color: #393a35;
+}
+
+.navbar-brand {
+ height: 50px;
+ padding: 15px 0;
+}
+
+
diff --git a/css/local.css b/css/local.css
new file mode 100644
index 0000000..a0dec8c
--- /dev/null
+++ b/css/local.css
@@ -0,0 +1,3 @@
+/* ikiwiki local style sheet */
+
+/* Add local styling here, instead of modifying style.css. */
diff --git a/css/style.css b/css/style.css
new file mode 100644
index 0000000..9f82899
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,596 @@
+/* ikiwiki style sheet */
+
+/* Note that instead of modifying this style sheet, you can instead edit
+ * local.css and use it to override or change settings in this one.
+ */
+
+/* html5 compat */
+article,aside,details,figcaption,figure,
+footer,header,hgroup,menu,nav,section {
+ display: block;
+}
+
+div.header, header.header {
+ margin: 0;
+ font-size: 140%;
+ font-weight: bold;
+ line-height: 1em;
+ display: block;
+}
+
+.inlineheader .author {
+ margin: 0;
+ font-size: 112%;
+ font-weight: bold;
+ display: block;
+}
+
+.actions ul {
+ margin: 0;
+ padding: 6px .4em;
+ height: 1em;
+ list-style-type: none;
+}
+.actions li {
+ display: inline;
+ padding: .2em;
+}
+.pageheader .actions ul {
+ border-bottom: 1px solid #000;
+}
+
+.inlinepage .actions ul {
+ border-bottom: 0;
+}
+
+#otherlanguages ul {
+ margin: 0;
+ padding: 6px;
+ list-style-type: none;
+}
+#otherlanguages li {
+ display: inline;
+ padding: .2em .4em;
+}
+.pageheader #otherlanguages {
+ border-bottom: 1px solid #000;
+}
+
+.inlinecontent,
+.inlineenclosure {
+ margin-top: .4em;
+}
+
+.pagefooter,
+.inlinefooter,
+.comments {
+ clear: both;
+}
+
+#pageinfo {
+ margin: 1em 0;
+ border-top: 1px solid #000;
+}
+
+.tags {
+ margin-top: 1em;
+}
+
+.inlinepage .tags {
+ display: inline;
+}
+
+.mapparent {
+ text-decoration: none;
+}
+
+.img caption {
+ font-size: 80%;
+ caption-side: bottom;
+ text-align: center;
+}
+
+img.img {
+ margin: 0.5ex;
+}
+
+.align-left {
+ float:left;
+}
+
+.align-right {
+ float:right;
+}
+
+#backlinks {
+ margin-top: 1em;
+}
+
+#searchform {
+ display: inline;
+ float: right;
+}
+
+#editcontent {
+ width: 98%;
+}
+
+.editcontentdiv {
+ width: auto;
+ overflow: auto;
+}
+
+img {
+ border-style: none;
+}
+
+pre {
+ overflow: auto;
+}
+
+div.recentchanges {
+ border-style: solid;
+ border-width: 1px;
+ overflow: auto;
+ width: auto;
+ clear: none;
+ background: #eee;
+ color: black !important;
+}
+.recentchanges .metadata {
+ padding: 0px 0.5em;
+}
+.recentchanges .changelog {
+ font-style: italic;
+ clear: both;
+ display: block;
+ padding: 1px 2px;
+ background: white !important;
+ color: black !important;
+}
+.recentchanges .desc {
+ display: none;
+}
+.recentchanges .diff {
+ display: none;
+}
+.recentchanges .committer {
+ float: left;
+ margin: 0;
+ width: 40%;
+}
+.recentchanges .committype {
+ float: left;
+ margin: 0;
+ width: 5%;
+ font-size: small;
+}
+.recentchanges .changedate {
+ float: left;
+ margin: 0;
+ width: 35%;
+ font-size: small;
+}
+.recentchanges .pagelinks,
+.recentchanges .revert {
+ float: right;
+ margin: 0;
+ width: 60%;
+}
+
+.blogform, #blogform {
+ padding: 10px 10px;
+ border: 1px solid #aaa;
+ background: #eee;
+ color: black !important;
+ width: auto;
+ overflow: auto;
+}
+
+.inlinepage {
+ padding: 10px 10px;
+ border: 1px solid #aaa;
+ overflow: auto;
+}
+
+.pagedate,
+.pagelicense,
+.pagecopyright {
+ font-style: italic;
+ display: block;
+ margin-top: 1em;
+}
+
+.archivepagedate {
+ font-style: italic;
+}
+.archivepage {
+ margin-bottom: 1em;
+}
+
+.error {
+ color: #C00;
+}
+
+.sidebar {
+ width: 20ex;
+ float: right;
+ margin-left: 4px;
+ margin-bottom: 4px;
+ margin-top: -1px;
+ padding: 0ex 2ex;
+ background: white;
+ border: 1px solid black;
+ color: black !important;
+}
+
+hr.poll {
+ height: 10pt;
+ color: white !important;
+ background: #eee;
+ border: 2px solid black;
+}
+div.poll {
+ margin-top: 1ex;
+ margin-bottom: 1ex;
+ padding: 1ex 1ex;
+ border: 1px solid #aaa;
+}
+
+span.color {
+ padding: 2px;
+}
+
+.comment-header,
+.microblog-header {
+ font-style: italic;
+ margin-top: .3em;
+}
+.comment .author,
+.microblog .author {
+ font-weight: bold;
+}
+.comment-subject {
+ font-weight: bold;
+}
+.comment-avatar {
+ float: right;
+}
+.comment {
+ border: 1px solid #aaa;
+ padding: 3px;
+}
+
+div.progress {
+ margin-top: 1ex;
+ margin-bottom: 1ex;
+ border: 1px solid #888;
+ width: 400px;
+ background: #eee;
+ color: black !important;
+ padding: 1px;
+}
+div.progress-done {
+ background: #ea6 !important;
+ color: black !important;
+ text-align: center;
+ padding: 1px;
+}
+
+/* things to hide in printouts */
+@media print {
+ .actions { display: none; }
+ .tags { display: none; }
+ .trails { display: none; }
+ .feedbutton { display: none; }
+ #searchform { display: none; }
+ .blogform, #blogform { display: none; }
+ #backlinks { display: none; }
+ .addcomment { display: none; }
+}
+
+/* infobox template */
+.infobox {
+ float: right;
+ margin-left: 2ex;
+ margin-top: 1ex;
+ margin-bottom: 1ex;
+ padding: 1ex 1ex;
+ border: 1px solid #aaa;
+ background: white;
+ color: black !important;
+}
+
+/* notebox template */
+.notebox {
+ float: right;
+ margin-left: 2ex;
+ margin-top: 1ex;
+ margin-bottom: 1ex;
+ padding: 1ex 1ex;
+ border: 1px solid #aaa;
+ width: 25%;
+ background: white;
+ color: black !important;
+}
+
+/* popup template and backlinks hiding */
+.popup {
+ border-bottom: 1px dotted #366;
+ color: #366;
+}
+.popup .balloon,
+.popup .paren,
+.popup .expand {
+ display: none;
+ text-align: left;
+}
+.popup:hover .balloon,
+.popup:focus .balloon {
+ position: absolute;
+ display: inline;
+ margin: 1em 0 0 -2em;
+ padding: 0.625em;
+ border: 2px solid;
+ background-color: #dee;
+ color: black;
+}
+
+/* form styling */
+fieldset {
+ margin: 1ex 0;
+ border: 1px solid black;
+}
+legend {
+ padding: 0 1ex;
+}
+.fb_submit {
+ float: left;
+ margin: 2px 0;
+}
+label.block {
+ display: block;
+}
+label.inline {
+ display: inline;
+}
+input#openid_identifier {
+ background: url(wikiicons/openidlogin-bg.gif) no-repeat;
+ background-color: #fff;
+ background-position: 0 50%;
+ color: #000;
+ padding-left: 18px;
+}
+input#searchbox {
+ background: url(wikiicons/search-bg.gif) no-repeat;
+ background-color: #fff;
+ background-position: 100% 50%;
+ color: #000;
+ padding-right: 16px;
+}
+/* invalid form fields */
+.fb_invalid {
+ color: red;
+ background: white !important;
+}
+/* required form fields */
+.fb_required {
+ font-weight: bold;
+}
+
+/* highlight plugin */
+pre.hl { color:#000000; background-color:#ffffff; }
+.hl.num { color:#2928ff; }
+.hl.esc { color:#ff00ff; }
+.hl.str { color:#ff0000; }
+.hl.dstr { color:#818100; }
+.hl.slc { color:#838183; font-style:italic; }
+.hl.com { color:#838183; font-style:italic; }
+.hl.dir { color:#008200; }
+.hl.sym { color:#000000; }
+.hl.line { color:#555555; }
+.hl.mark { background-color:#ffffbb; }
+.hl.kwa { color:#000000; font-weight:bold; }
+.hl.kwb { color:#830000; }
+.hl.kwc { color:#000000; font-weight:bold; }
+.hl.kwd { color:#010181; }
+
+/* calendar plugin */
+.month-calendar-day-this-day,
+.year-calendar-this-month {
+ background-color: #eee;
+}
+.month-calendar-day-head,
+.month-calendar-day-nolink,
+.month-calendar-day-link,
+.month-calendar-day-this-day,
+.month-calendar-day-future {
+ text-align: right;
+}
+.month-calendar-arrow A:link,
+.year-calendar-arrow A:link,
+.month-calendar-arrow A:visited,
+.year-calendar-arrow A:visited {
+ text-decoration: none;
+ font-weight: normal;
+ font-size: 150%;
+}
+
+/* outlines */
+li.L1 { list-style: upper-roman; }
+li.L2 { list-style: decimal; }
+li.L3 { list-style: lower-alpha; }
+li.L4 { list-style: disc; }
+li.L5 { list-style: square; }
+li.L6 { list-style: circle; }
+li.L7 { list-style: lower-roman; }
+li.L8 { list-style: upper-alpha; }
+
+/* tag cloud */
+.pagecloud {
+ float: right;
+ width: 30%;
+ text-align: center;
+ padding: 10px 10px;
+ border: 1px solid #aaa;
+ background: #eee;
+ color: black !important;
+}
+.smallestPC { font-size: 70%; }
+.smallPC { font-size: 85%; }
+.normalPC { font-size: 100%; }
+.bigPC { font-size: 115%; }
+.biggestPC { font-size: 130%; }
+
+/* orange feed button */
+.feedbutton {
+ background: #ff6600;
+ color: white !important;
+ border-left: 1px solid #cc9966;
+ border-top: 1px solid #ccaa99;
+ border-right: 1px solid #993300;
+ border-bottom: 1px solid #331100;
+ padding: 0px 0.5em 0px 0.5em;
+ font-family: sans-serif;
+ font-weight: bold;
+ font-size: small;
+ text-decoration: none;
+ margin-top: 1em;
+}
+.feedbutton:hover {
+ color: white !important;
+ background: #ff9900;
+}
+
+.FlattrButton {
+ display: none;
+}
+
+/* login selector */
+#login_choice {
+ display: none;
+}
+#login_input_area {
+ clear: both;
+ padding: 10px;
+}
+#login_btns, #login_btns br {
+ clear: both;
+}
+#login_highlight {
+ background-color: black;
+ float: left;
+}
+.login_large_btn {
+ padding: 1em 1.5em;
+ border: 1px solid #DDD;
+ margin: 3px;
+ float: left;
+}
+.login_small_btn {
+ padding: 4px 4px;
+ border: 1px solid #DDD;
+ margin: 3px;
+ float: left;
+}
+a.login_large_btn:focus {
+ outline: none;
+}
+a.login_large_btn:focus {
+ outline-style: none;
+}
+.login_selected {
+ border: 4px solid #DDD;
+}
+
+.fileupload-content .ui-progressbar {
+ width: 200px;
+ height: 20px;
+}
+.fileupload-content .ui-progressbar-value {
+ background: url(ikiwiki/images/pbar-ani.gif);
+}
+
+.trails {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+.trail {
+ display: block;
+ clear: both;
+ position: relative;
+}
+
+.trailprev {
+ display: block;
+ text-align: left;
+ position: absolute;
+ top: 0%;
+ left: 3%;
+ width: 30%;
+}
+
+.trailup {
+ display: block;
+ text-align: center;
+ margin-left: 35%;
+ margin-right: 35%;
+}
+
+.trailnext {
+ display: block;
+ text-align: right;
+ position: absolute;
+ top: 0%;
+ width: 30%;
+ right: 3%;
+}
+
+.trailsep {
+ display: none;
+}
+
+/* mobile/small-screen-friendly layout */
+@media (max-width: 600px) {
+ .sidebar {
+ width: auto;
+ float: none;
+ margin-top: 0;
+ border: none;
+ }
+
+ /* if the mobile browser is new enough, use flex layout to shuffle
+ * the sidebar to the end */
+ .page {
+ display: -webkit-box;
+ display: -webkit-flexbox;
+ display: -webkit-flex;
+ display: -moz-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-flex-direction: tb;
+ -webkit-flex-direction: column;
+ -webkit-flex-flow: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ }
+ #pageheader {
+ -webkit-box-ordinal-group: -1;
+ -webkit-order: -1;
+ -ms-box-ordinal-group: -1;
+ -ms-flex-order: -1;
+ order: -1;
+ }
+ .sidebar, #footer {
+ -webkit-box-ordinal-group: 1;
+ -webkit-order: 1;
+ -ms-box-ordinal-group: 1;
+ -ms-flex-order: 1;
+ order: 1;
+ }
+
+ .blogform, #blogform {
+ padding: 4px 4px;
+ }
+}
diff --git a/error/404.mdwn b/error/404.mdwn
new file mode 100644
index 0000000..f38e367
--- /dev/null
+++ b/error/404.mdwn
@@ -0,0 +1,14 @@
+[[!meta title="HTTP 404: Not Found"]]
+
+# HTTP 404
+## Not Found
+
+### The page could not be found or you don't have permission to view it.
+
+The resource that you are attempting to access does not exist or you don't have the necessary permissions to view it.
+
+Make sure the address is correct and that the page hasn't moved.
+
+Please contact us using [our support page](https://support.ilot.io) if you think this is a mistake.
+
+You can also check our [network status](https://status.ilot.io) for up-to-date status information on our services
diff --git a/error/422.mdwn b/error/422.mdwn
new file mode 100644
index 0000000..4ba84eb
--- /dev/null
+++ b/error/422.mdwn
@@ -0,0 +1,10 @@
+[[!meta title="HTTP 422: Unprocessable content"]]
+
+# HTTP 422
+## Unprocessable content
+
+### The change you requested is rejected.
+
+Make sure you have access to the thing you tried to changee
+
+Please contact us using [our support page](https://support.ilot.io) if you think this is a mistake
diff --git a/error/500.mdwn b/error/500.mdwn
new file mode 100644
index 0000000..f7a4f0e
--- /dev/null
+++ b/error/500.mdwn
@@ -0,0 +1,12 @@
+[[!meta title="HTTP 500: Internal Server Error"]]
+
+# HTTP 500
+## Internal Server Error
+
+### We're sorry. Something went wrong on our end
+
+Try refreshing the page, or going back and attempting the action again.
+
+Please contact us using [our support page](https://support.ilot.io) if this problem persists.
+
+You can also check our [network status](https://status.ilot.io) for up-to-date status information on our services
diff --git a/error/502.mdwn b/error/502.mdwn
new file mode 100644
index 0000000..59b961b
--- /dev/null
+++ b/error/502.mdwn
@@ -0,0 +1,13 @@
+[[!meta title="HTTP 502: Bad Gateway Error"]]
+
+# HTTP 502
+
+## Bad Gateway error
+
+### We're sorry. ilot is currently unavailable.
+
+Try refreshing the page, or going back and attempting the action again.
+
+Please contact us using [our support page](https://support.ilot.io) if this problem persists.
+
+You can also check our [network status](https://status.ilot.io) for up-to-date status information on our services
diff --git a/error/503.mdwn b/error/503.mdwn
new file mode 100644
index 0000000..4f0d689
--- /dev/null
+++ b/error/503.mdwn
@@ -0,0 +1,12 @@
+[[!meta title="HTTP 503: Service unavailable"]]
+
+# HTTP 503
+## Service unavailable
+
+### We're sorry. ilot is currently unavailable.
+
+Try refreshing the page, or going back and attempting the action again.
+
+Please contact us using [our support page](https://support.ilot.io) if this problem persists.
+
+You can also check our [network status](https://status.ilot.io) for up-to-date status information on our services
diff --git a/favicon-16x16.png b/favicon-16x16.png
new file mode 100644
index 0000000..e6a0546
Binary files /dev/null and b/favicon-16x16.png differ
diff --git a/favicon-24x24-white.png b/favicon-24x24-white.png
new file mode 100644
index 0000000..54b7584
Binary files /dev/null and b/favicon-24x24-white.png differ
diff --git a/favicon-24x24.png b/favicon-24x24.png
new file mode 100644
index 0000000..099de4b
Binary files /dev/null and b/favicon-24x24.png differ
diff --git a/favicon-32x32.png b/favicon-32x32.png
new file mode 100644
index 0000000..1fa2d09
Binary files /dev/null and b/favicon-32x32.png differ
diff --git a/favicon.ico b/favicon.ico
new file mode 100644
index 0000000..3680749
Binary files /dev/null and b/favicon.ico differ
diff --git a/favicon.png b/favicon.png
new file mode 100644
index 0000000..2c88a9a
Binary files /dev/null and b/favicon.png differ
diff --git a/fonts/glyphicons-halflings-regular.eot b/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 0000000..b93a495
Binary files /dev/null and b/fonts/glyphicons-halflings-regular.eot differ
diff --git a/fonts/glyphicons-halflings-regular.svg b/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..94fb549
--- /dev/null
+++ b/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,288 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/glyphicons-halflings-regular.ttf b/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 0000000..1413fc6
Binary files /dev/null and b/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/fonts/glyphicons-halflings-regular.woff b/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 0000000..9e61285
Binary files /dev/null and b/fonts/glyphicons-halflings-regular.woff differ
diff --git a/fonts/glyphicons-halflings-regular.woff2 b/fonts/glyphicons-halflings-regular.woff2
new file mode 100644
index 0000000..64539b5
Binary files /dev/null and b/fonts/glyphicons-halflings-regular.woff2 differ
diff --git a/footer.fr.mo b/footer.fr.mo
new file mode 100644
index 0000000..e93d1db
Binary files /dev/null and b/footer.fr.mo differ
diff --git a/footer.fr.po b/footer.fr.po
new file mode 100644
index 0000000..533e635
--- /dev/null
+++ b/footer.fr.po
@@ -0,0 +1,161 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: ilot.io\n"
+"POT-Creation-Date: 2025-06-12 16:36-0400\n"
+"PO-Revision-Date: 2025-06-12 16:44-0400\n"
+"Last-Translator: \n"
+"Language-Team: dev@ayakael.net\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 3.5\n"
+
+#. type: Content of: