Compare commits
67 commits
c0161e46bd
...
7b78a1c0f6
Author | SHA1 | Date | |
---|---|---|---|
7b78a1c0f6 | |||
058e586042 | |||
b530b6a9af | |||
8b5e6931df | |||
8564f1bd81 | |||
c0fc7ce758 | |||
6af93824aa | |||
d4363e2758 | |||
92ea838dce | |||
e3c0fa72d1 | |||
34e029cbb0 | |||
43b2cb6c71 | |||
01b39a1bc1 | |||
6a9ec3b6e5 | |||
00c3e7f677 | |||
4a5f23da84 | |||
c40f003590 | |||
73a37bcffe | |||
37a432d621 | |||
9491eb0586 | |||
ca8ba91bde | |||
d716bcf70e | |||
c04cbc2a24 | |||
e5afc16a04 | |||
6d09f217e3 | |||
038bfc4400 | |||
dcd89fe3ab | |||
480978dacc | |||
2007a27303 | |||
1dba0bb1d0 | |||
2b79ea73a3 | |||
7134d18c9e | |||
62b4aa17e0 | |||
fc9d86a67a | |||
c29a70b34b | |||
8cb0eeba28 | |||
0b33c0d947 | |||
28d7648c50 | |||
3c182fc1df | |||
dc7cc9e7dc | |||
f702890d6b | |||
889955adbc | |||
bbfde69bab | |||
a43f93b343 | |||
dcaa7f2b8a | |||
b69b2d6b57 | |||
7b11b92ae2 | |||
78cb787323 | |||
e5f2080e4d | |||
f27164c111 | |||
1a793b7440 | |||
bc01a6b5a6 | |||
0b6bb58195 | |||
4824d9d104 | |||
42fd23ee39 | |||
8b0e08306d | |||
2a5ba61bb5 | |||
95603d106c | |||
3861812c63 | |||
55f12c69a2 | |||
a3f324846c | |||
4de34dede0 | |||
092ef934cc | |||
23630205d3 | |||
c328185abc | |||
4cd2ef7f71 | |||
daeaa7fe0e |
48 changed files with 1602 additions and 340 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -3,4 +3,3 @@
|
||||||
*.webp filter=lfs diff=lfs merge=lfs -text
|
*.webp filter=lfs diff=lfs merge=lfs -text
|
||||||
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
||||||
*.png filter=lfs diff=lfs merge=lfs -text
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
*.webm filter=lfs diff=lfs merge=lfs -text
|
|
||||||
|
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,3 +1,9 @@
|
||||||
dofdev
|
dofdev
|
||||||
|
|
||||||
*.json
|
tmp/
|
||||||
|
|
||||||
|
*.json
|
||||||
|
|
||||||
|
web/public/fonts/
|
||||||
|
|
||||||
|
*.webm
|
6
go.mod
6
go.mod
|
@ -1,5 +1,5 @@
|
||||||
module github.com/spatialfree/dofdev
|
module dofdev
|
||||||
|
|
||||||
go 1.20
|
go 1.23.2
|
||||||
|
|
||||||
require github.com/gorilla/mux v1.8.1 // indirect
|
require github.com/gorilla/mux v1.8.1
|
||||||
|
|
10
no_sync.txt
Normal file
10
no_sync.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.git
|
||||||
|
.env
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
go.mod
|
||||||
|
go.sum
|
||||||
|
|
||||||
|
/tmp
|
||||||
|
|
||||||
|
data/*.json
|
24
readme.md
24
readme.md
|
@ -1,11 +1,23 @@
|
||||||
```shell
|
```shell
|
||||||
# build and run
|
# develop
|
||||||
go build && ./dofdev
|
air
|
||||||
|
|
||||||
# deploy
|
# deploy
|
||||||
rsync -avz --progress ~/go/src/dofdev/ root@dofdev:/root/dofdev/
|
go build
|
||||||
# server starting at: http://localhost:3210
|
rsync -avz --exclude-from='no_sync.txt' --progress ~/go/src/dofdev/ root@dofdev:/root/dofdev/
|
||||||
|
|
||||||
|
|
||||||
|
# misc
|
||||||
# track lfs
|
# track lfs
|
||||||
git lfs track "*.psd"
|
git lfs track "*.svg"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
todo:
|
||||||
|
snake leaderboard
|
||||||
|
POST store and GET snake{ []XYZi, len#, initials"" }
|
||||||
|
to keep data costs low as possible:
|
||||||
|
just store and share top 10
|
||||||
|
+buffer incase of removing cheater
|
||||||
|
and just store local top 10 highscores locally
|
||||||
|
|
||||||
|
page on spatial cursors
|
43
server.go
43
server.go
|
@ -5,8 +5,8 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/spatialfree/dofdev/src/router"
|
"dofdev/src/router"
|
||||||
"github.com/spatialfree/dofdev/tem"
|
"dofdev/tem"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -18,44 +18,9 @@ func main() {
|
||||||
r := router.New()
|
r := router.New()
|
||||||
|
|
||||||
// Start the web server
|
// Start the web server
|
||||||
log.Println("server starting on port 3210...")
|
addr := ":3232"
|
||||||
addr := ":3210"
|
log.Println("server starting on port" + addr)
|
||||||
// addr := "192.168.0.21:3000"
|
|
||||||
if err := http.ListenAndServe(addr, r); err != nil {
|
if err := http.ListenAndServe(addr, r); err != nil {
|
||||||
log.Fatalf("error starting server: %v", err)
|
log.Fatalf("error starting server: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fs := http.FileServer(http.Dir("./res"))
|
|
||||||
// http.Handle("/res/", http.StripPrefix("/res/", fs))
|
|
||||||
|
|
||||||
// http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// fmt.Println("request: ", r.URL.Path)
|
|
||||||
// http.ServeFile(w, r, "./index.html")
|
|
||||||
// })
|
|
||||||
|
|
||||||
// http.HandleFunc("/pass", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// fmt.Println("request: ", r.URL.Path)
|
|
||||||
// // fmt.Println("request: ", r.Header)
|
|
||||||
// fmt.Println("request: ", r.FormValue("pass"))
|
|
||||||
// fmt.Println("request: ", hash(r.FormValue("pass")))
|
|
||||||
// if hash(r.FormValue("pass")) == 3556498 {
|
|
||||||
// http.ServeFile(w, r, "./biz.html")
|
|
||||||
// } else {
|
|
||||||
// http.Error(w, "Forbidden", http.StatusForbidden)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// fmt.Println("server starting @ http://localhost:3210 ...")
|
|
||||||
// if err := http.ListenAndServe(":3210", nil); err != nil {
|
|
||||||
// panic(err)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// hash function
|
|
||||||
func hash(s string) uint32 {
|
|
||||||
h := uint32(0)
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
h = 31*h + uint32(s[i])
|
|
||||||
}
|
|
||||||
return h
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,15 @@ package router
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"dofdev/web/pages/about"
|
||||||
|
braillexr "dofdev/web/pages/braille_xr"
|
||||||
|
"dofdev/web/pages/games"
|
||||||
|
"dofdev/web/pages/mono"
|
||||||
|
"dofdev/web/pages/moves"
|
||||||
|
"dofdev/web/pages/projects"
|
||||||
|
"dofdev/web/pages/sc"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
braillexr "github.com/spatialfree/dofdev/web/pages/braille_xr"
|
|
||||||
"github.com/spatialfree/dofdev/web/pages/mono"
|
|
||||||
"github.com/spatialfree/dofdev/tem"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func New() *mux.Router {
|
func New() *mux.Router {
|
||||||
|
@ -14,12 +19,22 @@ func New() *mux.Router {
|
||||||
|
|
||||||
r.PathPrefix(("/public/")).Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("web/public/"))))
|
r.PathPrefix(("/public/")).Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("web/public/"))))
|
||||||
r.HandleFunc("/", mono.Handler)
|
r.HandleFunc("/", mono.Handler)
|
||||||
|
r.HandleFunc("/about", about.Handler)
|
||||||
|
r.HandleFunc("/moves", moves.Handler)
|
||||||
|
r.HandleFunc("/move/{hash}", moves.MoveHandler)
|
||||||
|
r.HandleFunc("/games", games.Handler)
|
||||||
|
r.HandleFunc("/game/{hash}", games.GameHandler)
|
||||||
|
r.HandleFunc("/projects", projects.Handler)
|
||||||
|
r.HandleFunc("/project/{hash}", projects.ProjectHandler)
|
||||||
|
|
||||||
|
r.HandleFunc("/sc", sc.Handler)
|
||||||
|
|
||||||
r.HandleFunc("/braille_xr", braillexr.Handler)
|
r.HandleFunc("/braille_xr", braillexr.Handler)
|
||||||
|
|
||||||
r.HandleFunc("/reload", func(w http.ResponseWriter, r *http.Request) {
|
// r.HandleFunc("/reload", func(w http.ResponseWriter, r *http.Request) {
|
||||||
tem.Load()
|
// tem.Load()
|
||||||
// route them back to where they came from
|
// // route them back to where they came from
|
||||||
http.Redirect(w, r, r.Header.Get("Referer"), http.StatusFound)
|
// http.Redirect(w, r, r.Header.Get("Referer"), http.StatusFound)
|
||||||
})
|
// })
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
<h2>shared accounts:</h2>
|
|
||||||
<!-- there might be sections for personal accounts later ~ -->
|
|
||||||
|
|
||||||
<div id='accounts'></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
accounts = []
|
|
||||||
|
|
||||||
el = document.getElementById('accounts')
|
|
||||||
for (i = 0; i < accounts.length; i++) {
|
|
||||||
a = accounts[i]
|
|
||||||
el.innerHTML += `<div class='account ${(a.dead ? 'dead' : '')}'>
|
|
||||||
<div>
|
|
||||||
<b>${a.name}</b>
|
|
||||||
<a href='${a.link}'>→</a>
|
|
||||||
</div>
|
|
||||||
<div>${a.user}</div>
|
|
||||||
<div class='pass'>
|
|
||||||
<div onclick='
|
|
||||||
this.innerHTML="✓ ";
|
|
||||||
navigator.clipboard.writeText("${a.pass}")
|
|
||||||
'>⧉ </div>
|
|
||||||
<div onclick='
|
|
||||||
this.innerHTML === "${a.pass}" ?
|
|
||||||
window.getSelection().selectAllChildren(this) :
|
|
||||||
this.innerHTML = "${a.pass}"
|
|
||||||
'>${'*'.repeat(a.pass.length)}</div>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.account {
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
.dead {
|
|
||||||
opacity: 0.666;
|
|
||||||
}
|
|
||||||
.pass {
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
font-family: 'Courier Prime', monospace;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
140
tem/html/core/head.html
Normal file
140
tem/html/core/head.html
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="language" content="English">
|
||||||
|
<title>{{ .Title }}</title>
|
||||||
|
<meta name="description" content="{{ .Desc }}">
|
||||||
|
<meta name="og:image" content="/public/img/knuckles_owo.png">
|
||||||
|
<link rel="shortcut icon" href="https://media.dof.dev/kit/logo.svg" type="image/svg+xml">
|
||||||
|
<link rel="stylesheet" href="/public/style.css?v4">
|
||||||
|
<script src="/public/js/mono.js?v1"></script>
|
||||||
|
<link rel="canonical" href="https://{{ .Host }}{{ .PagePath }}">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- nav -->
|
||||||
|
<div id="nav">
|
||||||
|
<div style="display: flex; gap: 12px;">
|
||||||
|
<div
|
||||||
|
id="nav_side"
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
width: auto;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a href="javascript:toggle_side()">
|
||||||
|
<img src="/public/img/icons/menu.svg?v1" height="32" width="auto" />
|
||||||
|
</a>
|
||||||
|
<a href="/about" style="display: flex; align-items: center; gap: 6px; text-decoration: none;">
|
||||||
|
<img src="https://media.dof.dev/kit/logo.svg?v1" height="32" width="auto" style="border-radius: 16px;" />
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
dofdev
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
background-color: #11111166;
|
||||||
|
color: var(--col-10);
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-radius: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a href="/">
|
||||||
|
<img src="/public/img/icons/search.svg?v1" height="16" width="auto" />
|
||||||
|
</a>
|
||||||
|
<input id="search" maxlength="24" placeholder="search" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="nav_border"></div>
|
||||||
|
|
||||||
|
<div class="disabled" style="display: flex; gap: 12px;">
|
||||||
|
<a href="/settings">
|
||||||
|
<img src="/public/img/icons/settings.svg?v2" height="32" width="auto" />
|
||||||
|
</a>
|
||||||
|
<a href="/profile">
|
||||||
|
<img src="/public/img/profile-pic.png?v1" height="32" width="auto" style="border-radius: 16px;" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="side">
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
gap: 6px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a href="/" class="onpage">
|
||||||
|
<img src="/public/img/icons/home.svg?v1" height="32" width="auto" />
|
||||||
|
<div>home</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/moves">
|
||||||
|
<img src="/public/img/icons/dofs.svg?v1" height="32" width="auto" />
|
||||||
|
<div>moves</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/games">
|
||||||
|
<img src="/public/img/icons/games.svg?v1" height="32" width="auto" />
|
||||||
|
<div>games</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/projects">
|
||||||
|
<img src="/public/img/icons/projects.svg?v1" height="32" width="auto" />
|
||||||
|
<div>projects</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
height: 2px;
|
||||||
|
width: 75%;
|
||||||
|
margin: 6px auto;
|
||||||
|
background: var(--col-06);
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
<a href="https://discord.com/invite/v9UF3TsX?utm_source=Discord%20Widget&utm_medium=Connect">
|
||||||
|
<img src="/public/img/icons/discord.svg?v1" height="32" width="auto" />
|
||||||
|
<div>discord</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="flex: 1;"></div>
|
||||||
|
|
||||||
|
<div id="support">
|
||||||
|
<a href="https://www.patreon.com/bePatron?u=31202689">
|
||||||
|
<img width="48px" src="/public/img/icons/patreon.svg?v29" style="border-radius: 24px;">
|
||||||
|
</a>
|
||||||
|
<a href="https://dofdev-shop.fourthwall.com">
|
||||||
|
<img width="48px" src="/public/img/icons/merch.svg?v29" style="border-radius: 24px;">
|
||||||
|
</a>
|
||||||
|
<a href="https://ko-fi.com/dofdev">
|
||||||
|
<img width="48px" src="/public/img/icons/kofi.svg?v29" style="border-radius: 24px;">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="foot">
|
||||||
|
{{ template "footer.html" }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="side_border"></div>
|
||||||
|
|
||||||
|
<main id="main">
|
|
@ -1,18 +0,0 @@
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'>
|
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
|
||||||
<script src='https://unpkg.com/htmx.org@1.9.5'></script>
|
|
||||||
<link rel="stylesheet" href="/public/style.css?v19">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<a style='
|
|
||||||
position: fixed;
|
|
||||||
top: 10px;
|
|
||||||
left: 10px;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
background-color: #000;
|
|
||||||
opacity: 0.02;
|
|
||||||
' href='/reload'></a>
|
|
|
@ -1,99 +0,0 @@
|
||||||
{{ template "head.html" .}}
|
|
||||||
|
|
||||||
<main>
|
|
||||||
|
|
||||||
<p style='
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 20px;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 2.0;
|
|
||||||
text-align: right;
|
|
||||||
color: white;
|
|
||||||
'>
|
|
||||||
An effort to open higher degrees of<br>
|
|
||||||
spatial interaction free<br>
|
|
||||||
to the world.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<img src='/public/img/dofdev_logo.svg?v22' width='100%'>
|
|
||||||
<p>degrees of freedom development</p>
|
|
||||||
|
|
||||||
<div class='shuffle' style='
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
align-items: center;
|
|
||||||
'>
|
|
||||||
<div style='color: white; font-size: 20px;'>Ethan Merchant
|
|
||||||
<a href='https://ethanmerchant.com' style='color: var(--light);'>@spatialfree</a>
|
|
||||||
</div>
|
|
||||||
<div style='color: white; font-size: 20px;'>Niko Ryan
|
|
||||||
<a href='https://twitter.com/opendegree' style='color: var(--light);'>@opendegree</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='t_symbol' style='
|
|
||||||
font-size: 32px;
|
|
||||||
'>×</div>
|
|
||||||
|
|
||||||
<div id='x'>
|
|
||||||
<a href='https://stereokit.net' target='_blank'>
|
|
||||||
<div style='
|
|
||||||
background-image: url("https://stereokit.net/img/StereoKitLogoLight.svg");
|
|
||||||
'></div>
|
|
||||||
</a>
|
|
||||||
<a href='https://www.projectnorthstar.org/' target='_blank'>
|
|
||||||
<div style='
|
|
||||||
background-image: url("/public/img/icons/northstar.svg");
|
|
||||||
'></div>
|
|
||||||
</a>
|
|
||||||
<a href='https://stardustxr.org' target='_blank'>
|
|
||||||
<div style='
|
|
||||||
background-image: url("https://stardustxr.org/img/icon.gif");
|
|
||||||
'></div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='t_symbol' style='
|
|
||||||
margin-top: 4rem;
|
|
||||||
'>∮</div>
|
|
||||||
|
|
||||||
<!-- <div style='height: 32px;'></div> -->
|
|
||||||
<!-- <div id='fdeg'>+</div> -->
|
|
||||||
|
|
||||||
<h1>projects</h1>
|
|
||||||
<p class='subtitle'>xr based interfaces</p>
|
|
||||||
|
|
||||||
<a href='/braille_xr'>braille_xr</a>
|
|
||||||
|
|
||||||
<div style='height: 32px;'></div>
|
|
||||||
<img src='/public/img/logo.svg' width='64px'>
|
|
||||||
<div style='height: 24px;'></div>
|
|
||||||
|
|
||||||
<input type='password' autofocus
|
|
||||||
name='pass' placeholder='pass'
|
|
||||||
hx-post='/pass'
|
|
||||||
hx-vals='{"pass": this.value}'
|
|
||||||
hx-swap='outerHTML'
|
|
||||||
>
|
|
||||||
<!-- <button hx-post='/clicked' hx-swap='outerHTML'>
|
|
||||||
Click Me
|
|
||||||
</button> -->
|
|
||||||
|
|
||||||
<footer>© 2018-2024 dofdev</footer>
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#x {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 32px;
|
|
||||||
> a > div {
|
|
||||||
min-width: 64px;
|
|
||||||
min-height: 64px;
|
|
||||||
background-size: contain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
200
tem/html/pages/about.html
Normal file
200
tem/html/pages/about.html
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div style="height: 64px; width: 100%;"></div>
|
||||||
|
|
||||||
|
<p style='
|
||||||
|
line-height: 1.75;
|
||||||
|
color: white;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
'>
|
||||||
|
An effort to open higher degrees of<br>
|
||||||
|
spatial interaction free<br>
|
||||||
|
to the world.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div style="height: 12px; width: 100%;"></div>
|
||||||
|
|
||||||
|
<img src='https://media.dof.dev/kit/logotype.svg?v22' width='256'>
|
||||||
|
<p>degrees of freedom development</p>
|
||||||
|
|
||||||
|
<div style="height: 12px; width: 100%;"></div>
|
||||||
|
|
||||||
|
<div class='shuffle' style='
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
align-items: center;
|
||||||
|
'>
|
||||||
|
<div style='color: white; font-size: 18px;'>
|
||||||
|
Ethan Merchant <span style="color: var(--col-01); font-size: 14px;">@spatialfree</span>
|
||||||
|
<a
|
||||||
|
href='https://ethanmerchant.com'
|
||||||
|
target="_blank"
|
||||||
|
style="text-decoration: none;"
|
||||||
|
>
|
||||||
|
🔗
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div style='color: white; font-size: 18px;'>
|
||||||
|
Niko Ryan <span style="color: var(--col-01); font-size: 14px;">@opendegree</span>
|
||||||
|
<a
|
||||||
|
href='https://nikoryan.com'
|
||||||
|
target="_blank"
|
||||||
|
style="text-decoration: none;"
|
||||||
|
>
|
||||||
|
🔗
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style='
|
||||||
|
color: var(--col-06);
|
||||||
|
font-size: 48px;
|
||||||
|
padding: 12px;
|
||||||
|
'>×</div>
|
||||||
|
|
||||||
|
<div id='x'>
|
||||||
|
{{ range .Data.Peers }}
|
||||||
|
<a
|
||||||
|
href='{{ .Project.Url }}'
|
||||||
|
title='{{ .Project.Name }}'
|
||||||
|
target='_blank'
|
||||||
|
>
|
||||||
|
<div style='
|
||||||
|
background-image: url("{{ .Project.Icon }}");
|
||||||
|
'></div>
|
||||||
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="flex: 1;"></div>
|
||||||
|
|
||||||
|
<div style="display: block; position: relative; width: auto;">
|
||||||
|
<div style="display: block; position: relative;">
|
||||||
|
<img src="/public/img/knuckles_owo-removebg.png?v29" loading="lazy" height="360px" style="margin-right: 0;">
|
||||||
|
<div class="scene">
|
||||||
|
<div class="cube">
|
||||||
|
<img class="degree" src="/public/img/icons/degree.svg?v29">
|
||||||
|
<div class="cube__face cube__face--front">
|
||||||
|
<div class="edge" style="position: absolute; left: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(000, 000, 255, 1), rgba(000, 255, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; top: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 255, 255, 1), rgba(255, 255, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; bottom: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 000, 255, 1), rgba(255, 000, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; right: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(255, 000, 255, 1), rgba(255, 255, 255, 1));"></div>
|
||||||
|
</div>
|
||||||
|
<div class="cube__face cube__face--back">
|
||||||
|
<div class="edge" style="position: absolute; left: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(255, 000, 000, 1), rgba(255, 255, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; top: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(255, 255, 000, 1), rgba(000, 255, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; bottom: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(255, 000, 000, 1), rgba(000, 000, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; right: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(000, 000, 000, 1), rgba(000, 255, 000, 1));"></div>
|
||||||
|
</div>
|
||||||
|
<div class="cube__face cube__face--right">
|
||||||
|
<div class="edge" style="position: absolute; left: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(255, 000, 255, 1), rgba(255, 255, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; top: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(255, 255, 255, 1), rgba(255, 255, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; bottom: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(255, 000, 255, 1), rgba(255, 000, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; right: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(255, 000, 000, 1), rgba(255, 255, 000, 1));"></div>
|
||||||
|
</div>
|
||||||
|
<div class="cube__face cube__face--left">
|
||||||
|
<div class="edge" style="position: absolute; left: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(000, 000, 000, 1), rgba(000, 255, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; top: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 255, 000, 1), rgba(000, 255, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; bottom: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 000, 000, 1), rgba(000, 000, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; right: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(000, 000, 255, 1), rgba(000, 255, 255, 1));"></div>
|
||||||
|
</div>
|
||||||
|
<div class="cube__face cube__face--top">
|
||||||
|
<div class="edge" style="position: absolute; left: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(000, 255, 255, 1), rgba(000, 255, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; top: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 255, 000, 1), rgba(255, 255, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; bottom: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 255, 255, 1), rgba(255, 255, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; right: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(255, 255, 255, 1), rgba(255, 255, 000, 1));"></div>
|
||||||
|
</div>
|
||||||
|
<div class="cube__face cube__face--bottom">
|
||||||
|
<div class="edge" style="position: absolute; left: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(000, 000, 000, 1), rgba(000, 000, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; top: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 000, 255, 1), rgba(255, 000, 255, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; bottom: -1px; left: -1px; right: -1px; height: 2px; background: linear-gradient(90deg, rgba(000, 000, 000, 1), rgba(255, 000, 000, 1));"></div>
|
||||||
|
<div class="edge" style="position: absolute; right: -1px; width: 2px; top: -1px; bottom: -1px; background: linear-gradient(00deg, rgba(255, 000, 000, 1), rgba(255, 000, 255, 1));"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display: block; position: absolute; bottom: 0; right: 0; padding: 10px;">
|
||||||
|
<a href="https://twitter.com/luciherzig" style="color: rgb(170 175 255);">@luciherzig</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#x {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 32px;
|
||||||
|
> a > div {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
background-size: contain;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scene {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 184px;
|
||||||
|
right: 206px;
|
||||||
|
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
perspective: 120px;
|
||||||
|
perspective-origin: 32px 16px;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.666));
|
||||||
|
}
|
||||||
|
.degree {
|
||||||
|
position: absolute;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
animation: unspin 6s linear infinite;
|
||||||
|
}
|
||||||
|
@keyframes unspin {
|
||||||
|
0% { transform: rotateY(460deg); }
|
||||||
|
50% { transform: rotateY(280deg); }
|
||||||
|
100% { transform: rotateY(100deg); }
|
||||||
|
}
|
||||||
|
.cube {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
/* transform: translateZ(-20px); */
|
||||||
|
animation: spin 6s linear infinite;
|
||||||
|
}
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: translateY(0px) rotateY( 80deg); }
|
||||||
|
50% { transform: translateY(5px) rotateY(260deg); }
|
||||||
|
100% { transform: translateY(0px) rotateY(440deg); }
|
||||||
|
}
|
||||||
|
.cube__face {
|
||||||
|
position: absolute;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
/* background: rgba(204, 204, 204, 0.5); */
|
||||||
|
}
|
||||||
|
.edge {
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.cube__face--front {
|
||||||
|
transform: rotateY(0deg) translateZ(16px);
|
||||||
|
}
|
||||||
|
.cube__face--right {
|
||||||
|
transform: rotateY(90deg) translateZ(16px);
|
||||||
|
}
|
||||||
|
.cube__face--back {
|
||||||
|
transform: rotateY(180deg) translateZ(16px);
|
||||||
|
}
|
||||||
|
.cube__face--left {
|
||||||
|
transform: rotateY(-90deg) translateZ(16px);
|
||||||
|
}
|
||||||
|
.cube__face--top {
|
||||||
|
transform: rotateX(90deg) translateZ(16px);
|
||||||
|
}
|
||||||
|
.cube__face--bottom {
|
||||||
|
transform: rotateX(-90deg) translateZ(16px);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,11 +1,39 @@
|
||||||
{{ template "head.html" .}}
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
<main>
|
<div id="top_img">
|
||||||
|
<video src='/public/braille_xr.webm' autoplay loop muted
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: bottom;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
</video>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
top: 66.66%; left: 0; right: 0; bottom: 0;
|
||||||
|
background: linear-gradient(in oklab to top, #FFFFFFFF, #FFFFFF00);
|
||||||
|
mix-blend-mode: color;
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h1>braille_xr</h1>
|
<!-- <div style="height: calc(44px + 12px);"></div> -->
|
||||||
<video src='/public/braille_xr.webm' width='100%' autoplay loop muted></video>
|
|
||||||
|
|
||||||
<div style='height: 64px; display: block; width: 100%;'></div>
|
<div
|
||||||
|
style="
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ template "title_desc.html" .}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div style='height: 1024px;'></div> -->
|
||||||
|
|
||||||
<h2>problem</h2>
|
<h2>problem</h2>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -17,7 +45,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
<img src='/public/img/brailliant_bi_40x.webp' width='60%'>
|
<img src='/public/img/brailliant_bi_40x.webp' width='60%'>
|
||||||
|
|
||||||
<div style='height: 64px; display: block; width: 100%;'></div>
|
<div style='height: 64px;'></div>
|
||||||
|
|
||||||
<h2>progress</h2>
|
<h2>progress</h2>
|
||||||
<p style='margin-top: 0;'>code, hardware, software and project files: <a href='https://git.dof.dev/dofdev/braille_xr'>git repo</a></p>
|
<p style='margin-top: 0;'>code, hardware, software and project files: <a href='https://git.dof.dev/dofdev/braille_xr'>git repo</a></p>
|
||||||
|
@ -29,11 +57,9 @@
|
||||||
</ul>
|
</ul>
|
||||||
<img src='/public/img/hack.webp' width='60%'>
|
<img src='/public/img/hack.webp' width='60%'>
|
||||||
|
|
||||||
<div style='height: 64px; display: block; width: 100%;'></div>
|
<div style='height: 64px;'></div>
|
||||||
|
|
||||||
<h2>support</h2>
|
<h2>support</h2>
|
||||||
<p style='margin-top: 0;'>have some resources or experience to throw our way?<br>contact us on our discord server: <a href=''>invite/quick link</a></p>
|
<p style='margin-top: 0;'>have some resources or experience to throw our way?<br>contact us on our discord server: <a href=''>invite/quick link</a></p>
|
||||||
|
|
||||||
<div style='height: 128px; display: block; width: 100%;'></div>
|
<div style='height: 128px;'> </div>
|
||||||
|
|
||||||
</main>
|
|
66
tem/html/pages/game.html
Normal file
66
tem/html/pages/game.html
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div id="top_img">
|
||||||
|
<!-- <div
|
||||||
|
style="
|
||||||
|
background-image: url(/public/img/hack.jpg);
|
||||||
|
background-position: bottom;
|
||||||
|
background-size: cover;
|
||||||
|
height: 100vh;
|
||||||
|
position: relative;
|
||||||
|
"
|
||||||
|
></div> -->
|
||||||
|
<video src='/public/games/{{ .Data.Hash }}.webm' autoplay loop muted
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: bottom;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
</video>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
top: 66.66%; left: 0; right: 0; bottom: 0;
|
||||||
|
background: linear-gradient(in oklab to top, #FFFFFFFF, #FFFFFF00);
|
||||||
|
mix-blend-mode: color;
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-flow: column;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 style='width: 100%; word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
<p>
|
||||||
|
{{ .Desc }}
|
||||||
|
</p>
|
||||||
|
</h1>
|
||||||
|
<!-- {{ template "title_desc.html" .}} -->
|
||||||
|
<!-- <img src='https://media.dof.dev/kit/logotype.svg?v22' width='66.6%'>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
color: var(--col-01);
|
||||||
|
background-color: #ffffff80;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 24px;
|
||||||
|
margin-top: -32px;
|
||||||
|
"
|
||||||
|
>degrees of freedom development</div> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>notes</h2>
|
||||||
|
<pre>{{ .Data.Game.Notes }}</pre>
|
||||||
|
|
||||||
|
<div style='height: 44px; width: 100%;'></div>
|
27
tem/html/pages/games.html
Normal file
27
tem/html/pages/games.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div style='height: 44px; width: 100%;'></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: left;
|
||||||
|
padding-left: 12px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 style='word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
</h1>
|
||||||
|
<p>{{ .Desc }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{ range $hash, $game := .Data.Games }}
|
||||||
|
<div>
|
||||||
|
<a href="/game/{{ $hash }}">
|
||||||
|
<h2>{{ $game.Name }}</h2>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
162
tem/html/pages/mono.html
Normal file
162
tem/html/pages/mono.html
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div id="top_img">
|
||||||
|
<!-- <div
|
||||||
|
style="
|
||||||
|
background-image: url(/public/img/hack.jpg);
|
||||||
|
background-position: bottom;
|
||||||
|
background-size: cover;
|
||||||
|
height: 100vh;
|
||||||
|
position: relative;
|
||||||
|
"
|
||||||
|
></div> -->
|
||||||
|
<video src='/public/games/{{ .Data.TopHash }}.webm' autoplay loop muted
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: bottom;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
</video>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
top: 66.66%; left: 0; right: 0; bottom: 0;
|
||||||
|
background: linear-gradient(in oklab to top, #FFFFFFFF, #FFFFFF00);
|
||||||
|
mix-blend-mode: color;
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<!-- space below nav -->
|
||||||
|
<!-- <div style="height: calc(44px + 12px);"></div> -->
|
||||||
|
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-flow: column;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $top_thing := index .Data.Games .Data.TopHash }}
|
||||||
|
<h1 style='width: 100%; word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ $top_thing.Name }}
|
||||||
|
<p>
|
||||||
|
{{ $top_thing.Desc }}
|
||||||
|
<br><br>
|
||||||
|
<a href="/game/{{ .Data.TopHash }}">see more</a>
|
||||||
|
</p>
|
||||||
|
</h1>
|
||||||
|
<!-- {{ template "title_desc.html" .}} -->
|
||||||
|
<!-- <img src='https://media.dof.dev/kit/logotype.svg?v22' width='66.6%'>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
color: var(--col-01);
|
||||||
|
background-color: #ffffff80;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 24px;
|
||||||
|
margin-top: -32px;
|
||||||
|
"
|
||||||
|
>degrees of freedom development</div> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>moves</h2>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
overflow-x: auto;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ range $hash, $move := .Data.Moves }}
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
width: 400px;
|
||||||
|
background-color: #00000080;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<video autoplay muted
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<source src="/public/moves/{{ $hash }}.webm" type="video/webm" />
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
<div>{{ $move.Name }}</div>
|
||||||
|
<a href="/move/{{ $hash }}">see more</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>games</h2>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
overflow-x: auto;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ range $hash, $game := .Data.Games }}
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
width: 400px;
|
||||||
|
background-color: #00000080;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<video autoplay muted
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<source src="/public/games/{{ $hash }}.webm" type="video/webm" />
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
<div>{{ $game.Name }}</div>
|
||||||
|
<a href="/game/{{ $hash }}">see more</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>projects</h2>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
overflow-x: auto;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ range $hash, $project := .Data.Projects }}
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
width: 400px;
|
||||||
|
background-color: #00000080;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div>{{ $project.Name }}</div>
|
||||||
|
<a href="/project/{{ $hash }}">see more</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div style='height: 128px; width: 100%;'></div>
|
64
tem/html/pages/move.html
Normal file
64
tem/html/pages/move.html
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
|
||||||
|
<div id="top_img">
|
||||||
|
<!-- <div
|
||||||
|
style="
|
||||||
|
background-image: url(/public/img/hack.jpg);
|
||||||
|
background-position: bottom;
|
||||||
|
background-size: cover;
|
||||||
|
height: 100vh;
|
||||||
|
position: relative;
|
||||||
|
"
|
||||||
|
></div> -->
|
||||||
|
<video src='/public/moves/{{ .Data.Hash }}.webm' autoplay loop muted
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: bottom;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
</video>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
top: 66.66%; left: 0; right: 0; bottom: 0;
|
||||||
|
background: linear-gradient(in oklab to top, #FFFFFFFF, #FFFFFF00);
|
||||||
|
mix-blend-mode: color;
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-flow: column;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 style='width: 100%; word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
<p>
|
||||||
|
{{ .Desc }}
|
||||||
|
</p>
|
||||||
|
</h1>
|
||||||
|
<!-- {{ template "title_desc.html" .}} -->
|
||||||
|
<!-- <img src='https://media.dof.dev/kit/logotype.svg?v22' width='66.6%'>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
color: var(--col-01);
|
||||||
|
background-color: #ffffff80;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 24px;
|
||||||
|
margin-top: -32px;
|
||||||
|
"
|
||||||
|
>degrees of freedom development</div> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style='height: 44px; width: 100%;'></div>
|
27
tem/html/pages/moves.html
Normal file
27
tem/html/pages/moves.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div style='height: 44px; width: 100%;'></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: left;
|
||||||
|
padding-left: 12px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 style='word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
</h1>
|
||||||
|
<p>{{ .Desc }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{ range $hash, $move := .Data.Moves }}
|
||||||
|
<div>
|
||||||
|
<a href="/move/{{ $hash }}">
|
||||||
|
<h2>{{ $move.Name }}</h2>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
18
tem/html/pages/project.html
Normal file
18
tem/html/pages/project.html
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div style='height: 44px; width: 100%;'></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: left;
|
||||||
|
padding-left: 12px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 style='word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
</h1>
|
||||||
|
<p>{{ .Desc }}</p>
|
||||||
|
</div>
|
27
tem/html/pages/projects.html
Normal file
27
tem/html/pages/projects.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div style='height: 44px; width: 100%;'></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: left;
|
||||||
|
padding-left: 12px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 style='word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
</h1>
|
||||||
|
<p>{{ .Desc }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{ range $hash, $project := .Data.Projects }}
|
||||||
|
<div>
|
||||||
|
<a href="/project/{{ $hash }}">
|
||||||
|
<h2>{{ $project.Name }}</h2>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
30
tem/html/pages/sc.html
Normal file
30
tem/html/pages/sc.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
|
||||||
|
<div style='height: 44px; width: 100%;'></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: left;
|
||||||
|
padding-left: 12px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 style='word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
</h1>
|
||||||
|
<p>{{ .Desc }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<img src="/public/img/spatial.svg" width="100%" />
|
||||||
|
|
||||||
|
<div style='height: 12px; width: 100%;'></div>
|
||||||
|
|
||||||
|
<h2>spatial computing</h2>
|
||||||
|
<p>signed unbounded 3d space</p>
|
||||||
|
|
||||||
|
<h2>paper computing</h2>
|
||||||
|
<p>unsigned bounded 2d space</p>
|
||||||
|
|
||||||
|
<div style='height: 128px; width: 100%;'></div>
|
30
tem/html/snippets/footer.html
Normal file
30
tem/html/snippets/footer.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<div id='copyright' style='
|
||||||
|
padding-bottom: 16px 0;
|
||||||
|
font-family: "legible", sans-serif;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
'>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a href='/license'>license</a>
|
||||||
|
<a href='/about'>about</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span id='copyright_year'>© 2018-_</span> <b>dofdev</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
// replace _ in #copyright w/ current year
|
||||||
|
let date = new Date()
|
||||||
|
let year = date.getFullYear()
|
||||||
|
let c = elbyid('copyright_year')
|
||||||
|
c.innerHTML = c.innerHTML.replace('_', year)
|
||||||
|
})
|
||||||
|
</script>
|
4
tem/html/snippets/title_desc.html
Normal file
4
tem/html/snippets/title_desc.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<h1 style='width: 100%; word-wrap: break-word; hyphens: auto;'>
|
||||||
|
{{ .Title }}
|
||||||
|
<p>{{ .Desc }}</p>
|
||||||
|
</h1>
|
32
tem/tem.go
32
tem/tem.go
|
@ -11,7 +11,8 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load() {
|
func Load() {
|
||||||
Templates = template.Must(template.ParseGlob("tem/html/*.html"))
|
func_map := template.FuncMap{}
|
||||||
|
Templates = template.Must(template.New("").Funcs(func_map).ParseGlob("tem/html/**/*.html"))
|
||||||
fmt.Println("templates loaded")
|
fmt.Println("templates loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +20,6 @@ func Render(
|
||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
r *http.Request,
|
r *http.Request,
|
||||||
template string,
|
template string,
|
||||||
page string,
|
|
||||||
title string,
|
title string,
|
||||||
desc string,
|
desc string,
|
||||||
page_data interface{},
|
page_data interface{},
|
||||||
|
@ -27,21 +27,21 @@ func Render(
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
data := struct {
|
data := struct {
|
||||||
Host string
|
Host string
|
||||||
Page string
|
PagePath string
|
||||||
Title string
|
Title string
|
||||||
Desc string
|
Desc string
|
||||||
Local bool
|
Local bool
|
||||||
Root bool
|
Root bool
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}{
|
}{
|
||||||
Host: r.Host,
|
Host: r.Host,
|
||||||
Page: page,
|
PagePath: r.URL.Path, // *see header canonical link
|
||||||
Title: title,
|
Title: title,
|
||||||
Desc: desc,
|
Desc: desc,
|
||||||
Local: true, // (os.Getenv("LOCAL") == "true"), // toggle here for flag testing
|
Local: true, // (os.Getenv("LOCAL") == "true"), // toggle here for flag testing
|
||||||
Root: true, // (os.Getenv("HOST_IDEABRELLA") == strings.ReplaceAll(r.Host, ":3000", "")),
|
Root: true, // (os.Getenv("HOST_DOFDEV") == strings.ReplaceAll(r.Host, ":3000", "")),
|
||||||
Data: page_data,
|
Data: page_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := Templates.ExecuteTemplate(w, template, data)
|
err := Templates.ExecuteTemplate(w, template, data)
|
||||||
|
|
72
web/pages/about/about.go
Normal file
72
web/pages/about/about.go
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package about
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"dofdev/tem"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
Name string
|
||||||
|
Url string
|
||||||
|
Icon string
|
||||||
|
}
|
||||||
|
type Profile struct {
|
||||||
|
Name string
|
||||||
|
Url string
|
||||||
|
Pfp string
|
||||||
|
}
|
||||||
|
type Peer struct {
|
||||||
|
Project Project
|
||||||
|
Profile Profile ``
|
||||||
|
}
|
||||||
|
|
||||||
|
var Peers = []Peer{
|
||||||
|
{
|
||||||
|
Project{
|
||||||
|
Name: "StereoKit",
|
||||||
|
Url: "https://stereokit.net",
|
||||||
|
Icon: "https://stereokit.net/img/StereoKitLogoLight.svg",
|
||||||
|
},
|
||||||
|
Profile{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Project{
|
||||||
|
Name: "Stardust XR",
|
||||||
|
Url: "https://stardustxr.org",
|
||||||
|
Icon: "https://stardustxr.org/img/icon.gif",
|
||||||
|
},
|
||||||
|
Profile{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Project{
|
||||||
|
Name: "Project Northstar",
|
||||||
|
Url: "https://www.projectnorthstar.org/",
|
||||||
|
Icon: "/public/img/icons/northstar.svg",
|
||||||
|
},
|
||||||
|
Profile{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Project{
|
||||||
|
Name: "Daemon XR",
|
||||||
|
Url: "https://daemonxr.com",
|
||||||
|
Icon: "/public/img/icons/daemonxr.png",
|
||||||
|
},
|
||||||
|
Profile{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := struct {
|
||||||
|
Peers []Peer
|
||||||
|
}{
|
||||||
|
Peers: Peers,
|
||||||
|
}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"about.html",
|
||||||
|
"dofdev",
|
||||||
|
"an effort to open higher degrees of spatial interaction free to the world.",
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package braillexr
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/spatialfree/dofdev/tem"
|
"dofdev/tem"
|
||||||
)
|
)
|
||||||
|
|
||||||
// func Handler(ctx *gin.Context) {
|
// func Handler(ctx *gin.Context) {
|
||||||
|
@ -14,7 +14,6 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
w, r,
|
w, r,
|
||||||
"braille_xr.html",
|
"braille_xr.html",
|
||||||
"braille_xr",
|
"braille_xr",
|
||||||
"braille_xr",
|
|
||||||
"refreshable braille display for rendering and input with handtracking",
|
"refreshable braille display for rendering and input with handtracking",
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
|
|
89
web/pages/games/games.go
Normal file
89
web/pages/games/games.go
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
package games
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"dofdev/tem"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Game struct {
|
||||||
|
Name string
|
||||||
|
Desc string
|
||||||
|
|
||||||
|
Notes string
|
||||||
|
}
|
||||||
|
|
||||||
|
var Games = map[string]Game{
|
||||||
|
"silo": {
|
||||||
|
Name: "stretch silo",
|
||||||
|
Desc: "a stretch cursor 360 missile defense game",
|
||||||
|
Notes: `start with air raid sirens
|
||||||
|
and shouted commands
|
||||||
|
shilouttes in the night
|
||||||
|
(fight or flight - adrenaline)
|
||||||
|
|
||||||
|
walk into futuristic vector battlestation
|
||||||
|
(step up buckle down)
|
||||||
|
|
||||||
|
overview of your silos and what you are protecting
|
||||||
|
missiles fly in
|
||||||
|
(take responsibility)
|
||||||
|
|
||||||
|
|
||||||
|
*ref typhon missile system`,
|
||||||
|
},
|
||||||
|
"snake": {
|
||||||
|
Name: "snake in a box",
|
||||||
|
Desc: "vr snake zencore",
|
||||||
|
Notes: `cute happy go lucky eating stuff
|
||||||
|
|
||||||
|
older and bigger
|
||||||
|
and have to deal with your past choices`,
|
||||||
|
},
|
||||||
|
"vien": {
|
||||||
|
Name: "vien",
|
||||||
|
Desc: "hordiculture",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := struct {
|
||||||
|
Games map[string]Game
|
||||||
|
}{
|
||||||
|
Games: Games,
|
||||||
|
}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"games.html",
|
||||||
|
"games",
|
||||||
|
"dof driven games",
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GameHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
hash := mux.Vars(r)["hash"]
|
||||||
|
|
||||||
|
game, ok := Games[hash]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := struct {
|
||||||
|
Hash string
|
||||||
|
Game Game
|
||||||
|
}{
|
||||||
|
Hash: hash,
|
||||||
|
Game: game,
|
||||||
|
}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"game.html",
|
||||||
|
game.Name,
|
||||||
|
game.Desc,
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
|
@ -3,48 +3,29 @@ package mono
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/spatialfree/dofdev/tem"
|
"dofdev/tem"
|
||||||
|
"dofdev/web/pages/games"
|
||||||
|
"dofdev/web/pages/moves"
|
||||||
|
"dofdev/web/pages/projects"
|
||||||
)
|
)
|
||||||
|
|
||||||
// func Handler(ctx *gin.Context) {
|
|
||||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
data := struct {
|
data := struct {
|
||||||
Projects []Project
|
TopHash string
|
||||||
|
Moves map[string]moves.Move
|
||||||
|
Games map[string]games.Game
|
||||||
|
Projects map[string]projects.Project
|
||||||
}{
|
}{
|
||||||
Projects,
|
TopHash: "silo",
|
||||||
|
Moves: moves.Moves,
|
||||||
|
Games: games.Games,
|
||||||
|
Projects: projects.Projects,
|
||||||
}
|
}
|
||||||
tem.Render(
|
tem.Render(
|
||||||
w, r,
|
w, r,
|
||||||
"mono.html",
|
"mono.html",
|
||||||
"",
|
|
||||||
"dofdev",
|
"dofdev",
|
||||||
"an effort to open higher degrees of spatial interaction free to the world.",
|
"an effort to open higher degrees of spatial interaction free to the world.",
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Project struct {
|
|
||||||
ID int
|
|
||||||
Title string
|
|
||||||
Description string
|
|
||||||
Art string
|
|
||||||
}
|
|
||||||
|
|
||||||
// This would ideally come from a database
|
|
||||||
var Projects = []Project{
|
|
||||||
{ID: 1,
|
|
||||||
Title: "Prompt-Train",
|
|
||||||
Description: "PromptTrain, the PromptWriting Excellence Engine, is here to help you enhance your writing skills and unleash your creativity. Receive valuable feedback on your prompts, compete in creative challenges, connect with a supportive community, and embark on your journey towards writing excellence.",
|
|
||||||
Art: "/res/projects/prompt-train.png",
|
|
||||||
},
|
|
||||||
{ID: 2,
|
|
||||||
Title: "Echo AI",
|
|
||||||
Description: "With EchoAI, creating AI personas is a breeze. Define your character's name, appearance, traits, speech patterns, emotional range, and background story. Submit website and training reference documents, and specify preferred topics and custom responses. EchoAI offers a user-friendly, step-by-step process to bring your Echo AI persona to life.",
|
|
||||||
Art: "/res/projects/echo-ai.png",
|
|
||||||
},
|
|
||||||
{ID: 3,
|
|
||||||
Title: "PromptScript",
|
|
||||||
Description: "PromptScript is a web based ai prompting language that allows you to orchestrate complex systematic patterns with large language models.",
|
|
||||||
Art: "/res/projects/promptscript.png",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
76
web/pages/moves/moves.go
Normal file
76
web/pages/moves/moves.go
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
package moves
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dofdev/tem"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Move struct {
|
||||||
|
Name string
|
||||||
|
Desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
var Moves = map[string]Move{
|
||||||
|
"color_cube": {
|
||||||
|
Name: "color_cube",
|
||||||
|
Desc: "color picker & indexer xyz >>> rgb",
|
||||||
|
},
|
||||||
|
"oriel": {
|
||||||
|
Name: "oriel",
|
||||||
|
Desc: "volumetric graphical control element",
|
||||||
|
},
|
||||||
|
"stretch_cursor": {
|
||||||
|
Name: "stretch_cursor",
|
||||||
|
Desc: "spatial control using hand distance",
|
||||||
|
},
|
||||||
|
"orbital_view": {
|
||||||
|
Name: "orbital_view",
|
||||||
|
Desc: "inversely viewed point of interest",
|
||||||
|
},
|
||||||
|
"fullstick": {
|
||||||
|
Name: "fullstick",
|
||||||
|
Desc: "joystick with full range of motion",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := struct {
|
||||||
|
Moves map[string]Move
|
||||||
|
}{
|
||||||
|
Moves: Moves,
|
||||||
|
}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"moves.html",
|
||||||
|
"moves",
|
||||||
|
"dof driven moves",
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MoveHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
hash := mux.Vars(r)["hash"]
|
||||||
|
|
||||||
|
move, ok := Moves[hash]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := struct {
|
||||||
|
Hash string
|
||||||
|
Move Move
|
||||||
|
}{
|
||||||
|
Hash: hash,
|
||||||
|
Move: move,
|
||||||
|
}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"move.html",
|
||||||
|
move.Name,
|
||||||
|
move.Desc,
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
62
web/pages/projects/projects.go
Normal file
62
web/pages/projects/projects.go
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
package projects
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dofdev/tem"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
Name string
|
||||||
|
Desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
var Projects = map[string]Project{
|
||||||
|
"braille_xr": {
|
||||||
|
Name: "braille_xr",
|
||||||
|
Desc: "refreshable braille display for rendering and input with handtracking",
|
||||||
|
},
|
||||||
|
"tungtap": {
|
||||||
|
Name: "tungtap",
|
||||||
|
Desc: "easily augment your system's keyboard",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := struct {
|
||||||
|
Projects map[string]Project
|
||||||
|
}{
|
||||||
|
Projects: Projects,
|
||||||
|
}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"projects.html",
|
||||||
|
"projects",
|
||||||
|
"dof driven projects",
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
hash := mux.Vars(r)["hash"]
|
||||||
|
|
||||||
|
project, ok := Projects[hash]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := struct {
|
||||||
|
Project Project
|
||||||
|
}{
|
||||||
|
Project: project,
|
||||||
|
}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"project.html",
|
||||||
|
project.Name,
|
||||||
|
project.Desc,
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
20
web/pages/sc/sc.go
Normal file
20
web/pages/sc/sc.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package sc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"dofdev/tem"
|
||||||
|
)
|
||||||
|
|
||||||
|
// func Handler(ctx *gin.Context) {
|
||||||
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := struct {
|
||||||
|
}{}
|
||||||
|
tem.Render(
|
||||||
|
w, r,
|
||||||
|
"sc.html",
|
||||||
|
"sc",
|
||||||
|
"spatial computing vs paper computing",
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
}
|
BIN
web/public/img/dofdev_logo.svg
(Stored with Git LFS)
BIN
web/public/img/dofdev_logo.svg
(Stored with Git LFS)
Binary file not shown.
BIN
web/public/img/icons/community.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/community.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/daemonxr.png
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/daemonxr.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/discord.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/discord.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/dofs.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/dofs.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/games.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/games.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/home.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/home.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/menu.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/menu.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/placeholder.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/placeholder.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/projects.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/projects.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/search.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/search.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/icons/settings.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/icons/settings.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
web/public/img/logo.svg
(Stored with Git LFS)
BIN
web/public/img/logo.svg
(Stored with Git LFS)
Binary file not shown.
BIN
web/public/img/spatial.svg
(Stored with Git LFS)
Normal file
BIN
web/public/img/spatial.svg
(Stored with Git LFS)
Normal file
Binary file not shown.
84
web/public/js/mono.js
Normal file
84
web/public/js/mono.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
elbyid = (id) => document.getElementById(id);
|
||||||
|
clamp = (num, min, max) => Math.min(Math.max(num, min), max);
|
||||||
|
clamp01 = (num) => clamp(num, 0, 1);
|
||||||
|
sign = (num) => (num === 0 ? 0 : num > 0 ? 1 : -1);
|
||||||
|
within = (num, min, max) => num >= min && num <= max;
|
||||||
|
lerp = (a, b, t) => a + t * (b - a);
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
let side_open = localStorage.getItem("side_open") ? true : false;
|
||||||
|
|
||||||
|
const nav_el = elbyid("nav");
|
||||||
|
const nav_border_el = elbyid("nav_border");
|
||||||
|
const nav_side_el = elbyid("nav_side");
|
||||||
|
const side_el = elbyid("side");
|
||||||
|
const side_border_el = elbyid("side_border");
|
||||||
|
const main_el = elbyid("main");
|
||||||
|
const top_img_el = elbyid("top_img");
|
||||||
|
|
||||||
|
nav_fade = () => {
|
||||||
|
if (window.scrollY == 0) {
|
||||||
|
if (!side_open) {
|
||||||
|
side_el.style.backgroundColor = side_border_el.style.backgroundColor =
|
||||||
|
"#80808000";
|
||||||
|
} else {
|
||||||
|
side_el.style.backgroundColor = "#808080FF";
|
||||||
|
side_border_el.style.backgroundColor = "#777777FF";
|
||||||
|
}
|
||||||
|
|
||||||
|
nav_el.style.backgroundColor = nav_border_el.style.backgroundColor =
|
||||||
|
"#80808000";
|
||||||
|
} else {
|
||||||
|
nav_el.style.backgroundColor = side_el.style.backgroundColor =
|
||||||
|
"#808080FF";
|
||||||
|
nav_border_el.style.backgroundColor =
|
||||||
|
side_border_el.style.backgroundColor = "#777777FF";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
nav_fade();
|
||||||
|
nav_el.style.transition =
|
||||||
|
nav_border_el.style.transition =
|
||||||
|
side_el.style.transition =
|
||||||
|
side_border_el.style.transition =
|
||||||
|
"background-color 0.166s";
|
||||||
|
|
||||||
|
window.addEventListener("scroll", (event) => {
|
||||||
|
nav_fade();
|
||||||
|
});
|
||||||
|
|
||||||
|
open_side = () => {
|
||||||
|
side_open = true;
|
||||||
|
localStorage.setItem("side_open", "open");
|
||||||
|
|
||||||
|
nav_side_el.style.width = "240px";
|
||||||
|
side_el.style.width = "240px";
|
||||||
|
side_el.classList.add("open");
|
||||||
|
side_border_el.style.left = "240px";
|
||||||
|
main_el.style.paddingLeft = "240px";
|
||||||
|
};
|
||||||
|
close_side = () => {
|
||||||
|
side_open = false;
|
||||||
|
localStorage.removeItem("side_open");
|
||||||
|
|
||||||
|
nav_side_el.style.width = "auto";
|
||||||
|
side_el.style.width = "64px";
|
||||||
|
side_el.classList.remove("open");
|
||||||
|
side_border_el.style.left = "64px";
|
||||||
|
main_el.style.paddingLeft = "64px";
|
||||||
|
};
|
||||||
|
update_side = () => {
|
||||||
|
if (side_open) {
|
||||||
|
open_side();
|
||||||
|
} else {
|
||||||
|
close_side();
|
||||||
|
}
|
||||||
|
nav_fade();
|
||||||
|
};
|
||||||
|
update_side();
|
||||||
|
toggle_side = () => {
|
||||||
|
side_open = !side_open;
|
||||||
|
update_side();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("load", () => {});
|
|
@ -1,45 +1,242 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible&display=swap');
|
@font-face {
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap');
|
font-family: "mono";
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Nanum+Myeongjo&display=swap');
|
src: url("/public/fonts/HurmitNerdFontMono-Regular.otf");
|
||||||
html {
|
font-weight: normal;
|
||||||
height: 100dvh;
|
font-style: normal;
|
||||||
margin: 0 auto;
|
font-display: swap;
|
||||||
max-width: 600px;
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "mono";
|
||||||
|
src: url("/public/fonts/HurmitNerdFontMono-Italic.otf");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "mono";
|
||||||
|
src: url("/public/fonts/HurmitNerdFontMono-Bold.otf");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "legible";
|
||||||
|
src: url("/public/fonts/AtkinsonHyperlegible-Regular.ttf");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "brand";
|
||||||
|
src: url("/public/fonts/HelveticaNeueMedium.otf");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--col-11: #fff;
|
||||||
|
--col-10: #eee;
|
||||||
|
--col-06: #999;
|
||||||
|
--col-05: #808080;
|
||||||
|
--col-04: #777;
|
||||||
|
--col-01: #111;
|
||||||
|
--col-00: #000;
|
||||||
}
|
}
|
||||||
* {
|
* {
|
||||||
|
all: unset;
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
text-wrap: balance;
|
font-family: "mono", monospace;
|
||||||
font-family: 'Atkinson Hyperlegible', sans-serif;
|
font-size: 14px;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
|
text-wrap: balance;
|
||||||
|
color: var(--col-01);
|
||||||
}
|
}
|
||||||
title, style, script {
|
*::-webkit-scrollbar {
|
||||||
|
background-color: #80808000;
|
||||||
|
width: 5px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
*::placeholder {
|
||||||
|
color: var(--col-06);
|
||||||
|
}
|
||||||
|
title,
|
||||||
|
style,
|
||||||
|
script {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
html {
|
||||||
|
background-color: var(--col-05);
|
||||||
|
height: 100dvh;
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
height: 100dvh;
|
height: 100dvh;
|
||||||
margin: 0 auto; padding: 0;
|
|
||||||
line-height: 1.5;
|
|
||||||
background-color: #808080;
|
|
||||||
color: #000;
|
|
||||||
}
|
}
|
||||||
main {
|
#nav {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 6px 12px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #80808000;
|
||||||
|
z-index: 5;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
#nav_border {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 42px;
|
||||||
|
height: 2px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
#side {
|
||||||
|
background-color: #80808000;
|
||||||
|
z-index: 4;
|
||||||
|
width: auto;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 6px;
|
||||||
|
padding-top: calc(44px + 6px);
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 6px;
|
||||||
|
> div > a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
/* background-color: #11111166; */
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 6px;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
flex-flow: column;
|
||||||
|
width: 52px;
|
||||||
|
gap: 0px;
|
||||||
|
font-family: "legible";
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--col-10);
|
||||||
|
|
||||||
|
> img {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> a.onpage {
|
||||||
|
background-color: #11111166;
|
||||||
|
}
|
||||||
|
> #support {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
> #foot {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#side a:hover {
|
||||||
|
background-color: #11111166;
|
||||||
|
transition: 0.166s;
|
||||||
|
}
|
||||||
|
#side.open {
|
||||||
|
> div > a {
|
||||||
|
flex-flow: row;
|
||||||
|
width: auto;
|
||||||
|
gap: 12px;
|
||||||
|
font-family: "mono";
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--col-01);
|
||||||
|
}
|
||||||
|
> #support {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
> #foot {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#side_border {
|
||||||
|
z-index: 4;
|
||||||
|
width: 2px;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100vh;
|
||||||
|
transform: translateX(-2px);
|
||||||
|
}
|
||||||
|
#main {
|
||||||
height: 100dvh;
|
height: 100dvh;
|
||||||
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
/* padding-top: 64px; */
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
/* max-width: 1024px; */
|
||||||
|
padding-left: 58px;
|
||||||
}
|
}
|
||||||
h1, h2 {
|
#top_img {
|
||||||
letter-spacing: 2px;
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 100vh;
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
color: #fff;
|
font-family: "mono";
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 64px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 12px 6px;
|
||||||
|
color: var(--col-10);
|
||||||
|
text-shadow: 1px 1px 1px var(--col-05);
|
||||||
|
|
||||||
|
> p {
|
||||||
|
font-family: "legible";
|
||||||
|
font-size: 16px;
|
||||||
|
text-shadow: none;
|
||||||
|
color: var(--col-01);
|
||||||
|
background-color: #ffffff80;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
min-height: 28px;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 420px;
|
||||||
|
margin: 6px auto;
|
||||||
|
padding: 12px 21px;
|
||||||
|
line-height: 22px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a, b, i, code, span {
|
h2 {
|
||||||
|
font-family: "mono";
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 32px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 12px 6px;
|
||||||
|
color: var(--col-10);
|
||||||
|
}
|
||||||
|
div,
|
||||||
|
input {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
i,
|
||||||
|
code,
|
||||||
|
span {
|
||||||
display: inline;
|
display: inline;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
|
@ -52,12 +249,19 @@ a {
|
||||||
a:focus {
|
a:focus {
|
||||||
filter: brightness(1.333);
|
filter: brightness(1.333);
|
||||||
}
|
}
|
||||||
b { font-weight: bold; }
|
b {
|
||||||
i { font-style: italic; }
|
font-weight: bold;
|
||||||
code {
|
}
|
||||||
font-family: 'DM Mono', monospace;
|
i {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
font-family: "DM Mono", monospace;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #0000FF;
|
color: #0000ff;
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
all: revert;
|
all: revert;
|
||||||
|
@ -68,38 +272,21 @@ ul {
|
||||||
li {
|
li {
|
||||||
all: revert;
|
all: revert;
|
||||||
}
|
}
|
||||||
img, video, canvas {
|
img,
|
||||||
|
video,
|
||||||
|
canvas {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
all: revert-layer;
|
all: revert-layer;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
border-radius: 6px;
|
|
||||||
}
|
}
|
||||||
video {
|
/* keep this at the end */
|
||||||
border-radius: 6px;
|
.disabled {
|
||||||
}
|
filter: grayscale(100%);
|
||||||
.t_symbol {
|
opacity: 0.666;
|
||||||
margin: 2rem auto;
|
cursor: not-allowed;
|
||||||
font-family: "Nanum Myeongjo", serif;
|
pointer-events: none;
|
||||||
text-align: center;
|
user-select: none;
|
||||||
font-size: 64px;
|
|
||||||
/* font-weight: bold; */
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
footer {
|
|
||||||
margin-top: 128px;
|
|
||||||
height: 64px;
|
|
||||||
line-height: 64px;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
font-size: 0.75em;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
outline: none;
|
|
||||||
border: none;
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: 32px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue