aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/frontend/html/zen.css
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenserver/frontend/html/zen.css')
-rw-r--r--src/zenserver/frontend/html/zen.css862
1 files changed, 827 insertions, 35 deletions
diff --git a/src/zenserver/frontend/html/zen.css b/src/zenserver/frontend/html/zen.css
index 74336f0e1..d3c6c9036 100644
--- a/src/zenserver/frontend/html/zen.css
+++ b/src/zenserver/frontend/html/zen.css
@@ -27,6 +27,7 @@
--theme_bright: #1f2328;
--theme_faint: #6e7781;
--theme_border_subtle: #d8dee4;
+ --theme_highlight: #b8860b44;
}
}
@@ -54,6 +55,7 @@
--theme_bright: #f0f6fc;
--theme_faint: #6e7681;
--theme_border_subtle: #21262d;
+ --theme_highlight: #e3b341aa;
}
}
@@ -81,6 +83,7 @@
--theme_bright: #1f2328;
--theme_faint: #6e7781;
--theme_border_subtle: #d8dee4;
+ --theme_highlight: #b8860b44;
}
:root[data-theme="dark"] {
@@ -106,6 +109,7 @@
--theme_bright: #f0f6fc;
--theme_faint: #6e7681;
--theme_border_subtle: #21262d;
+ --theme_highlight: #e3b341aa;
}
/* theme toggle ------------------------------------------------------------- */
@@ -214,34 +218,6 @@ button {
}
}
-/* service nav -------------------------------------------------------------- */
-
-#service_nav {
- display: flex;
- align-items: center;
- gap: 4px;
- margin-bottom: 16px;
- padding: 4px;
- background-color: var(--theme_g3);
- border: 1px solid var(--theme_g2);
- border-radius: 6px;
-
- a {
- padding: 6px 14px;
- border-radius: 4px;
- font-size: 13px;
- font-weight: 500;
- color: var(--theme_g1);
- text-decoration: none;
- transition: color 0.15s, background 0.15s;
- }
-
- a:hover {
- background-color: var(--theme_p4);
- color: var(--theme_g0);
- text-decoration: none;
- }
-}
/* links -------------------------------------------------------------------- */
@@ -358,6 +334,207 @@ a {
}
}
+/* sessions ----------------------------------------------------------------- */
+
+.sessions-section {
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 80px);
+}
+
+.sessions-layout {
+ display: flex;
+ gap: 1.5em;
+ align-items: flex-start;
+ flex-shrink: 0;
+}
+
+.sessions-table {
+ flex: 1;
+ min-width: 0;
+}
+
+.sessions-table .zen_table > div > div {
+ text-align: right;
+}
+
+.sessions-table .zen_table > div > div:nth-child(2) {
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+}
+
+.sessions-detail {
+ width: 600px;
+ flex-shrink: 0;
+ font-size: 13px;
+}
+
+.sessions-detail h3 {
+ margin: 0 0 0.6em 0;
+ font-size: 13px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ color: var(--theme_g1);
+}
+
+.sessions-detail .zen_table {
+ margin-bottom: 1em;
+}
+
+.sessions-detail-placeholder {
+ color: var(--theme_g1);
+ font-style: italic;
+}
+
+.sessions-selected {
+ background-color: var(--theme_p3) !important;
+}
+
+.sessions-log-panel {
+ margin-top: 12px;
+ border: 1px solid var(--theme_g3);
+ border-radius: 6px;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 200px;
+}
+.sessions-log-header {
+ display: flex;
+ align-items: center;
+ padding: 6px 12px;
+ background-color: var(--theme_bg1);
+ border-bottom: 1px solid var(--theme_g3);
+ flex-shrink: 0;
+}
+.sessions-log-title {
+ font-size: 12px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ color: var(--theme_g1);
+}
+.sessions-log-filter {
+ margin-left: 12px;
+ padding: 6px 12px;
+ font-size: 14px;
+ font-family: inherit;
+ border: 1px solid var(--theme_g2);
+ border-radius: 6px;
+ background: var(--theme_bg1);
+ color: var(--theme_bright);
+ outline: none;
+ width: 200px;
+}
+.sessions-log-filter:focus {
+ border-color: var(--theme_ln);
+ background: var(--theme_bg0);
+}
+.sessions-log-filter::placeholder {
+ color: var(--theme_g1);
+}
+.sessions-log-body {
+ flex: 1;
+ min-height: 0;
+ overflow-y: auto;
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 12px;
+ line-height: 1.5;
+ padding: 4px 0;
+ background-color: var(--theme_bg0);
+}
+.sessions-log-empty {
+ color: var(--theme_g1);
+ font-style: italic;
+ padding: 8px 12px;
+ font-family: inherit;
+}
+.sessions-log-trimmed {
+ color: var(--theme_g1);
+ font-style: italic;
+ padding: 2px 12px;
+ font-size: 11px;
+}
+.sessions-log-line {
+ padding: 0 12px;
+ white-space: pre;
+ display: flex;
+ gap: 8px;
+}
+.sessions-log-line:hover {
+ background-color: var(--theme_bg1);
+}
+.sessions-log-ts {
+ color: var(--theme_g1);
+ flex-shrink: 0;
+}
+.sessions-log-level {
+ flex-shrink: 0;
+ min-width: 4em;
+ font-weight: 600;
+}
+.sessions-log-level-info { color: var(--theme_ln); }
+.sessions-log-level-warn { color: #d29922; }
+.sessions-log-level-error { color: #f85149; }
+.sessions-log-level-debug { color: var(--theme_g1); }
+.sessions-log-msg {
+ white-space: pre-wrap;
+ word-break: break-all;
+}
+.sessions-log-data {
+ color: var(--theme_g1);
+ white-space: pre-wrap;
+ word-break: break-all;
+}
+
+.sessions-self-pill {
+ display: inline-block;
+ font-size: 0.7em;
+ font-weight: 600;
+ padding: 1px 6px;
+ margin-right: 6px;
+ border-radius: 8px;
+ background-color: var(--theme_p4);
+ color: var(--theme_g0);
+ vertical-align: middle;
+}
+
+.objectstore-bucket-detail {
+ grid-column: 1 / -1;
+ padding: 8px 16px;
+ background-color: var(--theme_bg1);
+ border-top: 1px solid var(--theme_g3);
+ font-size: 0.9em;
+}
+.objectstore-objects-table {
+ width: 100%;
+ border-collapse: collapse;
+}
+.objectstore-objects-table th {
+ text-align: left;
+ font-weight: 600;
+ padding: 4px 8px;
+ border-bottom: 1px solid var(--theme_g3);
+ color: var(--theme_g1);
+ font-size: 0.85em;
+}
+.objectstore-objects-table td {
+ padding: 2px 8px;
+ font-family: var(--font_mono);
+ font-size: 0.85em;
+}
+
+.sessions-pager {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-top: 8px;
+}
+.sessions-pager-label {
+ font-size: 0.85em;
+ opacity: 0.7;
+}
+
/* expandable cell ---------------------------------------------------------- */
.zen_expand_icon {
@@ -471,7 +648,7 @@ a {
border-radius: 6px;
background-color: var(--theme_p4);
border: 1px solid var(--theme_g2);
- width: 6em;
+ min-width: 6em;
cursor: pointer;
font-weight: 500;
transition: background 0.15s;
@@ -486,6 +663,8 @@ a {
padding: 2em;
min-height: 8em;
align-content: center;
+ white-space: pre-wrap;
+ text-align: left;
}
}
@@ -558,6 +737,20 @@ zen-banner {
margin-bottom: 24px;
}
+zen-banner:has(+ zen-nav) {
+ margin-bottom: -1px;
+}
+
+zen-banner:has(+ zen-nav)::part(banner) {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+zen-banner + zen-nav::part(nav-bar) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
/* error -------------------------------------------------------------------- */
#error {
@@ -610,18 +803,21 @@ zen-banner {
/* stats tiles -------------------------------------------------------------- */
-.stats-tiles {
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+.grid.stats-tiles {
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
}
.stats-tile {
cursor: pointer;
- transition: border-color 0.15s, background 0.15s;
+ transition: border-color 0.15s;
}
.stats-tile:hover {
border-color: var(--theme_p0);
- background: var(--theme_p4);
+}
+
+.stats-tile[data-over="true"] {
+ border-color: var(--theme_fail);
}
.stats-tile-detailed {
@@ -680,6 +876,81 @@ zen-banner {
font-size: 28px;
}
+/* HTTP summary panel ------------------------------------------------------- */
+
+.stats-http-panel {
+ display: grid;
+ grid-template-columns: 20% 1fr 1fr;
+ align-items: center;
+ margin-bottom: 16px;
+}
+
+.http-title {
+ font-size: 22px;
+ font-weight: 700;
+ color: var(--theme_bright);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ line-height: 1;
+}
+
+.http-section {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ padding: 0 24px;
+ border-left: 1px solid var(--theme_g2);
+}
+
+.http-section-label {
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--theme_g1);
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.stats-http-panel .tile-metrics {
+ flex-direction: row;
+ align-items: center;
+ gap: 20px;
+}
+
+/* workspaces page ---------------------------------------------------------- */
+
+.ws-id-wrap {
+ display: inline-flex;
+ align-items: center;
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 14px;
+}
+
+.ws-share-table {
+ width: 100%;
+ margin: 4px 0;
+}
+
+.ws-share-table th {
+ padding: 4px;
+}
+
+.ws-share-table td {
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 13px;
+ padding: 4px;
+}
+
+.ws-share-table td.ws-no-shares-cell {
+ color: var(--theme_g1);
+ font-style: italic;
+ font-family: inherit;
+ padding: 4px 8px;
+}
+
+.module-metrics-row td.ws-detail-cell {
+ padding-left: 24px;
+}
+
/* start -------------------------------------------------------------------- */
#start {
@@ -693,7 +964,7 @@ zen-banner {
/* info --------------------------------------------------------------------- */
-#info {
+#info, #storage, #network {
.info-tiles {
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
@@ -837,7 +1108,7 @@ html:has(#map) {
.card-title {
font-size: 14px;
font-weight: 600;
- color: var(--theme_g1);
+ color: var(--theme_g0);
margin-bottom: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
@@ -1081,3 +1352,524 @@ tr:last-child td {
background: var(--theme_g2);
color: var(--theme_bright);
}
+
+/* docs --------------------------------------------------------------------- */
+
+.docs-filter {
+ display: block;
+ width: 100%;
+ max-width: 300px;
+ padding: 8px 12px;
+ font-size: 14px;
+ font-family: inherit;
+ border: 1px solid var(--theme_g2);
+ border-radius: 6px;
+ background: var(--theme_bg1);
+ color: var(--theme_bright);
+ outline: none;
+ margin-bottom: 12px;
+}
+.docs-filter:focus {
+ border-color: var(--theme_ln);
+ background: var(--theme_bg0);
+}
+.docs-filter::placeholder {
+ color: var(--theme_g1);
+}
+.docs-highlight {
+ background: var(--theme_highlight);
+ color: inherit;
+ border-radius: 2px;
+ padding: 0 1px;
+}
+.docs-layout {
+ display: flex;
+ gap: 24px;
+}
+.docs-sidebar {
+ flex-shrink: 0;
+ width: 200px;
+ border-right: 1px solid var(--theme_g3);
+ padding-right: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ position: sticky;
+ top: 16px;
+ align-self: flex-start;
+}
+.docs-sidebar-link {
+ display: block;
+ padding: 6px 10px;
+ font-size: 13px;
+ color: var(--theme_g1);
+ text-decoration: none;
+ border-radius: 4px;
+}
+.docs-sidebar-link:hover {
+ color: var(--theme_g0);
+ background: var(--theme_g4);
+}
+.docs-sidebar-link.active {
+ color: var(--theme_bright);
+ background: var(--theme_g3);
+ font-weight: 500;
+}
+.docs-content {
+ flex: 1;
+ min-width: 0;
+ font-size: 16px;
+ line-height: 1.5;
+ color: var(--theme_g0);
+}
+.docs-content h1 {
+ font-size: 24px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ margin: 0 0 16px 0;
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--theme_g3);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+.docs-source-link {
+ font-size: 14px;
+ opacity: 0.4;
+ transition: opacity 0.15s;
+ text-decoration: none;
+}
+.docs-source-link::after {
+ content: "\2197";
+}
+.docs-source-link:hover,
+.docs-github-link:hover {
+ opacity: 1;
+}
+.docs-github-link {
+ font-size: 14px;
+ opacity: 0.4;
+ transition: opacity 0.15s;
+ text-decoration: none;
+}
+.docs-github-link::after {
+ content: "GH";
+ font-size: 10px;
+ font-weight: 700;
+ letter-spacing: -0.5px;
+}
+.docs-section {
+ margin-top: 16px;
+}
+.docs-section-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ cursor: pointer;
+ list-style: none;
+ user-select: none;
+ padding-bottom: 6px;
+ border-bottom: 1px solid var(--theme_g4);
+ margin-bottom: 8px;
+}
+.docs-section-title::-webkit-details-marker {
+ display: none;
+}
+.docs-section-title::before {
+ content: "\25B6";
+ display: inline-block;
+ margin-right: 8px;
+ font-size: 10px;
+ transition: transform 0.15s;
+ color: var(--theme_g1);
+}
+.docs-section[open] > .docs-section-title::before {
+ transform: rotate(90deg);
+}
+.docs-content h2 {
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ margin: 24px 0 8px 0;
+}
+.docs-content h3 {
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ margin: 16px 0 6px 0;
+}
+.docs-content p {
+ margin: 0 0 12px 0;
+}
+.docs-content code {
+ background: var(--theme_bg1);
+ padding: 1px 5px;
+ border-radius: 3px;
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 0.9em;
+ color: var(--theme_bright);
+}
+.docs-content pre {
+ background: var(--theme_bg1);
+ padding: 12px 16px;
+ border-radius: 6px;
+ overflow-x: auto;
+ margin: 0 0 12px 0;
+}
+.docs-content pre code {
+ background: none;
+ padding: 0;
+}
+.docs-content ul, .docs-content ol {
+ margin: 4px 0 12px 0;
+ padding-left: 24px;
+}
+.docs-content table {
+ border-collapse: collapse;
+ margin: 8px 0 12px 0;
+ font-size: 13px;
+}
+.docs-content th, .docs-content td {
+ border: 1px solid var(--theme_g3);
+ padding: 4px 10px;
+}
+.docs-content th {
+ background: var(--theme_bg1);
+ font-weight: 600;
+ color: var(--theme_bright);
+}
+.docs-content a {
+ color: var(--theme_ln);
+}
+.docs-mermaid {
+ margin: 12px 0;
+ overflow-x: auto;
+}
+.docs-mermaid svg {
+ max-width: 100%;
+ height: auto;
+}
+.docs-loading, .docs-error {
+ color: var(--theme_g1);
+ font-style: italic;
+}
+
+/* module action controls --------------------------------------------------- */
+
+.module-state-dot {
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ margin-right: 6px;
+ vertical-align: middle;
+ flex-shrink: 0;
+}
+
+.module-state-dot[data-state="provisioned"] { background: var(--theme_ok); }
+.module-state-dot[data-state="hibernated"] { background: var(--theme_warn); }
+.module-state-dot[data-state="unprovisioned"] { background: var(--theme_g1); }
+.module-state-dot[data-state="crashed"] { background: var(--theme_fail); }
+
+@keyframes module-dot-recovering {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_ok); }
+}
+
+@keyframes module-dot-hibernating {
+ 0%, 59.9% { background: var(--theme_warn); }
+ 60%, 100% { background: var(--theme_ok); }
+}
+@keyframes module-dot-waking {
+ 0%, 59.9% { background: var(--theme_ok); }
+ 60%, 100% { background: var(--theme_warn); }
+}
+@keyframes module-dot-provisioning {
+ 0%, 59.9% { background: var(--theme_ok); }
+ 60%, 100% { background: var(--theme_g1); }
+}
+@keyframes module-dot-deprovisioning-from-provisioned {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_ok); }
+}
+@keyframes module-dot-deprovisioning-from-hibernated {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_warn); }
+}
+
+.module-state-dot[data-state="hibernating"] { animation: module-dot-hibernating 1s steps(1, end) infinite; }
+.module-state-dot[data-state="waking"] { animation: module-dot-waking 1s steps(1, end) infinite; }
+.module-state-dot[data-state="provisioning"] { animation: module-dot-provisioning 1s steps(1, end) infinite; }
+.module-state-dot[data-state="recovering"] { animation: module-dot-recovering 1s steps(1, end) infinite; }
+.module-state-dot[data-state="deprovisioning"][data-prev-state="provisioned"] {
+ animation: module-dot-deprovisioning-from-provisioned 1s steps(1, end) infinite;
+}
+.module-state-dot[data-state="deprovisioning"][data-prev-state="hibernated"] {
+ animation: module-dot-deprovisioning-from-hibernated 1s steps(1, end) infinite;
+}
+.module-state-dot[data-state="deprovisioning"] {
+ animation: module-dot-deprovisioning-from-provisioned 1s steps(1, end) infinite;
+}
+
+@keyframes module-dot-obliterating-from-provisioned {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_ok); }
+}
+@keyframes module-dot-obliterating-from-hibernated {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_warn); }
+}
+
+.module-state-dot[data-state="obliterating"][data-prev-state="provisioned"] {
+ animation: module-dot-obliterating-from-provisioned 0.5s steps(1, end) infinite;
+}
+.module-state-dot[data-state="obliterating"][data-prev-state="hibernated"] {
+ animation: module-dot-obliterating-from-hibernated 0.5s steps(1, end) infinite;
+}
+.module-state-dot[data-state="obliterating"] {
+ animation: module-dot-obliterating-from-provisioned 0.5s steps(1, end) infinite;
+}
+
+.module-action-cell {
+ white-space: nowrap;
+ display: flex;
+ gap: 4px;
+}
+
+.module-action-wrap {
+ display: inline-block;
+ cursor: default;
+}
+
+.module-action-wrap:has(button:disabled) {
+ cursor: default;
+}
+
+.module-action-btn {
+ background: transparent;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ color: var(--theme_g1);
+ cursor: pointer;
+ font-size: 13px;
+ line-height: 1;
+ padding: 3px 6px;
+ transition: background 0.1s, color 0.1s;
+}
+
+.module-action-btn:not(:disabled):hover {
+ background: var(--theme_g2);
+ color: var(--theme_bright);
+}
+
+.module-action-btn:disabled {
+ color: var(--theme_border_subtle);
+ border-color: var(--theme_border_subtle);
+ pointer-events: none;
+}
+
+.module-bulk-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 5px;
+ background: transparent;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 12px;
+ font-weight: 600;
+ padding: 4px 10px;
+ color: var(--theme_g1);
+ transition: background 0.1s, color 0.1s;
+}
+
+.module-bulk-btn:not(:disabled):hover {
+ background: var(--theme_p3);
+ color: var(--theme_bright);
+}
+
+.module-bulk-btn:disabled {
+ opacity: 0.4;
+}
+
+.module-bulk-bar {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 6px 10px;
+ margin-bottom: 8px;
+ background: var(--theme_g2);
+ border-radius: 4px;
+ font-size: 12px;
+}
+
+.module-bulk-label {
+ margin-right: 8px;
+ color: var(--theme_g1);
+}
+
+.module-bulk-sep {
+ flex: 1;
+}
+
+.module-pager {
+ position: absolute;
+ right: 0;
+ top: 0;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.module-pager-btn {
+ background: transparent;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ color: var(--theme_g1);
+ cursor: pointer;
+ font-size: 12px;
+ padding: 4px 10px;
+ transition: background 0.1s, color 0.1s;
+}
+
+.module-pager-btn:not(:disabled):hover {
+ background: var(--theme_g2);
+ color: var(--theme_bright);
+}
+
+.module-pager-btn:disabled {
+ opacity: 0.35;
+ cursor: default;
+}
+
+.module-pager-label {
+ font-size: 12px;
+ color: var(--theme_g1);
+ min-width: 8em;
+ text-align: center;
+}
+
+.module-pager-search {
+ font-size: 12px;
+ padding: 4px 8px;
+ width: 14em;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ background: var(--theme_g4);
+ color: var(--theme_g0);
+ outline: none;
+ transition: border-color 0.15s, outline 0.3s;
+}
+
+.module-pager-search:focus {
+ border-color: var(--theme_p0);
+}
+
+.module-pager-search::placeholder {
+ color: var(--theme_g1);
+}
+
+@keyframes pager-search-flash {
+ from { box-shadow: inset 0 0 0 100px var(--theme_p2); }
+ to { box-shadow: inset 0 0 0 100px transparent; }
+}
+
+.zen_table > .pager-search-highlight > div {
+ animation: pager-search-flash 1s linear forwards;
+}
+
+.module-table .pager-search-highlight td {
+ animation: pager-search-flash 1s linear forwards;
+}
+
+@keyframes pager-loading-pulse {
+ 0%, 100% { opacity: 0.6; }
+ 50% { opacity: 0.2; }
+}
+
+.pager-loading {
+ color: var(--theme_g1);
+ font-style: italic;
+ font-size: 14px;
+ font-weight: 600;
+ padding: 12px 0;
+ animation: pager-loading-pulse 1.5s ease-in-out infinite;
+}
+
+.module-table td, .module-table th {
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+.module-expand-btn {
+ background: transparent;
+ border: none;
+ color: var(--theme_g1);
+ cursor: pointer;
+ font-size: 16px;
+ line-height: 1;
+ padding: 0 4px 0 0;
+ vertical-align: middle;
+}
+
+.module-expand-btn:hover {
+ color: var(--theme_bright);
+}
+
+.zen-copy-btn {
+ background: transparent;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ color: var(--theme_g1);
+ cursor: pointer;
+ font-size: 12px;
+ line-height: 1;
+ padding: 2px 5px;
+ margin-left: 6px;
+ vertical-align: middle;
+ flex-shrink: 0;
+ transition: background 0.1s, color 0.1s;
+}
+.zen-copy-btn:hover {
+ background: var(--theme_g2);
+ color: var(--theme_bright);
+}
+.zen-copy-btn.zen-copy-ok {
+ color: var(--theme_ok);
+ border-color: var(--theme_ok);
+}
+
+.zen-copy-wrap {
+ display: inline-flex;
+ align-items: center;
+ white-space: nowrap;
+}
+
+.module-metrics-row td {
+ padding: 6px 10px 10px 42px;
+ background: var(--theme_g3);
+ border-bottom: 1px solid var(--theme_g2);
+}
+
+.module-metrics-grid {
+ display: grid;
+ grid-template-columns: max-content minmax(9em, 1fr) max-content minmax(9em, 1fr);
+ gap: 3px 12px;
+ font-size: 11px;
+ font-variant-numeric: tabular-nums;
+}
+
+.module-metrics-label {
+ color: var(--theme_faint);
+ white-space: nowrap;
+}
+
+/* Right-column labels get extra left padding to visually separate the two pairs */
+.module-metrics-label:nth-child(4n+3) {
+ padding-left: 16px;
+}
+
+.module-metrics-value {
+ color: var(--theme_g0);
+ text-align: right;
+}