style.css 9.4 KB

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