This commit is contained in:
waalge 2023-08-07 14:57:16 +00:00
parent 3c9ca5a64e
commit 9496deea93
22 changed files with 392 additions and 1588 deletions

View File

@ -1,34 +0,0 @@
.components-flex {
display: flex;
gap: 1.4em;
flex-direction: row;
align-items: center;
justify-content: center;
}
.components-grid {
display: grid;
grid-column-gap: 1.4em;
grid-template-columns: auto;
grid-template-rows: auto;
align-items: center;
justify-content: center;
}
.image-grid {
display: grid;
grid-template-rows: auto;
display: grid;
grid-gap: 1em;
grid-template-rows: auto;
grid-template-columns: repeat(
auto-fit,
minmax(calc(var(--page-width) / 12), 1fr)
);
}
@media only screen and (min-width: 45em) {
.components-grid {
grid-template-columns: 3fr 9fr;
}
}

View File

@ -1,141 +0,0 @@
html {
font-size: 62.5%;
}
body {
font-size: 1.6rem;
color: #000;
}
header {
border-bottom: 0.2rem solid #000;
}
nav {
text-align: right;
}
nav a {
font-size: 1.8rem;
font-weight: bold;
color: black;
text-decoration: none;
text-transform: uppercase;
}
footer {
margin-top: 3rem;
padding: 1.2rem 0;
border-top: 0.2rem solid #000;
font-size: 1.2rem;
color: #555;
}
h1 {
font-size: 2.4rem;
}
h2 {
font-size: 2rem;
}
article .header {
font-size: 1.4rem;
font-style: italic;
color: #555;
}
.logo a {
font-weight: bold;
color: #000;
text-decoration: none;
}
@media (max-width: 319px) {
body {
width: 90%;
margin: 0;
padding: 0 5%;
}
header {
margin: 4.2rem 0;
}
nav {
margin: 0 auto 3rem;
text-align: center;
}
footer {
text-align: center;
}
.logo {
text-align: center;
margin: 1rem auto 3rem;
}
.logo a {
font-size: 2.4rem;
}
nav a {
display: block;
line-height: 1.6;
}
}
@media (min-width: 320px) {
body {
width: 90%;
margin: 0;
padding: 0 5%;
}
header {
margin: 4.2rem 0;
}
nav {
margin: 0 auto 3rem;
text-align: center;
}
footer {
text-align: center;
}
.logo {
text-align: center;
margin: 1rem auto 3rem;
}
.logo a {
font-size: 2.4rem;
}
nav a {
display: inline;
margin: 0 0.6rem;
}
}
@media (min-width: 640px) {
body {
width: 60rem;
margin: 0 auto;
padding: 0;
}
header {
margin: 0 0 3rem;
padding: 1.2rem 0;
}
nav {
margin: 0;
text-align: right;
}
nav a {
margin: 0 0 0 1.2rem;
display: inline;
}
footer {
text-align: right;
}
.logo {
margin: 0;
text-align: left;
}
.logo a {
float: left;
font-size: 1.8rem;
}
}

View File

@ -8,3 +8,59 @@
src: local("jetbrains-mono"), src: local("jetbrains-mono"),
url("/fonts/JetBrainsMono-Medium.woff2") format("woff2"); url("/fonts/JetBrainsMono-Medium.woff2") format("woff2");
} }
article {
margin-bottom: 2rem;
}
article>section> :is(p, h1, h2, h3, h4, h5, h6) {
margin-top: 2rem;
}
article>section>h1 {
margin-top: 2rem;
font-size: 3rem;
}
article>section>h1::before {
content: "# ";
}
article>section>h2 {
margin-top: 2rem;
font-size: 2rem;
}
article>section>h2::before {
content: "## ";
}
article>section>h3::before {
content: "### ";
}
article>section>h4::before {
content: "#### ";
}
article>section {
margin-top: 4rem;
}
article a {
text-decoration-color: rgb(239 68 68);
text-decoration-thickness: 4px;
text-decoration-line: underline;
transition-duration: 70ms;
}
article a:hover {
text-decoration-thickness: 8px;
text-decoration-color: rgb(185 28 28);
text-decoration-line: underline;
}
article ul {
margin-left: 2rem;
list-style-type: " ";
}

File diff suppressed because one or more lines are too long

View File

@ -1,349 +0,0 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 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 {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-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 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View File

@ -1,994 +0,0 @@
:root {
--global-font-size: 20px;
--global-line-height: 1.6em;
--global-space: 12px;
--font-stack: "JetBrains Mono", Menlo, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace,
serif;
--mono-font-stack: Menlo, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace,
serif;
--background-color: #222225;
--page-width: 60em;
--font-color: #e8e9ed;
--invert-font-color: #222225;
--secondary-color: #a3abba;
--tertiary-color: #a3abba;
--primary-color: #62c4ff;
--error-color: #ff3c74;
--progress-bar-background: #3f3f44;
--progress-bar-fill: #62c4ff;
--code-bg-color: #3f3f44;
--input-style: solid;
--display-h1-decoration: none;
}
* {
box-sizing: border-box;
text-rendering: geometricPrecision;
}
*::-moz-selection {
background: var(--primary-color);
color: var(--invert-font-color);
}
*::selection {
background: var(--primary-color);
color: var(--invert-font-color);
}
body {
font-size: var(--global-font-size);
color: var(--font-color);
line-height: var(--global-line-height);
margin: 0;
font-family: var(--font-stack);
word-wrap: break-word;
background-color: var(--background-color);
}
h1,
h2,
h3,
h4,
h5,
h6,
.logo {
line-height: var(--global-line-height);
}
a {
cursor: pointer;
color: var(--primary-color);
text-decoration: none;
}
a:hover {
background-color: var(--primary-color);
color: var(--invert-font-color);
}
em {
font-size: var(--global-font-size);
font-style: italic;
font-family: var(--font-stack);
color: var(--font-color);
}
blockquote,
code,
em,
strong {
line-height: var(--global-line-height);
}
blockquote,
code,
footer,
h1,
h2,
h3,
h4,
h5,
h6,
header,
li,
ol,
p,
section,
ul,
.logo {
float: none;
margin: 0;
padding: 0;
}
blockquote,
h1,
ol,
p,
ul,
.logo {
margin-top: calc(var(--global-space) * 2);
margin-bottom: calc(var(--global-space) * 2);
}
h1,
.logo {
position: relative;
display: inline-block;
display: table-cell;
padding: calc(var(--global-space) * 2) 0 calc(var(--global-space) * 2);
margin: 0;
overflow: hidden;
font-weight: 600;
}
h1::after {
content: "====================================================================================================";
position: absolute;
bottom: 5px;
left: 0;
display: var(--display-h1-decoration);
}
h1 + *,
.logo + * {
margin-top: 0;
}
h2,
h3,
h4,
h5,
h6 {
position: relative;
margin-bottom: var(--global-line-height);
font-weight: 600;
}
blockquote {
position: relative;
padding-left: calc(var(--global-space) * 2);
padding-left: 2ch;
overflow: hidden;
}
blockquote::after {
content: ">\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>";
white-space: pre;
position: absolute;
top: 0;
left: 0;
line-height: var(--global-line-height);
color: #9ca2ab;
}
code {
font-weight: inherit;
background-color: var(--code-bg-color);
font-family: var(--mono-font-stack);
}
code::after,
code::before {
content: "`";
display: inline;
}
pre code::after,
pre code::before {
content: "";
}
pre {
display: block;
word-break: break-all;
word-wrap: break-word;
color: var(--secondary-color);
background-color: var(--background-color);
border: 1px solid var(--secondary-color);
padding: var(--global-space);
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
}
pre code {
overflow-x: scroll;
padding: 0;
margin: 0;
display: inline-block;
min-width: 100%;
font-family: var(--mono-font-stack);
}
.terminal blockquote,
.terminal code,
.terminal h1,
.terminal h2,
.terminal h3,
.terminal h4,
.terminal h5,
.terminal h6,
.terminal strong,
.terminal .logo {
font-size: var(--global-font-size);
font-style: normal;
font-family: var(--font-stack);
color: var(--font-color);
}
.terminal-prompt {
position: relative;
white-space: nowrap;
}
.terminal-prompt::before {
content: "> ";
}
.terminal-prompt::after {
content: "";
animation: cursor 1200ms infinite;
background: var(--primary-color);
border-radius: 0;
display: inline-block;
height: 1em;
margin-left: 0.2em;
width: 3px;
bottom: -2px;
position: relative;
}
@-webkit-keyframes cursor {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes cursor {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
to {
opacity: 0;
}
}
li,
li > ul > li {
position: relative;
display: block;
padding-left: calc(var(--global-space) * 2);
}
nav > ul > li {
padding-left: 0;
}
li::after {
position: absolute;
top: 0;
left: 0;
}
ul > li::after {
content: "-";
}
nav ul > li::after {
content: "";
}
ol li::before {
content: counters(item, ".") ". ";
counter-increment: item;
}
ol ol li::before {
content: counters(item, ".") " ";
counter-increment: item;
}
.terminal-menu li::after,
.terminal-menu li::before {
display: none;
}
ol {
counter-reset: item;
}
ol li:nth-child(n+10)::after {
left: -7px;
}
ol ol {
margin-top: 0;
margin-bottom: 0;
}
.terminal-menu {
width: 100%;
}
.terminal-nav {
display: flex;
flex-direction: column;
align-items: flex-start;
}
ul ul {
margin-top: 0;
margin-bottom: 0;
}
.terminal-menu ul {
list-style-type: none;
padding: 0 !important;
display: flex;
flex-direction: column;
width: 100%;
flex-grow: 1;
font-size: var(--global-font-size);
margin-top: 0;
}
.terminal-menu li {
display: flex;
margin: 0 0 0.5em 0;
padding: 0;
}
ol.terminal-toc li {
border-bottom: 1px dotted var(--secondary-color);
padding: 0;
margin-bottom: 15px;
}
.terminal-menu li:last-child {
margin-bottom: 0;
}
ol.terminal-toc li a {
margin: 4px 4px 4px 0;
background: var(--background-color);
position: relative;
top: 6px;
text-align: left;
padding-right: 4px;
}
.terminal-menu li a:not(.btn) {
text-decoration: none;
display: block;
width: 100%;
border: none;
color: var(--secondary-color);
}
.terminal-menu li a.active {
color: var(--font-color);
}
.terminal-menu li a:hover {
background: none;
color: inherit;
}
ol.terminal-toc li::before {
content: counters(item, ".") ". ";
counter-increment: item;
position: absolute;
right: 0;
background: var(--background-color);
padding: 4px 0 4px 4px;
bottom: -8px;
}
ol.terminal-toc li a:hover {
background: var(--primary-color);
color: var(--invert-font-color);
}
hr {
position: relative;
overflow: hidden;
margin: calc(var(--global-space) * 4) 0;
border: 0;
border-bottom: 1px dashed var(--secondary-color);
}
p {
margin: 0 0 var(--global-line-height);
color: var(--global-font-color);
}
.container {
max-width: var(--page-width);
}
.container,
.container-fluid {
margin: 0 auto;
padding: 0 calc(var(--global-space) * 2);
}
img {
width: 100%;
}
.progress-bar {
height: 8px;
background-color: var(--progress-bar-background);
margin: 12px 0;
}
.progress-bar.progress-bar-show-percent {
margin-top: 38px;
}
.progress-bar-filled {
background-color: var(--progress-bar-fill);
height: 100%;
transition: width 0.3s ease;
position: relative;
width: 0;
}
.progress-bar-filled::before {
content: "";
border: 6px solid transparent;
border-top-color: var(--progress-bar-fill);
position: absolute;
top: -12px;
right: -6px;
}
.progress-bar-filled::after {
color: var(--progress-bar-fill);
content: attr(data-filled);
display: block;
font-size: 12px;
white-space: nowrap;
position: absolute;
border: 6px solid transparent;
top: -38px;
right: 0;
-ms-transform: translateX(50%);
transform: translateX(50%);
}
.progress-bar-no-arrow > .progress-bar-filled::before,
.progress-bar-no-arrow > .progress-bar-filled::after {
content: "";
display: none;
visibility: hidden;
opacity: 0;
}
table {
width: 100%;
border-collapse: collapse;
margin: var(--global-line-height) 0;
color: var(--font-color);
font-size: var(--global-font-size);
}
table td,
table th {
vertical-align: top;
border: 1px solid var(--font-color);
line-height: var(--global-line-height);
padding: calc(var(--global-space) / 2);
font-size: 1em;
}
table thead th {
font-size: 1em;
}
table tfoot tr th {
font-weight: 500;
}
table caption {
font-size: 1em;
margin: 0 0 1em 0;
}
table tbody td:first-child {
font-weight: 700;
color: var(--secondary-color);
}
.form {
width: 100%;
}
fieldset {
border: 1px solid var(--font-color);
padding: 1em;
}
label {
font-size: 1em;
color: var(--font-color);
}
input[type="email"],
input[type="text"],
input[type="number"],
input[type="password"],
input[type="search"] {
border: 1px var(--input-style) var(--font-color);
width: 100%;
padding: 0.7em 0.5em;
font-size: 1em;
font-family: var(--font-stack);
-webkit-appearance: none;
border-radius: 0;
}
input[type="email"]:active,
input[type="text"]:active,
input[type="number"]:active,
input[type="password"]:active,
input[type="search"]:active,
input[type="email"]:focus,
input[type="text"]:focus,
input[type="number"]:focus,
input[type="password"]:focus,
input[type="search"]:focus {
outline: none;
-webkit-appearance: none;
border: 1px solid var(--font-color);
}
input[type="text"]:not(:placeholder-shown):invalid,
input[type="email"]:not(:placeholder-shown):invalid,
input[type="password"]:not(:placeholder-shown):invalid,
input[type="search"]:not(:placeholder-shown):invalid,
input[type="number"]:not(:placeholder-shown):invalid {
border-color: var(--error-color);
}
input,
textarea {
color: var(--font-color);
background-color: var(--background-color);
}
input::placeholder,
textarea::placeholder {
color: var(--secondary-color) !important;
opacity: 1;
}
textarea {
height: auto;
width: 100%;
resize: none;
border: 1px var(--input-style) var(--font-color);
padding: 0.5em;
font-size: 1em;
font-family: var(--font-stack);
-webkit-appearance: none;
border-radius: 0;
}
textarea:focus {
outline: none;
-webkit-appearance: none;
border: 1px solid var(--font-color);
}
textarea:not(:placeholder-shown):invalid {
border-color: var(--error-color);
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus textarea:-webkit-autofill,
textarea:-webkit-autofill:hover textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
border: 1px solid var(--font-color);
-webkit-text-fill-color: var(--font-color);
box-shadow: 0 0 0 1000px var(--invert-font-color) inset;
-webkit-box-shadow: 0 0 0 1000px var(--invert-font-color) inset;
transition: background-color 5000s ease-in-out 0s;
}
.form-group {
margin-bottom: var(--global-line-height);
overflow: auto;
}
.btn {
border-style: solid;
border-width: 1px;
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
cursor: pointer;
outline: none;
padding: 0.65em 2em;
font-size: 1em;
font-family: inherit;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: relative;
z-index: 1;
}
.btn:active {
box-shadow: none;
}
.btn.btn-ghost {
border-color: var(--font-color);
color: var(--font-color);
background-color: transparent;
}
.btn.btn-ghost:focus,
.btn.btn-ghost:hover {
border-color: var(--tertiary-color);
color: var(--tertiary-color);
z-index: 2;
}
.btn.btn-ghost:hover {
background-color: transparent;
}
.btn-block {
width: 100%;
display: -ms-flexbox;
display: flex;
}
.btn-default {
background-color: var(--font-color);
border-color: var(--invert-font-color);
color: var(--invert-font-color);
}
.btn-default:hover,
.btn-default:focus:not(.btn-ghost) {
background-color: var(--secondary-color);
color: var(--invert-font-color);
}
.btn-default.btn-ghost:focus,
.btn-default.btn-ghost:hover {
border-color: var(--secondary-color);
color: var(--secondary-color);
z-index: 2;
}
.btn-error {
color: var(--invert-font-color);
background-color: var(--error-color);
border: 1px solid var(--error-color);
}
.btn-error:hover,
.btn-error:focus:not(.btn-ghost) {
background-color: var(--error-color);
border-color: var(--error-color);
}
.btn-error.btn-ghost {
border-color: var(--error-color);
color: var(--error-color);
}
.btn-error.btn-ghost:focus,
.btn-error.btn-ghost:hover {
border-color: var(--error-color);
color: var(--error-color);
z-index: 2;
}
.btn-primary {
color: var(--invert-font-color);
background-color: var(--primary-color);
border: 1px solid var(--primary-color);
}
.btn-primary:hover,
.btn-primary:focus:not(.btn-ghost) {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.btn-primary.btn-ghost {
border-color: var(--primary-color);
color: var(--primary-color);
}
.btn-primary.btn-ghost:focus,
.btn-primary.btn-ghost:hover {
border-color: var(--primary-color);
color: var(--primary-color);
z-index: 2;
}
.btn-small {
padding: 0.5em 1.3em !important;
font-size: 0.9em !important;
}
.btn-group {
overflow: auto;
}
.btn-group .btn {
float: left;
}
.btn-group .btn-ghost:not(:first-child) {
margin-left: -1px;
}
.terminal-card {
border: 1px solid var(--secondary-color);
}
.terminal-card > header {
color: var(--invert-font-color);
text-align: center;
background-color: var(--secondary-color);
padding: 0.5em 0;
}
.terminal-card > div:first-of-type {
padding: var(--global-space);
}
.terminal-timeline {
position: relative;
padding-left: 70px;
}
.terminal-timeline::before {
content: ' ';
background: var(--secondary-color);
display: inline-block;
position: absolute;
left: 35px;
width: 2px;
height: 100%;
z-index: 400;
}
.terminal-timeline .terminal-card {
margin-bottom: 25px;
}
.terminal-timeline .terminal-card::before {
content: ' ';
background: var(--invert-font-color);
border: 2px solid var(--secondary-color);
display: inline-block;
position: absolute;
margin-top: 25px;
left: 26px;
width: 15px;
height: 15px;
z-index: 400;
}
.terminal-alert {
color: var(--font-color);
padding: 1em;
border: 1px solid var(--font-color);
margin-bottom: var(--global-space);
}
.terminal-alert-error {
color: var(--error-color);
border-color: var(--error-color);
}
.terminal-alert-primary {
color: var(--primary-color);
border-color: var(--primary-color);
}
@media screen and (max-width: 960px) {
label {
display: block;
width: 100%;
}
pre::-webkit-scrollbar {
height: 3px;
}
}
@media screen and (max-width: 480px) {
form {
width: 100%;
}
}
@media only screen and (min-width: 30em) {
.terminal-nav {
flex-direction: row;
align-items: center;
}
.terminal-menu ul {
flex-direction: row;
justify-items: flex-end;
align-items: center;
justify-content: flex-end;
margin-top: calc(var(--global-space) * 2);
}
.terminal-menu li {
margin: 0;
margin-right: 2em;
}
.terminal-menu li:last-child {
margin-right: 0;
}
}
.terminal-media:not(:last-child) {
margin-bottom: 1.25rem;
}
.terminal-media-left {
padding-right: var(--global-space);
}
.terminal-media-left,
.terminal-media-right {
display: table-cell;
vertical-align: top;
}
.terminal-media-right {
padding-left: var(--global-space);
}
.terminal-media-body {
display: table-cell;
vertical-align: top;
}
.terminal-media-heading {
font-size: 1em;
font-weight: 700;
}
.terminal-media-content {
margin-top: 0.3rem;
}
.terminal-placeholder {
background-color: var(--secondary-color);
text-align: center;
color: var(--font-color);
font-size: 1rem;
border: 1px solid var(--secondary-color);
}
figure > img {
padding: 0;
}
.terminal-avatarholder {
width: calc(var(--global-space) * 5);
height: calc(var(--global-space) * 5);
}
.terminal-avatarholder img {
padding: 0;
}
figure {
margin: 0;
}
figure > figcaption {
color: var(--secondary-color);
text-align: center;
}
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: var(--block-background-color);
color: var(--font-color);
}
.hljs-comment,
.hljs-quote {
color: var(--secondary-color);
}
.hljs-variable {
color: var(--font-color);
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-built_in,
.hljs-name,
.hljs-tag {
color: var(--primary-color);
}
.hljs-string,
.hljs-title,
.hljs-section,
.hljs-attribute,
.hljs-literal,
.hljs-template-tag,
.hljs-template-variable,
.hljs-type,
.hljs-addition {
color: var(--secondary-color);
}
.hljs-string {
color: var(--secondary-color);
}
.hljs-deletion,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-meta {
color: var(--primary-color);
}
.hljs-doctag {
color: var(--secondary-color);
}
.hljs-attr {
color: var(--primary-color);
}
.hljs-symbol,
.hljs-bullet,
.hljs-link {
color: var(--primary-color);
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

View File

3
content/index.md Normal file
View File

@ -0,0 +1,3 @@
---
title: Kompact.io
---

View File

@ -0,0 +1,109 @@
---
title: Are we zk-Cardano yet?
date: 2023-08-07
---
Not so long ago Emurgo announced they were doing a Cardano centered hackathon.
It was a welcome prospect - very few similar such events seem to exist in the space.
Things went monotonically south ever since the announcement, but that's a different story.
One particularly interesting quirk was that of the three "tracks" of the hackathon,
one was _Zero Knowledge_ (aka zk).
Why particularly interesting quirk? In some sense it is not surprising:
zk has been very trendy these last few years around blockchains.
However, building on Cardano is notoriously challenging.
Building with zk on a zk-native blockchain is itself a very steep learning curve.
So combining the two, zk on Cardano seemed... a bit mad.
This post is borne out of a best effort of how far "zk on Cardano" can be pushed.
## What is zk?
There is no shortage of explanations describing what zk is
( _eg_ [by Vitalik](https://vitalik.ca/general/2021/01/26/snarks.html) or [a full mooc](https://zk-learning.org/) ).
There is also a reasonable breath to the field of zk that includes things like distributed compute.
Zk involves some really neat maths that lets you do some seemingly magical feats,
and pairs well with blockchain in extending what is functionally possible.
Let's stick to a simple and prototypical example.
Suppose Alice and Bob are playing battleships.
The game begins with Alice and Bob placing their ships within their own coordinate grid.
They then take in terms picking coordinates to "bomb".
If they hit nothing, then their turn ends, but if they hit a ship then they guess again.
The winner is the first to sink all their opponent's ships.
Alice knows Bob has a reputation of being a notorious liar; how can she enjoy the game?
Each guess she makes, Bob says gleefully shouts "Miss!".
She can't ask Bob to show he's not lying by revealing the actual locations of the ships.
She could ask Charlie to independently verify Bob's not lying,
but then what if Charlie is actually on team Bob and also lies.
Or Bob might suspect Charlie is actually on team Alice, slyly brought in to give could Alice some hints.
Is there a way that Bob can prove to Alice that each guess is a miss,
but without revealing the locations of the ships either to Alice or anyone else?
The answer is yes.
Using zk Bob can produce a proof each time Alice's guess misses if and only if it honestly does.
Alice can inspect each proof and verify Bob's response.
Alice can interrogate the proof as much as she wants, but she won't learn anything more than
her guess was a miss.
There are multitude of different ways to do this,
but essentially it involves modeling the problem as a bunch of algebra
over finite fields - like a lot of cryptography.
What's the snark of zk-snark?
Snark stands for _Succinct Non-Interactive Argument of Knowledge_.
And without saying anything more: it means that Alice has to do way less algebra than Bob.
In applications this is important, because Bob might not be able to lie anymore,
but he could still waste Alice's time.
## Sudoku snark
Sudoku snark was the entrant to Emurgo hackathon.
The summary/ pitch/ story deck is [here](https://pub.kompact.io/sudoku-snark).
Links to associated repos [plutus-zk](https://github.com/waalge/plutus-zk) and [sudoku-snark](https://github.com/waalge/sudoku-snark).
Just after the hackathon got underway there was a large PR merged into the main branch of plutus.
It's a mammoth PR that is the culmination of many many months of work.
In it were some fundamental primitives needed for running zk algos.
The idea of the project was as follows:
- write a validator implementing a zk algorithm with the new primitives
- write a program to generate the setup and proofs
- try to get a version of hydra running this newest version of plutus.
Unsurprisingly to anyone who's hung around the Cardano repos long enough,
this final part is where things got stuck.
Things got as far as running a cluster of nodes in the Conway era supposedly with the latest plutus
but some unrelated changes seemed to thwart any chance of building transactions.
The validator uses [groth16](https://eprint.iacr.org/2016/260.pdf).
In part because this was already mostly available from the plutus repo itself.
It is also the most obvious candidate to begin with.
It's relatively mature, relatively simple, can be implemented from the new primitives,
and, importantly in Cardano land, has small proof size.
(As far as I know, the smallest of comparable algos.)
The program to generate the setup and proofs uses the arkworks framework.
Again this was initially inspired by a script from the IOG team.
The choice of game, sudoku, was in turn inspired by an arkworks example.
It's not the most compelling of choices, but it did for now.
The intended game play involved locking Ada at a utxo
spendable only if a player could provide proof you knew the solution.
And through the magic of zk, not disclosing to the competition the solution itself.
Other details were TBC: is it first and second prizes? are players whitelisted?
## So are we zk-Cardano yet?
We're close.
There is potentially still quite a stretch between being in the plutus repo and being run on-chain.
The word on the street is that it might happen before the end of 2023.
Before it's available on mainnet there will be versions the Cardano node available,
and so possibly plumb-able into hydra without causing oneself an aneurysm.

View File

@ -0,0 +1,108 @@
---
title: Are we zk-Cardano yet?
date: 2023-08-07
---
Not so long ago Emurgo announced they were doing a Cardano centered hackathon.
It was a welcome prospect - very few similar such events seem to exist in the space.
Things went monotonically south ever since the announcement, but that's a different story.
One particularly interesting quirk was that of the three "tracks" of the hackathon,
one was _Zero Knowledge_ (aka zk).
Why particularly interesting quirk? In some sense it is not suprising:
zK has been very trendy these last few years around blockchains.
However, building on Cardano is notoriously challenging.
Building with zk on a zk-native blockchain is itself a very steep learning curve.
So combining the two, zk on Cardano seemed... a bit mad.
This post is bourne out of a best effort of how far "zk on cardano" can be pushed.
## What is zk?
There is no shortage of explanations describing what zk is [TODO: Links].
There is also a reasonable breath to the field of zk that includes things like distributed compute.
Zk involves some really neat maths that lets you do some seemingly magical feats,
and pairs well with blockchain in extending what is functionally possible.
Let's stick to a simple and prototypical example.
Suppose Alice and Bob are playing battleships.
The game begins with Alice and Bob placing their ships within their own coordinate grid.
They then take in terms picking coordinates to "bomb".
If they hit nothing, then their turn ends, but if they hit a ship then they guess again.
The winner is the first to sink all their oponents ships.
Alice knows Bob has a reputation of being a notorious liar; how can she enjoy the game?
Each guess she makes, Bob says gleefully shouts "Miss!".
She can't ask Bob to show he's not lying by revealing the actual locations of the ships.
She could ask Charlie to independently verify Bob's not lying,
but then what if Charlie is actually on team Bob and also lies.
Or Bob might suspect Charlie is actually on team Alice, slyly brought in to give could Alice some hints.
Is there a way that Bob can prove to Alice that each guess is a miss,
but without revealing the locations of the ships either to Alice or anyone else?
The answer is yes.
Using zk Bob can produce a proof each time Alice's guess misses if and only if it honestly does.
Alice can inspect each proof and verify Bob's response.
Alice can interogate the proof as much as she wants, but she won't learn anything more than
her guess was a miss.
There are multiplitude of different ways to do this,
but essentially it involves modelling the problem as a bunch of algebra
over finite fields - like a lot of cryptography.
What's the snark of zk-snark?
Snark stands for _Succinct Non-Interactive Argument of Knowledge_.
And without saying anything more: it means that Alice has to do way less algebra than Bob.
In applications this is important, because Bob might not be able to lie anymore,
but he could still waste Alice's time.
## Sudoku snark
Sudoku snark was the entrant to Emurgo hackathon.
The summary/ pitch/ story deck is [here](https://pub.kompact.io/sudoku-snark).
Links to associated repos [plutus-zk]() and [sudoku-snark]().
Just after the hackathon got underway there was a large PR merged into the main branch of plutus.
It's a mammoth PR that is the culmination of many many months of work.
In it were some fundamental primitives needed for running zk algos.
The idea of the project was as follows:
- write a validator implementing a zk algorithm with the new primitives
- write a programme to generate the setup and proofs
- try to get a version of hydra running this newest version of plutus.
Unsurprisingly to anyone who's hung around the Cardano repos long enough,
this final part is where things got stuck.
Things got as far as running a cluster of nodes in the conway era supposedly with the latest plutus
but some unrelated changes seemed to thwart any chance of building transactions.
The validator uses [groth16].
In part because this was already mostly available from the plutus repo itself.
It is also the most obvious candidate to begin with.
It's relatively mature, relatively simple, can be implemented from the new primitives,
and, importantly in cardano land, has small proof size.
(As far as I know, the smallest of comparable algos.)
The program to generate the setup and proofs uses the arkworks framework.
Again this was initially inspired by a script from the IOG team.
The choice of game, sudoku, was in turn inspired by an arkworks example.
It's not the most compelling of choices, but it did for now.
The intended game play involved locking ada at a utxo
spendable only if a player could provide proof you knew the solution.
And through the magic of zk, not disclosing to the competition the solution itself.
Other details were TBC: is it first and second prizes? are players whitelisted?
## So are we zk-Cardano yet?
We're close.
There is potentially still quite a stretch between being in the plutus repo and being run on-chain.
The word on the street is that it might happen before the end of 2023.
Before it's available on mainnet there will be versions the cardano node available,
and so possibly plumbable into hydra without causing oneself an aneurysm.

View File

@ -8,5 +8,6 @@ executable site
build-depends: base == 4.* build-depends: base == 4.*
, hakyll == 4.15.* , hakyll == 4.15.*
, hip == 1.5.* , hip == 1.5.*
, filepath
ghc-options: -threaded -rtsopts -with-rtsopts=-N ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010 default-language: Haskell2010

53
site.hs
View File

@ -2,70 +2,62 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
import Data.Monoid (mappend) import Data.Monoid (mappend)
import Hakyll import Hakyll
import System.FilePath (splitExtension, joinPath, splitDirectories, replaceExtension)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
main :: IO () main :: IO ()
main = hakyll $ do main = hakyll $ do
match "content/favicon.png" $ do match "content/favicon.png" $ do
route rmContentPrefix route rmPrefix
compile copyFileCompiler compile copyFileCompiler
match "content/images/*" $ do match "content/images/*" $ do
route rmContentPrefix route rmPrefix
compile copyFileCompiler compile copyFileCompiler
match "content/scripts/*" $ do match "content/scripts/*" $ do
route rmContentPrefix route rmPrefix
compile copyFileCompiler compile copyFileCompiler
match "content/css/*" $ do match "content/css/*" $ do
route rmContentPrefix route rmPrefix
compile compressCssCompiler compile compressCssCompiler
match "content/fonts/*" $ do match "content/fonts/*" $ do
route rmContentPrefix route rmPrefix
compile copyFileCompiler compile copyFileCompiler
match (fromList ["content/about.rst", "content/contact.markdown"]) $ do match "content/posts/*.md" $ do
route $ setExtension "html" route rmPrefixMd
compile $ pandocCompiler
>>= loadAndApplyTemplate "templates/default.html" defaultContext
>>= relativizeUrls
match "content/posts/*" $ do
route $ setExtension "html"
compile $ pandocCompiler compile $ pandocCompiler
>>= loadAndApplyTemplate "templates/post.html" postCtx >>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx >>= loadAndApplyTemplate "templates/default.html" postCtx
>>= relativizeUrls >>= relativizeUrls
create ["archive.html"] $ do create ["blog.html"] $ do
route idRoute route idRoute
compile $ do compile $ do
posts <- recentFirst =<< loadAll "content/posts/*" posts <- recentFirst =<< loadAll "content/posts/*.md"
let archiveCtx = let archiveCtx =
listField "posts" postCtx (return posts) `mappend` listField "posts" postCtx (return posts) `mappend`
constField "title" "Archives" `mappend` constField "title" "Blog" `mappend`
defaultContext defaultContext
makeItem "" makeItem ""
>>= loadAndApplyTemplate "templates/archive.html" archiveCtx >>= loadAndApplyTemplate "templates/blog.html" archiveCtx
>>= loadAndApplyTemplate "templates/default.html" archiveCtx >>= loadAndApplyTemplate "templates/default.html" archiveCtx
>>= relativizeUrls >>= relativizeUrls
match "content/index.html" $ do match "content/index.md" $ do
route rmContentPrefix route rmPrefixMd
compile $ do compile $ do
posts <- recentFirst =<< loadAll "content/posts/*" let indexCtx = defaultContext
let indexCtx =
listField "posts" postCtx (return posts) `mappend`
defaultContext
getResourceBody getResourceBody
>>= applyAsTemplate indexCtx >>= applyAsTemplate indexCtx
>>= loadAndApplyTemplate "templates/default.html" indexCtx >>= loadAndApplyTemplate "templates/index.html" indexCtx
>>= relativizeUrls >>= relativizeUrls
match "templates/*" $ compile templateBodyCompiler match "templates/*" $ compile templateBodyCompiler
@ -74,7 +66,16 @@ main = hakyll $ do
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
postCtx :: Context String postCtx :: Context String
postCtx = postCtx =
dateField "date" "%B %e, %Y" `mappend` dateField "date" "%Y-%m-%d" `mappend`
defaultContext defaultContext
rmContentPrefix = gsubRoute "content/" (const "") setExtensionInner :: String -> FilePath -> FilePath
setExtensionInner = flip replaceExtension
rmPrefixInner :: FilePath -> FilePath
rmPrefixInner = joinPath . tail . splitDirectories
rmPrefix :: Routes
rmPrefix = customRoute $ rmPrefixInner . toFilePath
rmPrefixMd = customRoute $ rmPrefixInner . setExtensionInner "html" . toFilePath

View File

@ -1,2 +0,0 @@
Here you can find all my previous posts:
$partial("templates/post-list.html")$

12
templates/blog.html Normal file
View File

@ -0,0 +1,12 @@
<section id="services" class="py-6 px-2 flex flex-col gap-12">
<header class="text-3xl">
# blog
</header>
<div class="text-gray-700 mt-4">
A nascent initiative sharing some of the things happening at Kompact.io.
</div>
</section>
<section class="py-6 px-2 flex flex-col gap-12">
$partial("templates/post-list.html")$
</section>

View File

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="/favicon.png"> <link rel="icon" type="image/x-icon" href="/favicon.png">
<link href="/css/mini.css" rel="stylesheet"> <link href="/css/mini.css" rel="stylesheet">
</head> </head>
<body> <body>
@ -13,18 +14,11 @@
<hr /> <hr />
$partial("templates/nav.html")$ $partial("templates/nav.html")$
<hr /> <hr />
$partial("templates/hero.html")$ $body$
<hr />
$partial("templates/services.html")$
<hr />
$partial("templates/pricing.html")$
<hr />
$partial("templates/contact.html")$
<hr /> <hr />
$partial("templates/footer.html")$ $partial("templates/footer.html")$
<hr />
$body$
</div> </div>
</body> </body>
</html> </html>

30
templates/index.html Normal file
View File

@ -0,0 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="/favicon.png">
<title>$title$</title>
<link href="/css/mini.css" rel="stylesheet">
</head>
<body>
<div class="container mx-auto">
<hr />
$partial("templates/nav.html")$
<hr />
$partial("templates/hero.html")$
<hr />
$partial("templates/services.html")$
<hr />
$partial("templates/pricing.html")$
<hr />
$partial("templates/contact.html")$
<hr />
$partial("templates/footer.html")$
<hr />
</div>
</body>
</html>

View File

@ -1,25 +1,22 @@
<nav class="mx-2 sm:mx-4"> <nav class="mx-2 sm:mx-4">
<div class="relative flex h-16 items-center justify-between "> <div class="relative flex h-16 items-center justify-between ">
<div> <div>
<a href="/">
Kompact.io Kompact.io
</a>
</div> </div>
<div> <div>
<ul class="flex flex-row gap-4 md:gap-8"> <ul class="flex flex-row gap-4 md:gap-8">
<li> <li>
<a href="#services"> <a href="/index.html#contact">
services
</a>
</li>
<li>
<a href="#pricing">
pricing
</a>
</li>
<li>
<a href="#contact">
contact contact
</a> </a>
</li> </li>
<li>
<a href="/blog.html">
blog
</a>
</li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -1,7 +1,12 @@
<ul> <ul class="text-lg ml-4">
$for(posts)$ $for(posts)$
<li> <li class="mt-4">
<a href="$url$">$title$</a> - $date$ <a href="$url$">
<span class="text-gray-700">
$date$ ::
</span>
$title$
</a>
</li> </li>
$endfor$ $endfor$
</ul> </ul>

View File

@ -1,8 +1,17 @@
<article> <article>
<section class="header"> <section class="header">
<h1>
$title$
</h1>
$if(date)$
<p>
Posted on $date$ Posted on $date$
</p>
$endif$
$if(author)$ $if(author)$
<p>
by $author$ by $author$
</p>
$endif$ $endif$
</section> </section>
<section> <section>