diff --git a/internal/idlewatcher/handle_http.go b/internal/idlewatcher/handle_http.go
index 3d87067a..bc9773da 100644
--- a/internal/idlewatcher/handle_http.go
+++ b/internal/idlewatcher/handle_http.go
@@ -47,6 +47,10 @@ func isFaviconPath(path string) bool {
return path == "/favicon.ico"
}
+func isLoadingPageCSSPath(path string) bool {
+ return path == "/style.css"
+}
+
func (w *Watcher) redirectToStartEndpoint(rw http.ResponseWriter, r *http.Request) {
uri := "/"
if w.cfg.StartEndpoint != "" {
@@ -96,6 +100,13 @@ func (w *Watcher) wakeFromHTTP(rw http.ResponseWriter, r *http.Request) (shouldN
return false
}
+ if isLoadingPageCSSPath(r.URL.Path) {
+ rw.Header().Set("Content-Type", "text/css")
+ rw.WriteHeader(http.StatusOK)
+ rw.Write(cssBytes)
+ return false
+ }
+
// Check if start endpoint is configured and request path matches
if w.cfg.StartEndpoint != "" && r.URL.Path != w.cfg.StartEndpoint {
http.Error(rw, "Forbidden: Container can only be started via configured start endpoint", http.StatusForbidden)
diff --git a/internal/idlewatcher/html/loading_page.html b/internal/idlewatcher/html/loading_page.html
index a1c891f7..104fa105 100644
--- a/internal/idlewatcher/html/loading_page.html
+++ b/internal/idlewatcher/html/loading_page.html
@@ -4,109 +4,8 @@
{{.Title}}
-
+
+
diff --git a/internal/idlewatcher/html/style.css b/internal/idlewatcher/html/style.css
new file mode 100644
index 00000000..5832276d
--- /dev/null
+++ b/internal/idlewatcher/html/style.css
@@ -0,0 +1,91 @@
+/* size variables */
+:root {
+ --dot-size: 12px;
+ --logo-size: 100px;
+}
+/* Global Styles */
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+body {
+ font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
+ font-size: 16px;
+ line-height: 1.5;
+ color: #f8f9fa;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ margin: 0;
+ gap: 32px;
+ background: linear-gradient(135deg, #121212 0%, #1e1e1e 100%);
+}
+
+/* Container */
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 48px;
+ border-radius: 16px;
+ background-color: rgba(30, 30, 30, 0.6);
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
+ backdrop-filter: blur(8px);
+ max-width: 90%;
+ transition: all 0.3s ease;
+}
+
+/* Spinner Styles */
+.loading-dots {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 8px;
+ padding-top: 20px;
+ padding-bottom: 6px;
+}
+.dot {
+ width: var(--dot-size);
+ height: var(--dot-size);
+ background-color: #66d9ef;
+ border-radius: 50%;
+ animation: bounce 1.3s infinite ease-in-out;
+}
+.dot:nth-child(1) {
+ animation-delay: -0.32s;
+}
+.dot:nth-child(2) {
+ animation-delay: -0.16s;
+}
+@keyframes bounce {
+ 0%,
+ 80%,
+ 100% {
+ transform: translateY(0);
+ }
+ 40% {
+ transform: translateY(-10px);
+ }
+}
+
+/* Message Styles */
+.message {
+ font-size: 20px;
+ font-weight: 500;
+ text-align: center;
+ color: #f8f9fa;
+ max-width: 500px;
+ letter-spacing: 0.3px;
+ white-space: nowrap;
+}
+
+/* Logo */
+.logo {
+ width: var(--logo-size);
+ height: var(--logo-size);
+}
diff --git a/internal/idlewatcher/loading_page.go b/internal/idlewatcher/loading_page.go
index 8407080e..6639d716 100644
--- a/internal/idlewatcher/loading_page.go
+++ b/internal/idlewatcher/loading_page.go
@@ -3,7 +3,7 @@ package idlewatcher
import (
"bytes"
_ "embed"
- "text/template"
+ "html/template"
"github.com/yusing/goutils/http/httpheaders"
)
@@ -18,6 +18,9 @@ type templateData struct {
var loadingPage []byte
var loadingPageTmpl = template.Must(template.New("loading_page").Parse(string(loadingPage)))
+//go:embed html/style.css
+var cssBytes []byte
+
func (w *Watcher) makeLoadingPageBody() []byte {
msg := w.cfg.ContainerName() + " is starting..."