mirror of
https://codeberg.org/keyoxide/keyoxide-web.git
synced 2024-12-22 23:09:29 -07:00
WIP Integrating redesign
This commit is contained in:
parent
8e2cea8690
commit
8c85f49def
30 changed files with 1971 additions and 1191 deletions
|
@ -1,5 +1,3 @@
|
||||||
# FAQ
|
|
||||||
|
|
||||||
[[toc]]
|
[[toc]]
|
||||||
|
|
||||||
## What is Keyoxide?
|
## What is Keyoxide?
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# Getting started
|
|
||||||
|
|
||||||
Glad you made it here :)
|
Glad you made it here :)
|
||||||
|
|
||||||
Let's get you started on setting up your online identity and profile page.
|
Let's get you started on setting up your online identity and profile page.
|
||||||
|
|
|
@ -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"
|
"ext": "js,json,css,pug,md"
|
||||||
}
|
}
|
|
@ -43,13 +43,25 @@ if (process.env.ONION_URL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
router.get('/', (req, res) => {
|
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) => {
|
router.get('/getting-started', (req, res) => {
|
||||||
let rawContent = fs.readFileSync(`./content/getting-started.md`, "utf8");
|
let rawContent = fs.readFileSync(`./content/getting-started.md`, "utf8");
|
||||||
const content = md.render(rawContent);
|
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) => {
|
router.get('/faq', (req, res) => {
|
||||||
|
@ -60,7 +72,7 @@ router.get('/faq', (req, res) => {
|
||||||
let rawContent = fs.readFileSync(`./content/faq.md`, "utf8");
|
let rawContent = fs.readFileSync(`./content/faq.md`, "utf8");
|
||||||
rawContent = rawContent.replace('${domain}', req.app.get('domain'));
|
rawContent = rawContent.replace('${domain}', req.app.get('domain'));
|
||||||
const content = mdAlt.render(rawContent);
|
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) => {
|
router.get('/guides', (req, res) => {
|
||||||
|
@ -69,12 +81,18 @@ router.get('/guides', (req, res) => {
|
||||||
|
|
||||||
router.get('/guides/:guideId', (req, res) => {
|
router.get('/guides/:guideId', (req, res) => {
|
||||||
let env = {};
|
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;
|
if (err) throw err;
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.render(`404`)
|
||||||
|
return
|
||||||
|
}
|
||||||
const content = md.render(rawContent, env);
|
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;
|
module.exports = router;
|
||||||
|
|
BIN
static/img/logo_circle.png
Normal file
BIN
static/img/logo_circle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 412 KiB |
1198
static/scripts.js
1198
static/scripts.js
File diff suppressed because it is too large
Load diff
439
static/styles-old.css
Normal file
439
static/styles-old.css
Normal 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%;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,439 +1,494 @@
|
||||||
/*
|
:root {
|
||||||
Copyright (C) 2021 Yarmo Mackenbach
|
--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;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #444;
|
padding: 1.6rem 0 0;
|
||||||
|
line-height: 1.6rem;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
background-color: #9dd3f0;
|
color: var(--grey-900);
|
||||||
background-image: url('/static/img/background.svg');
|
/* background-color: var(--purple-100); */
|
||||||
background-repeat: repeat;
|
|
||||||
background-size: 512px;
|
|
||||||
background-position: -16px -16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
height: 64px;
|
display: flex;
|
||||||
padding: 8px;
|
justify-content: center;
|
||||||
margin: 0 0 48px;
|
align-items: center;
|
||||||
font-size: 1.1em;
|
margin: 0 1.6rem 4.8rem;
|
||||||
background-color: #fff;
|
padding: 0.8rem;
|
||||||
box-shadow: 0 8px 16px rgba(0,0,0,0.15);
|
/* 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 {
|
header .container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
}
|
||||||
|
header nav {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
header a.logo {
|
nav a.text {
|
||||||
display: inline-block;
|
font-size: 0.9em;
|
||||||
height: 100%;
|
margin: 0;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--purple-700);
|
||||||
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
header .logo img {
|
nav a.text:hover {
|
||||||
height: 100%;
|
color: #fff;
|
||||||
margin: 0 1em 0 0;
|
background-color: var(--purple-500);
|
||||||
}
|
}
|
||||||
nav a {
|
main {
|
||||||
margin-left: 12px;
|
flex: 1;
|
||||||
|
margin: 0 1.6rem;
|
||||||
}
|
}
|
||||||
footer {
|
footer {
|
||||||
color: #777;
|
margin: 4.8rem 0 0;
|
||||||
margin: 64px 0;
|
padding: 0 1.6rem 1.6rem;
|
||||||
padding: 0 32px;
|
background-color: var(--purple-900);
|
||||||
font-size: 0.9em;
|
color: var(--purple-200);
|
||||||
overflow-wrap: break-word;
|
|
||||||
}
|
|
||||||
footer a {
|
|
||||||
color: #777;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
/*max-width: 720px;*/
|
|
||||||
max-width: 770px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: 1440px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
.content {
|
section.long_form {
|
||||||
padding: 16px 32px 32px;
|
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;
|
background-color: #fff;
|
||||||
border-radius: 8px;
|
background-color: var(--purple-50);
|
||||||
box-shadow: 0 8px 16px rgba(0,0,0,0.15);
|
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 {
|
.spacer {
|
||||||
flex: 1;
|
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;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--grey-700);
|
||||||
}
|
}
|
||||||
.flex-column {
|
.claim .claim__links a, .claim .claim__links span, p.subtle-links a {
|
||||||
flex: 1 0 250px;
|
font-size: 1rem;
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
color: var(--grey-700);
|
||||||
}
|
}
|
||||||
.bigBtn {
|
/* p.subtle-links a:first-of-type {
|
||||||
display: inline-block;
|
margin: 0;
|
||||||
margin-bottom: 12px;
|
} */
|
||||||
padding: 6px 12px;
|
.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;
|
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-transform: uppercase;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background: #3f9acc;
|
border-radius: 32px;
|
||||||
background: linear-gradient(0deg, #3892c2 0%, #6abae5 100%);
|
|
||||||
border: 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
.bigBtn:hover {
|
.buttons a:hover {
|
||||||
color: #fff;
|
background-color: #ccc;
|
||||||
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 {
|
h1 {
|
||||||
margin: 0 0 24px 0;
|
font-size: 1.6em;
|
||||||
color: #222;
|
margin: 3.2rem 0 1.6rem;
|
||||||
/* background-color: #9dd3f0; */
|
font-weight: normal;
|
||||||
background-color: #fff;
|
color: var(--purple-500);
|
||||||
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;
|
cursor: default;
|
||||||
}
|
}
|
||||||
h2 {
|
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 {
|
h2 small {
|
||||||
content: "";
|
margin-left: 0.8rem;
|
||||||
display: block;
|
padding: 3px 6px;
|
||||||
width: 100%;
|
background-color: var(--purple-400);
|
||||||
height: 2px;
|
color: #fff;
|
||||||
/* background: linear-gradient(90deg, #8b76f2 0%, #3892c2 50%, #6abae5 100%); */
|
border-radius: 4px;
|
||||||
background: linear-gradient(90deg, #3892c2 0%, #6abae5 100%);
|
}
|
||||||
border-radius: 1px;
|
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 {
|
p {
|
||||||
line-height: 1.4em;
|
margin: 1.6rem 0;
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
color: #3f9acc;
|
color: var(--blue-700);
|
||||||
}
|
|
||||||
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 {
|
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 {
|
pre {
|
||||||
white-space: pre-wrap;
|
padding: 8px 12px;
|
||||||
}
|
background-color: var(--purple-100);
|
||||||
code {
|
border: 1px solid var(--purple-500);
|
||||||
padding: 2px;
|
overflow-x: scroll;
|
||||||
background-color: #eee;
|
line-height: 1.2rem;
|
||||||
border: solid 1px #ddd;
|
|
||||||
user-select: all;
|
|
||||||
}
|
}
|
||||||
pre code {
|
pre code {
|
||||||
display: block;
|
padding: 0;
|
||||||
padding: 8px;
|
background-color: 0px;
|
||||||
word-break: break-word;
|
border: 0px;
|
||||||
/* word-break: break-all; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 128px;
|
height: 128px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
input[type="text"] {
|
|
||||||
margin: 0 12px 12px 0;
|
form {
|
||||||
width: 45%;
|
margin: 0 0 5.6rem;
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
}
|
||||||
input[type="radio"] {
|
form input[type="submit"] {
|
||||||
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;
|
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%;
|
width: 100%;
|
||||||
max-width: 128px;
|
padding: 0.4rem 0.8rem;
|
||||||
border-radius: 100%;
|
/* color: #fff; */
|
||||||
margin-right: 32px;
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background-color: #fff;
|
||||||
|
border: solid 1px var(--blue-700);
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
#profileName {
|
form input[type="submit"]:hover {
|
||||||
font-size: 1.6em;
|
background-color: var(--blue-700);
|
||||||
font-weight: bold;
|
color: #fff;
|
||||||
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%;
|
|
||||||
}
|
|
||||||
}
|
}
|
6
views-old/404.pug
Normal file
6
views-old/404.pug
Normal 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
67
views-old/guides.pug
Normal 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
103
views-old/index.pug
Normal 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's the
|
||||||
|
a(href='/9f0048ac0b23301e1f77e994909f6bd6f80f485d') developer'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'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'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
41
views-old/profile.pug
Normal 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…
|
||||||
|
else
|
||||||
|
p Loading keys & verifying proofs…
|
||||||
|
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')
|
|
@ -1,6 +1,5 @@
|
||||||
extends template.base.pug
|
extends templates/base.pug
|
||||||
|
|
||||||
block content
|
block content
|
||||||
.content
|
|
||||||
h1 404
|
h1 404
|
||||||
p The requested page could not be found :(
|
p The requested page could not be found :(
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
extends template.base.pug
|
extends templates/base.pug
|
||||||
|
|
||||||
block content
|
block content
|
||||||
.content
|
|
||||||
h1 Guides
|
h1 Guides
|
||||||
.guides
|
.hcards.hcards--guides.hcards--max-3
|
||||||
.guides__section
|
.card.guides__section
|
||||||
h3 Using Keyoxide
|
h3 Using Keyoxide
|
||||||
|
p
|
||||||
a(href='/guides/verify') Verifying a signature
|
a(href='/guides/verify') Verifying a signature
|
||||||
br
|
br
|
||||||
a(href='/guides/encrypt') Encrypting a message
|
a(href='/guides/encrypt') Encrypting a message
|
||||||
|
@ -16,16 +16,18 @@ block content
|
||||||
br
|
br
|
||||||
a(href='/guides/self-hosting-keyoxide') Self-hosting Keyoxide
|
a(href='/guides/self-hosting-keyoxide') Self-hosting Keyoxide
|
||||||
|
|
||||||
.guides__section
|
.card.guides__section
|
||||||
h3 OpenPGP and identity proofs
|
h3 OpenPGP and identity proofs
|
||||||
|
p
|
||||||
a(href='/guides/openpgp-proofs') How OpenPGP identity proofs work
|
a(href='/guides/openpgp-proofs') How OpenPGP identity proofs work
|
||||||
br
|
br
|
||||||
a(href='/guides/web-key-directory') Uploading keys using web key directory
|
a(href='/guides/web-key-directory') Uploading keys using web key directory
|
||||||
br
|
br
|
||||||
a(href='/guides/signature-profiles') Using signature profiles
|
a(href='/guides/signature-profiles') Using signature profiles
|
||||||
|
|
||||||
.guides__section
|
.card.guides__section
|
||||||
h3 Adding proofs
|
h3 Adding proofs
|
||||||
|
p
|
||||||
a(href='/guides/devto') Dev.to
|
a(href='/guides/devto') Dev.to
|
||||||
br
|
br
|
||||||
a(href='/guides/discourse') Discourse
|
a(href='/guides/discourse') Discourse
|
||||||
|
@ -54,14 +56,16 @@ block content
|
||||||
br
|
br
|
||||||
a(href='/guides/xmpp') XMPP+OMEMO
|
a(href='/guides/xmpp') XMPP+OMEMO
|
||||||
|
|
||||||
.guides__section
|
.card.guides__section
|
||||||
h3 Other services
|
h3 Other services
|
||||||
|
p
|
||||||
a(href='/guides/feature-comparison-keybase') Feature comparison with Keybase
|
a(href='/guides/feature-comparison-keybase') Feature comparison with Keybase
|
||||||
br
|
br
|
||||||
a(href='/guides/migrating-from-keybase') Migrating from Keybase
|
a(href='/guides/migrating-from-keybase') Migrating from Keybase
|
||||||
|
|
||||||
.guides__section
|
.card.guides__section
|
||||||
h3 Managing proofs in GnuPG
|
h3 Managing proofs in GnuPG
|
||||||
|
p
|
||||||
a(href='/guides/managing-proofs-listing') Listing proofs
|
a(href='/guides/managing-proofs-listing') Listing proofs
|
||||||
br
|
br
|
||||||
a(href='/guides/managing-proofs-deleting') Deleting proofs
|
a(href='/guides/managing-proofs-deleting') Deleting proofs
|
||||||
|
|
159
views/index.pug
159
views/index.pug
|
@ -1,100 +1,75 @@
|
||||||
extends template.base.pug
|
extends templates/base.pug
|
||||||
|
|
||||||
block content
|
block content
|
||||||
.content
|
if highlights.length > 0
|
||||||
h1 Keyoxide
|
h2 Highlights
|
||||||
|
.hcards.hcards--highlights
|
||||||
|
each hl in highlights
|
||||||
|
.card.card--small-profile
|
||||||
|
p.name= hl.name
|
||||||
p
|
p
|
||||||
a(href="/") Keyoxide
|
span.fingerprint= hl.fingerprint
|
||||||
| 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's the
|
|
||||||
a(href='/9f0048ac0b23301e1f77e994909f6bd6f80f485d') developer'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'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'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
|
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
|
br
|
||||||
a(href='/proofs') Verify distributed identity proofs
|
a(href='/') Getting started
|
||||||
.flex-column
|
br
|
||||||
h2 Utilities
|
a(href='/') Guides
|
||||||
|
br
|
||||||
|
a(href='/') FAQ
|
||||||
|
|
||||||
|
.card
|
||||||
|
h3 Utilities
|
||||||
p
|
p
|
||||||
a(href='/util/profile-url') Profile URL generator
|
a(href='/util/profile-url') Profile URL generator
|
||||||
br
|
br
|
||||||
|
|
6
views/long-form-content.pug
Normal file
6
views/long-form-content.pug
Normal 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
32
views/partials/footer.pug
Normal 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 © 2021 Keyoxide project contributors
|
11
views/partials/header.pug
Normal file
11
views/partials/header.pug
Normal 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
|
|
@ -1,41 +1,29 @@
|
||||||
doctype html
|
extends templates/base.pug
|
||||||
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
|
block js
|
||||||
.content
|
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
|
noscript
|
||||||
p Keyoxide requires JavaScript to function.
|
p Keyoxide requires JavaScript to function.
|
||||||
span#profileUid(style='display: none;') #{uid}
|
span#profileUid(style='display: none;') #{uid}
|
||||||
span#profileServer(style='display: none;') #{server}
|
span#profileServer(style='display: none;') #{server}
|
||||||
span#profileMode(style='display: none;') #{mode}
|
span#profileMode(style='display: none;') #{mode}
|
||||||
|
|
||||||
if (mode == 'sig')
|
if (mode == 'sig')
|
||||||
#profileSigInput
|
#profileSigInput.card
|
||||||
form#form-generate-signature-profile(method='post')
|
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')
|
textarea#plaintext_input(name='plaintext_input')
|
||||||
input(type='submit', name='submit', value='Generate profile').bigBtn
|
input(type='submit', name='submit', value='Generate profile')
|
||||||
#profileHeader
|
|
||||||
img#profileAvatar(src='/static/img/avatar_placeholder.png' alt='avatar' style='display: none')
|
#profileHeader.card.card--profileHeader
|
||||||
p#profileName
|
|
||||||
#profileData
|
#profileProofs.card
|
||||||
if (mode == 'sig')
|
if (mode == 'sig')
|
||||||
p Waiting for input…
|
//- p Waiting for input…
|
||||||
else
|
else
|
||||||
p Loading keys & verifying proofs…
|
p Loading keys & verifying proofs…
|
||||||
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
18
views/templates/base.pug
Normal 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
|
Loading…
Reference in a new issue