/* Component library — all UI primitives map to DESIGN.md tokens. */ [hidden] { display: none !important; } /* ---------- Top Navigation ---------- */ .top-nav { display: flex; align-items: center; gap: var(--space-lg); height: var(--nav-height); padding: 0 var(--space-xl); background-color: var(--color-canvas); border-bottom: 1px solid var(--color-hairline); } .top-nav .wordmark { display: flex; align-items: center; gap: var(--space-xs); font: var(--typo-title-md); font-weight: 500; color: var(--color-ink); } .top-nav .wordmark .spike { width: 16px; height: 16px; color: var(--color-ink); } .top-nav nav { display: flex; gap: var(--space-md); flex: 1; } .top-nav nav a { padding: var(--space-xs) var(--space-sm); color: var(--color-muted); font: var(--typo-nav-link); border-radius: var(--radius-md); text-decoration: none; } .top-nav nav a:hover { color: var(--color-ink); background-color: var(--color-surface-soft); } .top-nav nav a.active { color: var(--color-ink); background-color: var(--color-surface-card); } /* ---------- Nav-right cluster (lang switcher + New Job) ---------- */ .nav-right { display: flex; align-items: center; gap: var(--space-md); margin-left: auto; } .lang-switcher { display: inline-flex; align-items: center; gap: 4px; height: 32px; padding: 0 8px; border-radius: var(--radius-md); background-color: var(--color-surface-soft); } .lang-btn { background: transparent; border: none; padding: 4px 8px; font: var(--typo-caption); color: var(--color-muted); border-radius: var(--radius-sm); cursor: pointer; line-height: 1; } .lang-btn:hover { color: var(--color-ink); } .lang-btn.active { background-color: var(--color-canvas); color: var(--color-ink); box-shadow: 0 1px 2px rgba(20, 20, 19, 0.06); } .lang-sep { color: var(--color-muted-soft); font: var(--typo-caption); user-select: none; } /* ---------- Buttons ---------- */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs); height: 40px; padding: 12px 20px; font: var(--typo-button); border-radius: var(--radius-md); border: 1px solid transparent; cursor: pointer; text-decoration: none; transition: background-color 120ms ease; user-select: none; } .btn-primary { background-color: var(--color-primary); color: var(--color-on-primary); } .btn-primary:hover { background-color: var(--color-primary-active); text-decoration: none; } .btn-primary:disabled { background-color: var(--color-primary-disabled); color: var(--color-muted); cursor: not-allowed; } .btn-secondary { background-color: var(--color-canvas); color: var(--color-ink); border-color: var(--color-hairline); } .btn-secondary:hover { background-color: var(--color-surface-soft); text-decoration: none; } .btn-danger { background-color: transparent; color: var(--color-error); border-color: var(--color-hairline); } .btn-danger:hover { background-color: var(--color-error); color: var(--color-on-primary); border-color: var(--color-error); } .btn-icon { width: 36px; height: 36px; padding: 0; border-radius: var(--radius-full); background-color: var(--color-canvas); color: var(--color-ink); border: 1px solid var(--color-hairline); font-size: 16px; } .btn-icon:hover { background-color: var(--color-surface-soft); } .btn-sm { height: 32px; padding: 8px 12px; font-size: 13px; } /* ---------- Cards ---------- */ .card { background-color: var(--color-surface-card); border-radius: var(--radius-lg); padding: var(--space-xl); } .card-outline { background-color: var(--color-canvas); border: 1px solid var(--color-hairline); border-radius: var(--radius-lg); padding: var(--space-xl); } .card-dark { background-color: var(--color-surface-dark); color: var(--color-on-dark); border-radius: var(--radius-lg); padding: var(--space-xl); } /* ---------- Connector tiles (remote cards) ---------- */ .connector-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-md); } .connector-tile { background-color: var(--color-canvas); border: 1px solid var(--color-hairline); border-radius: var(--radius-lg); padding: var(--space-lg); display: flex; flex-direction: column; gap: var(--space-xs); cursor: pointer; text-decoration: none; color: inherit; } .connector-tile:hover { background-color: var(--color-surface-soft); border-color: var(--color-surface-cream-strong); } .connector-tile .tile-name { font: var(--typo-title-sm); color: var(--color-ink); } .connector-tile .tile-type { font: var(--typo-caption); color: var(--color-muted); } /* Tile with action overlay (edit/delete buttons in top-right corner) */ .connector-tile.tile-with-actions { position: relative; } .connector-tile.tile-with-actions .tile-actions { position: absolute; top: var(--space-xs); right: var(--space-xs); display: flex; gap: var(--space-xxs); opacity: 0; transition: opacity 120ms ease; } .connector-tile.tile-with-actions:hover .tile-actions { opacity: 1; } .connector-tile.tile-with-actions .tile-actions button { width: 28px; height: 28px; padding: 0; border: 1px solid var(--color-hairline); border-radius: var(--radius-sm); background-color: var(--color-canvas); color: var(--color-muted); font-size: 14px; line-height: 1; cursor: pointer; } .connector-tile.tile-with-actions .tile-actions button:hover { background-color: var(--color-surface-card); color: var(--color-ink); } .connector-tile.tile-with-actions .tile-actions button.danger:hover { background-color: var(--color-error); color: var(--color-on-primary); border-color: var(--color-error); } /* ---------- Inputs ---------- */ .input, .select { width: 100%; height: 40px; padding: 10px 14px; font: var(--typo-body-md); background-color: var(--color-canvas); color: var(--color-ink); border: 1px solid var(--color-hairline); border-radius: var(--radius-md); outline: none; transition: border-color 120ms ease, box-shadow 120ms ease; } .input:focus, .select:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-15); } .field { display: flex; flex-direction: column; gap: var(--space-xs); } .field label { font: var(--typo-caption); color: var(--color-muted); } .input-action { display: flex; align-items: center; gap: var(--space-xs); } .input-action .input { flex: 1; min-width: 0; } .input-action .btn { flex-shrink: 0; } .input-action .select { flex: 0 0 150px; width: auto; } .segmented { display: inline-flex; width: fit-content; padding: 3px; border: 1px solid var(--color-hairline); border-radius: var(--radius-md); background-color: var(--color-surface-soft); } .segmented label { position: relative; color: var(--color-muted); } .segmented input { position: absolute; opacity: 0; pointer-events: none; } .segmented span { display: inline-flex; align-items: center; justify-content: center; min-width: 92px; height: 32px; padding: 0 var(--space-sm); border-radius: var(--radius-sm); cursor: pointer; font: var(--typo-button); } .segmented input:checked + span { background-color: var(--color-canvas); color: var(--color-ink); box-shadow: 0 1px 2px rgba(20, 20, 19, 0.06); } .segmented-wide { max-width: 100%; flex-wrap: wrap; } .recurrence-fields { display: grid; gap: var(--space-md); } .recurrence-fields[hidden] { display: none; } /* ---------- Badges ---------- */ .badge { display: inline-flex; align-items: center; padding: 4px 12px; font: var(--typo-caption); border-radius: var(--radius-pill); background-color: var(--color-surface-card); color: var(--color-ink); } .badge-coral { background-color: var(--color-primary); color: var(--color-on-primary); font: var(--typo-caption-uppercase); letter-spacing: var(--typo-caption-uppercase-tracking); } .badge-success { background-color: var(--color-success); color: var(--color-on-primary); } .badge-warning { background-color: var(--color-warning); color: var(--color-on-primary); } .badge-error { background-color: var(--color-error); color: var(--color-on-primary); } /* ---------- Breadcrumbs ---------- */ .breadcrumbs { display: flex; align-items: center; gap: var(--space-xxs); flex-wrap: wrap; } .breadcrumbs a, .breadcrumbs span { padding: var(--space-xs) calc(var(--space-sm) + 2px); font: var(--typo-nav-link); color: var(--color-muted); border-radius: var(--radius-md); text-decoration: none; } .breadcrumbs a:hover { color: var(--color-ink); background-color: var(--color-surface-soft); } .breadcrumbs .current { color: var(--color-ink); background-color: var(--color-surface-card); } .breadcrumbs .sep { padding: 0 var(--space-xxs); color: var(--color-muted-soft); } /* ---------- Tables ---------- */ .table { width: 100%; border-collapse: collapse; } .table th, .table td { text-align: left; padding: var(--space-sm) var(--space-md); font: var(--typo-body-sm); color: var(--color-body); } .table thead th { font: var(--typo-caption); color: var(--color-muted); border-bottom: 1px solid var(--color-hairline); } .table tbody tr { border-bottom: 1px solid var(--color-hairline-soft); } .table tbody tr:last-child { border-bottom: none; } .table tbody tr:hover { background-color: var(--color-surface-soft); } .table .col-name { font: var(--typo-body-md); color: var(--color-ink); } .table .col-name a { color: var(--color-ink); text-decoration: none; } .table .col-name a:hover { color: var(--color-primary); text-decoration: underline; } .table .col-mono { font: var(--typo-code); color: var(--color-muted); } .table .col-num { text-align: right; font-variant-numeric: tabular-nums; } .table .row-dir .col-name a { color: var(--color-primary); } /* ---------- Progress bar ---------- */ .progress { width: 100%; height: 4px; background-color: var(--color-surface-card); border-radius: var(--radius-pill); overflow: hidden; } .progress > span { display: block; height: 100%; background-color: var(--color-primary); transition: width 200ms ease; } /* ---------- Toolbar ---------- */ .toolbar { display: flex; align-items: center; gap: var(--space-sm); flex-wrap: wrap; } .toolbar .spacer { flex: 1; } /* ---------- Section header ---------- */ .section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-md); margin-bottom: var(--space-lg); } .section-head h2 { font: var(--typo-display-md); letter-spacing: var(--typo-display-md-tracking); } .section-head .subtitle { color: var(--color-muted); font: var(--typo-body-sm); } /* ---------- Empty state ---------- */ .empty { padding: var(--space-section) var(--space-xl); text-align: center; color: var(--color-muted); } .empty h3 { margin-bottom: var(--space-sm); font: var(--typo-display-sm); letter-spacing: var(--typo-display-sm-tracking); color: var(--color-ink); } /* ---------- Toast ---------- */ .toast-stack { position: fixed; bottom: var(--space-lg); right: var(--space-lg); display: flex; flex-direction: column; gap: var(--space-sm); z-index: 100; } .toast { padding: var(--space-sm) var(--space-lg); background-color: var(--color-surface-dark); color: var(--color-on-dark); border-radius: var(--radius-lg); font: var(--typo-body-sm); max-width: 360px; box-shadow: var(--shadow-hover); } .toast-error { background-color: var(--color-error); color: var(--color-on-primary); } .toast-success { background-color: var(--color-success); color: var(--color-on-primary); } /* ---------- Modal ---------- */ .modal-overlay { position: fixed; inset: 0; background-color: rgba(20, 20, 19, 0.4); display: flex; align-items: center; justify-content: center; z-index: 200; padding: var(--space-lg); } .modal { background-color: var(--color-surface-dark); color: var(--color-on-dark); border-radius: var(--radius-lg); padding: var(--space-lg); width: 100%; max-width: 480px; display: flex; flex-direction: column; gap: var(--space-md); } .modal h3 { font: var(--typo-title-lg); color: var(--color-on-dark); margin: 0; } .modal label { color: var(--color-on-dark-soft); font: var(--typo-caption); } .modal .input, .modal .select { background-color: var(--color-surface-dark-elevated); color: var(--color-on-dark); border-color: var(--color-surface-dark-elevated); } .modal .input:focus, .modal .select:focus { border-color: var(--color-primary); } .modal-actions { display: flex; justify-content: flex-end; gap: var(--space-sm); } .modal .btn-secondary { background-color: var(--color-surface-dark-elevated); color: var(--color-on-dark); border-color: transparent; } .folder-picker { max-width: 640px; } .folder-picker-path { padding: var(--space-sm) var(--space-md); background-color: var(--color-surface-dark-elevated); border-radius: var(--radius-md); color: var(--color-on-dark-soft); font: var(--typo-code); word-break: break-all; } .folder-picker-list { display: flex; flex-direction: column; gap: var(--space-xs); max-height: 360px; overflow: auto; } .folder-picker-row { width: 100%; padding: var(--space-sm) var(--space-md); background-color: var(--color-surface-dark-elevated); color: var(--color-on-dark); border: 1px solid transparent; border-radius: var(--radius-md); text-align: left; font: var(--typo-body-sm); cursor: pointer; } .folder-picker-row:hover { border-color: var(--color-primary); } .folder-picker-row:disabled { color: var(--color-muted-soft); cursor: not-allowed; opacity: 0.6; } /* ---------- Footer ---------- */ .footer { background-color: var(--color-surface-dark); color: var(--color-on-dark-soft); padding: var(--space-xxl) var(--space-xl); margin-top: var(--space-section); flex-shrink: 0; } .footer-inner { max-width: var(--content-max); margin: 0 auto; display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: var(--space-xl); } .footer h4 { color: var(--color-on-dark); font: var(--typo-title-sm); font-family: var(--font-body); font-weight: 500; margin-bottom: var(--space-sm); } .footer a { color: var(--color-on-dark-soft); font: var(--typo-body-sm); text-decoration: none; } .footer a:hover { color: var(--color-on-dark); } .footer .colophon { grid-column: 1 / -1; margin-top: var(--space-lg); padding-top: var(--space-lg); border-top: 1px solid var(--color-surface-dark-elevated); color: var(--color-on-dark-soft); font: var(--typo-caption); } /* ---------- Configure: provider picker + dynamic form ---------- */ .provider-search { margin-bottom: var(--space-lg); } .provider-search input { max-width: 360px; } .banner { display: flex; align-items: flex-start; gap: var(--space-sm); padding: var(--space-md) var(--space-lg); border-radius: var(--radius-md); background-color: var(--color-surface-card); color: var(--color-body-strong); font: var(--typo-body-sm); margin-bottom: var(--space-lg); } .banner-warning { background-color: color-mix(in srgb, var(--color-warning) 18%, var(--color-canvas)); border: 1px solid color-mix(in srgb, var(--color-warning) 35%, transparent); } .banner code { display: block; margin-top: var(--space-xs); padding: var(--space-xs) var(--space-sm); background-color: var(--color-surface-dark); color: var(--color-on-dark); border-radius: var(--radius-sm); font: var(--typo-code); white-space: pre-wrap; user-select: all; } .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md) var(--space-lg); } .form-grid .field-full { grid-column: 1 / -1; } .form-grid .field-bool { flex-direction: row; align-items: center; gap: var(--space-sm); } .form-grid .field-bool input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--color-primary); } .field .field-help { font: var(--typo-body-sm); color: var(--color-muted); line-height: 1.4; } .field .field-required { color: var(--color-error); margin-left: 2px; } .form-section-title { grid-column: 1 / -1; font: var(--typo-caption-uppercase); letter-spacing: var(--typo-caption-uppercase-tracking); color: var(--color-muted-soft); margin-top: var(--space-sm); padding-top: var(--space-sm); border-top: 1px solid var(--color-hairline-soft); } .form-section-title:first-child { margin-top: 0; border-top: none; padding-top: 0; } .advanced-toggle-wrap { grid-column: 1 / -1; margin-top: var(--space-sm); } .advanced-section { grid-column: 1 / -1; display: contents; } .advanced-section.hidden { display: none; } .danger-zone { border: 1px solid var(--color-error); border-radius: var(--radius-md); padding: var(--space-lg); margin-top: var(--space-xl); background-color: color-mix(in srgb, var(--color-error) 5%, var(--color-canvas)); } .danger-zone h4 { font: var(--typo-title-sm); font-family: var(--font-body); color: var(--color-error); margin: 0 0 var(--space-xs); } .danger-zone p { font: var(--typo-body-sm); color: var(--color-muted); margin-bottom: var(--space-md); } /* ---------- Job cell with action + src→dst ---------- */ .job-cell { display: flex; flex-direction: column; gap: 2px; min-width: 200px; } .job-cell .job-action { font: var(--typo-caption-uppercase); letter-spacing: var(--typo-caption-uppercase-tracking); color: var(--color-muted); } .job-cell .job-paths { font: var(--typo-body-sm); color: var(--color-body); word-break: break-all; } .job-cell .job-paths .arrow { color: var(--color-muted-soft); margin: 0 var(--space-xxs); } .job-actions { display: inline-flex; justify-content: flex-end; gap: var(--space-xs); flex-wrap: wrap; } .job-detail-row { background-color: var(--color-surface-soft); } .job-detail { display: grid; gap: var(--space-sm); padding: var(--space-sm) 0; } .job-detail dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xs) var(--space-lg); margin: 0; } .job-detail dl div { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: var(--space-sm); } .job-detail dt { color: var(--color-muted); font: var(--typo-caption); } .job-detail dd { margin: 0; color: var(--color-body); font: var(--typo-code); word-break: break-word; } .job-detail-output span { display: block; margin-bottom: var(--space-xs); color: var(--color-muted); font: var(--typo-caption); } .job-detail-output pre { max-height: 220px; margin: 0; padding: var(--space-sm); overflow: auto; white-space: pre-wrap; word-break: break-word; background-color: var(--color-canvas); border: 1px solid var(--color-hairline-soft); border-radius: var(--radius-sm); color: var(--color-body); font: var(--typo-code); } /* ---------- Responsive ---------- */ @media (max-width: 1024px) { .connector-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } .footer-inner { grid-template-columns: 1fr 1fr; } .form-grid { grid-template-columns: 1fr; } } @media (max-width: 768px) { main { padding: var(--space-md); } .connector-grid { grid-template-columns: 1fr; } .footer-inner { grid-template-columns: 1fr; } .top-nav { padding: 0 var(--space-md); } .top-nav nav { display: none; } }