WIP Integrating redesign

This commit is contained in:
Yarmo Mackenbach 2021-03-01 15:01:34 +01:00
parent 8e2cea8690
commit 8c85f49def
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1
30 changed files with 1971 additions and 1191 deletions

View file

@ -1,5 +1,3 @@
# FAQ
[[toc]]
## What is Keyoxide?

View file

@ -1,5 +1,3 @@
# Getting started
Glad you made it here :)
Let's get you started on setting up your online identity and profile page.

View file

@ -1,3 +1,9 @@
{
"env": {
"NODE_ENV": "development",
"KX_HIGHLIGHTS_1_NAME": "Yarmo Mackenbach",
"KX_HIGHLIGHTS_1_DESCRIPTION": "Admin and developer of keyoxide.org",
"KX_HIGHLIGHTS_1_FINGERPRINT": "9f0048ac0b23301e1f77e994909f6bd6f80f485d"
},
"ext": "js,json,css,pug,md"
}

View file

@ -43,13 +43,25 @@ if (process.env.ONION_URL) {
}
router.get('/', (req, res) => {
res.render('index');
let highlights = []
for (let index = 1; index < 4; index++) {
if (process.env[`KX_HIGHLIGHTS_${index}_NAME`]
&& process.env[`KX_HIGHLIGHTS_${index}_FINGERPRINT`]) {
highlights.push({
name: process.env[`KX_HIGHLIGHTS_${index}_NAME`],
description: process.env[`KX_HIGHLIGHTS_${index}_DESCRIPTION`],
fingerprint: process.env[`KX_HIGHLIGHTS_${index}_FINGERPRINT`],
})
}
}
res.render('index', {highlights: highlights});
});
router.get('/getting-started', (req, res) => {
let rawContent = fs.readFileSync(`./content/getting-started.md`, "utf8");
const content = md.render(rawContent);
res.render(`basic`, { title: `Getting started - Keyoxide`, content: content });
res.render(`long-form-content`, { title: `Getting started`, content: content });
});
router.get('/faq', (req, res) => {
@ -60,7 +72,7 @@ router.get('/faq', (req, res) => {
let rawContent = fs.readFileSync(`./content/faq.md`, "utf8");
rawContent = rawContent.replace('${domain}', req.app.get('domain'));
const content = mdAlt.render(rawContent);
res.render(`basic`, { title: `Frequently Asked Questions - Keyoxide`, content: content });
res.render(`long-form-content`, { title: `Frequently Asked Questions`, content: content });
});
router.get('/guides', (req, res) => {
@ -69,12 +81,18 @@ router.get('/guides', (req, res) => {
router.get('/guides/:guideId', (req, res) => {
let env = {};
let rawContent = fs.readFileSync(`./content/guides/${req.params.guideId}.md`, "utf8", (err, data) => {
let rawContent
try {
rawContent = fs.readFileSync(`./content/guides/${req.params.guideId}.md`, "utf8", (err, data) => {
if (err) throw err;
return data;
});
} catch (error) {
res.render(`404`)
return
}
const content = md.render(rawContent, env);
res.render(`basic`, { title: `${env.title} - Keyoxide`, content: content });
res.render(`long-form-content`, { title: `${env.title}`, content: content });
});
module.exports = router;

BIN
static/img/logo_circle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

File diff suppressed because it is too large Load diff

439
static/styles-old.css Normal file
View file

@ -0,0 +1,439 @@
/*
Copyright (C) 2021 Yarmo Mackenbach
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.
You should have received a copy of the GNU Affero General Public License along
with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer network,
you should also make sure that it provides a way for users to get its source.
For example, if your program is a web application, its interface could display
a "Source" link that leads users to an archive of the code. There are many
ways you could offer source, and different solutions will be better for different
programs; see section 13 for the specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
*/
* {
box-sizing: border-box;
}
body {
margin: 0;
color: #444;
font-family: sans-serif;
background-color: #9dd3f0;
background-image: url('/static/img/background.svg');
background-repeat: repeat;
background-size: 512px;
background-position: -16px -16px;
}
header {
height: 64px;
padding: 8px;
margin: 0 0 48px;
font-size: 1.1em;
background-color: #fff;
box-shadow: 0 8px 16px rgba(0,0,0,0.15);
}
header .container {
display: flex;
align-items: center;
height: 100%;
}
header a.logo {
display: inline-block;
height: 100%;
}
header .logo img {
height: 100%;
margin: 0 1em 0 0;
}
nav a {
margin-left: 12px;
}
footer {
color: #777;
margin: 64px 0;
padding: 0 32px;
font-size: 0.9em;
overflow-wrap: break-word;
}
footer a {
color: #777;
}
.container {
/*max-width: 720px;*/
max-width: 770px;
width: 100%;
margin: 0 auto;
}
.content {
padding: 16px 32px 32px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 8px 16px rgba(0,0,0,0.15);
}
.spacer {
flex: 1;
}
.flex-column-container {
display: flex;
flex-wrap: wrap;
}
.flex-column {
flex: 1 0 250px;
}
.bigBtn {
display: inline-block;
margin-bottom: 12px;
padding: 6px 12px;
color: #fff;
font-size: 1.1em;
text-transform: uppercase;
text-decoration: none;
background: #3f9acc;
background: linear-gradient(0deg, #3892c2 0%, #6abae5 100%);
border: 0;
border-radius: 8px;
cursor: pointer;
}
.bigBtn:hover {
color: #fff;
background-color: #72bde6;
background: linear-gradient(0deg, #4da4d2 0%, #82c5ea 100%);
}
.fancyBtn {
display: inline-block;
margin-bottom: 12px;
padding: 8px 24px;
color: #fff;
font-size: 1.1em;
text-transform: uppercase;
text-decoration: none;
font-weight: bold;
background: #8b76f2;
/* background: linear-gradient(90deg, #8b76f2 0%, #6abae5 100%); */
background: linear-gradient(90deg, #6957c4 0%, #43afea 100%);
border: 0;
border-radius: 64px;
cursor: pointer;
}
.fancyBtn:hover {
color: #fff;
background-color: #a595f4;
/* background: linear-gradient(90deg, #a595f4 0%, #93d9ff 100%); */
/* background: linear-gradient(90deg, #6957c4 0%, #43afea 100%); */
background: linear-gradient(90deg, #8b76f2 0%, #6abae5 100%);
}
.full-width {
width: 100% !important;
}
h1 {
margin: 0 0 24px 0;
color: #222;
/* background-color: #9dd3f0; */
background-color: #fff;
text-align: center;
cursor: default;
}
h1::after {
content: "";
display: block;
width: 100%;
height: 4px;
margin-top: 12px;
background: linear-gradient(90deg, #8b76f2 0%, #6abae5 100%);
border-radius: 2px;
}
h2, h3 {
margin-top: 32px;
color: #222;
cursor: default;
}
h2 {
padding-right: 32px;
}
h2::after {
content: "";
display: block;
width: 100%;
height: 2px;
/* background: linear-gradient(90deg, #8b76f2 0%, #3892c2 50%, #6abae5 100%); */
background: linear-gradient(90deg, #3892c2 0%, #6abae5 100%);
border-radius: 1px;
}
p {
line-height: 1.4em;
font-size: 1.1em;
}
a {
color: #3f9acc;
}
a:hover {
color: #6957c4;
}
a.bigBtn {
margin-right: 8px;
}
a.header-anchor {
text-decoration: none;
opacity: 0.5;
}
a.header-anchor:hover {
opacity: 1;
}
ul {
list-style: "- ";
}
pre {
white-space: pre-wrap;
}
code {
padding: 2px;
background-color: #eee;
border: solid 1px #ddd;
user-select: all;
}
pre code {
display: block;
padding: 8px;
word-break: break-word;
/* word-break: break-all; */
}
textarea {
width: 100%;
height: 128px;
resize: vertical;
font-size: 0.9rem;
}
input[type="text"] {
margin: 0 12px 12px 0;
width: 45%;
font-size: 0.9rem;
}
input[type="radio"] {
vertical-align: sub;
}
input[type="submit"] {
width: 100%;
}
input[type="submit"][disabled="true"] {
cursor: default;
pointer-events: none;
opacity: 0.3;
}
select {
margin: 0 0 16px 0;
}
.green, a.proofUrl.proofUrl--verified {
color: #499539;
}
.red {
color: red;
}
.label {
display: inline-block;
margin: 0 0 8px;
}
.modes {
display: none;
}
.modes.modes--visible {
display: block;
}
.container--profile {
margin-top: 64px;
}
.container--profile .content {
padding-top: 32px;
font-size: 1.2em;
}
.container--profile footer {
text-align: center;
}
.guides {
display: flex;
flex-wrap: wrap;
}
.guides__section {
flex: 1 0 250px;
}
.guides__section a {
line-height: 1.8em;
}
#profileHeader {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 32px;
background-color: #c4e3f657;
padding: 15px;
border-radius: 15px;
}
#profileAvatar {
width: 100%;
max-width: 128px;
border-radius: 100%;
margin-right: 32px;
}
#profileName {
font-size: 1.6em;
font-weight: bold;
display: inline-block;
max-width: 100%;
white-space: wrap;
overflow: hidden;
text-overflow: ellipsis;
}
#profileData {
background-color: #dceef957;
padding: 15px;
border-radius: 15px;
}
.profileDataItem {
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.profileDataItem--separator {
margin-top: 1em;
font-weight: bold;
}
.profileDataItem__label {
display: inline-block;
position: relative;
flex: 1;
min-height: 32px;
padding: 0 8px;
max-width: 20%;
font-size: 0.9em;
line-height: 1.6em;
color: #777;
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-transform: capitalize;
}
.profileDataItem__value {
display: inline-block;
flex: 1;
min-height: 32px;
max-width: 100%;
padding: 0 8px;
}
.profileDataItem__value a {
display: inline-block;
max-width: 100%;
margin-right: 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.profileDataItem__value small {
color: white;
background: #2178ff;
border-radius: 6px;
padding: 2.8px 5px;
font-size: 0.65em;
vertical-align: middle;
}
a.proofUrl {
color: #777;
}
a.proofQR {
line-height: 0;
background-color: #499539;
border-radius: 2px;
}
a.proofQR:hover {
background-color: #6abb5a;
}
#form-generate-signature-profile {
margin-bottom: 2em;
font-size: 0.9rem;
}
#qrcode {
display: flex;
justify-content: center;
max-width: 100%;
width: auto !important;
height: auto !important;
margin: 32px auto;
}
noscript {
display: block;
margin-bottom: 2rem;
padding: 8px;
background-color: #f0e68c;
text-align: center;
}
noscript p {
margin: 0;
font-size: 1rem;
}
@media (max-width: 680px) {
#profileHeader {
flex-direction: column;
}
#profileAvatar {
margin: 0;
}
#profileName {
font-size: 1.2em;
}
.profileDataItem {
flex-direction: column;
margin-bottom: 8px;
}
.profileDataItem__label {
max-width: 100%;
min-height: 28px;
text-align: left;
}
.profileDataItem__value {
min-height: 28px;
}
.profileDataItem--noLabel .profileDataItem__label {
display: none;
}
#profileData .profileDataItem__value a:first-child {
max-width: 85%;
}
#profileData #profileProofs .profileDataItem__value a:first-child {
display: block;
}
input[type="text"] {
width: 100%;
}
}

View file

@ -1,439 +1,494 @@
/*
Copyright (C) 2021 Yarmo Mackenbach
:root {
--grey-500: hsl(0, 0%, 50%);
--grey-600: hsl(0, 0%, 40%);
--grey-700: hsl(0, 0%, 30%);
--grey-900: hsl(0, 0%, 10%);
--green-300: hsl(110, 45%, 70%);
--green-400: hsl(110, 45%, 60%);
--green-600: hsl(110, 45%, 40%);
--red-400: hsl(10, 60%, 60%);
--blue-500: hsl(201, 80%, 59%);
--blue-700: hsl(201, 90%, 30%);
--purple-50: hsl(250, 30%, 98%);
--purple-100: hsl(250, 48%, 95%);
--purple-200: hsl(250, 48%, 90%);
--purple-300: hsl(250, 48%, 85%);
--purple-400: hsl(250, 48%, 70%);
--purple-500: hsl(250, 48%, 65%);
--purple-600: hsl(250, 48%, 60%);
--purple-700: hsl(250, 48%, 55%);
--purple-900: hsl(250, 38%, 45%);
--yellow-100: hsl(56, 100%, 95%);
--yellow-200: hsl(56, 100%, 90%);
--yellow-500: hsl(56, 100%, 65%);
}
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.
You should have received a copy of the GNU Affero General Public License along
with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer network,
you should also make sure that it provides a way for users to get its source.
For example, if your program is a web application, its interface could display
a "Source" link that leads users to an archive of the code. There are many
ways you could offer source, and different solutions will be better for different
programs; see section 13 for the specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
*/
* {
box-sizing: border-box;
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
color: #444;
padding: 1.6rem 0 0;
line-height: 1.6rem;
font-family: sans-serif;
background-color: #9dd3f0;
background-image: url('/static/img/background.svg');
background-repeat: repeat;
background-size: 512px;
background-position: -16px -16px;
color: var(--grey-900);
/* background-color: var(--purple-100); */
}
header {
height: 64px;
padding: 8px;
margin: 0 0 48px;
font-size: 1.1em;
background-color: #fff;
box-shadow: 0 8px 16px rgba(0,0,0,0.15);
display: flex;
justify-content: center;
align-items: center;
margin: 0 1.6rem 4.8rem;
padding: 0.8rem;
/* background-color: var(--purple-50); */
border-radius: 16px;
}
header a.logo {
width: 64px;
margin: 0 0.8rem;
font-size: 1.6rem;
text-transform: uppercase;
text-decoration: none;
color: var(--purple-700);
}
header a.logo img {
width: 100%;
}
header .container {
display: flex;
}
header nav {
flex: 1;
display: flex;
align-items: center;
height: 100%;
}
header a.logo {
display: inline-block;
height: 100%;
nav a.text {
font-size: 0.9em;
margin: 0;
padding: 0.5em 1em;
text-transform: uppercase;
text-decoration: none;
color: var(--purple-700);
border-radius: 4px;
}
header .logo img {
height: 100%;
margin: 0 1em 0 0;
nav a.text:hover {
color: #fff;
background-color: var(--purple-500);
}
nav a {
margin-left: 12px;
main {
flex: 1;
margin: 0 1.6rem;
}
footer {
color: #777;
margin: 64px 0;
padding: 0 32px;
font-size: 0.9em;
overflow-wrap: break-word;
}
footer a {
color: #777;
margin: 4.8rem 0 0;
padding: 0 1.6rem 1.6rem;
background-color: var(--purple-900);
color: var(--purple-200);
}
.container {
/*max-width: 720px;*/
max-width: 770px;
width: 100%;
max-width: 1440px;
margin: 0 auto;
}
.content {
padding: 16px 32px 32px;
section.long_form {
width: 100%;
max-width: 720px;
margin: 0 auto;
}
section.profile, .demo {
max-width: 720px;
margin: 0 auto;
}
section.profile .card, .demo .card {
background-color: transparent;
border: 0;
box-shadow: 0 0 0 transparent;
}
section.profile p, .demo p {
/* margin: 0.8rem 0; */
font-size: 1.2rem;
}
.demo {
margin: 9.6rem auto;
font-size: 1.6rem;
}
.card {
margin: 0 0 1.6rem;
padding: 0 1.6rem;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 8px 16px rgba(0,0,0,0.15);
background-color: var(--purple-50);
border: 2px solid var(--purple-200);
box-shadow: 0 4px 12px var(--purple-100);
}
.card--profileHeader {
display: flex;
flex-wrap: wrap;
gap: 2rem;
/* text-align: center; */
}
.card--profileHeader p, .card--profileHeader small {
margin: 0 0 1.2rem;
}
.card--small-profile {
display: flex;
flex-direction: column;
padding-top: 1rem;
text-align: center;
border-radius: 4px;
}
.card--small-profile-dummy {
opacity: 0.5;
border: 0;
box-shadow: unset;
}
.card--small-profile .name {
font-size: 1.4em;
/* font-weight: bold; */
}
.card--small-profile p {
margin-top: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card--small-profile a {
display: block;
padding: 0.4rem 0.8rem;
/* color: #fff; */
text-decoration: none;
text-transform: uppercase;
background-color: #fff;
border: solid 1px var(--blue-700);
border-radius: 4px;
}
.card--small-profile a:hover {
/* background-color: rgba(255, 255, 255, 0.3); */
background-color: var(--blue-700);
color: #fff;
}
#profileName {
font-size: 2rem;
color: var(--grey-700);
}
#profileURLFingerprint {
font-size: 1rem;
margin: 0 0 1.2rem;
}
.hcards {
display: grid;
grid-gap: 1.6rem;
grid-template-columns: repeat(auto-fit, minmax(256px, 1fr));
margin-bottom: 1.6rem;
}
.hcards--features {
text-align: center;
}
.hcards .card {
margin: 0;
}
.hcards--col-1-2, .hcards--col-2-1 {
grid-template-columns: repeat(auto-fit, minmax(256px, 1fr));
}
.hcards--col-1-2 .card, .hcards--col-2-1 .card {
grid-column: 1 / 2;
}
@media screen and (min-width: 1024px) {
.hcards--max-3 {
grid-template-columns: 1fr 1fr 1fr;
}
.hcards--col-1-2, .hcards--col-2-1 {
grid-template-columns: repeat(3, 1fr);
}
}
@media screen and (min-width: 720px) {
.hcards--col-2-1 .card:nth-of-type(1) {
grid-column: 1 / -2;
}
.hcards--col-2-1 .card:nth-of-type(2) {
grid-column: -2 / -1;
}
.hcards--col-1-2 .card:nth-of-type(1) {
grid-column: 1 / 2;
}
.hcards--col-1-2 .card:nth-of-type(2) {
grid-column: 2 / -1;
}
}
@media screen and (max-width: 640px) {
header {
flex-direction: column;
}
header .spacer {
display: none;
}
header a.logo {
margin-bottom: 1.6rem;
order: -1;
}
}
.spacer {
flex: 1;
}
.flex-column-container {
.warning {
padding: calc(0.8rem - 2px) 0.8rem;
background-color: var(--yellow-200);
border: solid 2px var(--yellow-500);
}
.warning p:first-of-type {
margin-top: 0;
}
.warning p:last-of-type {
margin-bottom: 0;
}
.claim {
display: flex;
align-items: center;
width: 100%;
margin: 0.8rem 0;
padding: 0.8rem 1.2rem;
background-color: var(--purple-100);
border-radius: 8px;
}
.claim p {
margin: 0;
}
.claim .claim__main {
flex: 1;
}
.claim .claim__description p {
font-size: 1.4rem;
line-height: 2rem;
}
.claim .claim__links p, p.subtle-links {
display: flex;
flex-wrap: wrap;
font-size: 1rem;
color: var(--grey-700);
}
.flex-column {
flex: 1 0 250px;
.claim .claim__links a, .claim .claim__links span, p.subtle-links a {
font-size: 1rem;
margin: 0 10px 0 0;
color: var(--grey-700);
}
.bigBtn {
display: inline-block;
margin-bottom: 12px;
padding: 6px 12px;
/* p.subtle-links a:first-of-type {
margin: 0;
} */
.claim .serviceProvider {
color: var(--grey-500);
}
.claim .claim__verification {
display: flex;
align-items: center;
justify-content: center;
min-width: 48px;
height: 48px;
border-radius: 100%;
background-color: var(--red-400);
color: #fff;
font-size: 1.1em;
font-size: 2rem;
user-select: none;
}
.claim .claim__verification--true {
background-color: var(--green-400);
}
@media screen and (max-width: 640px) {
.claim .claim__description p {
font-size: 1.2rem;
}
.claim .claim__links a, p.subtle-links a {
font-size: 0.9rem;
}
}
@media screen and (max-width: 480px) {
.claim .claim__description p {
font-size: 1rem;
}
.claim .claim__verification {
min-width: 36px;
height: 36px;
font-size: 1.6rem;
}
}
/* .demo {
text-align: center;
margin: 9.6rem 0;
font-size: 1.6rem;
}
.demo .claim {
margin: 1.6rem 0;
} */
.avatar {
display: inline-block;
min-width: 96px;
max-width: 128px;
/* margin-top: 1.6rem; */
text-align: center;
}
.avatar img {
width: 100%;
border-radius: 24px;
}
.buttons {
/* margin: 2.4rem 0; */
margin: 1.2rem 0;
}
.buttons a {
display: inline-block;
margin-right: 0.8rem;
padding: 6px 24px;
background-color: #eaeaea;
color: #333;
text-transform: uppercase;
text-decoration: none;
background: #3f9acc;
background: linear-gradient(0deg, #3892c2 0%, #6abae5 100%);
border: 0;
border-radius: 8px;
cursor: pointer;
border-radius: 32px;
}
.bigBtn:hover {
color: #fff;
background-color: #72bde6;
background: linear-gradient(0deg, #4da4d2 0%, #82c5ea 100%);
}
.fancyBtn {
display: inline-block;
margin-bottom: 12px;
padding: 8px 24px;
color: #fff;
font-size: 1.1em;
text-transform: uppercase;
text-decoration: none;
font-weight: bold;
background: #8b76f2;
/* background: linear-gradient(90deg, #8b76f2 0%, #6abae5 100%); */
background: linear-gradient(90deg, #6957c4 0%, #43afea 100%);
border: 0;
border-radius: 64px;
cursor: pointer;
}
.fancyBtn:hover {
color: #fff;
background-color: #a595f4;
/* background: linear-gradient(90deg, #a595f4 0%, #93d9ff 100%); */
/* background: linear-gradient(90deg, #6957c4 0%, #43afea 100%); */
background: linear-gradient(90deg, #8b76f2 0%, #6abae5 100%);
}
.full-width {
width: 100% !important;
.buttons a:hover {
background-color: #ccc;
}
h1 {
margin: 0 0 24px 0;
color: #222;
/* background-color: #9dd3f0; */
background-color: #fff;
text-align: center;
cursor: default;
}
h1::after {
content: "";
display: block;
width: 100%;
height: 4px;
margin-top: 12px;
background: linear-gradient(90deg, #8b76f2 0%, #6abae5 100%);
border-radius: 2px;
}
h2, h3 {
margin-top: 32px;
color: #222;
font-size: 1.6em;
margin: 3.2rem 0 1.6rem;
font-weight: normal;
color: var(--purple-500);
cursor: default;
}
h2 {
padding-right: 32px;
font-size: 1.4em;
margin: 3.2rem 0 1.6rem;
font-weight: normal;
color: var(--purple-500);
cursor: default;
}
h2::after {
content: "";
display: block;
width: 100%;
height: 2px;
/* background: linear-gradient(90deg, #8b76f2 0%, #3892c2 50%, #6abae5 100%); */
background: linear-gradient(90deg, #3892c2 0%, #6abae5 100%);
border-radius: 1px;
h2 small {
margin-left: 0.8rem;
padding: 3px 6px;
background-color: var(--purple-400);
color: #fff;
border-radius: 4px;
}
h3 {
margin: 1.6rem 0;
font-size: 1.3em;
line-height: 1.6rem;
color: var(--grey-600);
font-weight: normal;
/* text-align: center; */
cursor: default;
}
h3 small {
margin-left: 0.8rem;
padding: 3px 6px;
background-color: var(--purple-400);
color: #fff;
border-radius: 4px;
}
h4 {
margin: 3.2rem 0 1.6rem 0;
font-size: 1.3em;
line-height: 1.6rem;
color: var(--grey-800);
color: var(--purple-700);
font-weight: normal;
cursor: default;
}
h4 small {
margin-left: 0.8rem;
padding: 3px 6px;
background-color: var(--purple-400);
color: #fff;
border-radius: 4px;
}
p {
line-height: 1.4em;
font-size: 1.1em;
margin: 1.6rem 0;
}
a {
color: #3f9acc;
}
a:hover {
color: #6957c4;
}
a.bigBtn {
margin-right: 8px;
}
a.header-anchor {
text-decoration: none;
opacity: 0.5;
}
a.header-anchor:hover {
opacity: 1;
color: var(--blue-700);
}
ul {
list-style: "- ";
padding-left: 1em;
list-style: '- ';
}
/* .bg--flare {
background: #f12711;
background: -webkit-linear-gradient(to right, #f5af19, #f12711);
background: linear-gradient(to right, #f5af19, #f12711);
} */
main h1:first-of-type {
margin-top: 1.6rem;
}
.long_form h2 {
/* margin-top: 3.2rem; */
/* font-size: 1rem; */
/* font-weight: bold; */
text-align: left;
color: var(--grey-700);
}
footer h1 {
margin-bottom: 0.8rem;
color: var(--purple-200);
font-size: 1.2rem;
font-weight: bold;
/* border-bottom: solid 1px var(--purple-200); */
}
footer a {
color: var(--purple-100);
}
code {
padding: 8px;
background-color: var(--purple-100);
border: 1px solid var(--purple-500);
}
pre {
white-space: pre-wrap;
}
code {
padding: 2px;
background-color: #eee;
border: solid 1px #ddd;
user-select: all;
padding: 8px 12px;
background-color: var(--purple-100);
border: 1px solid var(--purple-500);
overflow-x: scroll;
line-height: 1.2rem;
}
pre code {
display: block;
padding: 8px;
word-break: break-word;
/* word-break: break-all; */
padding: 0;
background-color: 0px;
border: 0px;
}
textarea {
width: 100%;
height: 128px;
resize: vertical;
font-size: 0.9rem;
}
input[type="text"] {
margin: 0 12px 12px 0;
width: 45%;
font-size: 0.9rem;
form {
margin: 0 0 5.6rem;
}
input[type="radio"] {
vertical-align: sub;
}
input[type="submit"] {
width: 100%;
}
input[type="submit"][disabled="true"] {
cursor: default;
pointer-events: none;
opacity: 0.3;
}
select {
margin: 0 0 16px 0;
}
.green, a.proofUrl.proofUrl--verified {
color: #499539;
}
.red {
color: red;
}
.label {
display: inline-block;
margin: 0 0 8px;
}
.modes {
display: none;
}
.modes.modes--visible {
form input[type="submit"] {
display: block;
}
.container--profile {
margin-top: 64px;
}
.container--profile .content {
padding-top: 32px;
font-size: 1.2em;
}
.container--profile footer {
text-align: center;
}
.guides {
display: flex;
flex-wrap: wrap;
}
.guides__section {
flex: 1 0 250px;
}
.guides__section a {
line-height: 1.8em;
}
#profileHeader {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 32px;
background-color: #c4e3f657;
padding: 15px;
border-radius: 15px;
}
#profileAvatar {
width: 100%;
max-width: 128px;
border-radius: 100%;
margin-right: 32px;
padding: 0.4rem 0.8rem;
/* color: #fff; */
text-decoration: none;
text-transform: uppercase;
background-color: #fff;
border: solid 1px var(--blue-700);
border-radius: 4px;
cursor: pointer;
}
#profileName {
font-size: 1.6em;
font-weight: bold;
display: inline-block;
max-width: 100%;
white-space: wrap;
overflow: hidden;
text-overflow: ellipsis;
}
#profileData {
background-color: #dceef957;
padding: 15px;
border-radius: 15px;
}
.profileDataItem {
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.profileDataItem--separator {
margin-top: 1em;
font-weight: bold;
}
.profileDataItem__label {
display: inline-block;
position: relative;
flex: 1;
min-height: 32px;
padding: 0 8px;
max-width: 20%;
font-size: 0.9em;
line-height: 1.6em;
color: #777;
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-transform: capitalize;
}
.profileDataItem__value {
display: inline-block;
flex: 1;
min-height: 32px;
max-width: 100%;
padding: 0 8px;
}
.profileDataItem__value a {
display: inline-block;
max-width: 100%;
margin-right: 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.profileDataItem__value small {
color: white;
background: #2178ff;
border-radius: 6px;
padding: 2.8px 5px;
font-size: 0.65em;
vertical-align: middle;
}
a.proofUrl {
color: #777;
}
a.proofQR {
line-height: 0;
background-color: #499539;
border-radius: 2px;
}
a.proofQR:hover {
background-color: #6abb5a;
}
#form-generate-signature-profile {
margin-bottom: 2em;
font-size: 0.9rem;
}
#qrcode {
display: flex;
justify-content: center;
max-width: 100%;
width: auto !important;
height: auto !important;
margin: 32px auto;
}
noscript {
display: block;
margin-bottom: 2rem;
padding: 8px;
background-color: #f0e68c;
text-align: center;
}
noscript p {
margin: 0;
font-size: 1rem;
}
@media (max-width: 680px) {
#profileHeader {
flex-direction: column;
}
#profileAvatar {
margin: 0;
}
#profileName {
font-size: 1.2em;
}
.profileDataItem {
flex-direction: column;
margin-bottom: 8px;
}
.profileDataItem__label {
max-width: 100%;
min-height: 28px;
text-align: left;
}
.profileDataItem__value {
min-height: 28px;
}
.profileDataItem--noLabel .profileDataItem__label {
display: none;
}
#profileData .profileDataItem__value a:first-child {
max-width: 85%;
}
#profileData #profileProofs .profileDataItem__value a:first-child {
display: block;
}
input[type="text"] {
width: 100%;
}
form input[type="submit"]:hover {
background-color: var(--blue-700);
color: #fff;
}

6
views-old/404.pug Normal file
View file

@ -0,0 +1,6 @@
extends template.base.pug
block content
.content
h1 404
p The requested page could not be found :(

67
views-old/guides.pug Normal file
View file

@ -0,0 +1,67 @@
extends template.base.pug
block content
.content
h1 Guides
.guides
.guides__section
h3 Using Keyoxide
a(href='/guides/verify') Verifying a signature
br
a(href='/guides/encrypt') Encrypting a message
br
a(href='/guides/proofs') Verifying identity proofs
br
a(href='/guides/contributing') Contributing to Keyoxide
br
a(href='/guides/self-hosting-keyoxide') Self-hosting Keyoxide
.guides__section
h3 OpenPGP and identity proofs
a(href='/guides/openpgp-proofs') How OpenPGP identity proofs work
br
a(href='/guides/web-key-directory') Uploading keys using web key directory
br
a(href='/guides/signature-profiles') Using signature profiles
.guides__section
h3 Adding proofs
a(href='/guides/devto') Dev.to
br
a(href='/guides/discourse') Discourse
br
a(href='/guides/dns') Domain / DNS
br
a(href='/guides/gitea') Gitea
br
a(href='/guides/github') GitHub
br
a(href='/guides/gitlab') GitLab
br
a(href='/guides/hackernews') Hackernews
br
a(href='/guides/lobsters') Lobste.rs
br
a(href='/guides/mastodon') Mastodon
br
a(href='/guides/owncast') Owncast
br
a(href='/guides/pleroma') Pleroma
br
a(href='/guides/reddit') Reddit
br
a(href='/guides/twitter') Twitter
br
a(href='/guides/xmpp') XMPP+OMEMO
.guides__section
h3 Other services
a(href='/guides/feature-comparison-keybase') Feature comparison with Keybase
br
a(href='/guides/migrating-from-keybase') Migrating from Keybase
.guides__section
h3 Managing proofs in GnuPG
a(href='/guides/managing-proofs-listing') Listing proofs
br
a(href='/guides/managing-proofs-deleting') Deleting proofs

103
views-old/index.pug Normal file
View file

@ -0,0 +1,103 @@
extends template.base.pug
block content
.content
h1 Keyoxide
p
a(href="/") Keyoxide
| is a modern, secure and privacy-friendly platform to establish your
strong decentralized online identity
| .
a(href="/getting-started").fancyBtn Get started here
h2 About
p
strong Keyoxide
| allows you to link accounts on various online services and platforms together, prove they belong to you and establish an online identity. This puts
strong you
| , the internet citizen, in charge when it comes to defining who you are on the internet instead of large corporations.
p
| As an example, here&apos;s the
a(href='/9f0048ac0b23301e1f77e994909f6bd6f80f485d') developer&apos;s Keyoxide profile
| .
p
strong Keyoxide
| is developed by
a(href='https://yarmo.eu') Yarmo Mackenbach
| . The AGPL-v3-licensed code is hosted on
a(href='https://codeberg.org/keyoxide/web') Codeberg
| . It uses
a(href='https://github.com/openpgpjs/openpgpjs') openpgp.js
| for all cryptographic operations.
h2 Features
h3 Decentralized online identity proofs
ul
li You decide which accounts are linked together
li You decide where this data is stored
li Keyoxide does not hold your identity data on its servers
li Keyoxide merely verifies the identity proofs and displays them
h3 Empowering the internet citizen
ul
li A verified identity proof proves ownership of an account and builds trust
li No bad actor can impersonate you as long as your accounts aren&apos;t compromised
li Your online identity data is safe from greedy internet corporations
h3 User-centric platform
ul
li Easily encrypt messages and verify signatures from the profile page
li
| Keyoxide generates QR codes that integrate with
a(href='https://www.openkeychain.org/') OpenKeychain
| and
a(href='https://conversations.im/') Conversations
li Keyoxide fetches the key wherever the user decides to store it
li Keyoxide is self-hostable, meaning you could put it on any server you trust
h3 Secure and privacy-friendly
ul
li Keyoxide doesn&apos;t want your personal data, track you or show you ads
li You never give data to Keyoxide, it simply uses the data you have made public
li
| Keyoxide relies on OpenPGP, a widely used public-key cryptography standard (
a(href='https://tools.ietf.org/html/rfc4880') RFC-4880
| )
li
| Cryptographic operations are performed in-browser by
a(href='https://openpgpjs.org/') OpenPGP.js
| , a library maintained by
a(href='https://protonmail.com/blog/openpgpjs-email-encryption/') ProtonMail
h3 Free Open Source Software
ul
li
| Keyoxide is licensed under the
a(href='https://codeberg.org/keyoxide/web/src/branch/main/LICENSE') AGPL-v3 license
li
| The source code is hosted on
a(href='https://codeberg.org/keyoxide/web') Codeberg.org
li
| Even the
a(href='https://drone.keyoxide.org/keyoxide/web/') CI/CD activity
| is publicly visible
.flex-column-container
.flex-column
h2 Cryptographic operations
p
a(href='/verify') Verify PGP signature
br
a(href='/encrypt') Encrypt PGP message
br
a(href='/proofs') Verify distributed identity proofs
.flex-column
h2 Utilities
p
a(href='/util/profile-url') Profile URL generator
br
a(href='/util/wkd') Web Key Directory URL generator
br
a(href='/util/qrfp') Fingerprint QR generator

41
views-old/profile.pug Normal file
View file

@ -0,0 +1,41 @@
doctype html
head
meta(charset='utf-8')
meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='robots' content='noindex')
link(rel='shortcut icon' href='/favicon.svg')
title Keyoxide
link(rel='stylesheet' href='/static/styles.css')
main.container.container--profile
.content
noscript
p Keyoxide requires JavaScript to function.
span#profileUid(style='display: none;') #{uid}
span#profileServer(style='display: none;') #{server}
span#profileMode(style='display: none;') #{mode}
if (mode == 'sig')
#profileSigInput
form#form-generate-signature-profile(method='post')
p Please enter the raw profile signature below and press "Generate profile".
textarea#plaintext_input(name='plaintext_input')
input(type='submit', name='submit', value='Generate profile').bigBtn
#profileHeader
img#profileAvatar(src='/static/img/avatar_placeholder.png' alt='avatar' style='display: none')
p#profileName
#profileData
if (mode == 'sig')
p Waiting for input&mldr;
else
p Loading keys &amp; verifying proofs&mldr;
footer
p
| Generated by
a(href='/') Keyoxide
| (
a(href="https://codeberg.org/keyoxide/web/releases")= settings.keyoxide_version
| ).
script(type='application/javascript' src='/static/openpgp.min.js' charset='utf-8')
script(type='application/javascript' src='/static/doip.js' charset='utf-8')
script(type='application/javascript' src='/static/scripts.js' charset='utf-8')

View file

@ -1,6 +1,5 @@
extends template.base.pug
extends templates/base.pug
block content
.content
h1 404
p The requested page could not be found :(

View file

@ -1,11 +1,11 @@
extends template.base.pug
extends templates/base.pug
block content
.content
h1 Guides
.guides
.guides__section
.hcards.hcards--guides.hcards--max-3
.card.guides__section
h3 Using Keyoxide
p
a(href='/guides/verify') Verifying a signature
br
a(href='/guides/encrypt') Encrypting a message
@ -16,16 +16,18 @@ block content
br
a(href='/guides/self-hosting-keyoxide') Self-hosting Keyoxide
.guides__section
.card.guides__section
h3 OpenPGP and identity proofs
p
a(href='/guides/openpgp-proofs') How OpenPGP identity proofs work
br
a(href='/guides/web-key-directory') Uploading keys using web key directory
br
a(href='/guides/signature-profiles') Using signature profiles
.guides__section
.card.guides__section
h3 Adding proofs
p
a(href='/guides/devto') Dev.to
br
a(href='/guides/discourse') Discourse
@ -54,14 +56,16 @@ block content
br
a(href='/guides/xmpp') XMPP+OMEMO
.guides__section
.card.guides__section
h3 Other services
p
a(href='/guides/feature-comparison-keybase') Feature comparison with Keybase
br
a(href='/guides/migrating-from-keybase') Migrating from Keybase
.guides__section
.card.guides__section
h3 Managing proofs in GnuPG
p
a(href='/guides/managing-proofs-listing') Listing proofs
br
a(href='/guides/managing-proofs-deleting') Deleting proofs

View file

@ -1,100 +1,75 @@
extends template.base.pug
extends templates/base.pug
block content
.content
h1 Keyoxide
if highlights.length > 0
h2 Highlights
.hcards.hcards--highlights
each hl in highlights
.card.card--small-profile
p.name= hl.name
p
a(href="/") Keyoxide
| is a modern, secure and privacy-friendly platform to establish your
strong decentralized online identity
| .
a(href="/getting-started").fancyBtn Get started here
h2 About
p
strong Keyoxide
| allows you to link accounts on various online services and platforms together, prove they belong to you and establish an online identity. This puts
strong you
| , the internet citizen, in charge when it comes to defining who you are on the internet instead of large corporations.
p
| As an example, here&apos;s the
a(href='/9f0048ac0b23301e1f77e994909f6bd6f80f485d') developer&apos;s Keyoxide profile
| .
p
strong Keyoxide
| is developed by
a(href='https://yarmo.eu') Yarmo Mackenbach
| . The AGPL-v3-licensed code is hosted on
a(href='https://codeberg.org/keyoxide/web') Codeberg
| . It uses
a(href='https://github.com/openpgpjs/openpgpjs') openpgp.js
| for all cryptographic operations.
h2 Features
h3 Decentralized online identity proofs
ul
li You decide which accounts are linked together
li You decide where this data is stored
li Keyoxide does not hold your identity data on its servers
li Keyoxide merely verifies the identity proofs and displays them
h3 Empowering the internet citizen
ul
li A verified identity proof proves ownership of an account and builds trust
li No bad actor can impersonate you as long as your accounts aren&apos;t compromised
li Your online identity data is safe from greedy internet corporations
h3 User-centric platform
ul
li Easily encrypt messages and verify signatures from the profile page
li
| Keyoxide generates QR codes that integrate with
a(href='https://www.openkeychain.org/') OpenKeychain
| and
a(href='https://conversations.im/') Conversations
li Keyoxide fetches the key wherever the user decides to store it
li Keyoxide is self-hostable, meaning you could put it on any server you trust
h3 Secure and privacy-friendly
ul
li Keyoxide doesn&apos;t want your personal data, track you or show you ads
li You never give data to Keyoxide, it simply uses the data you have made public
li
| Keyoxide relies on OpenPGP, a widely used public-key cryptography standard (
a(href='https://tools.ietf.org/html/rfc4880') RFC-4880
| )
li
| Cryptographic operations are performed in-browser by
a(href='https://openpgpjs.org/') OpenPGP.js
| , a library maintained by
a(href='https://protonmail.com/blog/openpgpjs-email-encryption/') ProtonMail
h3 Free Open Source Software
ul
li
| Keyoxide is licensed under the
a(href='https://codeberg.org/keyoxide/web/src/branch/main/LICENSE') AGPL-v3 license
li
| The source code is hosted on
a(href='https://codeberg.org/keyoxide/web') Codeberg.org
li
| Even the
a(href='https://drone.keyoxide.org/keyoxide/web/') CI/CD activity
| is publicly visible
.flex-column-container
.flex-column
h2 Cryptographic operations
p
a(href='/verify') Verify PGP signature
span.fingerprint= hl.fingerprint
br
a(href='/encrypt') Encrypt PGP message
span.details= hl.description
.spacer
p
a(href=`/${hl.fingerprint}`) View profile
- var n = 0
while n < 3-highlights.length
.card.card--small-profile-dummy
- n++
.demo
.card.card--profile
.claim
.claim__main
.claim__description
p @alice@example.instance
.claim__links
p
span Fediverse
a(href="#") View account
a(href="#") View proof
a(href="#") Details
.claim__verification.claim__verification--true ✔
h2 About Keyoxide
.hcards.hcards--features.hcards--max-3
.card
h3 Online identity
p Establish an identity by verifiably linking your online accounts.
.card
h3 Decentralized
p No central server or database. Control how your data is stored and accessed.
.card
h3 Privacy
p No data is collected. Your data is yours and yours only.
.card
h3 Cryptography
p Your online identity verifiably signed with widely-used OpenPGP.
.card
h3 Open Source
p All Keyoxide projects are licensed under AGPL-3.0-or-later.
.card
h3 Funded by donations
p Transparent funding. Keyoxide stands against VC and surveillance capitalism.
h2 Links
.hcards
.card
h3 Getting started
p
a(href='/') What is Keyoxide?
br
a(href='/proofs') Verify distributed identity proofs
.flex-column
h2 Utilities
a(href='/') Getting started
br
a(href='/') Guides
br
a(href='/') FAQ
.card
h3 Utilities
p
a(href='/util/profile-url') Profile URL generator
br

View file

@ -0,0 +1,6 @@
extends templates/base.pug
block content
section.long_form
h1= title
.card !{ content }

32
views/partials/footer.pug Normal file
View file

@ -0,0 +1,32 @@
footer
.container
.hcards
div
h1 keyoxide.org
a(href="/") Homepage
br
a(href="/") What is Keyoxide?
br
a(href="/") Getting started
br
a(href="/") Guides
br
a(href="/") FAQ
div
h1 Keyoxide project
a(href="/") Keyoxide.org
br
a(href="/") Keyoxide on Fediverse
br
a(href="/") Key to Identity Foundation
div
h1 Development
a(href="/") Source code
br
a(href="/") CI/CD
br
a(href="/") doip.js
p.copyright &copy; 2021 Keyoxide project contributors

11
views/partials/header.pug Normal file
View file

@ -0,0 +1,11 @@
header
nav
.spacer
a.text(href='/') About
a.text(href='/getting-started') Getting started
a.logo(href='/')
img(src='/static/img/logo_circle.png' alt='Keyoxide')
nav
a.text(href='/guides') Guides
a.text(href='/faq') FAQ
.spacer

View file

@ -1,41 +1,29 @@
doctype html
head
meta(charset='utf-8')
meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='robots' content='noindex')
link(rel='shortcut icon' href='/favicon.svg')
title Keyoxide
link(rel='stylesheet' href='/static/styles.css')
extends templates/base.pug
main.container.container--profile
.content
block js
script(type='application/javascript' src='/static/openpgp.min.js' charset='utf-8')
script(type='application/javascript' src='/static/doip.js' charset='utf-8')
script(type='application/javascript' src='/static/scripts.js' charset='utf-8')
block content
section.profile
noscript
p Keyoxide requires JavaScript to function.
span#profileUid(style='display: none;') #{uid}
span#profileServer(style='display: none;') #{server}
span#profileMode(style='display: none;') #{mode}
if (mode == 'sig')
#profileSigInput
#profileSigInput.card
form#form-generate-signature-profile(method='post')
p Please enter the raw profile signature below and press "Generate profile".
label(for="plaintext_input") Please enter the raw profile signature below and press "Generate profile".
textarea#plaintext_input(name='plaintext_input')
input(type='submit', name='submit', value='Generate profile').bigBtn
#profileHeader
img#profileAvatar(src='/static/img/avatar_placeholder.png' alt='avatar' style='display: none')
p#profileName
#profileData
input(type='submit', name='submit', value='Generate profile')
#profileHeader.card.card--profileHeader
#profileProofs.card
if (mode == 'sig')
p Waiting for input&mldr;
//- p Waiting for input&mldr;
else
p Loading keys &amp; verifying proofs&mldr;
footer
p
| Generated by
a(href='/') Keyoxide
| (
a(href="https://codeberg.org/keyoxide/web/releases")= settings.keyoxide_version
| ).
script(type='application/javascript' src='/static/openpgp.min.js' charset='utf-8')
script(type='application/javascript' src='/static/doip.js' charset='utf-8')
script(type='application/javascript' src='/static/scripts.js' charset='utf-8')

18
views/templates/base.pug Normal file
View file

@ -0,0 +1,18 @@
doctype html
head
meta(charset='utf-8')
meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='theme-color' content='#fff')
link(rel='shortcut icon' href='/favicon.svg')
title= (title ? title : "Keyoxide")
link(rel='stylesheet' href='/static/styles.css')
include ../partials/header.pug
main
.container
block content
include ../partials/footer.pug
block js