consistent and better styling

This commit is contained in:
Zoe
2025-09-29 15:59:31 +00:00
parent 83512c3584
commit 8c9ad40776
6 changed files with 154 additions and 54 deletions

View File

@@ -1,5 +1,24 @@
@import "tailwindcss"; @import "tailwindcss";
@theme {
--color-accent: oklch(57.93% 0.258 294.12);
--color-success: oklch(70.19% 0.158 160.44);
--color-error: oklch(63.43% 0.251 28.48);
--color-base: oklch(11% .007 285);
--color-surface: oklch(19% 0.007 314.66);
--color-overlay: oklch(26% 0.008 314.66);
--color-muted: oklch(63% 0.015 286);
--color-subtle: oklch(72% 0.015 286);
--color-text: oklch(87% 0.015 286);
--color-highlight-sm: oklch(30.67% 0.007 286);
--color-highlight: oklch(39.26% 0.010 286);
--color-highlight-lg: oklch(47.72% 0.011 286);
}
@font-face { @font-face {
font-family: "Instrument Sans"; font-family: "Instrument Sans";
src: url("/assets/fonts/InstrumentSans-VariableFont_wdth,wght.woff2") format("woff2"); src: url("/assets/fonts/InstrumentSans-VariableFont_wdth,wght.woff2") format("woff2");
@@ -13,6 +32,7 @@
html { html {
line-height: normal; line-height: normal;
color-scheme: dark; color-scheme: dark;
color: var(--color-text);
} }
h1, h1,
@@ -36,14 +56,72 @@ h3 {
font-size: 1.25rem; font-size: 1.25rem;
} }
button {
cursor: pointer;
}
input:not(.search) { input:not(.search) {
@apply px-4 py-2 rounded-md w-full bg-[#1C1C21] border border-[#2E2E32] placeholder:text-[#8A8E90] text-white focus-visible:outline-none transition-colors duration-300 ease-out overflow-hidden; @apply px-4 py-2 rounded-md w-full bg-surface border border-highlight-sm/70 placeholder:text-highlight text-text focus-visible:outline-none transition-colors duration-300 ease-out overflow-hidden;
&[type="file"] { &[type="file"] {
@apply p-0 cursor-pointer; @apply p-0 cursor-pointer;
&::file-selector-button { &::file-selector-button {
@apply px-2 py-2 mr-1 bg-[hsl(240,6%,18%)] text-white cursor-pointer; @apply px-2 py-2 mr-1 bg-highlight text-subtle cursor-pointer;
} }
} }
}
.link-card {
background: var(--color-overlay);
display: flex;
flex-direction: row;
text-decoration: none;
border-radius: 1rem;
padding: 0.625rem;
align-items: center;
transition-property: box-shadow, transform, translate;
transition-duration: 150ms;
transition-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
&:hover {
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
transform: translateY(-4px);
}
&:active {
box-shadow: 0 2px 4px -2px rgb(0 0 0 / 0.1);
transform: translateY(2px);
}
}
@media (prefers-reduced-motion: reduce) {
.link-card {
transition: none;
&:hover {
transform: none;
}
&:active {
transform: none;
}
}
}
.link-card img {
margin-right: 0.5rem;
user-select: none;
border-radius: 0.375rem;
aspect-ratio: 1/1;
object-fit: cover;
}
.link-card div {
word-break: break-all;
}
.link-card div p {
color: var(--color-subtle);
} }

View File

@@ -9,7 +9,7 @@
<style>{{{inlineCSS}}}</style> <style>{{{inlineCSS}}}</style>
</head> </head>
<body class="bg-[#151316] text-white"> <body class="bg-surface text-text">
{{embed}} {{embed}}
</body> </body>
{{{devContent}}} {{{devContent}}}

View File

@@ -1,4 +1,5 @@
<div id="blur-target" class="transition-[filter] ease-[cubic-bezier(0.45,0,0.55,1)] duration-300"> <div id="blur-target"
class="transition-[filter] motion-reduce:transition-none ease-[cubic-bezier(0.45,0,0.55,1)] duration-300">
<header class="flex w-full p-3"> <header class="flex w-full p-3">
<a href="/" <a href="/"
class="flex items-center flex-row gap-2 text-white border-b hover:border-transparent justify-center"> class="flex items-center flex-row gap-2 text-white border-b hover:border-transparent justify-center">
@@ -21,7 +22,7 @@
alt="{{this.Name}}" src="{{this.Icon}}" /> alt="{{this.Name}}" src="{{this.Icon}}" />
<h2 class="capitalize break-all">{{this.Name}}</h2> <h2 class="capitalize break-all">{{this.Name}}</h2>
<button onclick="deleteCategory({{this.ID}})" <button onclick="deleteCategory({{this.ID}})"
class="w-fit h-fit flex p-0.5 bg-[#1C1C21] border-solid border-[#211F23] rounded-md hover:bg-[#29292e] cursor-pointer"><svg class="w-fit h-fit flex p-0.5 bg-base border border-highlight rounded-md hover:filter hover:brightness-125 cursor-pointer"><svg
xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"> xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">
<path fill="none" stroke="#ff1919" stroke-linecap="round" stroke-linejoin="round" <path fill="none" stroke="#ff1919" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" stroke-width="2"
@@ -30,16 +31,14 @@
</div> </div>
<div class="p-2.5 grid grid-cols-[repeat(auto-fill,_minmax(min(330px,_100%),_1fr))] gap-2"> <div class="p-2.5 grid grid-cols-[repeat(auto-fill,_minmax(min(330px,_100%),_1fr))] gap-2">
{{#each this.Links}} {{#each this.Links}}
<div key="link-{{this.ID}}" <div key="link-{{this.ID}}" class="link-card relative">
class="rounded-2xl bg-[#211F23] p-2.5 flex flex-row items-center shadow-md hover:shadow-xl transition-[shadow,transform,translate] ease-[cubic-bezier(0.16,1,0.3,1)] hover:-translate-y-1 relative"> <img width="64" height="64" draggable="false" src="{{this.Icon}}" alt="{{this.Name}}" />
<img class="mr-2 select-none rounded-md aspect-square object-cover" width="64" height="64" <div>
draggable="false" src="{{this.Icon}}" alt="{{this.Name}}" />
<div class="break-all">
<h3>{{this.Name}}</h3> <h3>{{this.Name}}</h3>
<p class="text-[#D7D7D7]">{{this.Description}}</p> <p>{{this.Description}}</p>
</div> </div>
<button onclick="deleteLink({{this.ID}}, {{this.CategoryID}})" <button onclick="deleteLink({{this.ID}}, {{this.CategoryID}})"
class="w-fit h-fit flex p-0.5 bg-[#1C1C21] border-solid border-[#211F23] rounded-md hover:bg-[#29292e] cursor-pointer absolute right-1 top-1"><svg class="w-fit h-fit flex p-0.5 bg-base border border-highlight/70 rounded-md hover:filter hover:brightness-125 cursor-pointer absolute right-1 top-1"><svg
xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"> xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">
<path fill="none" stroke="#ff1919" stroke-linecap="round" stroke-linejoin="round" <path fill="none" stroke="#ff1919" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" stroke-width="2"
@@ -48,7 +47,7 @@
</div> </div>
{{/each}} {{/each}}
<div onclick="openModal('link', {{this.ID}})" <div onclick="openModal('link', {{this.ID}})"
class="rounded-2xl border border-dashed border-[#656565] p-2.5 flex flex-row items-center shadow-md hover:shadow-xl transition-[shadow,transform] ease-[cubic-bezier(0.16,1,0.3,1)] pointer-cursor select-none cursor-pointer"> class="rounded-2xl border border-dashed border-subtle p-2.5 flex flex-row items-center hover:underline transition-[box-shadow,transform] ease-[cubic-bezier(0.45,0,0.55,1)] duration-150 pointer-cursor select-none cursor-pointer">
<svg class="mr-2" xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24"> <svg class="mr-2" xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="M12 5v14m-7-7h14" /> stroke-width="2" d="M12 5v14m-7-7h14" />
@@ -64,7 +63,7 @@
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="M12 5v14m-7-7h14" /> stroke-width="2" d="M12 5v14m-7-7h14" />
</svg> </svg>
<h2 onclick="openModal('category')" class="text-[#656565] underline decoration-dashed cursor-pointer"> <h2 onclick="openModal('category')" class="text-subtle underline decoration-dashed cursor-pointer">
Add a new category Add a new category
</h2> </h2>
</div> </div>
@@ -73,8 +72,8 @@
</div> </div>
<div id="modal-container" <div id="modal-container"
class="flex modal-bg fixed top-0 left-0 bottom-0 right-0 bg-[#00000070] justify-center items-center"> class="flex modal-bg fixed top-0 left-0 bottom-0 right-0 bg-black/45 justify-center items-center">
<div class="bg-[#151316] rounded-xl overflow-hidden w-fit p-4 modal"> <div class="bg-overlay rounded-xl overflow-hidden w-full p-4 modal max-w-sm">
<div id="category-contents" class="hidden"> <div id="category-contents" class="hidden">
<h3>Create A category</h3> <h3>Create A category</h3>
<form id="category-form" action="/api/categories" method="post" <form id="category-form" action="/api/categories" method="post"
@@ -87,7 +86,7 @@
<label for="linkIcon">Icon</label> <label for="linkIcon">Icon</label>
<input type="file" name="icon" id="linkIcon" accept=".svg" required /> <input type="file" name="icon" id="linkIcon" accept=".svg" required />
</div> </div>
<button class="px-4 py-2 rounded-md w-full bg-[#8A42FF] text-white border-0" type="submit">Create <button class="px-4 py-2 rounded-md w-full bg-accent text-white border-0" type="submit">Create
category</button> category</button>
</form> </form>
<span id="category-message"></span> <span id="category-message"></span>
@@ -113,7 +112,7 @@
<label for="linkIcon">Icon</label> <label for="linkIcon">Icon</label>
<input required type="file" name="icon" id="linkIcon" accept="image/*" /> <input required type="file" name="icon" id="linkIcon" accept="image/*" />
</div> </div>
<button class="px-4 py-2 rounded-md w-full bg-[#8A42FF] text-white border-0" type="submit">Add <button class="px-4 py-2 rounded-md w-full bg-accent text-white border-0" type="submit">Add
link</button> link</button>
</form> </form>
<span id="link-message"></span> <span id="link-message"></span>
@@ -245,28 +244,49 @@
.modal-bg { .modal-bg {
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease, visibility 0s 0.3s;
transition-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
} }
.modal-bg.is-visible { .modal-bg.is-visible {
visibility: visible; visibility: visible;
opacity: 1; opacity: 1;
transition-delay: 0s;
} }
.modal { .modal {
opacity: 0; opacity: 0;
transform: translateY(20px) scale(0.95);
transition: opacity 0.3s ease, transform 0.3s ease;
transition-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
} }
.modal.is-visible { .modal.is-visible {
opacity: 1; opacity: 1;
visibility: visible; }
transform: translateY(0) scale(1);
transition-delay: 0s; @media (prefers-reduced-motion: no-preference) {
.modal-bg {
visibility: hidden;
opacity: 0;
transition: opacity 0.3s ease, visibility 0s 0.3s;
transition-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
}
.modal-bg.is-visible {
visibility: visible;
opacity: 1;
transition-delay: 0s;
}
.modal {
opacity: 0;
transform: translateY(20px) scale(0.95);
transition: opacity 0.3s ease, transform 0.3s ease;
transition-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
}
.modal.is-visible {
opacity: 1;
visibility: visible;
transform: translateY(0) scale(1);
transition-delay: 0s;
}
} }
</style> </style>

View File

@@ -1,5 +1,5 @@
<main class="flex justify-center items-center h-screen relative bg-[#0E0A0E]"> <main class="flex justify-center items-center h-screen relative bg-base">
<div class="flex bg-[#151316] rounded-xl overflow-hidden"> <div class="flex bg-surface rounded-xl overflow-hidden">
<img src="/assets/leaves.webp" class="h-96 w-64 object-cover" /> <img src="/assets/leaves.webp" class="h-96 w-64 object-cover" />
<div class="flex flex-col p-4 text-center"> <div class="flex flex-col p-4 text-center">
<h2 class="text-2xl"> <h2 class="text-2xl">
@@ -8,8 +8,7 @@
<form action="/admin/login" method="post" class="flex flex-col gap-y-3 my-2"> <form action="/admin/login" method="post" class="flex flex-col gap-y-3 my-2">
<input type="text" name="username" placeholder="Username" /> <input type="text" name="username" placeholder="Username" />
<input type="password" name="password" placeholder="Password" /> <input type="password" name="password" placeholder="Password" />
<button class="px-4 py-2 rounded-md w-full bg-[#8A42FF] text-white border-0" <button class="px-4 py-2 rounded-md w-full bg-accent text-white border-0" type="submit">Login</button>
type="submit">Login</button>
</form> </form>
<span id="message"></span> <span id="message"></span>
</div> </div>

View File

@@ -1,8 +1,8 @@
<main class="grid grid-rows-3 grid-cols-[1fr] justify-center items-center h-screen bg-[#0E0A0E]"> <main class="grid grid-rows-3 grid-cols-[1fr] justify-center items-center h-screen bg-base">
<div class="flex h-full p-2.5 justify-between"> <div class="flex h-full p-2.5 justify-between">
<div> <div>
{{#if WeatherData}} {{#if WeatherData}}
<div class="text-[#BABABA] flex items-center"> <div class="text-subtle flex items-center">
<span class="mr-2 flex items-center"> <span class="mr-2 flex items-center">
{{{WeatherData.Icon}}} {{{WeatherData.Icon}}}
</span> </span>
@@ -15,20 +15,25 @@
</div> </div>
<div> <div>
{{#if UptimeData}} {{#if UptimeData}}
<div class="text-[#BABABA] flex items-end flex-col"> <div class="text-subtle flex items-end flex-col">
{{#each UptimeData}} {{#each UptimeData}}
<div class="flex items-center"> <div class="flex items-center">
<span class="mr-2 flex items-center"> <span class="mr-2 flex items-center">
{{{this.FriendlyName}}} {{{this.FriendlyName}}}
</span> </span>
<div class="relative my-auto"> <div class="relative my-auto size-2">
{{#if (eq this.Status 2)}} <div class="relative my-auto size-2 flex-shrink-0 flex-grow-0">
<span class="absolute w-2 h-2 rounded-full bg-emerald-400 animate-ping block"></span> <svg class="absolute w-full h-full animate-ping" viewBox="0 0 10 10">
<span class="relative w-2 h-2 rounded-full bg-emerald-500 block"></span> <circle cx="5" cy="5" r="5"
{{else}} class="fill-current {{#if (eq this.Status 2)}} text-success {{else}} text-error {{/if}}">
<span class="absolute w-2 h-2 rounded-full bg-rose-400 animate-ping block"></span> </circle>
<span class="relative w-2 h-2 rounded-full bg-rose-500 block"></span> </svg>
{{/if}} <svg class="relative w-full h-full" viewBox="0 0 10 10">
<circle cx="5" cy="5" r="5"
class="fill-current {{#if (eq this.Status 2)}} text-success {{else}} text-error {{/if}}">
</circle>
</svg>
</div>
</div> </div>
</div> </div>
{{/each}} {{/each}}
@@ -62,12 +67,12 @@
</div> </div>
<form class="w-full max-w-3xl" action="{{ SearchProviderURL }}" method="GET"> <form class="w-full max-w-3xl" action="{{ SearchProviderURL }}" method="GET">
<input name="{{ SearchParam }}" aria-label="Search bar" <input name="{{ SearchParam }}" aria-label="Search bar"
class="w-full bg-[#1C1C21] border border-[#2E2E32] rounded-full px-3 py-1 text-white h-7 focus-visible:outline-none placeholder:italic placeholder:text-[#434343] search" class="w-full bg-surface border border-highlight-sm/70 rounded-full px-3 py-1 text-white h-7 focus-visible:outline-none placeholder:italic placeholder:text-highlight search"
placeholder="Search..." /> placeholder="Search..." />
</form> </form>
</div> </div>
</main> </main>
<section class="flex justify-center w-full"> <section class="flex justify-center w-full bg-surface">
<div class="w-full sm:w-4/5 p-2.5"> <div class="w-full sm:w-4/5 p-2.5">
{{#each Categories}} {{#each Categories}}
<div class="flex items-center mt-2 first:mt-0"> <div class="flex items-center mt-2 first:mt-0">
@@ -76,18 +81,16 @@
<h2 class="capitalize break-all">{{this.Name}}</h2> <h2 class="capitalize break-all">{{this.Name}}</h2>
</div> </div>
<div class="p-2.5 grid grid-cols-[repeat(auto-fill,_minmax(min(330px,_100%),_1fr))] gap-2"> <div class="p-2.5 grid grid-cols-[repeat(auto-fill,_minmax(min(330px,_100%),_1fr))] gap-2">
{{#each this.Links}} <a href="{{this.URL}}" {{#each this.Links}} <a href="{{this.URL}}" class="link-card" draggable="false" target="_blank"
class="underline-none text-unset rounded-2xl bg-[#211F23] p-2.5 flex flex-row items-center shadow-md hover:shadow-xl transition-[shadow,transform,translate] ease-[cubic-bezier(0.16,1,0.3,1)] hover:-translate-y-1" rel="noopener noreferrer">
draggable="false" target="_blank" rel="noopener noreferrer"> <img width="64" height="64" draggable="false" src="{{this.Icon}}" alt="{{this.Name}}" />
<img class="mr-2 select-none rounded-md aspect-square object-cover" width="64" height="64" <div>
draggable="false" src="{{this.Icon}}" alt="{{this.Name}}" />
<div class="break-all">
<h3>{{this.Name}}</h3> <h3>{{this.Name}}</h3>
<p class="text-[#D7D7D7]">{{this.Description}}</p> <p>{{this.Description}}</p>
</div> </div>
</a> </a>
{{else}} {{else}}
<p class="text-[#D7D7D7]">No links here, add one!</p> <p class="text-subtle">No links here, add one!</p>
{{/each}} {{/each}}
</div> </div>
{{/each}} {{/each}}

View File

@@ -13,6 +13,6 @@
"dev": "go generate; PASSPORT_DEV_MODE=true go run main.go", "dev": "go generate; PASSPORT_DEV_MODE=true go run main.go",
"build": "go generate && go build -tags netgo,prod -ldflags=\"-w -s\" -o passport" "build": "go generate && go build -tags netgo,prod -ldflags=\"-w -s\" -o passport"
}, },
"pattern": "**/*.go,templates/views/**/*.hbs,styles/**/*.css,assets/**/*.{svg,png,jpg,jpeg,webp,woff2,ttf,otf,eot,ico,gif,webp}", "pattern": "**/*.go,templates/**/*.hbs,styles/**/*.css,assets/**/*.{svg,png,jpg,jpeg,webp,woff2,ttf,otf,eot,ico,gif,webp}",
"shutdown_signal": "SIGINT" "shutdown_signal": "SIGINT"
} }