Week 06 of 2024

Development log of Tad Lispy website

13 items
  1. Setup the development environment with Nix flake
  2. Run zola init
  3. Setup a home page
  4. Create a blog section with one post
  5. Write a second blog post with a link to the first
  6. Write a code block to see the highlighting
  7. Import my standard Makefile
  8. Setup GitLab CI
  9. Correct project name in GitLab CI config
  10. Correct project name in GitLab CI (for real)
  11. Fix CI: do not run make install goal
  12. Style the site with pico.css
  13. Display the blog index content

Setup the development environment with Nix flake

On by Tad Lispy

new file mode 100644
index 0000000..5330b9c
--- /dev/null
+++ b/.envrc
@@ -0,0 +1,28 @@
+shopt -s globstar
+
+watch_file **/*.nix
+watch_file flake.lock
+watch_file rust-toolchain.toml
+
+use_flake() {
+    mkdir -p "$(direnv_layout_dir)"
+    eval "$(nix print-dev-env --profile "$(direnv_layout_dir)/flake-profile")"
+}
+
+if (nix help flake &> /dev/null)
+then
+    # Nix with flakes support
+    use flake
+
+elif command -v lorri
+then
+    # Lorri is installed
+    eval "$(lorri direnv)"
+
+else
+    # Standard nix - going to be slooow
+    use nix
+
+fi
+
+source_env_if_exists .envrc.private
new file mode 100644
index 0000000..6da990c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.direnv/
+.envrc.private
+/result
+/public/
new file mode 100644
index 0000000..587cbde
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,61 @@
+{
+  "nodes": {
+    "flake-utils": {
+      "inputs": {
+        "systems": "systems"
+      },
+      "locked": {
+        "lastModified": 1705309234,
+        "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1707268954,
+        "narHash": "sha256-2en1kvde3cJVc3ZnTy8QeD2oKcseLFjYPLKhIGDanQ0=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "f8e2ebd66d097614d51a56a755450d4ae1632df1",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "flake-utils": "flake-utils",
+        "nixpkgs": "nixpkgs"
+      }
+    },
+    "systems": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
new file mode 100644
index 0000000..0182e93
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,36 @@
+{
+  description = "Playing with the Zola static site generator";
+
+  inputs = {
+    nixpkgs.url      = "github:NixOS/nixpkgs/nixos-unstable";
+    flake-utils.url  = "github:numtide/flake-utils";
+  };
+
+  outputs = { self, nixpkgs, flake-utils }:
+    flake-utils.lib.eachDefaultSystem (system:
+      let
+        project-name = "zola-playground";
+        overlays = [  ];
+        pkgs = import nixpkgs {
+          inherit system overlays;
+        };
+        buildInputs = with pkgs; [
+        ];
+        nativeBuildInputs = with pkgs; [
+          zola
+          gnumake
+        ];
+      in
+      {
+        devShell = pkgs.mkShell {
+          inherit buildInputs nativeBuildInputs;
+          name = "${project-name}-develpoment-shell";
+          packages = with pkgs; [
+            pkgs.jq
+            pkgs.miniserve
+          ];
+          project_name = project-name; # Expose as an environment variable for make
+        };
+      }
+    );
+}

Run zola init

On by Tad Lispy

It generated a bunch of empty directories and the config file. Guess I will have to fill the directories now.

new file mode 100644
index 0000000..9cf214d
--- /dev/null
+++ b/config.toml
@@ -0,0 +1,16 @@
+# The URL the site will be built for
+base_url = "https://tad-lispy.gitlab.io/zola-playground/"
+
+# Whether to automatically compile all Sass files in the sass directory
+compile_sass = true
+
+# Whether to build a search index to be used later on by a JavaScript library
+build_search_index = true
+
+[markdown]
+# Whether to do syntax highlighting
+# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola
+highlight_code = true
+
+[extra]
+# Put all your custom variables here

Setup a home page

On by Tad Lispy

Using templates where base.html provides the structure and index.html provides the content specific to the home page.

new file mode 100644
index 0000000..8dcfffd
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html class="no-js" lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="x-ua-compatible" content="ie=edge">
+        <title>Tad Zola Playground</title>
+        <meta name="description" content="Playing with Zola">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+
+        <!-- TODO: Place favicon.ico in the root directory -->
+
+    </head>
+    <body>
+        <main>
+            {% block content %}{% endblock %}
+        </main>
+
+    </body>
+</html>
new file mode 100644
index 0000000..0a96a1e
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,5 @@
+{% extends "base.html" %}
+
+{% block content %}
+<h1 class="title">Welcome to the Zola playground!!!</h1>
+{% endblock content %}

Create a blog section with one post

On by Tad Lispy

There is a link to the section from home page.

new file mode 100644
index 0000000..66cf43e
--- /dev/null
+++ b/content/blog/_index.md
@@ -0,0 +1,10 @@
+---
+title: "Tad Blog"
+sort_by: "date"
+template: "blog.html"
+page_template: "blog-post.html"
+---
+
+Here go Tad writings.
+
+
new file mode 100644
index 0000000..3b465f9
--- /dev/null
+++ b/content/blog/first.md
@@ -0,0 +1,7 @@
+---
+title: "First Tad Post"
+date: 2024-02-09
+---
+
+Something something something and then we have **a blog**.
+
new file mode 100644
index 0000000..981065f
--- /dev/null
+++ b/templates/blog-post.html
@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+
+{% block content %}
+<hgroup>
+    <h1 class="title">{{ page.title }}</h1>
+    <p>{{ page.date }}</p>
+</hgroup>
+
+{{ page.content | safe }}
+{% endblock content %}
new file mode 100644
index 0000000..c4437c3
--- /dev/null
+++ b/templates/blog.html
@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+
+{% block content %}
+<h1 class="title">{{ section.title }}</h1>
+<ul>
+    {% for post in section.pages %}
+    <li><a href="{{ post.permalink | safe }}">{{ post.title }}</a></li>
+    {% endfor %}
+</ul>
+{% endblock content %}
index 0a96a1e..fb2a3dc 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -2,4 +2,6 @@
=
={% block content %}
=<h1 class="title">Welcome to the Zola playground!!!</h1>
+
+<p>See the <a href="{{ get_url(path='@/blog/_index.md') }}">blog posts</a>.</p>
={% endblock content %}

Write a second blog post with a link to the first

On by Tad Lispy

new file mode 100644
index 0000000..e98e03a
--- /dev/null
+++ b/content/blog/second.md
@@ -0,0 +1,7 @@
+---
+title: Something Else
+date: 2024-02-10
+---
+
+Yesterday I wrote about [something](@/blog/first.md). And now for something _completely_ different.
+

Write a code block to see the highlighting

On by Tad Lispy

index e98e03a..46dab12 100644
--- a/content/blog/second.md
+++ b/content/blog/second.md
@@ -5,3 +5,9 @@ date: 2024-02-10
=
=Yesterday I wrote about [something](@/blog/first.md). And now for something _completely_ different.
=
+Here is some Rust:
+
+``` rust
+let rust = Awesome::Cool; 
+```
+

Import my standard Makefile

On by Tad Lispy

So I don't have to remember all the Zola commands.

new file mode 100644
index 0000000..7cb4fb5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,109 @@
+include Makefile.d/defaults.mk
+
+all: ## Build the program (DEFAULT)
+all: test build
+.PHONY: all
+
+build: # Compile the website into the public/ directory
+build: public
+.PHONY: build
+
+test:
+	zola check
+.PHONY: test
+
+
+install: ## Install the content into the ${prefix}/ directory
+install: prefix ?= $(out)
+install:
+	test "$(prefix)"
+	mkdir --parents "$(prefix)"
+	cp --recursive "public/*" "public/.*" "$(prefix)/"
+.PHONY: install
+
+
+public:
+	zola build
+	touch $@
+
+### DEVELOPMENT
+
+develop: ## Watch and serve a development version of the website
+develop:
+	zola serve
+.PHONY: develop
+
+serve: ## Serve the built webiste
+serve: public
+serve:
+	miniserve --index=index.html --interfaces=127.0.0.1 "$<"
+.PHONY: serve
+
+clean: ## Remove all build artifacts
+clean:
+	git clean -dfX \
+		--exclude='!.envrc.private' \
+		--exclude='!private/**/*'
+.PHONY: clean
+
+help: ## Print this help message
+help:
+	@
+	echo "Useage: make [ goals ]"
+	echo
+	echo "Available goals:"
+	echo
+	cat $(MAKEFILE_LIST) | awk -f Makefile.d/make-goals.awk
+.PHONY: help
+
+
+### NIX SPECIFIC
+
+export nix := nix --experimental-features "nix-command flakes"
+export nix-cache-name := software-garden
+
+result: ## Build the program using Nix
+result:
+	cachix use $(nix-cache-name)
+	$(nix) build --print-build-logs
+.PHONY: result
+
+nix-cache: ## Push Nix binary cache to Cachix
+nix-cache: result
+	$(nix) flake archive --json \
+	| jq --raw-output '.path, (.inputs | to_entries [] .value.path)' \
+	| cachix push $(nix-cache-name)
+
+	$(nix) path-info --recursive \
+	| cachix push $(nix-cache-name)
+
+
+### OCI BUILD IMAGE RELATED
+
+build-image: ## Create an OCI image with build environment (to be used in CI)
+build-image: flake.nix
+build-image: flake.lock
+build-image:
+	nix build \
+		--print-build-logs \
+		.#docker-image
+	cp --dereference result $@
+
+load-build-image: ## Load the OCI image using Podman
+load-build-image: build-image
+	gzip --decompress $^ --to-stdout | podman image load
+.PHONY: load-build-image
+
+build-inside-container: ## Build the program in an OCI container (e.g. to test CI)
+build-inside-container: load-build-image
+	# We need to know the project name to know which image to load. Can we do better?
+	test $${project_name}
+	podman run \
+		--rm \
+		--interactive \
+		--tty \
+		--volume ${PWD}:/src \
+		--workdir /src \
+		--entrypoint make \
+		localhost/$(project_name)-build-image
+.PHONY: build-inside-container
new file mode 100644
index 0000000..1a788da
--- /dev/null
+++ b/Makefile.d/defaults.mk
@@ -0,0 +1,39 @@
+# Default settings for Make
+
+# Always use strict bash
+SHELL := bash
+.SHELLFLAGS := -eu -o pipefail -c
+.ONESHELL:
+
+# If a recipe fails, delete it's targets to avoid broken state
+.DELETE_ON_ERROR:
+
+# Allow $$(variables) to be expanded in a second pass
+.SECONDEXPANSION:
+
+# Warn about undefined variables and
+# TODO: How to make it an error, like in bash strict mode?
+# TODO: Consider https://www.artificialworlds.net/blog/2015/04/22/treat-warnings-as-errors-in-a-gnu-makefile/
+MAKEFLAGS += --warn-undefined-variables
+MAKEFLAGS += --warn-undefined-functions
+
+# Remove implicit rules - no magic please
+# See https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
+MAKEFLAGS += --no-builtin-rules
+
+# Helper functions
+
+define slugify
+$(shell \
+	echo $(1) \
+		| tr '[:upper:]' '[:lower:]' \
+		| tr --squeeze-repeats --complement '[:alnum:]\n' '-' \
+)
+endef
+
+# General purpose variables
+
+author = $(shell git config user.name)
+
+timestamp = $(shell date '+%s')
+
new file mode 100644
index 0000000..ca79030
--- /dev/null
+++ b/Makefile.d/make-goals.awk
@@ -0,0 +1,4 @@
+# Section header
+match($0, /^### (.+)/, matches)        { printf "\n\n%s:\n\n", matches[1] }
+# Goal with description
+match($0, /^(.+):.* ## (.+)/, matches) { printf "  %-30s %s\n", matches[1], matches[2]}

Setup GitLab CI

On by Tad Lispy

index 6da990c..39ad8cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
=.envrc.private
=/result
=/public/
+/build-image
new file mode 100644
index 0000000..38afc6b
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,58 @@
+test:
+  stage: test
+  image: $CI_REGISTRY_IMAGE:build
+
+  script:
+    - make test
+
+  except:
+    - main
+
+pages:
+  stage: deploy
+  image: $CI_REGISTRY_IMAGE:build
+  script:
+    - base_url="/$(cut --delimiter='/' --fields=4- <<< $CI_PAGES_URL)"
+    - make test install prefix=public base_url=${base_url}
+
+  artifacts:
+    paths:
+      - public/
+
+  only:
+    - main
+
+build-image:
+  stage: build
+  image: nixpkgs/nix-flakes:nixos-23.11
+  script:
+    - nix run nixpkgs#gnumake -- build-image
+  artifacts:
+    paths:
+      - build-image
+  cache:
+    key: build-image
+    paths:
+      - build-image
+  rules:
+    - changes:
+        - flake.nix
+        - flake.lock
+
+
+publish-build-image:
+  stage: build
+  needs:
+    - build-image
+  dependencies:
+    - build-image
+  image: quay.io/podman/stable
+  script:
+    - podman image load --input build-image
+    - podman image tag bevy-animated-sprite-playground-build-image $CI_REGISTRY_IMAGE:build
+    - podman login --username $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD $CI_REGISTRY
+    - podman image push $CI_REGISTRY_IMAGE:build
+  rules:
+    - changes:
+        - flake.nix
+        - flake.lock
index 7cb4fb5..76dfde5 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@ all: test build
=.PHONY: all
=
=build: # Compile the website into the public/ directory
+build: base_url ?= ""
=build: public
=.PHONY: build
=
@@ -15,15 +16,17 @@ test:
=
=install: ## Install the content into the ${prefix}/ directory
=install: prefix ?= $(out)
+install: public
=install:
=	test "$(prefix)"
=	mkdir --parents "$(prefix)"
-	cp --recursive "public/*" "public/.*" "$(prefix)/"
+	cp --recursive $</* $(prefix)/
=.PHONY: install
=
=
+public: base_url ?= ""
=public:
-	zola build
+	zola build --base-url "$(base_url)"
=	touch $@
=
=### DEVELOPMENT
index 0182e93..d73d345 100644
--- a/flake.nix
+++ b/flake.nix
@@ -31,6 +31,29 @@
=          ];
=          project_name = project-name; # Expose as an environment variable for make
=        };
+        defaultPackage = pkgs.stdenv.mkDerivation {
+          name = project-name;
+          version = "1.0.0";
+          src = ./.;
+          inherit buildInputs nativeBuildInputs;
+        };
+        packages.docker-image = pkgs.dockerTools.buildLayeredImage {
+          name = "${project-name}-build-image";
+          tag = "latest";
+          created = "now";
+          contents = buildInputs ++ nativeBuildInputs ++ [
+            pkgs.bash
+            pkgs.coreutils
+            pkgs.git
+            pkgs.httpie
+            pkgs.cacert
+          ];
+          fakeRootCommands = ''
+            mkdir --parents /tmp
+          '';
+          enableFakechroot = true;
+          config.Cmd = [ "bash" ];
+        };
=      }
=    );
=}

Correct project name in GitLab CI config

On by Tad Lispy

index 38afc6b..4111a5f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,6 @@
+variables:
+  project_name: "bevy-animated-sprite-playground"
+
=test:
=  stage: test
=  image: $CI_REGISTRY_IMAGE:build
@@ -49,7 +52,7 @@ publish-build-image:
=  image: quay.io/podman/stable
=  script:
=    - podman image load --input build-image
-    - podman image tag bevy-animated-sprite-playground-build-image $CI_REGISTRY_IMAGE:build
+    - podman image tag "${project_name}-build-image" "$CI_REGISTRY_IMAGE:build"
=    - podman login --username $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD $CI_REGISTRY
=    - podman image push $CI_REGISTRY_IMAGE:build
=  rules:

Correct project name in GitLab CI (for real)

On by Tad Lispy

index 4111a5f..41fbec5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,5 +1,5 @@
=variables:
-  project_name: "bevy-animated-sprite-playground"
+  project_name: "zola-playground"
=
=test:
=  stage: test

Fix CI: do not run make install goal

On by Tad Lispy

It tries to copy from public/ to public/ and fails. There is no need for it, since Zola already produces files in public/ directory.

index 41fbec5..404dbd0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,7 +16,7 @@ pages:
=  image: $CI_REGISTRY_IMAGE:build
=  script:
=    - base_url="/$(cut --delimiter='/' --fields=4- <<< $CI_PAGES_URL)"
-    - make test install prefix=public base_url=${base_url}
+    - make base_url=${base_url}
=
=  artifacts:
=    paths:

Style the site with pico.css

On by Tad Lispy

new file mode 100644
index 0000000..160870c
--- /dev/null
+++ b/sass/_picocss/_functions.scss
@@ -0,0 +1,4 @@
+// Output color in RGB format
+@function to-rgb($color) {
+  @return unquote("rgb(#{red($color)}, #{green($color)}, #{blue($color)})");
+}
\ No newline at end of file
new file mode 100644
index 0000000..e2f653e
--- /dev/null
+++ b/sass/_picocss/_variables.scss
@@ -0,0 +1,69 @@
+// Config
+// ––––––––––––––––––––
+
+// Set the root element for $enable-semantic-container and $enable-responsive-spacings
+$semantic-root-element: "body" !default;
+
+// Enable <header>, <main>, <footer> inside $semantic-root-element as containers
+$enable-semantic-container: false !default;
+
+// Enable .container and .container-fluid
+$enable-class-container: true !default;
+
+// Enable a centered viewport for <header>, <main>, <footer> inside $enable-semantic-container 
+// Fluid layout if disabled
+$enable-viewport: true !default;
+
+// Enable responsive spacings for <header>, <main>, <footer>, <section>, <article>
+// Fixed spacings if disabled
+$enable-responsive-spacings: true !default;
+
+// Enable responsive typography
+// Fixed root element size if disabled
+$enable-responsive-typography: true !default;
+
+// Enable .classes
+// .classless version if disabled
+$enable-classes: true !default;
+
+// Enable .grid class
+$enable-grid: true !default;
+
+// Enable transitions
+$enable-transitions: true !default;
+
+// Enable overriding with !important
+$enable-important: true !default;
+
+// Responsive
+// ––––––––––––––––––––
+
+// xs: Extra small (portrait phones)
+// sm: Small(landscape phones)
+// md: Medium(tablets)
+// lg: Large(desktops)
+// xl: Extra large (large desktops)
+
+// NOTE:
+// To provide an easy and fine styling on each breakpoint
+// we didn't use @each, @mixin or @include.
+// That means you need to edit each CSS selector file to add a breakpoint
+
+// Breakpoints
+// 'null' disable the breakpoint
+$breakpoints: (
+  xs: 0,
+  sm: 576px,
+  md: 768px,
+  lg: 992px,
+  xl: 1200px,
+) !default;
+
+// Viewports
+$viewports: (
+  // 'null' disable the viewport on a breakpoint
+  sm: 510px,
+  md: 700px,
+  lg: 920px,
+  xl: 1130px
+) !default;
new file mode 100644
index 0000000..59b2c65
--- /dev/null
+++ b/sass/_picocss/components/_accordion.scss
@@ -0,0 +1,116 @@
+/**
+ * Accordion (<details>)
+ */
+
+details {
+  display: block;
+  margin-bottom: var(--spacing);
+  padding-bottom: var(--spacing);
+  border-bottom: var(--border-width) solid var(--accordion-border-color);
+
+  summary {
+    line-height: 1rem;
+    list-style-type: none;
+    cursor: pointer;
+
+    &:not([role]) {
+      color: var(--accordion-close-summary-color);
+    }
+
+    @if $enable-transitions {
+      transition: color var(--transition);
+    }
+
+    // Reset marker
+    &::-webkit-details-marker {
+      display: none;
+    }
+
+    &::marker {
+      display: none;
+    }
+
+    &::-moz-list-bullet {
+      list-style-type: none;
+    }
+
+    // Marker
+    &::after {
+      display: block;
+      width: 1rem;
+      height: 1rem;
+      margin-inline-start: calc(var(--spacing, 1rem) * 0.5);
+      float: right;
+      transform: rotate(-90deg);
+      background-image: var(--icon-chevron);
+      background-position: right center;
+      background-size: 1rem auto;
+      background-repeat: no-repeat;
+      content: "";
+
+      @if $enable-transitions {
+        transition: transform var(--transition);
+      }
+    }
+
+    &:focus {
+      outline: none;
+
+      &:not([role="button"]) {
+        color: var(--accordion-active-summary-color);
+      }
+    }
+
+    // Type button
+    &[role="button"] {
+      width: 100%;
+      text-align: left;
+
+      // Marker
+      &::after {
+        height: calc(1rem * var(--line-height, 1.5));
+        background-image: var(--icon-chevron-button);
+      }
+
+      @if $enable-classes {
+        // .contrast
+        &:not(.outline).contrast {
+          // Marker
+          &::after {
+            background-image: var(--icon-chevron-button-inverse);
+          }
+        }
+      }
+    }
+  }
+
+  // Open
+  &[open] {
+    > summary {
+      margin-bottom: calc(var(--spacing));
+
+      &:not([role]) {
+        &:not(:focus) {
+          color: var(--accordion-open-summary-color);
+        }
+      }
+
+      &::after {
+        transform: rotate(0);
+      }
+    }
+  }
+}
+
+[dir="rtl"] {
+  details {
+    summary {
+      text-align: right;
+
+      &::after {
+        float: left;
+        background-position: left center;
+      }
+    }
+  }
+}
new file mode 100644
index 0000000..924415e
--- /dev/null
+++ b/sass/_picocss/components/_card.scss
@@ -0,0 +1,36 @@
+/**
+ * Card (<article>)
+ */
+
+article {
+  margin: var(--block-spacing-vertical) 0;
+  padding: var(--block-spacing-vertical) var(--block-spacing-horizontal);
+  border-radius: var(--border-radius);
+  background: var(--card-background-color);
+  box-shadow: var(--card-box-shadow);
+
+  > header,
+  > footer {
+    margin-right: calc(var(--block-spacing-horizontal) * -1);
+    margin-left: calc(var(--block-spacing-horizontal) * -1);
+    padding: calc(var(--block-spacing-vertical) * 0.66)
+      var(--block-spacing-horizontal);
+    background-color: var(--card-sectionning-background-color);
+  }
+
+  > header {
+    margin-top: calc(var(--block-spacing-vertical) * -1);
+    margin-bottom: var(--block-spacing-vertical);
+    border-bottom: var(--border-width) solid var(--card-border-color);
+    border-top-right-radius: var(--border-radius);
+    border-top-left-radius: var(--border-radius);
+  }
+
+  > footer {
+    margin-top: var(--block-spacing-vertical);
+    margin-bottom: calc(var(--block-spacing-vertical) * -1);
+    border-top: var(--border-width) solid var(--card-border-color);
+    border-bottom-right-radius: var(--border-radius);
+    border-bottom-left-radius: var(--border-radius);
+  }
+}
new file mode 100644
index 0000000..a16e6d2
--- /dev/null
+++ b/sass/_picocss/components/_dropdown.scss
@@ -0,0 +1,214 @@
+/**
+ * Dropdown ([role="list"])
+ */
+
+// Menu
+details[role="list"],
+li[role="list"] {
+  position: relative;
+}
+
+details[role="list"] summary + ul,
+li[role="list"] > ul {
+  display: flex;
+  z-index: 99;
+  position: absolute;
+  top: auto;
+  right: 0;
+  left: 0;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  border: var(--border-width) solid var(--dropdown-border-color);
+  border-radius: var(--border-radius);
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+  background-color: var(--dropdown-background-color);
+  box-shadow: var(--card-box-shadow);
+  color: var(--dropdown-color);
+  white-space: nowrap;
+
+  li {
+    width: 100%;
+    margin-bottom: 0;
+    padding: calc(var(--form-element-spacing-vertical) * 0.5)
+      var(--form-element-spacing-horizontal);
+    list-style: none;
+
+    &:first-of-type {
+      margin-top: calc(var(--form-element-spacing-vertical) * 0.5);
+    }
+
+    &:last-of-type {
+      margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5);
+    }
+
+    a {
+      display: block;
+      margin: calc(var(--form-element-spacing-vertical) * -0.5)
+        calc(var(--form-element-spacing-horizontal) * -1);
+      padding: calc(var(--form-element-spacing-vertical) * 0.5)
+        var(--form-element-spacing-horizontal);
+      overflow: hidden;
+      color: var(--dropdown-color);
+      text-decoration: none;
+      text-overflow: ellipsis;
+
+      &:hover {
+        background-color: var(--dropdown-hover-background-color);
+      }
+    }
+  }
+}
+
+// Marker
+details[role="list"] summary,
+li[role="list"] > a {
+  &::after {
+    display: block;
+    width: 1rem;
+    height: calc(1rem * var(--line-height, 1.5));
+    margin-inline-start: 0.5rem;
+    float: right;
+    transform: rotate(0deg);
+    background-image: var(--icon-chevron);
+    background-position: right center;
+    background-size: 1rem auto;
+    background-repeat: no-repeat;
+    content: "";
+  }
+}
+
+// Global dropdown only
+details[role="list"] {
+  padding: 0;
+  border-bottom: none;
+
+  // Style <summary> as <select>
+  summary {
+    margin-bottom: 0;
+
+    &:not([role]) {
+      height: calc(
+        1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 +
+          var(--border-width) * 2
+      );
+      padding: var(--form-element-spacing-vertical)
+        var(--form-element-spacing-horizontal);
+      border: var(--border-width) solid var(--form-element-border-color);
+      border-radius: var(--border-radius);
+      background-color: var(--form-element-background-color);
+      color: var(--form-element-placeholder-color);
+      line-height: inherit;
+      cursor: pointer;
+
+      @if $enable-transitions {
+        transition: background-color var(--transition),
+          border-color var(--transition), color var(--transition),
+          box-shadow var(--transition);
+      }
+
+      &:active,
+      &:focus {
+        border-color: var(--form-element-active-border-color);
+        background-color: var(--form-element-active-background-color);
+      }
+
+      &:focus {
+        box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
+      }
+    }
+  }
+
+  // Close for details[role="list"]
+  &[open] summary {
+    border-bottom-right-radius: 0;
+    border-bottom-left-radius: 0;
+
+    &::before {
+      display: block;
+      z-index: 1;
+      position: fixed;
+      top: 0;
+      right: 0;
+      bottom: 0;
+      left: 0;
+      background: none;
+      content: "";
+      cursor: default;
+    }
+  }
+}
+
+// All Dropdowns inside <nav>
+nav details[role="list"] summary,
+nav li[role="list"] a {
+  display: flex;
+  direction: ltr;
+}
+
+nav details[role="list"] summary + ul,
+nav li[role="list"] > ul {
+  min-width: fit-content;
+  border-radius: var(--border-radius);
+
+  li a {
+    border-radius: 0;
+  }
+}
+
+// Dropdowns inside <nav> as nested <details>
+nav details[role="list"] {
+  summary,
+  summary:not([role]) {
+    height: auto;
+    padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
+  }
+
+  &[open] summary {
+    border-radius: var(--border-radius);
+  }
+
+  summary + ul {
+    margin-top: var(--outline-width);
+    margin-inline-start: 0;
+  }
+
+  summary[role="link"] {
+    margin-bottom: calc(var(--nav-link-spacing-vertical) * -1);
+    line-height: var(--line-height);
+
+    + ul {
+      margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width));
+      margin-inline-start: calc(var(--nav-link-spacing-horizontal) * -1);
+    }
+  }
+}
+
+// Dropdowns inside a <nav> without using <details>
+li[role="list"] {
+  // Open on hover (for mobile)
+  // or on active/focus (for keyboard navigation)
+  &:hover > ul,
+  a:active ~ ul,
+  a:focus ~ ul {
+    display: flex;
+  }
+
+  > ul {
+    display: none;
+    margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width));
+    margin-inline-start: calc(
+      var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal)
+    );
+  }
+
+  > a::after {
+    background-image: var(--icon-chevron);
+  }
+}
+
+label > details[role="list"] {
+  margin-top: calc(var(--spacing) * .25);
+  margin-bottom: var(--spacing);
+}
new file mode 100644
index 0000000..af5cb16
--- /dev/null
+++ b/sass/_picocss/components/_modal.scss
@@ -0,0 +1,168 @@
+/**
+ * Modal (<dialog>)
+ */
+
+:root {
+  --scrollbar-width: 0px;
+}
+
+dialog {
+  display: flex;
+  z-index: 999;
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  align-items: center;
+  justify-content: center;
+  width: inherit;
+  min-width: 100%;
+  height: inherit;
+  min-height: 100%;
+  padding: var(--spacing);
+  border: 0;
+  backdrop-filter: var(--modal-overlay-backdrop-filter);
+  background-color: var(--modal-overlay-background-color);
+  color: var(--color);
+
+  // Content
+  article {
+    $close-selector: if($enable-classes, ".close", "a[rel='prev']");
+    max-height: calc(100vh - var(--spacing) * 2);
+    overflow: auto;
+
+    @if map-get($breakpoints, "sm") {
+      @media (min-width: map-get($breakpoints, "sm")) {
+        max-width: map-get($viewports, "sm");
+      }
+    }
+
+    @if map-get($breakpoints, "md") {
+      @media (min-width: map-get($breakpoints, "md")) {
+        max-width: map-get($viewports, "md");
+      }
+    }
+
+    > header,
+    > footer {
+      padding: calc(var(--block-spacing-vertical) * 0.5)
+        var(--block-spacing-horizontal);
+    }
+
+    > header {
+      #{$close-selector} {
+        margin: 0;
+        margin-left: var(--spacing);
+        float: right;
+      }
+    }
+
+    > footer {
+      text-align: right;
+
+      [role="button"] {
+        margin-bottom: 0;
+
+        &:not(:first-of-type) {
+          margin-left: calc(var(--spacing) * 0.5);
+        }
+      }
+    }
+
+    p {
+      &:last-of-type {
+        margin: 0;
+      }
+    }
+
+    // Close icon
+    #{$close-selector} {
+      display: block;
+      width: 1rem;
+      height: 1rem;
+      margin-top: calc(var(--block-spacing-vertical) * -0.5);
+      margin-bottom: var(--typography-spacing-vertical);
+      margin-left: auto;
+      background-image: var(--icon-close);
+      background-position: center;
+      background-size: auto 1rem;
+      background-repeat: no-repeat;
+      opacity: 0.5;
+
+      @if $enable-transitions {
+        transition: opacity var(--transition);
+      }
+
+      &:is([aria-current], :hover, :active, :focus) {
+        opacity: 1;
+      }
+    }
+  }
+
+  // Closed state
+  &:not([open]),
+  &[open="false"] {
+    display: none;
+  }
+}
+
+// Utilities
+@if $enable-classes {
+  .modal-is-open {
+    padding-right: var(--scrollbar-width, 0px);
+    overflow: hidden;
+    pointer-events: none;
+    touch-action: none;
+
+    dialog {
+      pointer-events: auto;
+    }
+  }
+}
+
+// Animations
+@if ($enable-classes and $enable-transitions) {
+  $animation-duration: 0.2s;
+
+  :where(.modal-is-opening, .modal-is-closing) {
+    dialog,
+    dialog > article {
+      animation-duration: $animation-duration;
+      animation-timing-function: ease-in-out;
+      animation-fill-mode: both;
+    }
+
+    dialog {
+      animation-duration: ($animation-duration * 4);
+      animation-name: modal-overlay ;
+
+      > article {
+        animation-delay: $animation-duration;
+        animation-name: modal;
+      }
+    }
+  }
+
+  .modal-is-closing {
+    dialog,
+    dialog > article {
+      animation-delay: 0s;
+      animation-direction: reverse;
+    }
+  }
+
+  @keyframes modal-overlay {
+    from {
+      backdrop-filter: none;
+      background-color: transparent;
+    }
+  }
+
+  @keyframes modal {
+    from {
+      transform: translateY(-100%);
+      opacity: 0;
+    }
+  }
+}
new file mode 100644
index 0000000..06fdd22
--- /dev/null
+++ b/sass/_picocss/components/_nav.scss
@@ -0,0 +1,141 @@
+/**
+ * Nav
+ */
+
+// Reboot based on :
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+
+// Prevent VoiceOver from ignoring list semantics in Safari (opinionated)
+:where(nav li)::before {
+  float: left;
+  content: "\200B";
+}
+
+// Pico
+// ––––––––––––––––––––
+
+// Horizontal Nav
+nav,
+nav ul {
+  display: flex;
+}
+
+nav {
+  justify-content: space-between;
+
+  ol,
+  ul {
+    align-items: center;
+    margin-bottom: 0;
+    padding: 0;
+    list-style: none;
+
+    &:first-of-type {
+      margin-left: calc(var(--nav-element-spacing-horizontal) * -1);
+    }
+    &:last-of-type {
+      margin-right: calc(var(--nav-element-spacing-horizontal) * -1);
+    }
+  }
+
+  li {
+    display: inline-block;
+    margin: 0;
+    padding: var(--nav-element-spacing-vertical)
+      var(--nav-element-spacing-horizontal);
+
+    // Minimal support for buttons and forms elements
+    > * {
+      --spacing: 0;
+    }
+  }
+
+  :where(a, [role="link"]) {
+    display: inline-block;
+    margin: calc(var(--nav-link-spacing-vertical) * -1)
+      calc(var(--nav-link-spacing-horizontal) * -1);
+    padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
+    border-radius: var(--border-radius);
+    text-decoration: none;
+
+    &:is([aria-current], :hover, :active, :focus) {
+      text-decoration: none;
+    }
+  }
+
+  // Breadcrumb
+  &[aria-label="breadcrumb"] {
+    align-items: center;
+    justify-content: start;
+
+    & ul li {
+      &:not(:first-child) {
+        margin-inline-start: var(--nav-link-spacing-horizontal);
+      }
+
+      &:not(:last-child) {
+        ::after {
+          position: absolute;
+          width: calc(var(--nav-link-spacing-horizontal) * 2);
+          margin-inline-start: calc(var(--nav-link-spacing-horizontal) / 2);
+          content: "/";
+          color: var(--muted-color);
+          text-align: center;
+        }
+      }
+    }
+
+    & a[aria-current] {
+      background-color: transparent;
+      color: inherit;
+      text-decoration: none;
+      pointer-events: none;
+    }
+  }
+
+  // Minimal support for role="button"
+  [role="button"] {
+    margin-right: inherit;
+    margin-left: inherit;
+    padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
+  }
+}
+
+// Vertical Nav
+aside {
+  nav,
+  ol,
+  ul,
+  li {
+    display: block;
+  }
+
+  li {
+    padding: calc(var(--nav-element-spacing-vertical) * 0.5)
+      var(--nav-element-spacing-horizontal);
+
+    a {
+      display: block;
+    }
+
+    // Minimal support for links as buttons
+    [role="button"] {
+      margin: inherit;
+    }
+  }
+}
+
+// Breadcrumb RTL
+[dir="rtl"] {
+  nav {
+    &[aria-label="breadcrumb"] {
+      & ul li {
+        &:not(:last-child) {
+          ::after {
+            content: "\\";
+          }
+        }
+      }
+    }
+  }
+}
new file mode 100644
index 0000000..d62ddc0
--- /dev/null
+++ b/sass/_picocss/components/_progress.scss
@@ -0,0 +1,89 @@
+/**
+ * Progress
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// 1. Add the correct display in Edge 18- and IE
+// 2. Add the correct vertical alignment in Chrome, Edge, and Firefox
+progress {
+  display: inline-block; // 1
+  vertical-align: baseline; // 2
+}
+
+// Pico
+// ––––––––––––––––––––
+
+progress {
+  // Reset the default appearance
+  -webkit-appearance: none;
+  -moz-appearance: none;
+
+  // Styles
+  display: inline-block;
+  appearance: none;
+  width: 100%;
+  height: 0.5rem;
+  margin-bottom: calc(var(--spacing) * 0.5);
+  overflow: hidden;
+
+  // Remove Firefox and Opera border
+  border: 0;
+  border-radius: var(--border-radius);
+  background-color: var(--progress-background-color);
+
+  // IE10 uses `color` to set the bar background-color
+  color: var(--progress-color);
+
+  &::-webkit-progress-bar {
+    border-radius: var(--border-radius);
+    background: none;
+  }
+  &[value]::-webkit-progress-value {
+    background-color: var(--progress-color);
+  }
+  &::-moz-progress-bar {
+    background-color: var(--progress-color);
+  }
+
+  // Indeterminate state
+  @media (prefers-reduced-motion: no-preference) {
+    &:indeterminate {
+      background: var(--progress-background-color)
+        linear-gradient(
+          to right,
+          var(--progress-color) 30%,
+          var(--progress-background-color) 30%
+        )
+        top left / 150% 150% no-repeat;
+      animation: progress-indeterminate  1s linear infinite;
+
+      &[value]::-webkit-progress-value {
+        background-color: transparent;
+      }
+      &::-moz-progress-bar {
+        background-color: transparent;
+      }
+    }
+  }
+}
+
+[dir="rtl"] {
+  @media (prefers-reduced-motion: no-preference) {
+    progress:indeterminate {
+      animation-direction: reverse;
+    }
+  }
+}
+
+@keyframes progress-indeterminate {
+  0% {
+    background-position: 200% 0;
+  }
+  100% {
+    background-position: -200% 0;
+  }
+}
new file mode 100644
index 0000000..075a166
--- /dev/null
+++ b/sass/_picocss/content/_button.scss
@@ -0,0 +1,183 @@
+/**
+ * Button
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// 1. Change the font styles in all browsers
+// 2. Remove the margin on controls in Safari
+// 3. Show the overflow in Edge
+button {
+  margin: 0; // 2
+  overflow: visible; // 3
+  font-family: inherit; // 1
+  text-transform: none; // 1
+}
+
+// Correct the inability to style buttons in iOS and Safari
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button;
+}
+
+// Pico
+// ––––––––––––––––––––
+
+button {
+  display: block;
+  width: 100%;
+  margin-bottom: var(--spacing);
+}
+
+[role="button"] {
+  display: inline-block;
+  text-decoration: none;
+}
+
+button,
+input[type="submit"],
+input[type="button"],
+input[type="reset"],
+[role="button"] {
+  --background-color: var(--primary);
+  --border-color: var(--primary);
+  --color: var(--primary-inverse);
+  --box-shadow: var(--button-box-shadow, 0 0 0 rgba(0, 0, 0, 0));
+  padding: var(--form-element-spacing-vertical)
+    var(--form-element-spacing-horizontal);
+  border: var(--border-width) solid var(--border-color);
+  border-radius: var(--border-radius);
+  outline: none;
+  background-color: var(--background-color);
+  box-shadow: var(--box-shadow);
+  color: var(--color);
+  font-weight: var(--font-weight);
+  font-size: 1rem;
+  line-height: var(--line-height);
+  text-align: center;
+  cursor: pointer;
+
+  @if $enable-transitions {
+    transition: background-color var(--transition),
+      border-color var(--transition), color var(--transition),
+      box-shadow var(--transition);
+  }
+
+  &:is([aria-current], :hover, :active, :focus) {
+    --background-color: var(--primary-hover);
+    --border-color: var(--primary-hover);
+    --box-shadow: var(--button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0));
+    --color: var(--primary-inverse);
+  }
+
+  &:focus {
+    --box-shadow: var(--button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),
+      0 0 0 var(--outline-width) var(--primary-focus);
+  }
+}
+
+// .secondary, .contrast & .outline
+@if $enable-classes {
+
+  // Secondary
+  :is(button, input[type="submit"], input[type="button"], [role="button"]).secondary,
+  input[type="reset"] {
+    --background-color: var(--secondary);
+    --border-color: var(--secondary);
+    --color: var(--secondary-inverse);
+    cursor: pointer;
+
+    &:is([aria-current], :hover, :active, :focus) {
+      --background-color: var(--secondary-hover);
+      --border-color: var(--secondary-hover);
+      --color: var(--secondary-inverse);
+    }
+
+    &:focus {
+      --box-shadow: var(--button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),
+        0 0 0 var(--outline-width) var(--secondary-focus);
+    }
+  }
+
+  // Contrast
+  :is(button, input[type="submit"], input[type="button"], [role="button"]).contrast {
+    --background-color: var(--contrast);
+    --border-color: var(--contrast);
+    --color: var(--contrast-inverse);
+
+    &:is([aria-current], :hover, :active, :focus) {
+      --background-color: var(--contrast-hover);
+      --border-color: var(--contrast-hover);
+      --color: var(--contrast-inverse);
+    }
+
+    &:focus {
+      --box-shadow: var(--button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),
+        0 0 0 var(--outline-width) var(--contrast-focus);
+    }
+  }
+
+  // Outline (primary)
+  :is(button, input[type="submit"], input[type="button"], [role="button"]).outline,
+  input[type="reset"].outline {
+    --background-color: transparent;
+    --color: var(--primary);
+
+    &:is([aria-current], :hover, :active, :focus) {
+      --background-color: transparent;
+      --color: var(--primary-hover);
+    }
+  }
+
+  // Outline (secondary)
+  :is(button, input[type="submit"], input[type="button"], [role="button"]).outline.secondary,
+  input[type="reset"].outline {
+    --color: var(--secondary);
+
+    &:is([aria-current], :hover, :active, :focus) {
+      --color: var(--secondary-hover);
+    }
+  }
+
+  // Outline (contrast)
+  :is(button, input[type="submit"], input[type="button"], [role="button"]).outline.contrast {
+    --color: var(--contrast);
+
+    &:is([aria-current], :hover, :active, :focus) {
+      --color: var(--contrast-hover);
+    }
+  }
+} 
+@else {
+  // Secondary button without .class
+  input[type="reset"] {
+    --background-color: var(--secondary);
+    --border-color: var(--secondary);
+    --color: var(--secondary-inverse);
+    cursor: pointer;
+
+    &:is([aria-current], :hover, :active, :focus) {
+      --background-color: var(--secondary-hover);
+      --border-color: var(--secondary-hover);
+    }
+
+    &:focus {
+      --box-shadow: var(--button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),
+        0 0 0 var(--outline-width) var(--secondary-focus);
+    }
+  }
+}
+
+// Button [disabled]
+// Links without href are disabled by default
+:where(button, [type="submit"], [type="button"], [type="reset"], [role="button"])[disabled],
+:where(fieldset[disabled]) :is(button, [type="submit"], [type="button"], [type="reset"], [role="button"]),
+a[role="button"]:not([href]) {
+  opacity: 0.5;
+  pointer-events: none;
+}
new file mode 100644
index 0000000..e03b191
--- /dev/null
+++ b/sass/_picocss/content/_code.scss
@@ -0,0 +1,91 @@
+/**
+ * Code
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// 1. Correct the inheritance and scaling of font size in all browsers
+// 2. Correct the odd `em` font sizing in all browsers
+pre,
+code,
+kbd,
+samp {
+  font-size: 0.875em; // 2
+  font-family: var(--font-family); // 1
+}
+
+// Prevent overflow of the container in all browsers (opinionated)
+pre {
+  -ms-overflow-style: scrollbar;
+  overflow: auto;
+}
+
+// Pico
+// ––––––––––––––––––––
+
+pre,
+code,
+kbd {
+  border-radius: var(--border-radius);
+  background: var(--code-background-color);
+  color: var(--code-color);
+  font-weight: var(--font-weight);
+  line-height: initial;
+}
+
+code,
+kbd {
+  display: inline-block;
+  padding: 0.375rem 0.5rem;
+}
+
+pre {
+  display: block;
+  margin-bottom: var(--spacing);
+  overflow-x: auto;
+
+  > code {
+    display: block;
+    padding: var(--spacing);
+    background: none;
+    font-size: 14px;
+    line-height: var(--line-height);
+  }
+}
+
+// Code Syntax
+code {
+  // Tags
+  b {
+    color: var(--code-tag-color);
+    font-weight: var(--font-weight);
+  }
+
+  // Properties
+  i {
+    color: var(--code-property-color);
+    font-style: normal;
+  }
+
+  // Values
+  u {
+    color: var(--code-value-color);
+    text-decoration: none;
+  }
+
+  // Comments
+  em {
+    color: var(--code-comment-color);
+    font-style: normal;
+  }
+}
+
+// kbd
+kbd {
+  background-color: var(--code-kbd-background-color);
+  color: var(--code-kbd-color);
+  vertical-align: baseline;
+}
new file mode 100644
index 0000000..d48293b
--- /dev/null
+++ b/sass/_picocss/content/_embedded.scss
@@ -0,0 +1,48 @@
+/**
+ * Embedded content
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// Change the alignment on media elements in all browsers (opinionated)
+:where(audio, canvas, iframe, img, svg, video) {
+  vertical-align: middle;
+}
+
+// Add the correct display in IE 9-
+audio,
+video {
+  display: inline-block;
+}
+
+// Add the correct display in iOS 4-7
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+
+// Remove the border on iframes in all browsers (opinionated)
+:where(iframe) {
+  border-style: none;
+}
+
+// 1. Remove the border on images inside links in IE 10.
+// 2. Responsive by default
+img {
+  max-width: 100%; // 2
+  height: auto; // 2
+  border-style: none; // 1
+}
+
+// Change the fill color to match the text color in all browsers (opinionated)
+:where(svg:not([fill])) {
+  fill: currentColor;
+}
+
+// Hide the overflow in IE
+svg:not(:root) {
+  overflow: hidden;
+}
new file mode 100644
index 0000000..f22151e
--- /dev/null
+++ b/sass/_picocss/content/_form-alt-input-types.scss
@@ -0,0 +1,286 @@
+/**
+ * Form elements
+ * Alternatives input types (Not Checkboxes & Radios)
+ */
+
+// Color
+[type="color"] {
+  // Wrapper
+  @mixin color-wrapper {
+    padding: 0;
+  }
+
+  &::-webkit-color-swatch-wrapper {
+    @include color-wrapper;
+  }
+
+  &::-moz-focus-inner {
+    @include color-wrapper;
+  }
+
+  // Swatch
+  @mixin color-swatch {
+    border: 0;
+    border-radius: calc(var(--border-radius) * 0.5);
+  }
+
+  &::-webkit-color-swatch {
+    @include color-swatch;
+  }
+
+  &::-moz-color-swatch {
+    @include color-swatch;
+  }
+}
+
+// Date & Time
+// :not() are needed to add Specificity and avoid !important on padding
+input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"]) {
+  &:is([type="date"], [type="datetime-local"], [type="month"], [type="time"], [type="week"]) {
+    --icon-position: 0.75rem;
+    --icon-width: 1rem;
+    padding-right: calc(var(--icon-width) + var(--icon-position));
+    background-image: var(--icon-date);
+    background-position: center right var(--icon-position);
+    background-size: var(--icon-width) auto;
+    background-repeat: no-repeat;
+  }
+
+  // Time
+  &[type="time"] {
+    background-image: var(--icon-time);
+  }
+}
+
+// Calendar picker
+[type="date"],
+[type="datetime-local"],
+[type="month"],
+[type="time"],
+[type="week"] {
+  &::-webkit-calendar-picker-indicator {
+    width: var(--icon-width);
+    margin-right: calc(var(--icon-width) * -1);
+    margin-left: var(--icon-position);
+    opacity: 0;
+  }
+}
+
+[dir="rtl"]
+  :is([type="date"], [type="datetime-local"], [type="month"], [type="time"], [type="week"]) {
+  text-align: right;
+}
+
+// Calendar icons are hidden in Firefox
+@if $enable-important {
+  @-moz-document url-prefix() {
+    [type="date"],
+    [type="datetime-local"],
+    [type="month"],
+    [type="time"],
+    [type="week"] {
+      padding-right: var(--form-element-spacing-horizontal) !important;
+      background-image: none !important;
+    }
+  }
+}
+
+// File
+[type="file"] {
+  --color: var(--muted-color);
+  padding: calc(var(--form-element-spacing-vertical) * 0.5) 0;
+  border: 0;
+  border-radius: 0;
+  background: none;
+
+  @mixin file-selector-button {
+    --background-color: var(--secondary);
+    --border-color: var(--secondary);
+    --color: var(--secondary-inverse);
+    margin-right: calc(var(--spacing) / 2);
+    margin-left: 0;
+    margin-inline-start: 0;
+    margin-inline-end: calc(var(--spacing) / 2);
+    padding: calc(var(--form-element-spacing-vertical) * 0.5)
+      calc(var(--form-element-spacing-horizontal) * 0.5);
+    border: var(--border-width) solid var(--border-color);
+    border-radius: var(--border-radius);
+    outline: none;
+    background-color: var(--background-color);
+    box-shadow: var(--box-shadow);
+    color: var(--color);
+    font-weight: var(--font-weight);
+    font-size: 1rem;
+    line-height: var(--line-height);
+    text-align: center;
+    cursor: pointer;
+
+    @if $enable-transitions {
+      transition: background-color var(--transition),
+        border-color var(--transition), color var(--transition),
+        box-shadow var(--transition);
+    }
+
+    &:is(:hover, :active, :focus) {
+      --background-color: var(--secondary-hover);
+      --border-color: var(--secondary-hover);
+    }
+  }
+
+  &::file-selector-button {
+    @include file-selector-button;
+  }
+
+  &::-webkit-file-upload-button {
+    @include file-selector-button;
+  }
+
+  &::-ms-browse {
+    @include file-selector-button;
+  }
+}
+
+// Range
+[type="range"] {
+  // Config
+  $height-track: 0.25rem;
+  $height-thumb: 1.25rem;
+  $border-thumb: 2px;
+
+  // Styles
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  width: 100%;
+  height: $height-thumb;
+  background: none;
+
+  // Slider Track
+  @mixin slider-track {
+    width: 100%;
+    height: $height-track;
+    border-radius: var(--border-radius);
+    background-color: var(--range-border-color);
+
+    @if $enable-transitions {
+      transition: background-color var(--transition),
+        box-shadow var(--transition);
+    }
+  }
+
+  &::-webkit-slider-runnable-track {
+    @include slider-track;
+  }
+
+  &::-moz-range-track {
+    @include slider-track;
+  }
+
+  &::-ms-track {
+    @include slider-track;
+  }
+
+  // Slider Thumb
+  @mixin slider-thumb {
+    -webkit-appearance: none;
+    width: $height-thumb;
+    height: $height-thumb;
+    margin-top: #{(-($height-thumb * 0.5) + ($height-track * 0.5))};
+    border: $border-thumb solid var(--range-thumb-border-color);
+    border-radius: 50%;
+    background-color: var(--range-thumb-color);
+    cursor: pointer;
+
+    @if $enable-transitions {
+      transition: background-color var(--transition),
+        transform var(--transition);
+    }
+  }
+  &::-webkit-slider-thumb {
+    @include slider-thumb;
+  }
+
+  &::-moz-range-thumb {
+    @include slider-thumb;
+  }
+
+  &::-ms-thumb {
+    @include slider-thumb;
+  }
+
+  &:hover,
+  &:focus {
+    --range-border-color: var(--range-active-border-color);
+    --range-thumb-color: var(--range-thumb-hover-color);
+  }
+
+  &:active {
+    --range-thumb-color: var(--range-thumb-active-color);
+
+    // Slider Thumb
+    &::-webkit-slider-thumb {
+      transform: scale(1.25);
+    }
+
+    &::-moz-range-thumb {
+      transform: scale(1.25);
+    }
+
+    &::-ms-thumb {
+      transform: scale(1.25);
+    }
+  }
+}
+
+// Search
+// :not() are needed to add Specificity and avoid !important on padding
+input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"]) {
+  &[type="search"] {
+    padding-inline-start: calc(var(--form-element-spacing-horizontal) + 1.75rem);
+    border-radius: 5rem;
+    background-image: var(--icon-search);
+    background-position: center left 1.125rem;
+    background-size: 1rem auto;
+    background-repeat: no-repeat;
+    
+    &[aria-invalid] {
+      @if $enable-important {
+        padding-inline-start: calc(var(--form-element-spacing-horizontal) + 1.75rem) !important;
+      } 
+      @else {
+        padding-inline-start: calc(var(--form-element-spacing-horizontal) + 1.75rem);
+      }
+      background-position: center left 1.125rem, center right 0.75rem;
+    }
+
+    &[aria-invalid="false"] {
+      background-image: var(--icon-search), var(--icon-valid);
+    }
+
+    &[aria-invalid="true"] {
+      background-image: var(--icon-search), var(--icon-invalid);
+    }
+  }
+}
+
+// Cancel button
+[type="search"] {
+  &::-webkit-search-cancel-button {
+    -webkit-appearance: none;
+    display: none;
+  }
+}
+
+[dir="rtl"] {
+  :where(input) {
+    &:not([type="checkbox"], [type="radio"], [type="range"], [type="file"]) {
+      &[type="search"] {
+        background-position: center right 1.125rem;
+        
+        &[aria-invalid] {
+          background-position: center right 1.125rem, center left 0.75rem;
+        }
+      }
+    }
+  }
+}
new file mode 100644
index 0000000..c83d35e
--- /dev/null
+++ b/sass/_picocss/content/_form-checkbox-radio.scss
@@ -0,0 +1,138 @@
+/**
+ * Form elements
+ * Checkboxes & Radios
+ */
+
+[type="checkbox"],
+[type="radio"] {
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  width: 1.25em;
+  height: 1.25em;
+  margin-top: -0.125em;
+  margin-right: 0.375em;
+  margin-left: 0;
+  margin-inline-start: 0;
+  margin-inline-end: 0.375em;
+  border-width: var(--border-width);
+  font-size: inherit;
+  vertical-align: middle;
+  cursor: pointer;
+
+  &::-ms-check {
+    display: none; // unstyle IE checkboxes
+  }
+
+  &:checked,
+  &:checked:active,
+  &:checked:focus {
+    --background-color: var(--primary);
+    --border-color: var(--primary);
+    background-image: var(--icon-checkbox);
+    background-position: center;
+    background-size: 0.75em auto;
+    background-repeat: no-repeat;
+  }
+
+  & ~ label {
+    display: inline-block;
+    margin-right: 0.375em;
+    margin-bottom: 0;
+    cursor: pointer;
+  }
+}
+
+// Checkboxes
+[type="checkbox"] {
+  &:indeterminate {
+    --background-color: var(--primary);
+    --border-color: var(--primary);
+    background-image: var(--icon-minus);
+    background-position: center;
+    background-size: 0.75em auto;
+    background-repeat: no-repeat;
+  }
+}
+
+// Radios
+[type="radio"] {
+  border-radius: 50%;
+
+  &:checked,
+  &:checked:active,
+  &:checked:focus {
+    --background-color: var(--primary-inverse);
+    border-width: 0.35em;
+    background-image: none;
+  }
+}
+
+// Switchs
+[type="checkbox"][role="switch"] {
+  --background-color: var(--switch-background-color);
+  --border-color: var(--switch-background-color);
+  --color: var(--switch-color);
+
+  // Config
+  $switch-height: 1.25em;
+  $switch-width: 2.25em;
+  $switch-transition: 0.1s ease-in-out;
+
+  // Styles
+  width: $switch-width;
+  height: $switch-height;
+  border: var(--border-width) solid var(--border-color);
+  border-radius: $switch-height;
+  background-color: var(--background-color);
+  line-height: $switch-height;
+
+  &:focus {
+    --background-color: var(--switch-background-color);
+    --border-color: var(--switch-background-color);
+  }
+
+  &:checked {
+    --background-color: var(--switch-checked-background-color);
+    --border-color: var(--switch-checked-background-color);
+  }
+
+  &:before {
+    display: block;
+    width: calc(#{$switch-height} - (var(--border-width) * 2));
+    height: 100%;
+    border-radius: 50%;
+    background-color: var(--color);
+    content: "";
+
+    @if $enable-transitions {
+      transition: margin $switch-transition;
+    }
+  }
+
+  &:checked {
+    background-image: none;
+
+    &::before {
+      margin-left: calc(#{$switch-width * 0.5} - var(--border-width));
+      margin-inline-start: calc(#{$switch-width * 0.5} - var(--border-width));
+    }
+  }
+}
+
+// Aria-invalid
+[type="checkbox"],
+[type="checkbox"]:checked,
+[type="radio"],
+[type="radio"]:checked,
+[type="checkbox"][role="switch"],
+[type="checkbox"][role="switch"]:checked {
+  
+  &[aria-invalid="false"] {
+    --border-color: var(--form-element-valid-border-color);
+  }
+
+  &[aria-invalid="true"] {
+    --border-color: var(--form-element-invalid-border-color);
+  }
+}
\ No newline at end of file
new file mode 100644
index 0000000..1dda8f3
--- /dev/null
+++ b/sass/_picocss/content/_form.scss
@@ -0,0 +1,352 @@
+/**
+ * Form elements
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// 1. Change the font styles in all browsers
+// 2. Remove the margin in Firefox and Safari
+input,
+optgroup,
+select,
+textarea {
+  margin: 0; // 2
+  font-size: 1rem; // 1
+  line-height: var(--line-height); // 1
+  font-family: inherit; // 1
+  letter-spacing: inherit; // 2
+}
+
+// Show the overflow in IE.
+input {
+  overflow: visible;
+}
+
+// Remove the inheritance of text transform in Edge, Firefox, and IE
+select {
+  text-transform: none;
+}
+
+// 1. Correct the text wrapping in Edge and IE
+// 2. Correct the color inheritance from `fieldset` elements in IE
+// 3. Remove the padding so developers are not caught out when they zero out
+// `fieldset` elements in all browsers
+legend {
+  max-width: 100%; // 1
+  padding: 0; // 3
+  color: inherit; // 2
+  white-space: normal; // 1
+}
+
+// 1. Remove the default vertical scrollbar in IE
+textarea {
+  overflow: auto; // 1
+}
+
+// Remove the padding in IE 10
+[type="checkbox"],
+[type="radio"] {
+  padding: 0;
+}
+
+// Correct the cursor style of increment and decrement buttons in Safari
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+  height: auto;
+}
+
+// 1. Correct the odd appearance in Chrome and Safari
+// 2. Correct the outline style in Safari
+[type="search"] {
+  -webkit-appearance: textfield; // 1
+  outline-offset: -2px; // 2
+}
+
+// Remove the inner padding in Chrome and Safari on macOS
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+// 1. Correct the inability to style clickable types in iOS and Safari
+// 2. Change font properties to `inherit` in Safari
+::-webkit-file-upload-button {
+  -webkit-appearance: button; // 1
+  font: inherit; // 2
+}
+
+// Remove the inner border and padding of focus outlines in Firefox
+::-moz-focus-inner {
+  padding: 0;
+  border-style: none;
+}
+
+//  Remove the focus outline in Firefox
+:-moz-focusring {
+  outline: none;
+}
+
+// Remove the additional :invalid styles in Firefox
+:-moz-ui-invalid {
+  box-shadow: none;
+}
+
+// Change the inconsistent appearance in IE (opinionated)
+::-ms-expand {
+  display: none;
+}
+
+// Remove the border and padding in all browsers (opinionated)
+[type="file"],
+[type="range"] {
+  padding: 0;
+  border-width: 0;
+}
+
+// Pico
+// ––––––––––––––––––––
+
+// Force height for alternatives input types
+input:not([type="checkbox"], [type="radio"], [type="range"]) {
+  height: calc(
+    (1rem * var(--line-height)) + (var(--form-element-spacing-vertical) * 2) +
+      (var(--border-width) * 2)
+  );
+}
+
+// Fieldset
+fieldset {
+  margin: 0;
+  margin-bottom: var(--spacing);
+  padding: 0;
+  border: 0;
+}
+
+// Label & legend
+label,
+fieldset legend {
+  display: block;
+  margin-bottom: calc(var(--spacing) * 0.25);
+  font-weight: var(--form-label-font-weight, var(--font-weight));
+}
+
+// Blocks, 100%
+input:not([type="checkbox"], [type="radio"]),
+select,
+textarea {
+  width: 100%;
+}
+
+// Reset appearance (Not Checkboxes, Radios, Range and File)
+input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"]),
+select,
+textarea {
+  appearance: none;
+  padding: var(--form-element-spacing-vertical)
+    var(--form-element-spacing-horizontal);
+}
+
+// Commons styles
+input,
+select,
+textarea {
+  --background-color: var(--form-element-background-color);
+  --border-color: var(--form-element-border-color);
+  --color: var(--form-element-color);
+  --box-shadow: none;
+  border: var(--border-width) solid var(--border-color);
+  border-radius: var(--border-radius);
+  outline: none;
+  background-color: var(--background-color);
+  box-shadow: var(--box-shadow);
+  color: var(--color);
+  font-weight: var(--font-weight);
+
+  @if $enable-transitions {
+    transition: background-color var(--transition),
+      border-color var(--transition), color var(--transition),
+      box-shadow var(--transition);
+  }
+}
+
+// Active & Focus
+input:not([type="submit"], [type="button"], [type="reset"], [type="checkbox"], [type="radio"], [readonly]),
+:where(select, textarea) {
+  &:is(:active, :focus) {
+    --background-color: var(--form-element-active-background-color);
+  }
+}
+
+// Active & Focus
+input:not([type="submit"], [type="button"], [type="reset"], [role="switch"], [readonly]),
+:where(select, textarea) {
+  &:is(:active, :focus) {
+    --border-color: var(--form-element-active-border-color);
+  }
+}
+
+// Focus
+input:not([type="submit"], [type="button"], [type="reset"], [type="range"], [type="file"], [readonly]),
+select,
+textarea {
+  &:focus {
+    --box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
+  }
+}
+
+// Disabled
+input:not([type="submit"], [type="button"], [type="reset"])[disabled],
+select[disabled],
+textarea[disabled],
+:where(fieldset[disabled]) :is(input:not([type="submit"], [type="button"], [type="reset"]), select, textarea) {
+  --background-color: var(--form-element-disabled-background-color);
+  --border-color: var(--form-element-disabled-border-color);
+  opacity: var(--form-element-disabled-opacity);
+  pointer-events: none;
+}
+
+// Aria-invalid
+:where(input, select, textarea) {
+  &:not([type="checkbox"], [type="radio"], [type="date"], [type="datetime-local"], [type="month"], [type="time"], [type="week"]) {
+    &[aria-invalid] {
+      @if $enable-important {
+        padding-right: calc(
+          var(--form-element-spacing-horizontal) + 1.5rem
+        ) !important;
+        padding-left: var(--form-element-spacing-horizontal);
+        padding-inline-start: var(--form-element-spacing-horizontal) !important;
+        padding-inline-end: calc(
+          var(--form-element-spacing-horizontal) + 1.5rem
+        ) !important;
+      }
+      @else {
+        padding-right: calc(var(--form-element-spacing-horizontal) + 1.5rem);
+        padding-left: var(--form-element-spacing-horizontal);
+        padding-inline-start: var(--form-element-spacing-horizontal);
+        padding-inline-end: calc(var(--form-element-spacing-horizontal) + 1.5rem);
+      }
+      background-position: center right 0.75rem;
+      background-size: 1rem auto;
+      background-repeat: no-repeat;
+    }
+
+    &[aria-invalid="false"] {
+      background-image: var(--icon-valid);
+    }
+
+    &[aria-invalid="true"] {
+      background-image: var(--icon-invalid);
+    }
+  }
+
+  &[aria-invalid="false"] {
+    --border-color: var(--form-element-valid-border-color);
+
+    &:is(:active, :focus) {
+      @if $enable-important {
+        --border-color: var(--form-element-valid-active-border-color) !important;
+        --box-shadow: 0 0 0 var(--outline-width) var(--form-element-valid-focus-color) !important;
+      }
+      @else {
+        --border-color: var(--form-element-valid-active-border-color);
+        --box-shadow: 0 0 0 var(--outline-width) var(--form-element-valid-focus-color);
+      }
+    }
+  }
+
+  &[aria-invalid="true"] {
+    --border-color: var(--form-element-invalid-border-color);
+
+    &:is(:active, :focus) {
+      @if $enable-important {
+        --border-color: var(--form-element-invalid-active-border-color) !important;
+        --box-shadow: 0 0 0 var(--outline-width) var(--form-element-invalid-focus-color) !important;
+      }
+      @else {
+        --border-color: var(--form-element-invalid-active-border-color);
+        --box-shadow: 0 0 0 var(--outline-width) var(--form-element-invalid-focus-color);
+      }
+    }
+  }
+}
+
+[dir="rtl"] {
+  :where(input, select, textarea) {
+    &:not([type="checkbox"], [type="radio"]) {
+      &:is([aria-invalid], [aria-invalid="true"], [aria-invalid="false"] ){
+        background-position: center left 0.75rem;
+      }
+    }
+  }
+}
+
+// Placeholder
+input::placeholder,
+input::-webkit-input-placeholder,
+textarea::placeholder,
+textarea::-webkit-input-placeholder,
+select:invalid {
+  color: var(--form-element-placeholder-color);
+  opacity: 1;
+}
+
+// Margin bottom (Not Checkboxes and Radios)
+input:not([type="checkbox"], [type="radio"]),
+select,
+textarea {
+  margin-bottom: var(--spacing);
+}
+
+// Select
+select {
+  // Unstyle the caret on `<select>`s in IE10+.
+  &::-ms-expand {
+    border: 0;
+    background-color: transparent;
+  }
+
+  &:not([multiple], [size]) {
+    padding-right: calc(var(--form-element-spacing-horizontal) + 1.5rem);
+    padding-left: var(--form-element-spacing-horizontal);
+    padding-inline-start: var(--form-element-spacing-horizontal);
+    padding-inline-end: calc(var(--form-element-spacing-horizontal) + 1.5rem);
+    background-image: var(--icon-chevron);
+    background-position: center right 0.75rem;
+    background-size: 1rem auto;
+    background-repeat: no-repeat;
+  }
+}
+
+[dir="rtl"] {
+  select {
+    &:not([multiple], [size]) {
+      background-position: center left 0.75rem;
+    }
+  }
+}
+
+// Helper
+$inputs: "input, select, textarea";
+
+@if ($enable-classes and $enable-grid) {
+  $inputs: $inputs + ", .grid";
+}
+
+:where(#{$inputs}) {
+  + small {
+    display: block;
+    width: 100%;
+    margin-top: calc(var(--spacing) * -0.75);
+    margin-bottom: var(--spacing);
+    color: var(--muted-color);
+  }
+}
+
+// Styles for Input inside a label
+label {
+  > :where(input, select, textarea) {
+    margin-top: calc(var(--spacing) * 0.25);
+  }
+}
new file mode 100644
index 0000000..526baba
--- /dev/null
+++ b/sass/_picocss/content/_miscs.scss
@@ -0,0 +1,33 @@
+/**
+ * Miscs
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// 1. Correct the inheritance of border color in Firefox
+// 2. Add the correct box sizing in Firefox
+hr {
+  height: 0; // 2
+  border: 0;
+  border-top: 1px solid var(--muted-border-color);
+  color: inherit; // 1
+}
+
+// Add the correct display in IE 10+
+[hidden],
+template {
+  @if $enable-important {
+    display: none !important;
+  } 
+  @else {
+    display: none;
+  }
+}
+
+// Add the correct display in IE 9-
+canvas {
+  display: inline-block;
+}
new file mode 100644
index 0000000..d70cfd7
--- /dev/null
+++ b/sass/_picocss/content/_table.scss
@@ -0,0 +1,50 @@
+/**
+ * Table
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// 1. Collapse border spacing in all browsers (opinionated)
+// 2. Remove text indentation from table contents in Chrome, Edge, and Safari
+:where(table) {
+  width: 100%;
+  border-collapse: collapse; // 1
+  border-spacing: 0;
+  text-indent: 0; // 2
+}
+
+// Pico
+// ––––––––––––––––––––
+
+// Cells
+th,
+td {
+  padding: calc(var(--spacing) / 2) var(--spacing);
+  border-bottom: var(--border-width) solid var(--table-border-color);
+  color: var(--color);
+  font-weight: var(--font-weight);
+  font-size: var(--font-size);
+  text-align: left;
+  text-align: start;
+}
+
+// Footer
+tfoot {
+  th,
+  td {
+    border-top: var(--border-width) solid var(--table-border-color);
+    border-bottom: 0;
+  }
+}
+
+// Striped
+table {
+  &[role="grid"] {
+    tbody tr:nth-child(odd) {
+      background-color: var(--table-row-stripped-background-color);
+    }
+  }
+}
new file mode 100644
index 0000000..a9ed71b
--- /dev/null
+++ b/sass/_picocss/content/_typography.scss
@@ -0,0 +1,264 @@
+/**
+ * Typography
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// Add the correct font weight in Chrome, Edge, and Safari
+b,
+strong {
+  font-weight: bolder;
+}
+
+// Prevent `sub` and `sup` elements from affecting the line height in all browsers
+sub,
+sup {
+  position: relative;
+  font-size: 0.75em;
+  line-height: 0;
+  vertical-align: baseline;
+}
+sub {
+  bottom: -0.25em;
+}
+sup {
+  top: -0.5em;
+}
+
+// Pico
+// ––––––––––––––––––––
+
+address,
+blockquote,
+dl,
+figure,
+form,
+ol,
+p,
+pre,
+table,
+ul {
+  margin-top: 0;
+  margin-bottom: var(--typography-spacing-vertical);
+  color: var(--color);
+  font-style: normal;
+  font-weight: var(--font-weight);
+  font-size: var(--font-size);
+}
+
+// Links
+// 1. Remove the gray background on active links in IE 10
+a,
+[role="link"] {
+  --color: var(--primary);
+  --background-color: transparent;
+  outline: none;
+  background-color: var(--background-color); // 1
+  color: var(--color);
+  text-decoration: var(--text-decoration);
+
+  @if $enable-transitions {
+    transition: background-color var(--transition), color var(--transition),
+      text-decoration var(--transition), box-shadow var(--transition);
+  }
+
+  &:is([aria-current], :hover, :active, :focus) {
+    --color: var(--primary-hover);
+    --text-decoration: underline;
+  }
+
+  &:focus {
+    --background-color: var(--primary-focus);
+  }
+
+  @if $enable-classes {
+    // Secondary
+    &.secondary {
+      --color: var(--secondary);
+
+      &:is([aria-current], :hover, :active, :focus) {
+        --color: var(--secondary-hover);
+      }
+
+      &:focus {
+        --background-color: var(--secondary-focus);
+      }
+    }
+
+    // Contrast
+    &.contrast {
+      --color: var(--contrast);
+
+      &:is([aria-current], :hover, :active, :focus) {
+        --color: var(--contrast-hover);
+      }
+
+      &:focus {
+        --background-color: var(--contrast-focus);
+      }
+    }
+  }
+}
+
+// Headings
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  margin-top: 0;
+  margin-bottom: var(--typography-spacing-vertical);
+  color: var(--color);
+  font-weight: var(--font-weight);
+  font-size: var(--font-size);
+  font-family: var(--font-family);
+}
+
+h1 {
+  --color: var(--h1-color);
+}
+h2 {
+  --color: var(--h2-color);
+}
+h3 {
+  --color: var(--h3-color);
+}
+h4 {
+  --color: var(--h4-color);
+}
+h5 {
+  --color: var(--h5-color);
+}
+h6 {
+  --color: var(--h6-color);
+}
+
+// Margin-top for headings after a typography block
+:where(address, blockquote, dl, figure, form, ol, p, pre, table, ul) {
+  ~ :is(h1, h2, h3, h4, h5, h6) {
+    margin-top: var(--typography-spacing-vertical);
+  }
+}
+
+// Heading group
+@if $enable-classes == false {
+  hgroup {
+    margin-bottom: var(--typography-spacing-vertical);
+
+    > * {
+      margin-bottom: 0;
+    }
+
+    > *:last-child {
+      --color: var(--muted-color);
+      --font-weight: unset;
+      font-size: 1rem;
+      font-family: unset;
+    }
+  }
+}
+
+@if $enable-classes {
+  hgroup,
+  .headings {
+    margin-bottom: var(--typography-spacing-vertical);
+
+    > * {
+      margin-bottom: 0;
+    }
+
+    > *:last-child {
+      --color: var(--muted-color);
+      --font-weight: unset;
+      font-size: 1rem;
+      font-family: unset;
+    }
+  }
+}
+
+// Paragraphs
+p {
+  margin-bottom: var(--typography-spacing-vertical);
+}
+
+// Small
+small {
+  font-size: var(--font-size);
+}
+
+// Lists
+:where(dl, ol, ul) {
+  padding-right: 0;
+  padding-left: var(--spacing);
+  padding-inline-start: var(--spacing);
+  padding-inline-end: 0;
+
+  li {
+    margin-bottom: calc(var(--typography-spacing-vertical) * 0.25);
+  }
+}
+
+// Margin-top for nested lists
+// 1. Remove the margin on nested lists in Chrome, Edge, IE, and Safari
+:where(dl, ol, ul) {
+  :is(dl, ol, ul) {
+    margin: 0; // 1
+    margin-top: calc(var(--typography-spacing-vertical) * 0.25);
+  }
+}
+
+ul li {
+  list-style: square;
+}
+
+// Highlighted text
+mark {
+  padding: 0.125rem 0.25rem;
+  background-color: var(--mark-background-color);
+  color: var(--mark-color);
+  vertical-align: baseline;
+}
+
+// Blockquote
+blockquote {
+  display: block;
+  margin: var(--typography-spacing-vertical) 0;
+  padding: var(--spacing);
+  border-right: none;
+  border-left: 0.25rem solid var(--blockquote-border-color);
+  border-inline-start: 0.25rem solid var(--blockquote-border-color);
+  border-inline-end: none;
+
+  footer {
+    margin-top: calc(var(--typography-spacing-vertical) * 0.5);
+    color: var(--blockquote-footer-color);
+  }
+}
+
+// Abbreviations
+// 1. Remove underline decoration in Chrome, Edge, IE, Opera, and Safari
+abbr[title] {
+  border-bottom: 1px dotted;
+  text-decoration: none; // 1
+  cursor: help;
+}
+
+// Ins
+ins {
+  color: var(--ins-color);
+  text-decoration: none;
+}
+
+// del
+del {
+  color: var(--del-color);
+}
+
+// selection
+::selection {
+  background-color: var(--primary-focus);
+}
new file mode 100644
index 0000000..6a20bea
--- /dev/null
+++ b/sass/_picocss/layout/_container.scss
@@ -0,0 +1,42 @@
+@if ($enable-class-container and $enable-classes) {
+  /**
+ * Container
+ */
+
+  .container,
+  .container-fluid {
+    width: 100%;
+    margin-right: auto;
+    margin-left: auto;
+    padding-right: var(--spacing);
+    padding-left: var(--spacing);
+  }
+
+  .container {
+    @if map-get($breakpoints, "sm") {
+      @media (min-width: map-get($breakpoints, "sm")) {
+        max-width: map-get($viewports, "sm");
+        padding-right: 0;
+        padding-left: 0;
+      }
+    }
+
+    @if map-get($breakpoints, "md") {
+      @media (min-width: map-get($breakpoints, "md")) {
+        max-width: map-get($viewports, "md");
+      }
+    }
+
+    @if map-get($breakpoints, "lg") {
+      @media (min-width: map-get($breakpoints, "lg")) {
+        max-width: map-get($viewports, "lg");
+      }
+    }
+
+    @if map-get($breakpoints, "xl") {
+      @media (min-width: map-get($breakpoints, "xl")) {
+        max-width: map-get($viewports, "xl");
+      }
+    }
+  }
+}
new file mode 100644
index 0000000..1607659
--- /dev/null
+++ b/sass/_picocss/layout/_document.scss
@@ -0,0 +1,48 @@
+/**
+ * Document
+ * Content-box & Responsive typography
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// 1. Add border box sizing in all browsers (opinionated)
+// 2. Backgrounds do not repeat by default (opinionated)
+*,
+*::before,
+*::after {
+  box-sizing: border-box; // 1
+  background-repeat: no-repeat; // 2
+}
+
+// 1. Add text decoration inheritance in all browsers (opinionated)
+// 2. Add vertical alignment inheritance in all browsers (opinionated)
+::before,
+::after {
+  text-decoration: inherit; // 1
+  vertical-align: inherit; // 2
+}
+
+// 1. Use the default cursor in all browsers (opinionated)
+// 2. Change the line height in all browsers (opinionated)
+// 3. Breaks words to prevent overflow in all browsers (opinionated)
+// 4. Use a 4-space tab width in all browsers (opinionated)
+// 5. Remove the grey highlight on links in iOS (opinionated)
+// 6. Prevent adjustments of font size after orientation changes in iOS
+:where(:root) {
+  -webkit-tap-highlight-color: transparent; // 5
+  -webkit-text-size-adjust: 100%; // 6
+  text-size-adjust: 100%; // 6
+  background-color: var(--background-color);
+  color: var(--color);
+  font-weight: var(--font-weight);
+  font-size: var(--font-size);
+  line-height: var(--line-height); // 2
+  font-family: var(--font-family);
+  text-rendering: optimizeLegibility;
+  overflow-wrap: break-word; // 3
+  cursor: default; // 1
+  tab-size: 4; // 4
+}
new file mode 100644
index 0000000..572312b
--- /dev/null
+++ b/sass/_picocss/layout/_grid.scss
@@ -0,0 +1,24 @@
+@if ($enable-classes and $enable-grid) {
+  /**
+ * Grid
+ * Minimal grid system with auto-layout columns
+ */
+
+  .grid {
+    grid-column-gap: var(--grid-spacing-horizontal);
+    grid-row-gap: var(--grid-spacing-vertical);
+    display: grid;
+    grid-template-columns: 1fr;
+    margin: 0;
+
+    @if map-get($breakpoints, "lg") {
+      @media (min-width: map-get($breakpoints, "lg")) {
+        grid-template-columns: repeat(auto-fit, minmax(0%, 1fr));
+      }
+    }
+
+    & > * {
+      min-width: 0; // HACK for childs in overflow
+    }
+  }
+}
new file mode 100644
index 0000000..9b58ef7
--- /dev/null
+++ b/sass/_picocss/layout/_scroller.scss
@@ -0,0 +1,16 @@
+/**
+ * Horizontal scroller (<figure>)
+ */
+
+// Wrapper to make any content responsive across all viewports
+figure {
+  display: block;
+  margin: 0;
+  padding: 0;
+  overflow-x: auto;
+
+  figcaption {
+    padding: calc(var(--spacing) * 0.5) 0;
+    color: var(--muted-color);
+  }
+}
new file mode 100644
index 0000000..8bc6902
--- /dev/null
+++ b/sass/_picocss/layout/_section.scss
@@ -0,0 +1,8 @@
+/**
+ * Section
+ * Responsive spacings for section
+ */
+
+section {
+  margin-bottom: var(--block-spacing-vertical);
+}
new file mode 100644
index 0000000..00d73c5
--- /dev/null
+++ b/sass/_picocss/layout/_sectioning.scss
@@ -0,0 +1,70 @@
+/**
+ * Sectioning
+ * Container and responsive spacings for header, main, footer
+ */
+
+// Reboot based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// Render the `main` element consistently in IE
+main {
+  display: block;
+}
+
+// Pico
+// ––––––––––––––––––––
+
+// 1. Remove the margin in all browsers (opinionated)
+#{$semantic-root-element} {
+  width: 100%;
+  margin: 0; // 1
+
+  > header,
+  > main,
+  > footer {
+    width: 100%;
+    margin-right: auto;
+    margin-left: auto;
+
+    // Semantic container
+    @if $enable-semantic-container {
+      padding: var(--block-spacing-vertical) var(--block-spacing-horizontal);
+
+      // Centered viewport
+      @if $enable-viewport {
+        @if map-get($breakpoints, "sm") and $enable-viewport {
+          @media (min-width: map-get($breakpoints, "sm")) {
+            max-width: map-get($viewports, "sm");
+            padding-right: 0;
+            padding-left: 0;
+          }
+        }
+
+        @if map-get($breakpoints, "md") and $enable-viewport {
+          @media (min-width: map-get($breakpoints, "md")) {
+            max-width: map-get($viewports, "md");
+          }
+        }
+
+        @if map-get($breakpoints, "lg") and $enable-viewport {
+          @media (min-width: map-get($breakpoints, "lg")) {
+            max-width: map-get($viewports, "lg");
+          }
+        }
+
+        @if map-get($breakpoints, "xl") and $enable-viewport {
+          @media (min-width: map-get($breakpoints, "xl")) {
+            max-width: map-get($viewports, "xl");
+          }
+        }
+      }
+    }
+
+    // Semantic container
+    @else {
+      padding: var(--block-spacing-vertical) 0;
+    }
+  }
+}
new file mode 100644
index 0000000..c5ea832
--- /dev/null
+++ b/sass/_picocss/pico.classless.scss
@@ -0,0 +1,13 @@
+// Config
+// --------------------
+
+// Enable <header>, <main>, <footer> inside $semantic-root-element as containers
+$enable-semantic-container: true;
+
+// Enable .classes
+$enable-classes: false;
+
+// Pico Lib
+// --------------------
+
+@import "pico";
new file mode 100644
index 0000000..ef6af04
--- /dev/null
+++ b/sass/_picocss/pico.fluid.classless.scss
@@ -0,0 +1,16 @@
+// Config
+// --------------------
+
+// Enable <header>, <main>, <footer> inside $semantic-root-element as containers
+$enable-semantic-container: true;
+
+// Enable a centered viewport for <header>, <main>, <footer> inside $enable-semantic-container 
+$enable-viewport: false;
+
+// Enable .classes
+$enable-classes: false;
+
+// Pico Lib
+// --------------------
+
+@import "pico";
new file mode 100644
index 0000000..b248799
--- /dev/null
+++ b/sass/_picocss/pico.scss
@@ -0,0 +1,43 @@
+/*!
+ * Pico CSS v1.5.11 (https://picocss.com)
+ * Copyright 2019-2023 - Licensed under MIT
+ */
+
+// Config
+@import "variables";
+
+// Theming
+@import "themes/default";
+
+// Layout
+@import "layout/document"; // html
+@import "layout/sectioning"; // body, header, main, footer
+@import "layout/container"; // .container, .container-fluid
+@import "layout/section"; // section
+@import "layout/grid"; // .grid
+@import "layout/scroller"; // figure
+
+// Content
+@import "content/typography"; // a, headings, p, ul, blockquote, ...
+@import "content/embedded"; // audio, canvas, iframe, img, svg, video
+@import "content/button"; // button, a[role=button], type=button, type=submit ...
+@import "content/form"; // input, select, textarea, label, fieldset, legend
+@import "content/form-checkbox-radio"; // type=checkbox, type=radio, role=switch
+@import "content/form-alt-input-types"; // type=color, type=date, type=file, type=search, ...
+@import "content/table"; // table, tr, td, ...
+@import "content/code"; // pre, code, ...
+@import "content/miscs"; // hr, template, [hidden], dialog, canvas
+
+// Components
+@import "components/accordion"; // details, summary
+@import "components/card"; // article
+@import "components/modal"; // dialog
+@import "components/nav"; // nav
+@import "components/progress"; // progress
+@import "components/dropdown"; // dropdown
+
+// Utilities
+@import "utilities/loading"; // aria-busy=true
+@import "utilities/tooltip"; // data-tooltip
+@import "utilities/accessibility"; // -ms-touch-action, aria-*
+@import "utilities/reduce-motion"; // prefers-reduced-motion
new file mode 100644
index 0000000..cb9aa42
--- /dev/null
+++ b/sass/_picocss/pico.slim.scss
@@ -0,0 +1,47 @@
+/*!
+ * Pico CSS v1.5.11 (https://picocss.com)
+ * Copyright 2019-2023 - Licensed under MIT
+ *
+ * Slim version example
+ * You can export only the modules you need
+ */
+
+// Config
+// --------------------
+
+// Enable responsive spacings for <header>, <main>, <footer>, <section>, <article>
+$enable-responsive-spacings: false;
+
+// Enable transitions
+$enable-transitions: false;
+
+// Enable overriding with !important
+$enable-important: false;
+
+// Pico Lib
+// --------------------
+
+// Config
+@import "variables";
+
+// Theming
+@import "themes/default";
+
+// Layout
+@import "layout/document"; // html
+@import "layout/sectioning"; // body, header, main, footer
+@import "layout/container"; // .container, .container-fluid
+@import "layout/section"; // section
+@import "layout/grid"; // .grid
+@import "layout/scroller"; // figure
+
+// Content
+@import "content/typography"; // a, headings, p, ul, blockquote, ...
+@import "content/embedded"; // audio, canvas, iframe, img, svg, video
+@import "content/button"; // button, a[role=button], type=button, type=submit ...
+@import "content/form"; // input, select, textarea, label, fieldset, legend
+@import "content/table"; // table, tr, td, ...
+
+// Utilities
+@import "utilities/accessibility"; // -ms-touch-action, aria-*
+@import "utilities/reduce-motion"; // prefers-reduced-motion
new file mode 100644
index 0000000..4eaff47
--- /dev/null
+++ b/sass/_picocss/postcss.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+  syntax: "postcss-scss",
+  map: false,
+  plugins: {
+    "css-declaration-sorter": { 
+      order: "smacss" 
+    }
+  }
+}
\ No newline at end of file
new file mode 100644
index 0000000..c96b7e7
--- /dev/null
+++ b/sass/_picocss/themes/default.scss
@@ -0,0 +1,37 @@
+/**
+ * Theme: default
+ */
+
+// Variables
+@import "../variables";
+@import "default/colors";
+
+// Commons styles
+@import "default/styles";
+
+// Light theme (Default)
+// Can be forced with data-theme="light"
+@import "default/light";
+
+// Dark theme (Auto)
+// Automatically enabled if user has Dark mode enabled
+@import "default/dark";
+@media only screen and (prefers-color-scheme: dark) {
+  :root:not([data-theme]) {
+    @include dark;
+  }
+}
+
+// Dark theme (Forced)
+// Enabled if forced with data-theme="dark"
+[data-theme="dark"] {
+  @include dark;
+}
+
+// Accent-color
+progress,
+[type="checkbox"],
+[type="radio"],
+[type="range"] {
+  accent-color: var(--primary);
+}
new file mode 100644
index 0000000..19079ff
--- /dev/null
+++ b/sass/_picocss/themes/default/_colors.scss
@@ -0,0 +1,65 @@
+// Navy-Grey
+$grey-hue: 205 !default;
+$grey-50: hsl($grey-hue, 20%, 94%) !default;
+$grey-100: hsl($grey-hue, 18%, 86%) !default;
+$grey-200: hsl($grey-hue, 16%, 77%) !default;
+$grey-300: hsl($grey-hue, 14%, 68%) !default;
+$grey-400: hsl($grey-hue, 12%, 59%) !default;
+$grey-500: hsl($grey-hue, 10%, 50%) !default;
+$grey-600: hsl($grey-hue, 15%, 41%) !default;
+$grey-700: hsl($grey-hue, 20%, 32%) !default;
+$grey-800: hsl($grey-hue, 25%, 23%) !default;
+$grey-900: hsl($grey-hue, 30%, 15%) !default;
+
+// Light Blue
+$primary-hue: 195 !default;
+$primary-50: hsl($primary-hue, 90%, 94%) !default;
+$primary-100: hsl($primary-hue, 88%, 86%) !default;
+$primary-200: hsl($primary-hue, 86%, 77%) !default;
+$primary-300: hsl($primary-hue, 84%, 68%) !default;
+$primary-400: hsl($primary-hue, 82%, 59%) !default;
+$primary-500: hsl($primary-hue, 80%, 50%) !default;
+$primary-600: hsl($primary-hue, 85%, 41%) !default;
+$primary-700: hsl($primary-hue, 90%, 32%) !default;
+$primary-800: hsl($primary-hue, 95%, 23%) !default;
+$primary-900: hsl($primary-hue, 100%, 15%) !default;
+
+// Black & White
+$black: #000 !default;
+$white: #fff !default;
+
+// Amber
+$amber-50: #fff8e1 !default;
+$amber-100: #ffecb3 !default;
+$amber-200: #ffe082 !default;
+$amber-300: #ffd54f !default;
+$amber-400: #ffca28 !default;
+$amber-500: #ffc107 !default;
+$amber-600: #ffb300 !default;
+$amber-700: #ffa000 !default;
+$amber-800: #ff8f00 !default;
+$amber-900: #ff6f00 !default;
+
+// Green
+$green-50: #e8f5e9 !default;
+$green-100: #c8e6c9 !default;
+$green-200: #a5d6a7 !default;
+$green-300: #81c784 !default;
+$green-400: #66bb6a !default;
+$green-500: #4caf50 !default;
+$green-600: #43a047 !default;
+$green-700: #388e3c !default;
+$green-800: #2e7d32 !default;
+$green-900: #1b5e20 !default;
+
+// Red
+$red-50: #ffebee !default;
+$red-100: #ffcdd2 !default;
+$red-200: #ef9a9a !default;
+$red-300: #e57373 !default;
+$red-400: #ef5350 !default;
+$red-500: #f44336 !default;
+$red-600: #e53935 !default;
+$red-700: #d32f2f !default;
+$red-800: #c62828 !default;
+$red-900: #b71c1c !default;
new file mode 100644
index 0000000..2bf12e2
--- /dev/null
+++ b/sass/_picocss/themes/default/_dark.scss
@@ -0,0 +1,159 @@
+@import "../../functions";
+
+// Default: Dark theme
+@mixin dark {
+  --background-color: #{mix($black, $grey-900, 37.5%)};
+
+  // Texts colors
+  --color: #{$grey-200};
+  --h1-color: #{$grey-50};
+  --h2-color: #{mix($grey-100, $grey-50)};
+  --h3-color: #{$grey-100};
+  --h4-color: #{mix($grey-200, $grey-100)};
+  --h5-color: #{$grey-200};
+  --h6-color: #{mix($grey-300, $grey-200)};
+
+  // Muted colors
+  --muted-color: #{$grey-500};
+  --muted-border-color: #{mix($grey-900, $grey-800, 75%)};
+
+  // Primary colors
+  --primary: #{$primary-600};
+  --primary-hover: #{$primary-500};
+  --primary-focus: #{rgba($primary-600, 0.25)};
+  --primary-inverse: #{$white};
+
+  // Secondary colors
+  --secondary: #{$grey-600};
+  --secondary-hover: #{$grey-500};
+  --secondary-focus: #{rgba($grey-500, 0.25)};
+  --secondary-inverse: #{$white};
+
+  // Contrast colors
+  --contrast: #{$grey-50};
+  --contrast-hover: #{$white};
+  --contrast-focus: #{rgba($grey-500, 0.25)};
+  --contrast-inverse: #{$black};
+
+  // Highlighted text (<mark>)
+  --mark-background-color: #{mix($grey-300, $amber-300)};
+  --mark-color: #{mix($black, $grey-900, 37.5%)};
+
+  // Inserted (<ins>) & Deleted (<ins>)
+  --ins-color: #{$green-700};
+  --del-color: #{$red-800};
+
+  // Blockquote
+  --blockquote-border-color: var(--muted-border-color);
+  --blockquote-footer-color: var(--muted-color);
+
+  // Button
+  // To disable box-shadow, remove the var or set to '0 0 0 rgba(0, 0, 0, 0)'
+  // Don't use, 'none, 'false, 'null', '0', etc.
+  --button-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  --button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+
+  // Form elements
+  --form-element-background-color: #{mix($black, $grey-900, 37.5%)};
+  --form-element-border-color: #{mix($grey-800, $grey-700)};
+  --form-element-color: var(--color);
+  --form-element-placeholder-color: var(--muted-color);
+  --form-element-active-background-color: var(--form-element-background-color);
+  --form-element-active-border-color: var(--primary);
+  --form-element-focus-color: var(--primary-focus);
+  --form-element-disabled-background-color: #{$grey-800};
+  --form-element-disabled-border-color: #{$grey-700};
+  --form-element-disabled-opacity: 0.5;
+  --form-element-invalid-border-color: #{$red-900};
+  --form-element-invalid-active-border-color: #{$red-800};
+  --form-element-invalid-focus-color: #{rgba($red-800, 0.25)};
+  --form-element-valid-border-color: #{$green-800};
+  --form-element-valid-active-border-color: #{$green-700};
+  --form-element-valid-focus-color: #{rgba($green-700, 0.25)};
+
+  // Switch (input[type="checkbox"][role="switch"])
+  --switch-background-color: #{mix($grey-800, $grey-700)};
+  --switch-color: var(--primary-inverse);
+  --switch-checked-background-color: var(--primary);
+
+  // Range (input[type="range"])
+  --range-border-color: #{mix($grey-900, $grey-800)};
+  --range-active-border-color: #{$grey-800};
+  --range-thumb-border-color: var(--background-color);
+  --range-thumb-color: var(--secondary);
+  --range-thumb-hover-color: var(--secondary-hover);
+  --range-thumb-active-color: var(--primary);
+
+  // Table
+  --table-border-color: var(--muted-border-color);
+  --table-row-stripped-background-color: #{rgba($grey-500, 0.05)};
+
+  // Code
+  --code-background-color: #{mix($black, $grey-900, 12.5%)};
+  --code-color: var(--muted-color);
+  --code-kbd-background-color: var(--contrast);
+  --code-kbd-color: var(--contrast-inverse);
+  --code-tag-color: #{hsl(330, 30%, 50%)};
+  --code-property-color: #{hsl(185, 30%, 50%)};
+  --code-value-color: #{hsl(40, 10%, 50%)};
+  --code-comment-color: #{mix($grey-700, $grey-600)};
+
+  // Accordion (<details>)
+  --accordion-border-color: var(--muted-border-color);
+  --accordion-active-summary-color: var(--primary);
+  --accordion-close-summary-color: var(--color);
+  --accordion-open-summary-color: var(--muted-color);
+
+  // Card (<article>)
+  $box-shadow-elevation: 1rem;
+  $box-shadow-blur-strengh: 6rem;
+  $box-shadow-opacity: 0.06;
+  --card-background-color: #{mix($black, $grey-900, 25%)};
+  --card-border-color: var(--card-background-color);
+  --card-box-shadow:
+    #{($box-shadow-elevation * 0.5 * 0.029)} #{($box-shadow-elevation * 0.029)} #{($box-shadow-blur-strengh * 0.029)} #{rgba($black, ($box-shadow-opacity * 0.283))},
+    #{($box-shadow-elevation * 0.5 * 0.067)} #{($box-shadow-elevation * 0.067)} #{($box-shadow-blur-strengh * 0.067)} #{rgba($black, ($box-shadow-opacity * 0.4))},
+    #{($box-shadow-elevation * 0.5 * 0.125)} #{($box-shadow-elevation * 0.125)} #{($box-shadow-blur-strengh * 0.125)} #{rgba($black, ($box-shadow-opacity * 0.5))},
+    #{($box-shadow-elevation * 0.5 * 0.225)} #{($box-shadow-elevation * 0.225)} #{($box-shadow-blur-strengh * 0.225)} #{rgba($black, ($box-shadow-opacity * 0.6))},
+    #{($box-shadow-elevation * 0.5 * 0.417)} #{($box-shadow-elevation * 0.417)} #{($box-shadow-blur-strengh * 0.417)} #{rgba($black, ($box-shadow-opacity * 0.717))},
+    #{($box-shadow-elevation * 0.5)} #{$box-shadow-elevation} #{$box-shadow-blur-strengh} #{rgba($black, $box-shadow-opacity)},
+    0 0 0 0.0625rem #{rgba($black, ($box-shadow-opacity * 0.25) )};
+  --card-sectionning-background-color: #{mix($black, $grey-900, 12.5%)};
+
+  // Dropdown (<details role="list">)
+  --dropdown-background-color: #{$grey-900};
+  --dropdown-border-color: #{mix($grey-900, $grey-800)};
+  --dropdown-box-shadow: var(--card-box-shadow);
+  --dropdown-color: var(--color);
+  --dropdown-hover-background-color: #{rgba(mix($grey-900, $grey-800), 0.75)};
+
+  // Modal (<dialog>)
+  --modal-overlay-background-color: #{rgba(mix($grey-900, $grey-800), 0.8)};
+
+  // Progress
+  --progress-background-color: #{mix($grey-900, $grey-800)};
+  --progress-color: var(--primary);
+
+  // Loading ([aria-busy=true])
+  --loading-spinner-opacity: 0.5;
+
+  // Tooltip ([data-tooltip])
+  --tooltip-background-color: var(--contrast);
+  --tooltip-color: var(--contrast-inverse);
+
+  // Icons
+  --icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($white)}' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-300)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-chevron-button: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($white)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-chevron-button-inverse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($black)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-500)}' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
+  --icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-300)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
+  --icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($red-900)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E");
+  --icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($white)}' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");
+  --icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-300)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");
+  --icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-300)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($green-800)}' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
+  
+  // Document
+  color-scheme: dark;
+}
new file mode 100644
index 0000000..237fb8f
--- /dev/null
+++ b/sass/_picocss/themes/default/_light.scss
@@ -0,0 +1,159 @@
+@import "../../functions";
+
+// Default: Light theme
+[data-theme="light"],
+:root:not([data-theme="dark"]) {
+  --background-color: #{$white};
+
+  // Texts colors
+  --color: #{$grey-700};
+  --h1-color: #{$grey-900};
+  --h2-color: #{mix($grey-900, $grey-800)};
+  --h3-color: #{$grey-800};
+  --h4-color: #{mix($grey-800, $grey-700)};
+  --h5-color: #{$grey-700};
+  --h6-color: #{mix($grey-700, $grey-600)};
+
+  // Muted colors
+  --muted-color: #{$grey-500};
+  --muted-border-color: #{$grey-50};
+
+  // Primary colors
+  --primary: #{$primary-600};
+  --primary-hover: #{$primary-700};
+  --primary-focus: #{rgba($primary-600, 0.125)};
+  --primary-inverse: #{$white};
+
+  // Secondary colors
+  --secondary: #{$grey-600};
+  --secondary-hover: #{$grey-700};
+  --secondary-focus: #{rgba($grey-600, 0.125)};
+  --secondary-inverse: #{$white};
+
+  // Contrast colors
+  --contrast: #{$grey-900};
+  --contrast-hover: #{$black};
+  --contrast-focus: #{rgba($grey-600, 0.125)};
+  --contrast-inverse: #{$white};
+
+  // Highlighted text (<mark>)
+  --mark-background-color: #{mix($amber-100, $amber-50)};
+  --mark-color: #{mix($grey-900, $amber-900, 75%)};
+
+  // Inserted (<ins>) & Deleted (<ins>)
+  --ins-color: #{$green-700};
+  --del-color: #{$red-800};
+
+  // Blockquote
+  --blockquote-border-color: var(--muted-border-color);
+  --blockquote-footer-color: var(--muted-color);
+
+  // Button
+  // To disable box-shadow, remove the var or set to '0 0 0 rgba(0, 0, 0, 0)'
+  // Don't use, 'none, 'false, 'null', '0', etc.
+  --button-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  --button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+
+  // Form elements
+  --form-element-background-color: transparent;
+  --form-element-border-color: #{$grey-300};
+  --form-element-color: var(--color);
+  --form-element-placeholder-color: var(--muted-color);
+  --form-element-active-background-color: transparent;
+  --form-element-active-border-color: var(--primary);
+  --form-element-focus-color: var(--primary-focus);
+  --form-element-disabled-background-color: #{$grey-100};
+  --form-element-disabled-border-color: #{$grey-300};
+  --form-element-disabled-opacity: 0.5;
+  --form-element-invalid-border-color: #{$red-800};
+  --form-element-invalid-active-border-color: #{$red-700};
+  --form-element-invalid-focus-color: #{rgba($red-700, 0.125)};
+  --form-element-valid-border-color: #{$green-700};
+  --form-element-valid-active-border-color: #{$green-600};
+  --form-element-valid-focus-color: #{rgba($green-600, 0.125)};
+
+  // Switch (input[type="checkbox"][role="switch"])
+  --switch-background-color: #{$grey-200};
+  --switch-color: var(--primary-inverse);
+  --switch-checked-background-color: var(--primary);
+
+  // Range (input[type="range"])
+  --range-border-color: #{$grey-100};
+  --range-active-border-color: #{$grey-200};
+  --range-thumb-border-color: var(--background-color);
+  --range-thumb-color: var(--secondary);
+  --range-thumb-hover-color: var(--secondary-hover);
+  --range-thumb-active-color: var(--primary);
+
+  // Table
+  --table-border-color: var(--muted-border-color);
+  --table-row-stripped-background-color: #{mix($grey-50, $white)};
+
+  // Code
+  --code-background-color: #{$grey-50};
+  --code-color: var(--muted-color);
+  --code-kbd-background-color: var(--contrast);
+  --code-kbd-color: var(--contrast-inverse);
+  --code-tag-color: #{hsl(330, 40%, 50%)};
+  --code-property-color: #{hsl(185, 40%, 40%)};
+  --code-value-color: #{hsl(40, 20%, 50%)};
+  --code-comment-color: #{$grey-300};
+
+  // Accordion (<details>)
+  --accordion-border-color: var(--muted-border-color);
+  --accordion-close-summary-color: var(--color);
+  --accordion-open-summary-color: var(--muted-color);
+
+  // Card (<article>)
+  $box-shadow-elevation: 1rem;
+  $box-shadow-blur-strengh: 6rem;
+  $box-shadow-opacity: 0.06;
+  --card-background-color: var(--background-color);
+  --card-border-color: var(--muted-border-color);
+  --card-box-shadow:
+    #{($box-shadow-elevation * 0.5 * 0.029)} #{($box-shadow-elevation * 0.029)} #{($box-shadow-blur-strengh * 0.029)} #{rgba($grey-900, ($box-shadow-opacity * 0.283))},
+    #{($box-shadow-elevation * 0.5 * 0.067)} #{($box-shadow-elevation * 0.067)} #{($box-shadow-blur-strengh * 0.067)} #{rgba($grey-900, ($box-shadow-opacity * 0.4))},
+    #{($box-shadow-elevation * 0.5 * 0.125)} #{($box-shadow-elevation * 0.125)} #{($box-shadow-blur-strengh * 0.125)} #{rgba($grey-900, ($box-shadow-opacity * 0.5))},
+    #{($box-shadow-elevation * 0.5 * 0.225)} #{($box-shadow-elevation * 0.225)} #{($box-shadow-blur-strengh * 0.225)} #{rgba($grey-900, ($box-shadow-opacity * 0.6))},
+    #{($box-shadow-elevation * 0.5 * 0.417)} #{($box-shadow-elevation * 0.417)} #{($box-shadow-blur-strengh * 0.417)} #{rgba($grey-900, ($box-shadow-opacity * 0.717))},
+    #{($box-shadow-elevation * 0.5)} #{$box-shadow-elevation} #{$box-shadow-blur-strengh} #{rgba($grey-900, $box-shadow-opacity)},
+    0 0 0 0.0625rem #{rgba($grey-900, ($box-shadow-opacity * 0.25) )};
+  --card-sectionning-background-color: #{mix($grey-50, $white, 25%)};
+
+  // Dropdown (<details role="list">)
+  --dropdown-background-color: #{mix($grey-50, $white, 25%)};
+  --dropdown-border-color: #{mix($grey-100, $grey-50)};
+  --dropdown-box-shadow: var(--card-box-shadow);
+  --dropdown-color: var(--color);
+  --dropdown-hover-background-color: #{$grey-50};
+
+  // Modal (<dialog>)
+  --modal-overlay-background-color: #{rgba($grey-100, 0.7)};
+
+  // Progress
+  --progress-background-color: #{$grey-100};
+  --progress-color: var(--primary);
+
+  // Loading ([aria-busy=true])
+  --loading-spinner-opacity: 0.5;
+
+  // Tooltip ([data-tooltip])
+  --tooltip-background-color: var(--contrast);
+  --tooltip-color: var(--contrast-inverse);
+
+  // Icons
+  --icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($white)}' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-700)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-chevron-button: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($white)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-chevron-button-inverse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($white)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
+  --icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-500)}' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
+  --icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-700)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
+  --icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($red-800)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E");
+  --icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($white)}' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");
+  --icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-700)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");
+  --icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($grey-700)}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E"); 
+  --icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#{to-rgb($green-700)}' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
+  
+  // Document
+  color-scheme: light;
+}
new file mode 100644
index 0000000..3a0a46d
--- /dev/null
+++ b/sass/_picocss/themes/default/_styles.scss
@@ -0,0 +1,247 @@
+// Commons Styles
+:root {
+  // Typography
+  --font-family: system-ui, -apple-system, "Segoe UI", "Roboto", "Ubuntu",
+    "Cantarell", "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
+    "Segoe UI Symbol", "Noto Color Emoji";
+  --line-height: 1.5;
+  --font-weight: 400;
+  --font-size: 16px;
+
+  // Responsive typography
+  @if $enable-responsive-typography {
+    @if map-get($breakpoints, "sm") {
+      @media (min-width: map-get($breakpoints, "sm")) {
+        --font-size: 17px;
+      }
+    }
+
+    @if map-get($breakpoints, "md") {
+      @media (min-width: map-get($breakpoints, "md")) {
+        --font-size: 18px;
+      }
+    }
+
+    @if map-get($breakpoints, "lg") {
+      @media (min-width: map-get($breakpoints, "lg")) {
+        --font-size: 19px;
+      }
+    }
+
+    @if map-get($breakpoints, "xl") {
+      @media (min-width: map-get($breakpoints, "xl")) {
+        --font-size: 20px;
+      }
+    }
+  }
+
+  // Borders
+  --border-radius: 0.25rem;
+  --border-width: 1px;
+  --outline-width: 3px;
+
+  // Spacings
+  --spacing: 1rem;
+
+  // Spacings for typography elements
+  --typography-spacing-vertical: 1.5rem;
+
+  // Spacings for body > header, body > main, body > footer, section, article
+  --block-spacing-vertical: calc(var(--spacing) * 2);
+  --block-spacing-horizontal: var(--spacing);
+
+  @if ($enable-classes and $enable-grid) {
+    --grid-spacing-vertical: 0;
+    --grid-spacing-horizontal: var(--spacing);
+  }
+
+  // Spacings for form elements and button
+  --form-element-spacing-vertical: 0.75rem;
+  --form-element-spacing-horizontal: 1rem;
+
+  // Spacings for nav component
+  --nav-element-spacing-vertical: 1rem;
+  --nav-element-spacing-horizontal: 0.5rem;
+  --nav-link-spacing-vertical: 0.5rem;
+  --nav-link-spacing-horizontal: 0.5rem;
+
+  // Font weight for form labels & fieldsets legend
+  --form-label-font-weight: var(--font-weight);
+
+  // Transitions
+  --transition: 0.2s ease-in-out;
+
+  // Modal (<dialog>)
+  --modal-overlay-backdrop-filter: blur(0.25rem);
+}
+
+// Responsives spacings
+@if $enable-responsive-spacings {
+  // Sectioning
+  #{$semantic-root-element} > header,
+  #{$semantic-root-element} > main,
+  #{$semantic-root-element} > footer,
+  section {
+    @if map-get($breakpoints, "sm") {
+      @media (min-width: map-get($breakpoints, "sm")) {
+        --block-spacing-vertical: calc(var(--spacing) * 2.5);
+      }
+    }
+
+    @if map-get($breakpoints, "md") {
+      @media (min-width: map-get($breakpoints, "md")) {
+        --block-spacing-vertical: calc(var(--spacing) * 3);
+      }
+    }
+
+    @if map-get($breakpoints, "lg") {
+      @media (min-width: map-get($breakpoints, "lg")) {
+        --block-spacing-vertical: calc(var(--spacing) * 3.5);
+      }
+    }
+
+    @if map-get($breakpoints, "xl") {
+      @media (min-width: map-get($breakpoints, "xl")) {
+        --block-spacing-vertical: calc(var(--spacing) * 4);
+      }
+    }
+  }
+
+  // Card (<article>)
+  article {
+    @if map-get($breakpoints, "sm") {
+      @media (min-width: map-get($breakpoints, "sm")) {
+        --block-spacing-horizontal: calc(var(--spacing) * 1.25);
+      }
+    }
+
+    @if map-get($breakpoints, "md") {
+      @media (min-width: map-get($breakpoints, "md")) {
+        --block-spacing-horizontal: calc(var(--spacing) * 1.5);
+      }
+    }
+
+    @if map-get($breakpoints, "lg") {
+      @media (min-width: map-get($breakpoints, "lg")) {
+        --block-spacing-horizontal: calc(var(--spacing) * 1.75);
+      }
+    }
+
+    @if map-get($breakpoints, "xl") {
+      @media (min-width: map-get($breakpoints, "xl")) {
+        --block-spacing-horizontal: calc(var(--spacing) * 2);
+      }
+    }
+  }
+
+  // Modal
+  dialog > article {
+
+    --block-spacing-vertical: calc(var(--spacing) * 2);
+    --block-spacing-horizontal: var(--spacing);
+
+    @if map-get($breakpoints, "sm") {
+      @media (min-width: map-get($breakpoints, "sm")) {
+        --block-spacing-vertical: calc(var(--spacing) * 2.5);
+        --block-spacing-horizontal: calc(var(--spacing) * 1.25);
+      }
+    }
+
+    @if map-get($breakpoints, "md") {
+      @media (min-width: map-get($breakpoints, "md")) {
+        --block-spacing-vertical: calc(var(--spacing) * 3);
+        --block-spacing-horizontal: calc(var(--spacing) * 1.5);
+      }
+    }
+  }
+}
+
+// Link
+a {
+  --text-decoration: none;
+
+  // Secondary & Contrast
+  @if $enable-classes {
+    &.secondary,
+    &.contrast {
+      --text-decoration: underline;
+    }
+  }
+}
+
+// Small
+small {
+  --font-size: 0.875em;
+}
+
+// Headings
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  --font-weight: 700;
+}
+
+h1 {
+  --font-size: 2rem;
+  --typography-spacing-vertical: 3rem;
+}
+
+h2 {
+  --font-size: 1.75rem;
+  --typography-spacing-vertical: 2.625rem;
+}
+
+h3 {
+  --font-size: 1.5rem;
+  --typography-spacing-vertical: 2.25rem;
+}
+
+h4 {
+  --font-size: 1.25rem;
+  --typography-spacing-vertical: 1.874rem;
+}
+
+h5 {
+  --font-size: 1.125rem;
+  --typography-spacing-vertical: 1.6875rem;
+}
+
+// Forms elements
+[type="checkbox"],
+[type="radio"] {
+  --border-width: 2px;
+}
+
+[type="checkbox"][role="switch"] {
+  --border-width: 3px;
+}
+
+// Table
+thead,
+tfoot {
+  th,
+  td {
+    --border-width: 3px;
+  }
+}
+
+:not(thead, tfoot) > * > td {
+  --font-size: 0.875em;
+}
+
+// Code
+pre,
+code,
+kbd,
+samp {
+  --font-family: "Menlo", "Consolas", "Roboto Mono", "Ubuntu Monospace",
+    "Noto Mono", "Oxygen Mono", "Liberation Mono", monospace,
+    "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+}
+
+kbd {
+  --font-weight: bolder;
+}
new file mode 100644
index 0000000..e97ed7e
--- /dev/null
+++ b/sass/_picocss/utilities/_accessibility.scss
@@ -0,0 +1,52 @@
+/**
+ * Accessibility & User interaction
+ */
+
+// Based on :
+// - normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css
+// - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+// ––––––––––––––––––––
+
+// Accessibility
+
+// Change the cursor on control elements in all browsers (opinionated)
+[aria-controls] {
+  cursor: pointer;
+}
+
+// Change the cursor on disabled, not-editable, or otherwise inoperable elements in all browsers (opinionated)
+[aria-disabled="true"],
+[disabled] {
+  cursor: not-allowed;
+}
+
+// Change the display on visually hidden accessible elements in all browsers (opinionated)
+[aria-hidden="false"][hidden] {
+  display: initial;
+}
+
+[aria-hidden="false"][hidden]:not(:focus) {
+  clip: rect(0, 0, 0, 0);
+  position: absolute;
+}
+
+// User interaction
+// Remove the tapping delay in IE 10
+a,
+area,
+button,
+input,
+label,
+select,
+summary,
+textarea,
+[tabindex] {
+  -ms-touch-action: manipulation;
+}
+
+// Pico
+// ––––––––––––––––––––
+
+[dir="rtl"] {
+  direction: rtl;
+}
new file mode 100644
index 0000000..c6f3afe
--- /dev/null
+++ b/sass/_picocss/utilities/_loading.scss
@@ -0,0 +1,58 @@
+/**
+ * Loading ([aria-busy=true])
+ */
+
+
+// Cursor
+[aria-busy="true"] {
+  cursor: progress;
+}
+
+// Everyting except form elements
+[aria-busy="true"]:not(input, select, textarea, html) {
+
+  &::before {
+    display: inline-block;
+    width: 1em;
+    height: 1em;
+    border: 0.1875em solid currentColor;
+    border-radius: 1em;
+    border-right-color: transparent;
+    content: "";
+    vertical-align: text-bottom;
+    vertical-align: -.125em; // Visual alignment
+    animation: spinner 0.75s linear infinite;
+    opacity: var(--loading-spinner-opacity);
+  }
+
+  &:not(:empty) {
+    &::before {
+      margin-right: calc(var(--spacing) * 0.5);
+      margin-left: 0;
+      margin-inline-start: 0;
+      margin-inline-end: calc(var(--spacing) * 0.5);
+    }
+  }
+
+  &:empty {
+    text-align: center;
+  }
+}
+
+// Buttons and links
+button,
+input[type="submit"],
+input[type="button"],
+input[type="reset"],
+a {
+  &[aria-busy="true"] {
+    pointer-events: none;
+  }
+}
+
+// Animation: rotate
+@keyframes spinner {
+  to {
+    transform: rotate(360deg);
+  }
+}
new file mode 100644
index 0000000..ecfd6fd
--- /dev/null
+++ b/sass/_picocss/utilities/_reduce-motion.scss
@@ -0,0 +1,27 @@
+@if $enable-transitions and $enable-important {
+  /**
+ * Reduce Motion Features
+ */
+
+  // Based on :
+  // - sanitize.css v13.0.0 | CC0 1.0 Universal | github.com/csstools/sanitize.css
+  // ––––––––––––––––––––
+
+  // 1. Remove animations when motion is reduced (opinionated)
+  // 2. Remove fixed background attachments when motion is reduced (opinionated)
+  // 3. Remove timed scrolling behaviors when motion is reduced (opinionated)
+  // 4. Remove transitions when motion is reduced (opinionated)
+  @media (prefers-reduced-motion: reduce) {
+    *:not([aria-busy="true"]),
+    :not([aria-busy="true"])::before,
+    :not([aria-busy="true"])::after {
+      background-attachment: initial !important; // 2
+      animation-duration: 1ms !important; // 1
+      animation-delay: -1ms !important; // 1
+      animation-iteration-count: 1 !important; // 1
+      scroll-behavior: auto !important; // 3
+      transition-delay: 0s !important; // 4
+      transition-duration: 0s !important; // 4
+    }
+  }
+}
new file mode 100644
index 0000000..d0355a3
--- /dev/null
+++ b/sass/_picocss/utilities/_tooltip.scss
@@ -0,0 +1,278 @@
+/**
+ * Tooltip ([data-tooltip])
+ */
+
+[data-tooltip] {
+  position: relative;
+
+  &:not(a, button, input) {
+    border-bottom: 1px dotted;
+    text-decoration: none;
+    cursor: help;
+  }
+
+  &[data-placement="top"]::before,
+  &[data-placement="top"]::after,
+  &::before,
+  &::after {
+    display: block;
+    z-index: 99;
+    position: absolute;
+    bottom: 100%;
+    left: 50%;
+    padding: .25rem .5rem;
+    overflow: hidden;
+    transform: translate(-50%, -.25rem);
+    border-radius: var(--border-radius);
+    background: var(--tooltip-background-color);
+    content: attr(data-tooltip);
+    color: var(--tooltip-color);
+    font-style: normal;
+    font-weight: var(--font-weight);
+    font-size: .875rem;
+    text-decoration: none;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    opacity: 0;
+    pointer-events: none;
+  }
+  
+  // Caret
+  &[data-placement="top"]::after,
+  &::after {
+    padding: 0;
+    transform: translate(-50%, 0rem);
+    border-top: .3rem solid;
+    border-right: .3rem solid transparent;
+    border-left: .3rem solid transparent;
+    border-radius: 0;
+    background-color: transparent;
+    content: "";
+    color: var(--tooltip-background-color);
+  }
+
+  &[data-placement="bottom"] {
+    &::before,
+    &::after {
+      top: 100%;
+      bottom: auto;
+      transform: translate(-50%, .25rem);
+    }
+    
+    &:after{
+      transform: translate(-50%, -.3rem);
+      border: .3rem solid transparent;
+      border-bottom: .3rem solid;
+    }
+  }
+
+  &[data-placement="left"] {
+    &::before,
+    &::after {
+      top: 50%;
+      right: 100%;
+      bottom: auto;
+      left: auto;
+      transform: translate(-.25rem, -50%);
+    }
+    
+    &:after{
+      transform: translate(.3rem, -50%);
+      border: .3rem solid transparent;
+      border-left: .3rem solid;
+    }
+  }
+
+  &[data-placement="right"] {
+    &::before,
+    &::after {
+      top: 50%;
+      right: auto;
+      bottom: auto;
+      left: 100%;
+      transform: translate(.25rem, -50%);
+    }
+    
+    &:after{
+      transform: translate(-.3rem, -50%);
+      border: .3rem solid transparent;
+      border-right: .3rem solid;
+    }
+  }
+
+  // Display
+  &:focus,
+  &:hover {
+    &::before,
+    &::after {
+      opacity: 1;
+    }
+  }
+
+  
+  @if $enable-transitions {
+
+    // Animations, excluding touch devices
+    @media (hover: hover) and (pointer: fine) {
+      &[data-placement="bottom"]:focus,
+      &[data-placement="bottom"]:hover
+      &:focus,
+      &:hover {
+        &::before,
+        &::after {
+          animation-duration: .2s;
+          animation-name: tooltip-slide-top;
+        }
+
+        &::after {
+          animation-name: tooltip-caret-slide-top; 
+        }
+      }
+      
+      &[data-placement="bottom"] {
+        &:focus,
+        &:hover {
+          &::before,
+          &::after {
+            animation-duration: .2s;
+            animation-name: tooltip-slide-bottom;
+          }
+  
+          &::after {
+            animation-name: tooltip-caret-slide-bottom; 
+          }
+        }
+      }
+      
+      &[data-placement="left"] {
+        &:focus,
+        &:hover {
+          &::before,
+          &::after {
+            animation-duration: .2s;
+            animation-name: tooltip-slide-left;
+          }
+  
+          &::after {
+            animation-name: tooltip-caret-slide-left; 
+          }
+        }
+      }
+      
+      &[data-placement="right"] {
+        &:focus,
+        &:hover {
+          &::before,
+          &::after {
+            animation-duration: .2s;
+            animation-name: tooltip-slide-right;
+          }
+  
+          &::after {
+            animation-name: tooltip-caret-slide-right; 
+          }
+        }
+      }
+    }
+
+    @keyframes tooltip-slide-top {
+      from {
+        transform: translate(-50%, .75rem);
+        opacity: 0;
+      }
+      to {
+        transform: translate(-50%, -.25rem);
+        opacity: 1;
+      }
+    }
+    
+    @keyframes tooltip-caret-slide-top {
+      from {
+        opacity: 0;
+      }
+      50% {
+        transform: translate(-50%, -.25rem);
+        opacity: 0;
+      }
+      to {
+        transform: translate(-50%, 0rem);
+        opacity: 1;
+      }
+    }
+  
+    @keyframes tooltip-slide-bottom {
+      from {
+        transform: translate(-50%, -.75rem);
+        opacity: 0;
+      }
+      to {
+        transform: translate(-50%, .25rem);
+        opacity: 1;
+      }
+    }
+    
+    @keyframes tooltip-caret-slide-bottom {
+      from {
+        opacity: 0;
+      }
+      50% {
+        transform: translate(-50%, -.5rem);
+        opacity: 0;
+      }
+      to {
+        transform: translate(-50%, -.3rem);
+        opacity: 1;
+      }
+    }
+  
+    @keyframes tooltip-slide-left {
+      from {
+        transform: translate(.75rem, -50%);
+        opacity: 0;
+      }
+      to {
+        transform: translate(-.25rem, -50%);
+        opacity: 1;
+      }
+    }
+    
+    @keyframes tooltip-caret-slide-left {
+      from {
+        opacity: 0;
+      }
+      50% {
+        transform: translate(.05rem, -50%);
+        opacity: 0;
+      }
+      to {
+        transform: translate(.3rem, -50%);
+        opacity: 1;
+      }
+    }
+  
+    @keyframes tooltip-slide-right {
+      from {
+        transform: translate(-.75rem, -50%);
+        opacity: 0;
+      }
+      to {
+        transform: translate(.25rem, -50%);
+        opacity: 1;
+      }
+    }
+    
+    @keyframes tooltip-caret-slide-right {
+      from {
+        opacity: 0;
+      }
+      50% {
+        transform: translate(-.05rem, -50%);
+        opacity: 0;
+      }
+      to {
+        transform: translate(-.3rem, -50%);
+        opacity: 1;
+      }
+    }
+  }
+}
new file mode 100644
index 0000000..55c2b50
--- /dev/null
+++ b/sass/style.scss
@@ -0,0 +1 @@
+@import "_picocss/pico.scss";
index 8dcfffd..e9ba3d3 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -6,12 +6,13 @@
=        <title>Tad Zola Playground</title>
=        <meta name="description" content="Playing with Zola">
=        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <link rel="stylesheet" href="{{ get_url(path = "/style.css") }}" type="text/css" media="screen" />
=
=        <!-- TODO: Place favicon.ico in the root directory -->
=
=    </head>
=    <body>
-        <main>
+        <main class="container">
=            {% block content %}{% endblock %}
=        </main>
=

Display the blog index content

On by Tad Lispy

index c4437c3..35ccd78 100644
--- a/templates/blog.html
+++ b/templates/blog.html
@@ -2,6 +2,10 @@
=
={% block content %}
=<h1 class="title">{{ section.title }}</h1>
+
+<div>
+    {{ section.content | safe }}
+</div>
=<ul>
=    {% for post in section.pages %}
=    <li><a href="{{ post.permalink | safe }}">{{ post.title }}</a></li>