diff --git a/ui/src/index.css b/ui/src/index.css
index 13f99a8..1348c40 100644
--- a/ui/src/index.css
+++ b/ui/src/index.css
@@ -1,5 +1,11 @@
@import "tailwindcss";
@config "../tailwind.config.js";
+@plugin "@tailwindcss/typography";
+@plugin "@tailwindcss/forms";
+@plugin "@headlessui/tailwindcss";
+
+/* Dark mode uses CSS selector instead of prefers-color-scheme */
+@custom-variant dark (&:where(.dark, .dark *));
html {
@apply scroll-smooth;
@@ -12,6 +18,128 @@ body {
overflow: auto;
}
+@theme {
+ --font-sans: "Circular", sans-serif;
+ --font-display: "Circular", sans-serif;
+ --font-serif: "Circular", serif;
+ --font-mono: "Source Code Pro Variable", monospace;
+
+ --grid-layout: auto 1fr auto;
+ --grid-headerBody: auto 1fr;
+ --grid-bodyFooter: 1fr auto;
+ --grid-sidebar: 1fr minmax(360px, 25%);
+
+ --breakpoint-xs: 480px;
+ --breakpoint-2xl: 1440px;
+ --breakpoint-3xl: 1920px;
+ --breakpoint-4xl: 2560px;
+
+ /* Migrated animations */
+ --animate-enter: enter 0.2s ease-out;
+ --animate-leave: leave 0.15s ease-in forwards;
+ --animate-fadeInScale: fadeInScale 1s ease-out forwards;
+ --animate-fadeInScaleFloat:
+ fadeInScaleFloat 1s ease-out forwards, float 3s ease-in-out infinite;
+ --animate-fadeIn: fadeIn 1s ease-out forwards;
+ --animate-slideUpFade: slideUpFade 1s ease-out forwards;
+
+ --container-8xl: 88rem;
+ --container-9xl: 96rem;
+ --container-10xl: 104rem;
+ --container-11xl: 112rem;
+ --container-12xl: 120rem;
+
+ /* Migrated keyframes */
+ @keyframes enter {
+ 0% {
+ opacity: 0;
+ transform: scale(0.9);
+ }
+ 100% {
+ opacity: 1;
+ transform: scale(1);
+ }
+ }
+
+ @keyframes leave {
+ 0% {
+ opacity: 1;
+ transform: scale(1);
+ }
+ 100% {
+ opacity: 0;
+ transform: scale(0.9);
+ }
+ }
+
+ @keyframes fadeInScale {
+ 0% {
+ opacity: 0;
+ transform: scale(0.98);
+ }
+ 100% {
+ opacity: 1;
+ transform: scale(1);
+ }
+ }
+
+ @keyframes fadeInScaleFloat {
+ 0% {
+ opacity: 0;
+ transform: scale(0.98) translateY(10px);
+ }
+ 100% {
+ opacity: 1;
+ transform: scale(1) translateY(0);
+ }
+ }
+
+ @keyframes float {
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+ 50% {
+ transform: translateY(-10px);
+ }
+ }
+
+ @keyframes fadeIn {
+ 0% {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+ 70% {
+ opacity: 0.8;
+ transform: translateY(1px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ @keyframes slideUpFade {
+ 0% {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+}
+
+@utility max-width-* {
+ max-width: --modifier(--container- *, [length], [ *]);
+}
+
+/* Ensure there is not a `ms` and ms -> `...)ms` */
+@utility animation-delay-* {
+ animation-delay: --value(integer) ms;
+}
+
@property --grid-color-start {
syntax: "
";
initial-value: theme("colors.blue.50/10");
diff --git a/ui/src/routes/devices.$id.deregister.tsx b/ui/src/routes/devices.$id.deregister.tsx
index 55645f9..8c0a87f 100644
--- a/ui/src/routes/devices.$id.deregister.tsx
+++ b/ui/src/routes/devices.$id.deregister.tsx
@@ -71,7 +71,7 @@ export default function DevicesIdDeregister() {
const error = useActionData() as { message: string };
return (
-
+
+
-
+
diff --git a/ui/src/routes/devices.$id.tsx b/ui/src/routes/devices.$id.tsx
index fe13fe2..2e789a6 100644
--- a/ui/src/routes/devices.$id.tsx
+++ b/ui/src/routes/devices.$id.tsx
@@ -795,7 +795,7 @@ export default function KvmIdRoute() {
-
+
{!!ConnectionStatusElement && ConnectionStatusElement}
diff --git a/ui/src/routes/devices.already-adopted.tsx b/ui/src/routes/devices.already-adopted.tsx
index 671ac00..ee189a8 100644
--- a/ui/src/routes/devices.already-adopted.tsx
+++ b/ui/src/routes/devices.already-adopted.tsx
@@ -8,7 +8,7 @@ export default function DevicesAlreadyAdopted() {
<>
-
+
diff --git a/ui/src/routes/devices.tsx b/ui/src/routes/devices.tsx
index 9090646..b6af0f0 100644
--- a/ui/src/routes/devices.tsx
+++ b/ui/src/routes/devices.tsx
@@ -40,7 +40,7 @@ export default function DevicesRoute() {
useInterval(revalidate.revalidate, 4000);
return (
-
+
-
+
diff --git a/ui/src/routes/welcome-local.mode.tsx b/ui/src/routes/welcome-local.mode.tsx
index 68babaf..d3f9d3e 100644
--- a/ui/src/routes/welcome-local.mode.tsx
+++ b/ui/src/routes/welcome-local.mode.tsx
@@ -14,7 +14,6 @@ import api from "../api";
import { DeviceStatus } from "./welcome-local";
-
const loader = async () => {
const res = await api
.GET(`${DEVICE_API}/device/status`)
@@ -59,18 +58,24 @@ export default function WelcomeLocalModeRoute() {
-
+
-
-

+
+
-
Local Authentication Method
+
+ Local Authentication Method
+
Select how you{"'"}d like to secure your JetKVM device locally.
@@ -78,7 +83,7 @@ export default function WelcomeLocalModeRoute() {