Files
css-test/data/static/css/styles.css
T

1101 lines
27 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ── Brand font ────────────────────────────────────────────
ASB uses Overpass (open-source, SIL OFL) as their primary brand
typeface. Self-hosted as a single variable woff2 covering 400700. */
@font-face {
font-family: 'Overpass';
font-style: normal;
font-weight: 400 700;
font-display: swap;
src: url(../fonts/overpass-latin.woff2) format('woff2');
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Overpass', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
:root {
/* ASB brand yellow — used for highlights, hover, and the nav accent bar. */
--asb-yellow: #FFCC00;
--asb-yellow-dim: rgba(255, 204, 0, 0.5);
/* Shared tokens used across panels, inputs, and focus rings. */
--border: #2d2d3a;
--border-dk: #22222e;
--bg-input: #0f1117;
--accent: #6366f1;
}
::selection{
color: #000;
background: var(--asb-yellow);
}
nav{
position: fixed;
background: #000;
width: 100%;
padding: 10px 0;
z-index: 12;
border-bottom: 3px solid var(--asb-yellow);
}
nav .menu{
max-width: none;
width: 100%;
margin: auto;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 clamp(8px, 1vw, 16px);
}
.menu .logo a{
text-decoration: none;
color: var(--asb-yellow);
font-size: 35px;
font-weight: 600;
}
.menu ul{
display: flex;
}
.menu ul li{
list-style: none;
margin-left: 7px;
}
.menu ul li:first-child{
margin-left: 0px;
}
.menu ul li a{
text-decoration: none;
color: #fff;
font-size: 18px;
font-weight: 500;
padding: 0px 15px;
border-radius: 5px;
transition: all 0.3s ease;
}
.menu ul li a:hover{
background-color: var(--asb-yellow);
color: #000;
padding: 10px 15px;
}
/* ── Body & layout ─────────────────────────────────────────── */
body {
background: url(../images/recon_ranger_bg.jpg) no-repeat center center fixed;
background-size: cover;
color: #e2e8f0;
min-height: 100vh;
display: flex;
flex-direction: column;
}
body::before {
content: '';
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.55);
z-index: 0;
pointer-events: none;
}
main {
flex: 1;
padding-top: 70px; /* clear fixed nav */
padding-left: clamp(4px, 0.8vw, 12px);
padding-right: clamp(4px, 0.8vw, 12px);
position: relative;
z-index: 1;
}
footer {
position: relative;
z-index: 1;
background: rgba(0, 0, 0, 0.85);
color: #888;
text-align: center;
padding: 18px 20px;
font-size: 14px;
letter-spacing: 0.03em;
border-top: 1px solid #2d2d2d;
}
/* ── Dashboard content container ────────────────────────── */
.dashboard-container {
width: 100%;
margin: 8px 0;
padding: 14px clamp(10px, 1vw, 18px);
background: rgba(15, 17, 23, 0.45);
backdrop-filter: blur(6px);
border-radius: 12px;
display: flex;
flex-direction: column;
height: calc(100vh - 86px);
}
.dashboard-container h1 {
font-size: 28px;
font-weight: 600;
color: #f1f5f9;
margin-bottom: 8px;
padding-bottom: 8px;
border-bottom: 2px solid var(--asb-yellow);
letter-spacing: 0.02em;
flex-shrink: 0;
}
/* ── Data table ─────────────────────────────────────────── */
.table-scroll {
overflow-x: auto;
overflow-y: auto;
flex: 1;
border-radius: 10px;
min-height: 0;
}
.table-scroll .data-table thead th {
position: sticky;
top: 0;
z-index: 1;
}
.data-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
}
.data-table thead {
background: #1b1b2e;
}
.data-table thead th {
padding: 14px 18px;
text-align: left;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #94a3b8;
border-bottom: 1px solid var(--border);
white-space: nowrap;
}
.data-table tbody tr {
background: rgba(22, 22, 34, 0.72);
transition: background 0.15s ease;
}
.data-table tbody tr:nth-child(even) {
background: rgba(26, 26, 40, 0.72);
}
.data-table tbody tr:hover {
background: rgba(37, 37, 64, 0.85);
}
.data-table tbody td {
padding: 13px 18px;
border-bottom: 1px solid var(--border-dk);
color: #cbd5e1;
vertical-align: middle;
}
.data-table tbody tr:last-child td {
border-bottom: none;
}
/* ── Status badges ──────────────────────────────────────── */
.badge {
display: inline-block;
padding: 3px 10px;
border-radius: 999px;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.04em;
white-space: nowrap;
}
.badge-matched { background: rgba(34,197,94,0.15); color: #4ade80; }
.badge-unmatched { background: rgba(239,68,68,0.15); color: #f87171; }
.badge-pending { background: rgba(234,179,8,0.15); color: #facc15; }
.badge-none { background: rgba(100,116,139,0.15); color: #94a3b8; }
.badge-flag { background: rgba(249,115,22,0.15); color: #fb923c; }
/* ── Panel chrome ───────────────────────────────────────── */
/* Shared border + radius for every dark panel/card. Individual rules add
their own background, padding, and layout on top. */
.filter-bar, .timeline-day, .metric-card,
.editor-section, .editor-full-section, .editor-meta-strip, .editor-json-panel {
border: 1px solid var(--border);
border-radius: 10px;
}
/* ── Filter bar ─────────────────────────────────────────── */
.filter-bar {
display: flex;
flex-wrap: wrap;
align-items: flex-end;
gap: 16px;
margin-bottom: 8px;
padding: 12px 16px;
background: rgba(255, 255, 255, 0.04);
flex-shrink: 0;
}
.filter-group {
display: flex;
flex-direction: column;
gap: 6px;
}
.filter-group input {
font-size: 14px;
padding: 8px 12px;
border-radius: 6px;
min-width: 200px;
}
.filter-group input[type="date"]::-webkit-calendar-picker-indicator {
filter: invert(0.6);
cursor: pointer;
}
.filter-actions {
display: flex;
gap: 8px;
align-items: flex-end;
}
/* ── Form label — shared by filter bar and editor ───────── */
.filter-group label,
.editor-field label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.07em;
color: #94a3b8;
}
/* ── Form input base — shared bg/border/color ───────────── */
.filter-group input,
.editor-field input, .editor-field select, .editor-field textarea,
.schema-row input, .schema-row select,
.mapping-row input {
background: var(--bg-input);
border: 1px solid var(--border);
color: #e2e8f0;
}
/* ── Focus ring — all interactive inputs share this ─────── */
.filter-group input:focus,
.editor-field input:focus, .editor-field select:focus, .editor-field textarea:focus,
.schema-row input:focus, .schema-row select:focus,
.mapping-row input:focus {
outline: none;
border-color: var(--accent);
}
/* ── Buttons ────────────────────────────────────────────── */
.btn {
display: inline-block;
padding: 8px 18px;
border-radius: 6px;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.03em;
cursor: pointer;
text-decoration: none;
border: none;
transition: opacity 0.15s ease, background 0.15s ease;
white-space: nowrap;
}
.btn-primary {
background: var(--accent);
color: #fff;
}
.btn-primary:hover {
background: #4f46e5;
}
.btn-secondary {
background: rgba(255, 255, 255, 0.07);
color: #cbd5e1;
border: 1px solid var(--border);
}
.btn-secondary:hover:not(.btn-disabled) {
background: rgba(255, 255, 255, 0.13);
}
.btn-disabled {
opacity: 0.35;
cursor: default;
pointer-events: none;
}
.btn-sm {
padding: 5px 12px;
font-size: 12px;
}
/* ── Pagination ─────────────────────────────────────────── */
.pagination {
display: flex;
gap: 10px;
justify-content: flex-end;
margin-top: 8px;
flex-shrink: 0;
}
/* ── Dashboard timelines ────────────────────────────────── */
.timeline-wrap {
display: flex;
flex-direction: column;
gap: 22px;
overflow-y: auto;
flex: 1;
min-height: 0;
padding-right: 4px;
}
.timeline-day {
background: rgba(0, 0, 0, 0.3);
padding: 14px 18px 22px;
}
.timeline-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 14px;
flex-wrap: wrap;
gap: 10px;
}
.timeline-header h2 {
font-size: 16px;
font-weight: 600;
color: #f1f5f9;
letter-spacing: 0.02em;
}
.timeline-today-tag {
display: inline-block;
margin-left: 8px;
padding: 2px 8px;
border-radius: 999px;
background: rgba(99, 102, 241, 0.18);
color: #a5b4fc;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.timeline-legend {
display: flex;
gap: 14px;
font-size: 12px;
color: #94a3b8;
}
.legend-item {
display: inline-flex;
align-items: center;
gap: 6px;
}
.swatch {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 3px;
}
.swatch-completed { background: #4ade80; }
.swatch-running { background: #facc15; }
.swatch-scheduled { background: #818cf8; }
.timeline-axis {
position: relative;
height: 18px;
margin: 0 0 4px;
}
.tick {
position: absolute;
top: 0;
transform: translateX(-50%);
color: #64748b;
font-size: 10px;
letter-spacing: 0.05em;
}
.tick-label { user-select: none; }
.timeline-track {
--lane-count: 1;
--lane-height: 26px;
position: relative;
background: var(--bg-input);
border: 1px solid var(--border-dk);
border-radius: 6px;
min-height: 32px;
height: calc(var(--lane-count) * var(--lane-height) + 6px);
padding: 3px 0;
overflow: visible;
}
.gridline {
position: absolute;
top: 0;
bottom: 0;
width: 1px;
background: rgba(148, 163, 184, 0.08);
pointer-events: none;
}
.now-marker {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
background: #ef4444;
box-shadow: 0 0 6px rgba(239, 68, 68, 0.6);
pointer-events: none;
z-index: 3;
}
.timeline-empty {
color: #475569;
font-size: 12px;
text-align: center;
padding: 30px 0;
}
.job-bar {
--lane: 0;
position: absolute;
height: 22px;
top: calc(var(--lane) * var(--lane-height, 26px) + 3px);
border-radius: 4px;
padding: 0 6px;
display: flex;
align-items: center;
color: #0f172a;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.02em;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
z-index: 2;
min-width: 4px;
}
.job-bar-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
.job-bar-completed { background: rgba(74, 222, 128, 0.85); }
.job-bar-running { background: rgba(250, 204, 21, 0.85); }
.job-bar-scheduled {
background: rgba(129, 140, 248, 0.85);
border: 1px dashed rgba(255, 255, 255, 0.25);
color: #1e1b4b;
}
/* ── Dashboard metrics cards ────────────────────────────── */
.metrics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 14px;
margin-top: 18px;
padding-bottom: 4px;
}
.metric-card {
background: rgba(0, 0, 0, 0.3);
padding: 14px 16px 16px;
display: flex;
flex-direction: column;
gap: 10px;
min-width: 0;
}
.metric-card h3 {
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #94a3b8;
margin: 0;
padding-bottom: 6px;
border-bottom: 1px solid var(--asb-yellow);
}
.metric-card .num { font-variant-numeric: tabular-nums; text-align: right; }
.metric-card .good { color: #4ade80; }
.metric-card .bad { color: #f87171; }
.metric-card .warn { color: #facc15; }
.metric-card .muted { color: #64748b; font-size: 12px; }
.big-stat {
display: flex;
align-items: baseline;
gap: 8px;
}
.big-stat-value {
font-size: 36px;
font-weight: 700;
color: #f1f5f9;
letter-spacing: -0.01em;
line-height: 1;
}
.big-stat-sub { color: #94a3b8; font-size: 12px; }
.kv-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 6px;
}
.kv-list li {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 10px;
font-size: 13px;
color: #cbd5e1;
line-height: 1.35;
}
.kv-list li span:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
.metric-table-scroll {
/* Let the table scroll horizontally inside a narrow card instead of
spilling out. The card itself stays put. */
overflow-x: auto;
margin: 0 -4px;
}
.metric-table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
}
.metric-table th, .metric-table td {
padding: 6px 6px;
text-align: right;
color: #cbd5e1;
white-space: nowrap;
}
.metric-table thead th {
color: #94a3b8;
font-weight: 600;
font-size: 11px;
letter-spacing: 0.04em;
border-bottom: 1px solid var(--border);
}
.metric-table tbody th {
text-align: left;
color: #94a3b8;
font-weight: 500;
}
.metric-table tbody tr + tr td,
.metric-table tbody tr + tr th { border-top: 1px solid rgba(45, 45, 58, 0.6); }
.empty-note {
font-size: 13px;
padding: 6px 0;
}
/* Dashboard variant: allow content to flow & page to scroll naturally. */
.dashboard-container.dashboard-stack {
height: auto;
min-height: calc(100vh - 86px);
}
.dashboard-container.dashboard-stack .timeline-wrap {
flex: 0 0 auto;
overflow: visible;
}
/* ── Clickable rows / job links ─────────────────────────── */
.row-link {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 10px;
width: 100%;
color: inherit;
text-decoration: none;
padding: 2px 4px;
margin: -2px -4px;
border-radius: 4px;
transition: background 0.15s ease;
}
.row-link:hover { background: rgba(99, 102, 241, 0.12); }
.job-link {
color: var(--asb-yellow);
text-decoration: none;
font-weight: 600;
}
.job-link:hover { text-decoration: underline; }
.job-link .muted { font-weight: 400; }
a.job-bar { text-decoration: none; cursor: pointer; }
a.job-bar:hover { filter: brightness(1.1); box-shadow: 0 0 0 1px rgba(255,255,255,0.4); }
/* ── Job detail page ────────────────────────────────────── */
.detail-header {
margin-bottom: 14px;
padding-bottom: 10px;
border-bottom: 2px solid var(--asb-yellow);
}
.detail-header h1 {
border-bottom: none;
margin-bottom: 4px;
padding-bottom: 0;
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.detail-crumbs {
font-size: 13px;
color: #94a3b8;
margin-bottom: 6px;
}
.detail-crumbs a {
color: var(--asb-yellow);
text-decoration: none;
}
.detail-crumbs a:hover { text-decoration: underline; }
.detail-subtitle {
font-size: 13px;
margin-top: 4px;
}
.detail-subtitle code,
.kv-list code,
.metric-table code {
background: rgba(255,255,255,0.06);
padding: 1px 6px;
border-radius: 4px;
font-size: 12px;
color: #cbd5e1;
}
.swatch-failed { background: #f87171; }
/* Shared size for all job/config status badges (colour set per variant below) */
[class*="badge-status-"] { font-size: 13px; padding: 4px 12px; }
.badge-status-completed { background: rgba(34,197,94,0.18); color: #4ade80; }
.badge-status-failed { background: rgba(239,68,68,0.18); color: #f87171; }
.badge-status-running { background: rgba(234,179,8,0.18); color: #facc15; }
.badge-status-created { background: rgba(129,140,248,0.18); color: #a5b4fc; }
.badge-status-cancelled { background: rgba(100,116,139,0.18); color: #94a3b8; }
/* Config lifecycle status badges */
.badge-config-published { background: rgba(34,197,94,0.15); color: #4ade80; }
.badge-config-draft { background: rgba(234,179,8,0.15); color: #facc15; }
.badge-config-archived { background: rgba(100,116,139,0.15); color: #94a3b8; }
.history-timeline { padding: 14px 18px 16px; }
.history-track {
position: relative;
background: var(--bg-input);
border: 1px solid var(--border-dk);
border-radius: 6px;
height: 56px;
margin-bottom: 6px;
overflow: visible;
}
.history-dot {
position: absolute;
top: 50%;
width: 14px;
height: 14px;
margin-left: -7px;
margin-top: -7px;
border-radius: 50%;
background: #4ade80;
box-shadow: 0 0 0 2px rgba(15, 17, 23, 0.9);
transition: transform 0.15s ease, box-shadow 0.15s ease;
z-index: 2;
}
.history-dot:hover {
transform: scale(1.35);
z-index: 3;
}
.history-dot-completed { background: #4ade80; }
.history-dot-failed { background: #f87171; }
.history-dot-running { background: #facc15; }
.history-dot-scheduled {
background: #818cf8;
border: 1px dashed rgba(255,255,255,0.35);
}
.history-dot.is-current {
width: 18px;
height: 18px;
margin-left: -9px;
margin-top: -9px;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.55), 0 0 12px rgba(99,102,241,0.6);
z-index: 4;
}
.history-footnote {
font-size: 12px;
padding-top: 4px;
}
.metric-card-wide {
grid-column: 1 / -1;
}
.results-table tbody th {
width: 30%;
padding-right: 14px;
}
.results-table tbody td {
text-align: left;
}
.nested-item { display: block; font-size: 13px; }
.nested-key { color: #94a3b8; margin-right: 6px; }
/* ── Instant CSS tooltip (replaces native title= delay) ── */
/* Note: do NOT add `position: relative` here — it would override the
`position: absolute` on .job-bar / .history-dot. The pseudo-element below
positions relative to whichever ancestor is already positioned. */
[data-tip]::after {
content: attr(data-tip);
position: absolute;
bottom: calc(100% + 6px);
left: 50%;
transform: translateX(-50%);
background: var(--bg-input);
color: #e2e8f0;
border: 1px solid var(--border);
border-radius: 6px;
padding: 6px 9px;
font-size: 12px;
font-weight: 500;
white-space: nowrap;
pointer-events: none;
opacity: 0;
visibility: hidden;
z-index: 50;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
letter-spacing: 0.01em;
}
[data-tip]:hover::after,
[data-tip]:focus-visible::after {
opacity: 1;
visibility: visible;
transition-delay: 0s;
}
/* ── Config editor layout ───────────────────────────────── */
/* Meta strip — wrapping flex row of form fields */
.editor-meta-strip {
display: flex;
flex-wrap: wrap;
gap: 14px 20px;
padding: 16px 18px;
background: rgba(0,0,0,0.25);
margin-bottom: 16px;
}
/* Two-column body */
.editor-body {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 16px;
}
@media (max-width: 860px) {
.editor-body { grid-template-columns: 1fr; }
}
/* Section wrappers — shared chrome handled by the panel block above */
.editor-section,
.editor-full-section {
background: rgba(0,0,0,0.25);
padding: 14px 16px;
}
.editor-section {
display: flex;
flex-direction: column;
gap: 10px;
}
.editor-full-section {
margin-bottom: 16px;
}
.editor-section-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.editor-section-header h2 {
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #94a3b8;
padding-bottom: 6px;
border-bottom: 1px solid var(--asb-yellow);
flex: 1;
margin-right: 12px;
}
/* Individual form fields */
.editor-field {
display: flex;
flex-direction: column;
gap: 5px;
min-width: 160px;
}
.editor-field-wide { min-width: 260px; flex: 1; }
.editor-field-full { flex-basis: 100%; width: 100%; }
/* .editor-field label shares its rule with .filter-group label above */
.editor-field input,
.editor-field select,
.editor-field textarea {
border-radius: 6px;
font-size: 13px;
padding: 7px 11px;
transition: border-color 0.15s ease;
width: 100%;
}
.editor-field input[readonly] {
opacity: 0.6;
cursor: not-allowed;
}
.editor-field textarea { resize: vertical; }
.field-hint {
font-size: 11px;
color: #64748b;
line-height: 1.4;
}
.field-hint code {
background: rgba(255,255,255,0.06);
padding: 1px 5px;
border-radius: 3px;
font-size: 11px;
}
.req { color: #f87171; }
/* System config card */
.syscfg-card {
background: rgba(255,255,255,0.03);
border: 1px solid var(--border);
border-radius: 8px;
padding: 12px 14px;
margin-bottom: 10px;
}
.syscfg-card:last-child { margin-bottom: 0; }
.syscfg-card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.syscfg-card-title {
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--asb-yellow);
}
.syscfg-grid {
display: flex;
flex-wrap: wrap;
gap: 12px 16px;
}
.syscfg-section {
margin-top: 10px;
border-top: 1px solid var(--border);
padding-top: 8px;
}
.syscfg-section summary {
font-size: 12px;
font-weight: 600;
color: #94a3b8;
cursor: pointer;
user-select: none;
display: flex;
align-items: center;
gap: 8px;
padding: 4px 0;
}
.syscfg-section summary:hover { color: #e2e8f0; }
.syscfg-section-count {
font-size: 11px;
color: #64748b;
font-weight: 400;
font-style: italic;
}
.syscfg-section > .syscfg-grid,
.syscfg-section > .schema-builder {
padding-top: 10px;
}
/* URL test row */
.url-input-row {
display: flex;
gap: 8px;
align-items: stretch;
}
.url-input-row .url-scheme { flex-shrink: 0; width: auto; }
.url-input-row .url-path { flex: 1; width: 0; min-width: 0; }
.url-test-result {
margin-top: 6px;
padding: 8px 10px;
border-radius: 6px;
font-size: 12px;
font-family: monospace;
white-space: pre-wrap;
line-height: 1.5;
}
.url-test-loading { background: rgba(99,102,241,0.1); color: #a5b4fc; border: 1px solid #3730a3; }
.url-test-ok { background: rgba(34,197,94,0.08); color: #86efac; border: 1px solid #166534; }
.url-test-error { background: rgba(239,68,68,0.1); color: #fca5a5; border: 1px solid #991b1b; }
.url-test-info { background: rgba(234,179,8,0.08); color: #fde68a; border: 1px solid #78350f; }
/* Schema builder */
.schema-builder { display: flex; flex-direction: column; gap: 6px; }
.kv-table-header {
display: grid;
grid-template-columns: 1fr 1fr auto auto;
gap: 8px;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.07em;
color: #64748b;
padding: 0 2px;
}
.schema-row {
display: grid;
grid-template-columns: 1fr 1fr auto auto;
gap: 8px;
align-items: center;
}
.schema-row .idx-check {
width: 16px;
height: 16px;
accent-color: var(--accent);
cursor: pointer;
justify-self: center;
}
.schema-row input,
.schema-row select {
border-radius: 5px;
font-size: 12px;
padding: 5px 8px;
width: 100%;
}
.schema-type-cell {
display: flex;
align-items: center;
gap: 6px;
min-width: 0;
}
.schema-type-cell .schema-type-select {
width: auto;
min-width: 80px;
flex-shrink: 0;
}
.schema-fmt-wrapper {
flex: 1;
min-width: 0;
display: flex;
}
.schema-fmt-input {
width: 100%;
min-width: 80px;
}
.schema-dec-wrapper {
display: flex;
gap: 4px;
}
.schema-dec-prec,
.schema-dec-scale {
width: 54px;
}
/* Field mapping */
.mapping-header {
display: grid;
grid-template-columns: 1fr auto 1fr auto;
gap: 8px;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.07em;
color: #64748b;
padding: 0 2px 4px;
}
.mapping-row {
display: grid;
grid-template-columns: 1fr auto 1fr auto;
gap: 8px;
align-items: center;
margin-bottom: 6px;
}
.mapping-row input {
border-radius: 5px;
font-size: 13px;
padding: 6px 10px;
}
.mapping-arrow { color: var(--accent); font-size: 16px; text-align: center; }
/* Toggle checkbox */
.toggle-label {
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.toggle-label input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-track {
width: 36px;
height: 20px;
background: #2d2d3a;
border-radius: 999px;
position: relative;
transition: background 0.2s;
flex-shrink: 0;
}
.toggle-track::after {
content: '';
position: absolute;
top: 3px; left: 3px;
width: 14px; height: 14px;
background: #94a3b8;
border-radius: 50%;
transition: transform 0.2s, background 0.2s;
}
.toggle-label input:checked ~ .toggle-track { background: var(--accent); }
.toggle-label input:checked ~ .toggle-track::after { transform: translateX(16px); background: #fff; }
/* Action bar */
.editor-actions {
display: flex;
justify-content: flex-end;
gap: 10px;
padding: 12px 0 4px;
border-top: 1px solid var(--border);
margin-top: 4px;
}
/* JSON preview */
.editor-json-panel {
background: rgba(0,0,0,0.4);
padding: 16px;
margin-top: 16px;
}
.editor-json-pre {
background: #0a0c10;
border: 1px solid var(--border-dk);
border-radius: 6px;
padding: 14px;
font-size: 12px;
line-height: 1.6;
color: #cbd5e1;
overflow-x: auto;
max-height: 50vh;
white-space: pre;
}
/* Toast notification */
.editor-toast {
position: fixed;
bottom: 28px;
right: 28px;
background: #1e293b;
border: 1px solid #334155;
border-radius: 8px;
padding: 12px 20px;
font-size: 13px;
font-weight: 500;
color: #e2e8f0;
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
z-index: 200;
opacity: 0;
transform: translateY(8px);
transition: opacity 0.2s ease, transform 0.2s ease;
pointer-events: none;
}
.editor-toast-visible {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
.editor-toast-ok { border-left: 3px solid #4ade80; }
.editor-toast-warn { border-left: 3px solid #facc15; }
.editor-toast-error { border-left: 3px solid #f87171; }