Compare commits

...

17 Commits

Author SHA1 Message Date
75c7f6052c Merge pull request 'Automatic flake update - 2024-07-15T00:00+00:00' (#88) from flake-update-2024-07-15 into main
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
2024-07-15 00:00:55 +00:00
Clan Merge Bot
2834c998f2 update flake lock - 2024-07-15T00:00+00:00
All checks were successful
check / test (pull_request) Successful in 14s
buildbot/nix-eval Build done.
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/9f4128e00b0ae8ec65918efeba59db998750ead6' (2024-07-03)
  → 'github:NixOS/nixpkgs/7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9' (2024-07-12)
2024-07-15 00:00:17 +00:00
42a4bd5068 add clan svg files
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
2024-07-09 11:50:57 +02:00
c225dc56b1 add colon after bold text
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 15s
deploy / test (push) Successful in 16s
2024-07-08 21:12:51 +02:00
7910e332be cherry picked changes from Valentin Gagarin part 3
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
2024-07-08 21:11:57 +02:00
d72a88cd3a cherry picked changes from Valentin Gagarin part 2
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
2024-07-08 21:07:46 +02:00
46b4c704ac cherry picked changes from Valentin Gagarin
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 13s
deploy / test (push) Successful in 16s
2024-07-08 15:35:33 +02:00
3461ee83e0 Merge pull request 'make hacker effect accessible' (#82) from fricklerhandwerk/clan-homepage:accessibility into main
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
Reviewed-on: #82
2024-07-08 13:30:40 +00:00
6591d73f7c make hacker effect accessible
the plain word doesn't make any sense if JavaScript is disabled. the
additional effect still works even if the original word is what it's
supposed to be.
2024-07-08 13:30:40 +00:00
345216fcb4 Merge pull request 'update capitalisation in logo' (#79) from fricklerhandwerk/clan-homepage:main into main
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
Reviewed-on: #79
2024-07-08 13:14:15 +00:00
b410b826f4 update capitalisation in logo 2024-07-08 13:14:15 +00:00
0c3192e3cc Merge pull request 'Automatic flake update - 2024-07-08T00:00+00:00' (#85) from flake-update-2024-07-08 into main
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 14s
2024-07-08 00:01:19 +00:00
Clan Merge Bot
7bc0506669 update flake lock - 2024-07-08T00:00+00:00
All checks were successful
buildbot/nix-eval Build done.
check / test (pull_request) Successful in 52s
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9' (2024-06-30)
  → 'github:hercules-ci/flake-parts/9227223f6d922fee3c7b190b2cc238a99527bbb7' (2024-07-03)
• Updated input 'flake-parts/nixpkgs-lib':
    'eb9ceca17d.tar.gz?narHash=sha256-lIbdfCsf8LMFloheeE6N31%2BBMIeixqyQWbSr2vk79EQ%3D' (2024-06-01)
  → '5daf051448.tar.gz?narHash=sha256-Fm2rDDs86sHy0/1jxTOKB1118Q0O3Uc7EC0iXvXKpbI%3D' (2024-07-01)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/b2852eb9365c6de48ffb0dc2c9562591f652242a' (2024-06-27)
  → 'github:NixOS/nixpkgs/9f4128e00b0ae8ec65918efeba59db998750ead6' (2024-07-03)
2024-07-08 00:00:19 +00:00
320090825e Merge pull request 'Automatic flake update - 2024-07-01T00:00+00:00' (#78) from flake-update-2024-07-01 into main
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
2024-07-01 00:00:40 +00:00
Clan Merge Bot
4f8ac7b388 update flake lock - 2024-07-01T00:00+00:00
All checks were successful
buildbot/nix-eval Build done.
check / test (pull_request) Successful in 14s
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8' (2024-06-01)
  → 'github:hercules-ci/flake-parts/c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9' (2024-06-30)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/a71e967ef3694799d0c418c98332f7ff4cc5f6af' (2024-06-22)
  → 'github:NixOS/nixpkgs/b2852eb9365c6de48ffb0dc2c9562591f652242a' (2024-06-27)
2024-07-01 00:00:16 +00:00
e1f2de68e7 Rephrase automatic backups
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
2024-06-24 19:37:45 +02:00
1d63446790 Merge pull request 'Automatic flake update - 2024-06-24T00:00+00:00' (#77) from flake-update-2024-06-24 into main
All checks were successful
buildbot/nix-eval Build done.
check / test (push) Successful in 14s
deploy / test (push) Successful in 15s
2024-06-24 00:00:44 +00:00
40 changed files with 15104 additions and 2782 deletions

View File

@ -1,27 +1,13 @@
# Getting start with the repo
This is the source for the homepage.
We use [zola](https://www.getzola.org/) for building a static website.
## Build the homepage
This will build the website including pages defined in the clan-core repo under `/docs`:
```command
$ nix build
```
This is the source for the Clan homepage.
## Start a local webserver
This server will include all the pages from clan-core, but doesn't automatically refresh. Also make sure to wipe your browsers cache after each change.
```command
$ nix run .#serve
```
## zola build & serve
Alternatively `zola build` and `zola serve` can be used for development but the result will be missing the pages defined in the clan-core repo.
## Contributing
Send changes to https://git.clan.lol/clan/clan-homepage
@ -31,10 +17,3 @@ Send changes to https://git.clan.lol/clan/clan-homepage
```
$ nix run .#deploy
```
## Create a new post
```
$ nix run .#new-post "September Changelog"
```

View File

@ -1,41 +0,0 @@
{
perSystem = {
lib,
pkgs,
self',
...
}: {
apps.new-post.program = builtins.toString (pkgs.writeShellScript "new-post.sh" ''
export PATH="${lib.makeBinPath [
pkgs.coreutils pkgs.gitMinimal
]}"
if [ -z "$1" ]; then
echo "Usage: new-post.sh <title>"
exit 1
fi
title=$(echo "$1" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
root=$(git rev-parse --show-toplevel)
fname="$root/content/blog/$(date +%Y-%m-%d)-$title.md"
if [ -f "$fname" ]; then
echo "File already exists: $fname"
exit 1
fi
cat <<EOF > "$fname"
+++
title = "$1"
date = "$(date --iso-8601=seconds)"
draft = true
template = "blog/page.html"
[taxonomies]
authors = [] # TODO
[extra]
lead = "Some lead"
+++
Some text
EOF
echo "Created $fname"
git add "$fname"
'');
};
}

View File

@ -28,7 +28,7 @@
packages.serve = pkgs.writeShellScriptBin "serve-local" ''
echo "serving: ${self'.packages.website-localhost}"
${pkgs.python3}/bin/python -m http.server 1111 \
-d ${self'.packages.website-localhost}
-d website
'';
};
}

View File

@ -5,11 +5,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1717285511,
"narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
"lastModified": 1719994518,
"narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
"rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
"type": "github"
},
"original": {
@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1719075281,
"narHash": "sha256-CyyxvOwFf12I91PBWz43iGT1kjsf5oi6ax7CrvaMyAo=",
"lastModified": 1720768451,
"narHash": "sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a71e967ef3694799d0c418c98332f7ff4cc5f6af",
"rev": "7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9",
"type": "github"
},
"original": {
@ -36,14 +36,14 @@
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1717284937,
"narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=",
"lastModified": 1719876945,
"narHash": "sha256-Fm2rDDs86sHy0/1jxTOKB1118Q0O3Uc7EC0iXvXKpbI=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
}
},
"root": {

View File

@ -12,7 +12,6 @@
imports = [
./flake-parts/deploy.nix
./flake-parts/devShells
./flake-parts/new-post.nix
./flake-parts/website.nix
];
perSystem = {pkgs, ...}: {

BIN
static/cLAN/cLAN--black.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

BIN
static/cLAN/cLAN--black.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
static/cLAN/cLAN--white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

7823
static/cLAN/cLAN.ai Normal file

File diff suppressed because one or more lines are too long

BIN
static/cLAN/cLAN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

7121
static/cLAN/cLAN.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View File

@ -150,6 +150,9 @@ section {
body {
line-height: 1;
display: flex;
flex-direction: column;
margin-top: 3.5em;
}
ol,
@ -210,11 +213,6 @@ html {
box-sizing: inherit;
}
html,
body {
height: 100%;
}
body {
background: #ffffff;
}
@ -248,7 +246,6 @@ a {
-webkit-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
-ms-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
border-bottom: dotted 1px;
color: #4eb980;
text-decoration: none;
}
@ -379,22 +376,6 @@ blockquote {
}
@media screen and (max-width: 736px) {
.container {
width: 90% !important;
}
}
@media screen and (max-width: 480px) {
.container {
width: 100% !important;
}
}
/* Row */
.row {
@ -1863,7 +1844,12 @@ blockquote {
}
@media screen and (max-width: 480px) {
@media screen and (max-width: 580px) {
.header-nav-links a:first-child {
flex-basis: 100%;
text-align: center;
}
.row {
display: flex;
@ -2328,6 +2314,21 @@ textarea {
position: relative;
}
.image p {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
text-transform: uppercase;
font-weight: bold;
color: #fff;
background-color: #2C2C2C;
width: 66%;
padding: 0.1em 0.5em 0.1em 0.5em;
}
.image:after {
-moz-transition: opacity 0.25s ease-in-out;
-webkit-transition: opacity 0.25s ease-in-out;
@ -2875,7 +2876,7 @@ input[type="button"].small,
background-repeat: repeat-x, repeat, no-repeat;
background-size: 3200px 460px, auto, cover;
color: rgba(255, 255, 255, 0.8);
padding: 10em 0 20em 0;
padding: 1em 0 10vw 0;
position: relative;
text-align: center;
}
@ -2953,7 +2954,7 @@ input[type="button"].small,
}
#header h1 {
font-size: 2.5em;
font-size: 2em;
margin: 0;
}
@ -3128,6 +3129,9 @@ input[type="button"].small,
font-size: 14pt;
}
h3 {
font-size: 1.15em;
}
h2 {
font-size: 1.5em;
}
@ -3141,31 +3145,23 @@ input[type="button"].small,
header.major p {
font-size: 1.25em;
}
/* Header */
#header {
padding: 8em 0 16em 0;
}
#header h1 {
font-size: 2.25em;
}
#header p {
font-size: 1.25em;
line-height: 1.65em;
}
}
/* Normal */
@media screen and (max-width: 1280px) {
#header {
padding-bottom: 6em;
}
#header h1 {
font-size: 1.4em;
}
#clan-logo {
width: 14em;
height: 14em;
width: 11em;
height: 11em;
}
/* Basic */
@ -3224,7 +3220,6 @@ input[type="button"].small,
background-attachment: scroll, scroll, scroll;
background-image: url("images/top-1600.svg"), url("images/overlay.png"), url("../../images/header.jpg");
background-size: 1600px 230px, auto, cover;
padding: 6em 0 12em 0;
}
#header:before {
@ -3235,14 +3230,6 @@ input[type="button"].small,
height: 25px;
}
#header h1 {
font-size: 2em;
}
#header p {
font-size: 1.15em;
}
/* Footer */
#footer {
@ -3292,10 +3279,6 @@ input[type="button"].small,
height: 14em;
}
#header h1 {
font-size: 2em;
}
/* Section/Article */
header.major {
@ -3315,15 +3298,15 @@ input[type="button"].small,
@media screen and (max-width: 736px) {
#clan-logo {
width: 12em;
height: 12em;
width: 11em;
height: 11em;
}
/* Basic */
h2 {
font-size: 1em;
font-size: 1.1em;
}
h3 {
@ -3399,7 +3382,6 @@ input[type="button"].small,
#header {
background-image: url("images/top-1280.svg"), url("images/overlay.png"), url("../../images/header.jpg");
background-size: 1280px 184px, auto, cover;
padding: 3em 0 7em 0;
}
#header:before {
@ -3410,18 +3392,6 @@ input[type="button"].small,
height: 20px;
}
#header .logo {
font-size: 1.5em;
}
#header h1 {
font-size: 1.75em;
}
#header p {
font-size: 1em;
}
/* Footer */
#footer {
@ -3456,10 +3426,6 @@ input[type="button"].small,
height: 10em;
}
#header h1 {
font-size: 1.5em;
}
/* Section/Article */
header.major {
@ -3522,14 +3488,8 @@ input[type="button"].small,
/* Header */
#header {
padding-left: 2em;
padding-right: 2em;
padding-top: 5em;
}
#header br {
display: none;
}
}
}

View File

@ -35,4 +35,4 @@ document.querySelector("span").onmouseover = event => hacker_effect(event.target
let target = document.querySelector("span");
hacker_effect(target);
}, delay);
};
};

View File

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

View File

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

View File

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

View File

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

View File

@ -1,41 +0,0 @@
// Misc.
$misc: (
);
// Duration.
$duration: (
);
// Size.
$size: (
border-radius: 4px
);
// Font.
$font: (
);
// Palette.
$palette: (
bg: #ffffff,
fg: #6e6e6e,
fg-light: #888888,
fg-bold: #5b5b5b,
border: rgba(224,224,224,0.75),
border-bg: rgba(224,224,224,0.15),
border-bg2: rgba(224,224,224,0.35),
accent1: (
bg: #4eb980,
fg: rgba(255,255,255,0.8),
fg-light: rgba(255,255,255,0.5),
fg-bold: #ffffff
),
accent2: (
bg: #544d55,
fg: rgba(255,255,255,0.8),
fg-light: rgba(255,255,255,0.35),
fg-bold: #ffffff
)
);

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -26,89 +26,96 @@
<header class="top-header">
<div class="container">
<nav class="header-nav-links">
<a href="https://docs.clan.lol/">Get started</a>
<a href="https://docs.clan.lol/blog/">Blog</a>
<a href="https://docs.clan.lol/">Getting Started</a>
<a href="https://matrix.to/#/#clan:lassul.us">Chat</a>
<a href="https://git.clan.lol/clan/clan-core">Code</a>
</nav>
</div>
</header>
<!-- Header -->
<div id="header">
<img src="static/logo/clan-white.png" alt="Clan White" id="clan-logo">
<h1>Build your own
<span data-value="DARKNET" class="hacker-effect">TDERKAN</span>
</h1>
</div>
<!-- Header -->
<div id="header">
<img src="static/logo/clan-white.png" alt="Clan White" id="clan-logo">
<h1>Build your own
<span data-value="DARKNET" class="hacker-effect">TDERKAN</span>
</h1>
</div>
<!-- Main -->
<div id="main">
<!-- Main -->
<div id="main">
<header class="major container medium">
<h2>Peer-to-Peer self-hosting
<br /> made easy for developers
</h2>
</header>
<header class="major container medium">
<h2>Peer-to-Peer self-hosting
<br /> made easy for developers
</h2>
</header>
<div class="box alt container">
<section class="feature left">
<a href="https://docs.clan.lol/" class="image"><img src="images/open_source.webp" alt="" /></a>
<div class="content">
<h3>Community Owned</h3>
<p>
Clan is a proudly open-source project, inviting everyone to contribute and collaborate.
No fear of lock-in or vendor restrictions. Your data, your rules.
</p>
</div>
</section>
<section class="feature right">
<a href="https://docs.clan.lol/" class="image"><img src="images/fleet_management.webp" alt="" /></a>
<div class="content">
<h3>Machine Management</h3>
<p>
Easily manage fleets of interconnected computers without a central server.
Deploy your computers everywhere, with the same configuration and data.
</p>
<div class="box alt container">
<section class="feature left">
<a href="https://docs.clan.lol/" class="image">
<img src="images/fleet_management.webp" alt="" />
<p>Your computers, your rules</p>
</a>
<div class="content">
<h3>Declarative Fleet Management</h3>
<!-- customization and control -->
<p>
Customize and control your entire network from a single Git repository.
Recreate any setup with the same configuration and data on a whim.
</p>
</div>
</section>
<section class="feature right">
<a href="https://docs.clan.lol/" class="image">
<img src="images/mesh_vpn.webp" alt="" />
<p>Become independent of a centralized internet</p>
</a>
<div class="content">
<h3>Private Internet</h3>
<!-- privacy and independence -->
<p>
Connect all your devices in a peer-to-peer virtual private network.
Run self-hosted services and provide access to your family, friends, or coworkers.
</p>
</div>
</section>
<section class="feature left">
<a href="https://docs.clan.lol/" class="image"><img src="images/mesh_vpn.webp" alt="" /></a>
<div class="content">
<h3>Private Internet</h3>
<p>
Connect all your devices into a secure, private network with our peer-to-peer Mesh VPN.
Share services with your friends & coworkers, without the need to expose them to the public internet.
</p>
</div>
</section>
</section>
<section class="feature left">
<a href="https://docs.clan.lol/" class="image">
<img src="images/open_source.webp" alt="" />
<p>Own the code you run</p>
</a>
<div class="content">
<h3>Community Owned</h3>
<!-- ownership and sovereignty -->
<p>
No vendor lock-in or artificial restrictions.
Proudly open-source for everyone to learn, contribute, and collaborate.
</p>
</div>
</section>
</div>
<footer class="major container medium">
<p class="actions special"><a href="what-is-clan.html" class="button">What is Clan?</a></p>
<p>Continue reading to learn more.</p>
</footer>
</div>
<!-- Footer -->
<div id="footer">
<div class="container medium">
<footer class="major container medium">
<h3>What is Clan?</h3>
<p>Discover our features by reading further</p>
<ul class="actions special">
<li><a href="wclan.html" class="button">Learn More</a></li>
</ul>
</footer>
</div>
<!-- Footer -->
<div id="footer">
<div class="container medium">
<ul class="copyright">
<li>&copy; Clan. All rights reserved.</li>
<li>Design: <a href="http://html5up.net">HTML5 UP</a></li>
</ul>
<ul class="copyright">
<li>&copy; Clan. All rights reserved.</li>
<li>Design: <a href="http://html5up.net">HTML5 UP</a></li>
</ul>
</div>
</div>
</div>
<!-- Scripts -->
<script src="assets/js/main.js"></script>
<!-- Scripts -->
<script src="assets/js/main.js"></script>
</body>
</body>
</html>
</html>

View File

@ -2,14 +2,15 @@
<html>
<head>
<title>What is Clan? A feature overview</title>
<title>What is Clan? Feature overview</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="assets/css/main.css" />
<link rel="icon" type="image/png" href="static/dark-favicon/128x128.png">
<meta property="og:title" content="What is Clan?" />
<meta property="og:description" content="What is Clan? A guide through its features" />
<meta property="og:title" content="Clan - Build your own Darknet" />
<meta property="og:description" content="Peer-to-Peer self-hosting made easy for developers. Deploy your computers everywhere, with the same configuration and data." />
<meta property="og:image" content="https://clan.lol/static/dark-favicon/128x128.png" />
<meta property="og:url" content="https://docs.clan.lol" />
<meta property="og:type" content="website" />
@ -40,17 +41,10 @@
padding-bottom: 1em;
}
.highlight {
#highlight {
color: #5b5b5b;
padding: 1em;
border-radius: 5px;
font-size: 1.2em;
font-size: 1.05em;
font-weight: bold;
text-align: center;
margin: 2em 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
@ -59,8 +53,8 @@
<header class="top-header">
<div class="container">
<nav class="header-nav-links">
<a href="https://docs.clan.lol/">Get started</a>
<a href="https://docs.clan.lol/blog/">Blog</a>
<a href="https://docs.clan.lol/">Getting Started</a>
<a href="https://matrix.to/#/#clan:lassul.us">Chat</a>
<a href="https://git.clan.lol/clan/clan-core">Code</a>
</nav>
@ -71,37 +65,48 @@
<div id="main">
<header class="major container medium">
<h2>What is Clan?</h2>
<p class="highlight">Clan is a setup tool that centralizes machine configurations for peer-to-peer self-hosted networks.</p>
<p id="highlight">
Clan is a configuration management, secret provisioning, and backup automation framework.
</p>
</header>
<div class="box alt container content-section">
<details>
<summary><b>Unified Git Repository</b>: Centralize secrets & configurations in a single repository</summary>
<p>Clan uses a single Git repository to define everything about your machines. This central repository utilizes Nix or JSON files to specify configurations, including disk formatting. This streamlined and unified approach gives you the power to manage your servers from a central point without relying on a centralized provider, scaling your IT infrastructure on your own terms.</p>
<summary><b>Uniform interface:</b> Manage your networks from a single source of truth</summary>
<p>
Clan allows you specify everything about the machines you control, using a single Git repository.
Declare disk layout, service configuration, access control, backup strategies, and more in the <a href="https://nix.dev/manual/nix/stable/language/">Nix language</a> or <a href="https://www.json.org">JSON</a>.
Scale your IT infrastructure on your own terms.
No need to rely on a centralized provider.
</p>
</details>
<details>
<summary><b>Automated Secret Management</b>: Auto-generate and share secrets with your peers</summary>
<p>Passwords and other sensitive information are encrypted within the Git repository and automatically decrypted during deployment. This keeps your secrets safe while also simplifying their management. Clan supports sharing secrets between admins, fostering collaboration and maintaining reproducibility and convenience without sacrificing security.</p>
<summary><b>Automated secret management:</b> Automatically generate and provision secrets</summary>
<p>
Passwords and other sensitive information are encrypted next to your configuration data, and automatically decrypted during deployment of services and their clients.
This keeps your secrets safe while also simplifying their management.
</p>
</details>
<details>
<summary><b>Automated Service Setup</b>: Install services as if they were applications</summary>
<summary><b>Automated Service Setup:</b> Install services as if they were applications</summary>
<p>Setting up a service can be quite complex: many server adjustments need to be made, from setting up a database to adjusting webserver configurations and generating the correct private keys. Clan aims to make setting up a service as easy as installing an application. Through the <a href="https://docs.clan.lol/reference/clanModules/borgbackup-static/">Modules</a> system, everything down to secrets can be set up through a smooth automated process.</p>
</details>
<details>
<summary><b>Automated Backups</b>: Syncronize state and backup to other peers automatically</summary>
<p>Each clan service specifies a state directory where all service state data is stored. This setup allows for the automatic backup of every service to other peers, including Postgres databases. With the <a href="https://docs.clan.lol/reference/clanModules/syncthing/">Syncthing</a> clan module you can have perfect replicas of your laptop.</p>
<summary><b>Automated Backups:</b> Synchronize state and backup to other peers automatically</summary>
<p>Each clan service designates a state directory where all service state data is stored. This setup enables the automatic backup of every service to other peers, including Postgres databases. Using the <a href="https://docs.clan.lol/reference/clanModules/syncthing/">Syncthing</a> clan module, you can create perfect replicas of your laptop.</p>
</details>
<details>
<summary><b>Peer-to-peer Mesh VPN</b>: Securely connect machines over a private network.</summary>
<summary><b>Peer-to-peer Mesh VPN:</b> Securely connect machines over a private network.</summary>
<p>All machines in your Clan are interconnected through a self-configuring peer-to-peer mesh VPN. This additional layer of protection ensures that sensitive services, which might have too much attack surface to be hosted on the public internet, can still be made available on your Clan's network.</p>
</details>
<details>
<summary><b>Live Overwrites</b>: Deploy configurations over existing Linux distributions via SSH.</summary>
<summary><b>Live Overwrites:</b> Deploy configurations over existing Linux distributions via SSH.</summary>
<p>With Clan, you can skip the cumbersome task of bootstrapping specific installation images. Clan allows you to overwrite any existing Linux distribution live over SSH, eliminating time-consuming setup processes. Deploy updates or new configurations swiftly and efficiently, maximizing uptime and minimizing hassle.</p>
</details>
@ -121,6 +126,7 @@
</footer>
</div>
<!-- Footer -->
<div id="footer">
<div class="container medium">