diff --git a/internal/web/static/panel.css b/internal/web/static/panel.css
new file mode 100644
index 0000000..f264094
--- /dev/null
+++ b/internal/web/static/panel.css
@@ -0,0 +1,119 @@
+/* Panel stylesheet. It lives in a file rather than in a
diff --git a/internal/web/templates_test.go b/internal/web/templates_test.go
index c042598..b8c6b32 100644
--- a/internal/web/templates_test.go
+++ b/internal/web/templates_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"io/fs"
"path"
+ "regexp"
"strings"
"testing"
"time"
@@ -96,6 +97,53 @@ func TestReloadFormLivesOnlyOnTheStatusPage(t *testing.T) {
})
}
+// The panel's Content-Security-Policy is a plain default-src 'self' with no
+// inline exemption (phase 14.A), which makes inline script and inline style a
+// failure mode rather than a style question: an onclick= handler or a
+// style="..." attribute added to a template does not error, it silently stops
+// working in the browser. Behaviour belongs in static/panel.js (triggered from
+// a data- attribute), appearance in static/panel.css.
+func TestNoTemplateUsesInlineScriptOrStyle(t *testing.T) {
+ inlineHandler := regexp.MustCompile(`\son[a-z]+\s*=`)
+ inlineStyle := regexp.MustCompile(`\sstyle\s*=|