style.css 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. * Manage admin UI. Single hand-written stylesheet, no framework and no build
  3. * step, built on custom properties. Neutral palette, because this is an
  4. * operations tool rather than a branded surface.
  5. */
  6. :root {
  7. --c-text: #16191d;
  8. --c-muted: #5c6470;
  9. --c-bg: #f4f5f7;
  10. --c-surface: #ffffff;
  11. --c-surface-alt: #fafbfc;
  12. --c-border: #d9dde3;
  13. --c-border-strong: #b9c0c9;
  14. --c-primary: #1f3b63;
  15. --c-primary-soft: #2c527f;
  16. --c-ok: #1a6b3c;
  17. --c-ok-soft: #eaf6ee;
  18. --c-warn: #8a5a00;
  19. --c-warn-soft: #fdf3e0;
  20. --c-error: #a52218;
  21. --c-error-soft: #fceceb;
  22. --c-shadow: rgba(16, 20, 26, 0.08);
  23. --radius: 8px;
  24. }
  25. * {
  26. margin: 0;
  27. padding: 0;
  28. box-sizing: border-box;
  29. }
  30. body {
  31. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  32. line-height: 1.55;
  33. color: var(--c-text);
  34. background: var(--c-bg);
  35. }
  36. code, pre, .mono-cell {
  37. font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  38. font-size: 0.875em;
  39. }
  40. a {
  41. color: var(--c-primary);
  42. text-underline-offset: 0.18em;
  43. }
  44. a:hover {
  45. color: var(--c-primary-soft);
  46. }
  47. .container {
  48. width: min(1180px, 100% - 2.5rem);
  49. margin: 0 auto;
  50. padding: 1.75rem 0 3rem;
  51. }
  52. /* --- Top bar ----------------------------------------------------------- */
  53. .topbar {
  54. background: var(--c-primary);
  55. color: #fff;
  56. }
  57. .topbar-inner {
  58. width: min(1180px, 100% - 2.5rem);
  59. margin: 0 auto;
  60. display: flex;
  61. flex-wrap: wrap;
  62. align-items: center;
  63. gap: 1rem 1.5rem;
  64. padding: 0.85rem 0;
  65. }
  66. .brand {
  67. display: flex;
  68. flex-direction: column;
  69. line-height: 1.25;
  70. }
  71. .brand-name {
  72. font-weight: 600;
  73. font-size: 1.05rem;
  74. }
  75. .brand-product {
  76. font-size: 0.8rem;
  77. opacity: 0.75;
  78. }
  79. .topnav {
  80. display: flex;
  81. flex-wrap: wrap;
  82. gap: 0.25rem;
  83. margin-right: auto;
  84. }
  85. .topnav a {
  86. color: #fff;
  87. text-decoration: none;
  88. padding: 0.4rem 0.75rem;
  89. border-radius: var(--radius);
  90. font-size: 0.925rem;
  91. }
  92. .topnav a:hover {
  93. background: rgba(255, 255, 255, 0.12);
  94. color: #fff;
  95. }
  96. .topnav a[aria-current="page"] {
  97. background: rgba(255, 255, 255, 0.2);
  98. font-weight: 600;
  99. }
  100. .topbar-logout {
  101. margin-left: auto;
  102. }
  103. /* --- Typography -------------------------------------------------------- */
  104. h1 {
  105. font-size: 1.6rem;
  106. margin-bottom: 1.25rem;
  107. }
  108. h2 {
  109. font-size: 1.2rem;
  110. margin: 2rem 0 0.85rem;
  111. }
  112. h3 {
  113. font-size: 1.05rem;
  114. }
  115. p + p {
  116. margin-top: 0.6rem;
  117. }
  118. .muted {
  119. color: var(--c-muted);
  120. }
  121. .hint {
  122. color: var(--c-muted);
  123. font-size: 0.85rem;
  124. margin-top: 0.3rem;
  125. }
  126. .empty {
  127. background: var(--c-surface);
  128. border: 1px dashed var(--c-border-strong);
  129. border-radius: var(--radius);
  130. padding: 1.25rem;
  131. color: var(--c-muted);
  132. }
  133. /* --- Alerts ------------------------------------------------------------ */
  134. .alert {
  135. border-radius: var(--radius);
  136. padding: 0.7rem 0.9rem;
  137. margin-bottom: 0.6rem;
  138. border: 1px solid transparent;
  139. }
  140. .alert-success {
  141. background: var(--c-ok-soft);
  142. border-color: #bfe0cb;
  143. color: var(--c-ok);
  144. }
  145. .alert-error {
  146. background: var(--c-error-soft);
  147. border-color: #f0c3bf;
  148. color: var(--c-error);
  149. }
  150. /* --- Cards ------------------------------------------------------------- */
  151. .cards {
  152. display: grid;
  153. grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  154. gap: 0.9rem;
  155. margin-bottom: 1.5rem;
  156. }
  157. .card {
  158. background: var(--c-surface);
  159. border: 1px solid var(--c-border);
  160. border-radius: var(--radius);
  161. padding: 0.9rem 1rem;
  162. box-shadow: 0 1px 2px var(--c-shadow);
  163. }
  164. .card-label {
  165. font-size: 0.775rem;
  166. text-transform: uppercase;
  167. letter-spacing: 0.04em;
  168. color: var(--c-muted);
  169. }
  170. .card-value {
  171. font-size: 1.35rem;
  172. font-weight: 600;
  173. margin-top: 0.15rem;
  174. }
  175. .card-hint {
  176. font-size: 0.8rem;
  177. color: var(--c-muted);
  178. }
  179. /* --- Panels ------------------------------------------------------------ */
  180. .panel {
  181. background: var(--c-surface);
  182. border: 1px solid var(--c-border);
  183. border-radius: var(--radius);
  184. padding: 1.15rem;
  185. margin-bottom: 1.25rem;
  186. box-shadow: 0 1px 2px var(--c-shadow);
  187. }
  188. .panel-head {
  189. display: flex;
  190. flex-wrap: wrap;
  191. align-items: center;
  192. gap: 0.65rem;
  193. margin-bottom: 0.9rem;
  194. }
  195. .panel-head h2,
  196. .panel-head h3 {
  197. margin: 0;
  198. }
  199. /* --- Tables ------------------------------------------------------------ */
  200. .table-scroll {
  201. overflow-x: auto;
  202. background: var(--c-surface);
  203. border: 1px solid var(--c-border);
  204. border-radius: var(--radius);
  205. }
  206. .data-table {
  207. width: 100%;
  208. border-collapse: collapse;
  209. font-size: 0.925rem;
  210. }
  211. .data-table th,
  212. .data-table td {
  213. text-align: left;
  214. padding: 0.6rem 0.8rem;
  215. border-bottom: 1px solid var(--c-border);
  216. vertical-align: top;
  217. }
  218. .data-table thead th {
  219. background: var(--c-surface-alt);
  220. font-size: 0.8rem;
  221. text-transform: uppercase;
  222. letter-spacing: 0.03em;
  223. color: var(--c-muted);
  224. white-space: nowrap;
  225. }
  226. .data-table tbody tr:last-child th,
  227. .data-table tbody tr:last-child td {
  228. border-bottom: none;
  229. }
  230. .mono-cell {
  231. word-break: break-all;
  232. max-width: 22ch;
  233. }
  234. /* --- Definition lists -------------------------------------------------- */
  235. .meta-list {
  236. display: grid;
  237. grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  238. gap: 0.5rem 1.25rem;
  239. margin-bottom: 1rem;
  240. }
  241. .meta-list dt {
  242. font-size: 0.775rem;
  243. text-transform: uppercase;
  244. letter-spacing: 0.03em;
  245. color: var(--c-muted);
  246. }
  247. .meta-list dd {
  248. font-size: 0.95rem;
  249. }
  250. /* --- Forms ------------------------------------------------------------- */
  251. .form-row {
  252. display: grid;
  253. grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  254. gap: 0.9rem;
  255. }
  256. .form-group {
  257. margin-bottom: 0.9rem;
  258. }
  259. .form-group label {
  260. display: block;
  261. font-weight: 600;
  262. font-size: 0.9rem;
  263. margin-bottom: 0.3rem;
  264. }
  265. input[type="text"],
  266. input[type="password"],
  267. input[type="number"],
  268. input[type="file"] {
  269. width: 100%;
  270. padding: 0.5rem 0.65rem;
  271. border: 1px solid var(--c-border-strong);
  272. border-radius: var(--radius);
  273. font: inherit;
  274. background: #fff;
  275. color: inherit;
  276. }
  277. input:focus-visible,
  278. button:focus-visible,
  279. a:focus-visible {
  280. outline: 2px solid var(--c-primary);
  281. outline-offset: 2px;
  282. }
  283. .inline-form {
  284. margin-bottom: 1rem;
  285. }
  286. .button-row {
  287. display: flex;
  288. flex-wrap: wrap;
  289. gap: 0.5rem;
  290. align-items: center;
  291. }
  292. /* --- Buttons ----------------------------------------------------------- */
  293. .btn {
  294. display: inline-block;
  295. padding: 0.45rem 0.9rem;
  296. border: 1px solid var(--c-primary);
  297. border-radius: var(--radius);
  298. background: var(--c-primary);
  299. color: #fff;
  300. font: inherit;
  301. font-size: 0.9rem;
  302. cursor: pointer;
  303. }
  304. .btn:hover {
  305. background: var(--c-primary-soft);
  306. border-color: var(--c-primary-soft);
  307. }
  308. .btn-secondary {
  309. background: #fff;
  310. color: var(--c-primary);
  311. }
  312. .btn-secondary:hover {
  313. background: var(--c-surface-alt);
  314. color: var(--c-primary-soft);
  315. }
  316. .btn-danger {
  317. background: #fff;
  318. border-color: var(--c-error);
  319. color: var(--c-error);
  320. }
  321. .btn-danger:hover {
  322. background: var(--c-error);
  323. color: #fff;
  324. }
  325. .btn-quiet {
  326. background: transparent;
  327. border-color: rgba(255, 255, 255, 0.45);
  328. color: #fff;
  329. }
  330. .btn-quiet:hover {
  331. background: rgba(255, 255, 255, 0.14);
  332. border-color: rgba(255, 255, 255, 0.7);
  333. }
  334. /* --- Badges ------------------------------------------------------------ */
  335. .badge {
  336. display: inline-block;
  337. padding: 0.1rem 0.5rem;
  338. border-radius: 999px;
  339. font-size: 0.775rem;
  340. font-weight: 600;
  341. white-space: nowrap;
  342. }
  343. .badge-ok {
  344. background: var(--c-ok-soft);
  345. color: var(--c-ok);
  346. }
  347. .badge-warn {
  348. background: var(--c-warn-soft);
  349. color: var(--c-warn);
  350. }
  351. .badge-error {
  352. background: var(--c-error-soft);
  353. color: var(--c-error);
  354. }
  355. /* --- Code and tokens --------------------------------------------------- */
  356. .code-block {
  357. background: #16191d;
  358. color: #e8ecf1;
  359. padding: 0.85rem 1rem;
  360. border-radius: var(--radius);
  361. overflow-x: auto;
  362. white-space: pre;
  363. }
  364. .log-tail {
  365. max-height: 20rem;
  366. overflow-y: auto;
  367. }
  368. .token-box {
  369. background: var(--c-warn-soft);
  370. border: 1px solid #e6cf9d;
  371. border-radius: var(--radius);
  372. padding: 1.15rem;
  373. margin-bottom: 1.5rem;
  374. }
  375. .token-value {
  376. background: #16191d;
  377. color: #ffd98a;
  378. padding: 0.7rem 0.9rem;
  379. border-radius: var(--radius);
  380. overflow-x: auto;
  381. word-break: break-all;
  382. white-space: pre-wrap;
  383. margin: 0.5rem 0 0.9rem;
  384. }
  385. /* --- Login ------------------------------------------------------------- */
  386. .login-body {
  387. display: flex;
  388. align-items: center;
  389. justify-content: center;
  390. min-height: 100vh;
  391. padding: 1.5rem;
  392. }
  393. .login-panel {
  394. background: var(--c-surface);
  395. border: 1px solid var(--c-border);
  396. border-radius: var(--radius);
  397. padding: 1.75rem;
  398. width: min(380px, 100%);
  399. box-shadow: 0 2px 10px var(--c-shadow);
  400. }
  401. .login-panel h1 {
  402. margin-bottom: 0.15rem;
  403. }
  404. .login-panel form {
  405. margin-top: 1.25rem;
  406. }
  407. .login-panel .btn {
  408. width: 100%;
  409. }
  410. /* --- Footer ------------------------------------------------------------ */
  411. .footer {
  412. border-top: 1px solid var(--c-border);
  413. background: var(--c-surface);
  414. padding: 1.15rem 0;
  415. color: var(--c-muted);
  416. font-size: 0.875rem;
  417. }
  418. .footer .container {
  419. padding: 0;
  420. }