diff --git a/internal/lkgateway/topbar_shot_test.go b/internal/lkgateway/topbar_shot_test.go
new file mode 100644
index 0000000..72f617e
--- /dev/null
+++ b/internal/lkgateway/topbar_shot_test.go
@@ -0,0 +1,27 @@
+package lkgateway
+
+import (
+ "html/template"
+ "net/http/httptest"
+ "os"
+ "testing"
+)
+
+// Снимок шапки для визуальной проверки: страница пишется в файл, если задан BJ_SHOT_OUT.
+func TestTopbarShot(t *testing.T) {
+ out := os.Getenv("BJ_SHOT_OUT")
+ if out == "" {
+ t.Skip("BJ_SHOT_OUT не задан")
+ }
+ a, err := newAdmin()
+ if err != nil {
+ t.Fatal(err)
+ }
+ rec := httptest.NewRecorder()
+ p := nowPage("Настройка", "setup")
+ p.NPR = true
+ render(rec, a.modulePage, modulePageData{page: p, Content: template.HTML(`
содержимое страницы
`)})
+ if err := os.WriteFile(out, rec.Body.Bytes(), 0o644); err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/internal/lkgateway/web/templates/layout.html b/internal/lkgateway/web/templates/layout.html
index d2a0383..ff2144a 100644
--- a/internal/lkgateway/web/templates/layout.html
+++ b/internal/lkgateway/web/templates/layout.html
@@ -85,7 +85,7 @@ body {
border-radius:10px; box-shadow:0 8px 30px rgba(0,0,0,.14); min-width:210px; z-index:60; padding:6px; }
.nav .ddmenu a { display:block; padding:8px 12px; border-radius:7px; }
.topbar-right { display:flex; align-items:center; gap:12px; flex:none; padding-left:10px; }
-@media (max-width:1200px){ .sys-status span:not(.pulse){ display:none } .sys-status{ padding:5px 8px } .topbar .clock{ display:none } }
+@media (max-width:1100px){ .sys-status span:not(.pulse){ display:none } .sys-status{ padding:5px 8px } .topbar .clock{ display:none } .user-dd .user-role{ display:none } }
/* Строка системного статуса — состояние читается всегда */
.sys-status { display:inline-flex; align-items:center; gap:7px; font-size:12px; font-weight:600; color:var(--text-2); padding:5px 11px 5px 9px; border:1px solid var(--border); border-radius:20px; background:var(--card-2); white-space:nowrap; }
.sys-status .pulse { width:8px; height:8px; border-radius:50%; background:var(--ok); box-shadow:0 0 0 0 var(--ok-weak); animation:pulse 2.4s var(--ease) infinite; }
@@ -99,7 +99,20 @@ body {
}
.theme-toggle svg { width:16px; height:16px; }
.theme-toggle:hover { background:var(--border); color:var(--text); }
-.topbar .clock { font-size:12px; color:var(--muted); font-family:var(--mono); font-variant-numeric:tabular-nums; letter-spacing:-0.02em; }
+.topbar .clock { font-size:11px; color:var(--muted); font-family:var(--mono); font-variant-numeric:tabular-nums; letter-spacing:-0.02em; }
+.sys-block { display:inline-flex; flex-direction:column; align-items:center; gap:2px; line-height:1.1; }
+.sys-block .sys-status { padding:3px 9px 3px 7px; font-size:11.5px; }
+.user-dd .ddbtn.user-chip { display:inline-flex; flex-direction:column; align-items:flex-start; padding:4px 10px; border-radius:8px; margin:0; max-width:220px; }
+.user-dd .user-name { font-size:12.5px; }
+.nav .ddmenu.ddmenu-right, .user-dd .ddmenu { left:auto; right:0; min-width:190px; }
+.user-dd { position:relative; }
+.user-dd .ddmenu { display:none; position:absolute; top:100%; right:0; margin-top:8px; background:var(--card); border:1px solid var(--border); border-radius:10px; padding:6px; box-shadow:0 10px 30px rgba(0,0,0,.12); z-index:50; }
+.user-dd:hover .ddmenu, .user-dd:focus-within .ddmenu { display:block; }
+.user-dd::after { content:''; position:absolute; top:100%; left:0; right:0; height:10px; }
+.user-dd .ddmenu a { display:block; padding:8px 12px; border-radius:7px; font-size:13px; color:var(--text-2); text-decoration:none; white-space:nowrap; }
+.user-dd .ddmenu a:hover, .user-dd .ddmenu a.active { background:var(--accent-weak); color:var(--accent-strong); }
+.user-dd:hover .ddbtn, .user-dd.active .ddbtn { background:var(--accent-weak); }
+.ddsep { display:block; height:1px; background:var(--border); margin:6px 4px; }
/* ---- Контент ---- */
main { padding:24px; max-width:1200px; margin:0 auto; }
@@ -304,16 +317,25 @@ label { font-size:13px; font-weight:500; }
Справочник НРД{{end}}
{{end}}
- {{if can "settings"}}Администратор
- Настройка
- Статус{{end}}
- Справка
- {{with curUser}}
{{if .Name}}{{.Name}}{{else}}{{.Login}}{{end}}{{.RoleTitle}}Выйти{{else}}{{if authOpen}}
без входа{{end}}{{end}}
-
- {{if .IsMockMode}}{{if devOn}}Эмуляция{{else}}Нет связи с НРД{{end}}{{else}}НРД на связи{{end}}
-
{{.Now}}
+
+
+ {{if .IsMockMode}}{{if devOn}}Эмуляция{{else}}Нет связи с НРД{{end}}{{else}}НРД на связи{{end}}
+ {{.Now}}
+
+
+
+ {{with curUser}}{{if .Name}}{{.Name}}{{else}}{{.Login}}{{end}}{{else}}без входа{{end}} ▾
+ {{with curUser}}{{.RoleTitle}}{{else}}вход открыт{{end}}
+
+
+