New login page, with the option to go back by adding ?basic to the URL

This commit is contained in:
Cameron Reed 2024-10-01 12:30:33 -06:00
parent 036d3ade92
commit 98d973af6c
8 changed files with 203 additions and 72 deletions

View File

@ -14,7 +14,7 @@ func Login(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Location", "/")
w.WriteHeader(http.StatusSeeOther)
} else {
templates.LoginPage().Render(r.Context(), w)
templates.LoginPage(r.URL.Query().Has("basic")).Render(r.Context(), w)
}
return
}
@ -53,7 +53,7 @@ func CreateAccount(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Location", "/")
w.WriteHeader(http.StatusSeeOther)
} else {
templates.CreateAccountBox().Render(r.Context(), w)
templates.CreateAccountBox(false).Render(r.Context(), w)
}
return
}

View File

@ -14,5 +14,5 @@ func RootPage(w http.ResponseWriter, r *http.Request) {
return
}
templates.RootPage(username).Render(r.Context(), w)
templates.RootPage(username, false).Render(r.Context(), w)
}

View File

@ -1,6 +1,6 @@
package templates
templ loginSkeleton() {
templ loginSkeleton(basic_css bool) {
<!Doctype HTML>
<html lang="en-US">
<head>
@ -8,7 +8,11 @@ templ loginSkeleton() {
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/css/login.css"/>
if basic_css {
<link rel="stylesheet" href="/css/login_basic.css"/>
} else {
<link rel="stylesheet" href="/css/login.css"/>
}
<script src="/js/login.js"></script>
<script src="/js/lib/htmx.min.js"></script>
@ -20,32 +24,34 @@ templ loginSkeleton() {
</html>
}
templ LoginPage() {
@loginSkeleton() {
templ LoginPage(basic_css bool) {
@loginSkeleton(basic_css) {
<form id="login-box" hx-post="/login" hx-swap="none">
<h1>Login</h1>
<h1>Welcome</h1>
<div>
<label for="username">Username</label><br/>
<input id="username" name="username" type="text" required/>
<div class="credentials-wrapper">
<label for="username">Username</label>
<input id="username" class="credentials" name="username" type="text" placeholder="Username" required/>
<div style="margin: 20px"></div>
<div class="gap"></div>
<label for="password">Password</label><br/>
<input id="password" name="password" type="password" required/>
<label for="password">Password</label>
<input id="password" class="credentials" name="password" type="password" placeholder="Password" required/>
<label for="stay-logged-in">Keep me logged in</label>
<input id="stay-logged-in" name="stay-logged-in" type="checkbox"/><br/>
<div>
<label class="normal-text" for="stay-logged-in">Keep me logged in</label>
<input id="stay-logged-in" name="stay-logged-in" type="checkbox"/>
</div>
<button type="submit">Log in</button>
<a href="/create-account">Create Account</a>
<button type="submit" class="login-btn">Log in</button>
<a href="/create-account">No Account? Create one!</a>
</div>
</form>
}
}
templ CreateAccountBox() {
@loginSkeleton() {
templ CreateAccountBox(basic_css bool) {
@loginSkeleton(basic_css) {
<form id="login-box" hx-post="/create-account">
<h1>Create Account</h1>

View File

@ -8,7 +8,7 @@ package templates
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
func loginSkeleton() templ.Component {
func loginSkeleton(basic_css bool) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
@ -26,7 +26,22 @@ func loginSkeleton() templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype HTML><html lang=\"en-US\"><head><title>Todo login</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><link rel=\"stylesheet\" href=\"/css/login.css\"><script src=\"/js/login.js\"></script><script src=\"/js/lib/htmx.min.js\"></script></head><body>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype HTML><html lang=\"en-US\"><head><title>Todo login</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if basic_css {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"/css/login_basic.css\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"/css/login.css\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script src=\"/js/login.js\"></script><script src=\"/js/lib/htmx.min.js\"></script></head><body>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -42,7 +57,7 @@ func loginSkeleton() templ.Component {
})
}
func LoginPage() templ.Component {
func LoginPage(basic_css bool) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
@ -72,13 +87,13 @@ func LoginPage() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form id=\"login-box\" hx-post=\"/login\" hx-swap=\"none\"><h1>Login</h1><div><label for=\"username\">Username</label><br><input id=\"username\" name=\"username\" type=\"text\" required><div style=\"margin: 20px\"></div><label for=\"password\">Password</label><br><input id=\"password\" name=\"password\" type=\"password\" required> <label for=\"stay-logged-in\">Keep me logged in</label> <input id=\"stay-logged-in\" name=\"stay-logged-in\" type=\"checkbox\"><br><button type=\"submit\">Log in</button> <a href=\"/create-account\">Create Account</a></div></form>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form id=\"login-box\" hx-post=\"/login\" hx-swap=\"none\"><h1>Welcome</h1><div class=\"credentials-wrapper\"><label for=\"username\">Username</label> <input id=\"username\" class=\"credentials\" name=\"username\" type=\"text\" placeholder=\"Username\" required><div class=\"gap\"></div><label for=\"password\">Password</label> <input id=\"password\" class=\"credentials\" name=\"password\" type=\"password\" placeholder=\"Password\" required><div><label class=\"normal-text\" for=\"stay-logged-in\">Keep me logged in</label> <input id=\"stay-logged-in\" name=\"stay-logged-in\" type=\"checkbox\"></div><button type=\"submit\" class=\"login-btn\">Log in</button> <a href=\"/create-account\">No Account? Create one!</a></div></form>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = loginSkeleton().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
templ_7745c5c3_Err = loginSkeleton(basic_css).Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -86,7 +101,7 @@ func LoginPage() templ.Component {
})
}
func CreateAccountBox() templ.Component {
func CreateAccountBox(basic_css bool) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
@ -122,7 +137,7 @@ func CreateAccountBox() templ.Component {
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = loginSkeleton().Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
templ_7745c5c3_Err = loginSkeleton(basic_css).Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@ -6,7 +6,7 @@ import (
"github.com/Cameron-Reed1/todo-web/types"
)
templ RootPage(username string) {
templ RootPage(username string, basic_css bool) {
<!Doctype HTML>
<html lang="en-US" data-show-completed="false">
<head>
@ -14,7 +14,11 @@ templ RootPage(username string) {
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/css/styles.css"/>
if basic_css {
<link rel="stylesheet" href="/css/basic.css"/>
} else {
<link rel="stylesheet" href="/css/styles.css"/>
}
<script src="/js/script.js"></script>
<script src="/js/lib/htmx.min.js"></script>

View File

@ -14,7 +14,7 @@ import (
"github.com/Cameron-Reed1/todo-web/types"
)
func RootPage(username string) templ.Component {
func RootPage(username string, basic_css bool) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
@ -32,14 +32,29 @@ func RootPage(username string) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype HTML><html lang=\"en-US\" data-show-completed=\"false\"><head><title>Todo</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><link rel=\"stylesheet\" href=\"/css/styles.css\"><script src=\"/js/script.js\"></script><script src=\"/js/lib/htmx.min.js\"></script><!-- Font Awesome --><script src=\"https://kit.fontawesome.com/469cdddb31.js\" crossorigin=\"anonymous\"></script></head><body><nav><div id=\"nav-container\"><div id=\"nav-left\" class=\"nav-section\"><a id=\"new-button\" class=\"focus-highlight\" href=\"#create-item\">New</a></div><div id=\"nav-center\" class=\"nav-section\"></div><div id=\"nav-right\" class=\"nav-section\"><div><label for=\"show-completed\">Show completed</label> <input id=\"show-completed\" type=\"checkbox\" name=\"show-completed\"></div><div id=\"profile\"><div id=\"profile-icon\" class=\"focus-highlight\"><i class=\"fa-solid fa-user\"></i> <i class=\"fa-solid fa-caret-down\"></i></div><div id=\"profile-dropdown\"><div id=\"profile-name\" class=\"focus-highlight\">")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype HTML><html lang=\"en-US\" data-show-completed=\"false\"><head><title>Todo</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if basic_css {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"/css/basic.css\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"/css/styles.css\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script src=\"/js/script.js\"></script><script src=\"/js/lib/htmx.min.js\"></script><!-- Font Awesome --><script src=\"https://kit.fontawesome.com/469cdddb31.js\" crossorigin=\"anonymous\"></script></head><body><nav><div id=\"nav-container\"><div id=\"nav-left\" class=\"nav-section\"><a id=\"new-button\" class=\"focus-highlight\" href=\"#create-item\">New</a></div><div id=\"nav-center\" class=\"nav-section\"></div><div id=\"nav-right\" class=\"nav-section\"><div><label for=\"show-completed\">Show completed</label> <input id=\"show-completed\" type=\"checkbox\" name=\"show-completed\"></div><div id=\"profile\"><div id=\"profile-icon\" class=\"focus-highlight\"><i class=\"fa-solid fa-user\"></i> <i class=\"fa-solid fa-caret-down\"></i></div><div id=\"profile-dropdown\"><div id=\"profile-name\" class=\"focus-highlight\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(username)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 44, Col: 85}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 48, Col: 85}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@ -88,7 +103,7 @@ func TodoItem(item types.Todo) templ.Component {
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("item-%d", item.Id))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 128, Col: 45}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 132, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
@ -101,7 +116,7 @@ func TodoItem(item types.Todo) templ.Component {
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", item.Id))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 128, Col: 105}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 132, Col: 105}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
@ -114,7 +129,7 @@ func TodoItem(item types.Todo) templ.Component {
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", item.Start))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 128, Col: 150}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 132, Col: 150}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
@ -127,7 +142,7 @@ func TodoItem(item types.Todo) templ.Component {
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", item.Due))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 128, Col: 191}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 132, Col: 191}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@ -150,7 +165,7 @@ func TodoItem(item types.Todo) templ.Component {
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(string(templ.URL(fmt.Sprintf("/set/%d", item.Id))))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 129, Col: 137}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 133, Col: 137}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
@ -163,7 +178,7 @@ func TodoItem(item types.Todo) templ.Component {
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(item.Text)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 130, Col: 42}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 134, Col: 42}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
@ -176,7 +191,7 @@ func TodoItem(item types.Todo) templ.Component {
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/delete/%d", item.Id))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 133, Col: 101}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 137, Col: 101}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
@ -215,7 +230,7 @@ func OobTodoItem(targetSelector string, item types.Todo) templ.Component {
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s:%s", "afterend", targetSelector))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 139, Col: 71}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 143, Col: 71}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
@ -262,7 +277,7 @@ func TodoList(fillerText string, items []types.Todo) templ.Component {
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(items)))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 145, Col: 80}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 149, Col: 80}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
@ -275,7 +290,7 @@ func TodoList(fillerText string, items []types.Todo) templ.Component {
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fillerText)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 146, Col: 45}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/templates/root.templ`, Line: 150, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {

View File

@ -9,48 +9,75 @@ body {
align-items: center;
font-family: sans-serif;
background-image: url(/img/login.jpg);
background-size: cover;
background-position: center;
}
#login-box {
padding: 0 10px;
width: 275px;
height: min(calc(100lvh - 110px), 450px);
border: 4px solid black;
border-radius: 12px;
backdrop-filter: blur(10px);
border: none;
border-radius: 25px;
background-color: #27272750;
padding: 25px;
width: 750px;
height: 500px;
box-shadow: 0px 10px 50px 2px rgba(0,0,0,0.95);
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
label {
margin-left: 4px;
h1 {
text-align: center;
color: white;
}
a {
display: block;
font-size: .85rem;
}
p, a, .normal-text {
color: white;
text-decoration: none;
}
.credentials {
border: none;
padding: 10px;
border-radius: 10px;
margin: 20px;
background-color: #27272750;
color: white;
}
.login-btn {
padding: 10px 20px;
text-decoration: none;
border-radius: 6px;
font-size: 1rem;
cursor: pointer;
margin: 35px 0 25px 0;
background-color: green;
color: white;
border: none;
}
.credentials-wrapper {
display: grid;
justify-items: center;
}
.credentials-wrapper > label {
display: none;
}
input[type="text"],
input[type="password"] {
width: 267px;
}
button {
padding: 10px 20px;
text-decoration: none;
border: 2px solid;
border-radius: 6px;
box-shadow: black 2px 2px 3px 0;
background-color: white;
font-size: 1rem;
cursor: pointer;
margin: 35px 0 25px 0;
color: blue;
}
a {
display: block;
font-size: .85rem;
text-decoration: none;
}
h1 {
text-align: center;
}

View File

@ -0,0 +1,64 @@
body {
margin: 0;
padding: 0;
height: 100vh;
height: 100lvh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-family: sans-serif;
}
#login-box {
padding: 0 10px;
width: 275px;
height: min(calc(100lvh - 110px), 450px);
border: 4px solid black;
border-radius: 12px;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
label {
margin-left: 4px;
}
input[type="text"],
input[type="password"] {
width: 267px;
}
input::placeholder {
color: transparent;
}
button {
padding: 10px 20px;
text-decoration: none;
border: 2px solid;
border-radius: 6px;
box-shadow: black 2px 2px 3px 0;
background-color: white;
font-size: 1rem;
cursor: pointer;
margin: 35px 0 25px 0;
color: blue;
}
a {
display: block;
font-size: .85rem;
text-decoration: none;
}
h1 {
text-align: center;
}
.gap {
height: 20px;
}