@import url('tokens.css');

/* ============================================================================
   Connector page (master-detail) — tree-pane toolbar, panel cards, pipeline.
   ============================================================================ */

/* The driver-registry row that opens the tree — a selectable leaf drawn outside the TreeView,
   under the column masthead the scaffold draws (ui-md-tree-header, shared.css). */
/* The registry row is a real button: the column's other rows are reached with the keyboard through
   the tree, and this one is drawn outside it, so it takes the element that already answers Enter
   and Space and announces itself. The reset below is what keeps it looking like the row it is. */
.cn-drivers-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    margin-bottom: var(--space-2);
    border-radius: var(--radius-md);
    cursor: pointer;
    width: 100%;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
}

.cn-drivers-row:hover { background: var(--color-overlay-hover); }
.cn-drivers-row.selected { background: var(--color-surface); box-shadow: inset 0 0 0 1px var(--color-stroke); }
.cn-drivers-row .cn-drivers-name { font-weight: var(--font-weight-bold); font-size: var(--font-size-label); flex: 1 1 auto; }
.cn-drivers-row .cn-drivers-count { font-size: var(--font-size-description); color: var(--color-text-secondary); }

/* The head of a table a panel holds: what the table is, and the one command that grows it. The
   verb rides here, above the rows it adds to, instead of on the page's command bar, which keeps
   what acts on the selected node. */
.cn-table-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-3);
}

.cn-table-head .cn-card-title { margin-bottom: 0; }

/* Tree-pane toolbar: how the column is narrowed — search + state filter. What grows it is the
   column's footer command (ui-md-tree-footer, shared.css), whose menu is the shared primitive. */
.cn-tree-toolbar { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-3); }
.cn-search-row { display: flex; gap: var(--space-2); align-items: center; }
.cn-search-row .ui-input { flex: 1 1 auto; }

/* Segmented state filter (All / OK / Issues / Off). */
.cn-filter {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-1);
    padding: var(--space-1);
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
}

.cn-filter-seg {
    font-size: var(--font-size-description);
    color: var(--color-text-secondary);
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    padding: var(--space-2) 0;
    cursor: pointer;
}

.cn-filter-seg:hover { background: var(--color-overlay-hover); }
.cn-filter-seg.active {
    background: var(--color-surface);
    color: var(--color-text);
    font-weight: var(--font-weight-semibold);
    box-shadow: var(--shadow-card);
}

.cn-tree-divider { height: 1px; background: var(--color-stroke); margin: var(--space-1) var(--space-1) var(--space-2); }

/* Detail panels. A panel opens with the shared header (ui-panel-head*, shared.css); what is left
   here is the tag panel's own identity line and the quiet sub the cards below reuse. */
.cn-panel { width: 100%; }
.cn-panel-title { font-size: var(--font-size-section); font-weight: var(--font-weight-semibold); }
.cn-panel-sub { font-size: var(--font-size-description); color: var(--color-text-secondary); margin-top: var(--space-1); }
.cn-discovery-progress { margin-bottom: var(--space-3); }
.cn-discovery-progress.awaiting-cleanup { color: var(--color-caution); font-weight: var(--font-weight-semibold); }
.cn-error-text { color: var(--color-critical); font-size: var(--font-size-description); margin-top: var(--space-2); }

.cn-discovery-setup {
    padding: var(--space-4);
    margin-bottom: var(--space-4);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-lg);
    background: var(--color-surface-alt);
}

.cn-discovery-setup-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-3);
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
}

.cn-discovery-setup-head .cn-card-title { margin-bottom: 0; color: var(--color-text); }
.cn-discovery-target-field { flex: 2 1 280px; }
.cn-discovery-units-field { flex: 1 1 180px; }
.cn-discovery-port-field { flex: 1 1 260px; }
.cn-discovery-port-control { display: flex; align-items: center; gap: var(--space-2); }
.cn-discovery-port-control > .cn-serial-port-field { min-width: 130px; flex: 1 1 auto; }
.cn-serial-port-field { display: flex; min-width: 0; }
.cn-serial-port-field .ui-input {
    min-width: 0;
    flex: 1 1 auto;
    border-right: 0;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
}
.cn-serial-port-picker {
    width: 42px;
    min-width: 42px;
    flex: 0 0 42px;
    padding-inline: 0;
    justify-content: center;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
/* Compact picker: only the chevron shows; the chosen value lives in the paired text field. */
.cn-serial-port-picker .ui-combobox-value { display: none; }
.cn-serial-port-empty {
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
}
.cn-discovery-budget {
    margin-top: var(--space-3);
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
    font-variant-numeric: tabular-nums;
}
.cn-discovery-budget.error { color: var(--color-critical); }

.cn-pairing {
    padding: var(--space-5);
    margin-bottom: var(--space-4);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-lg);
    background: var(--color-surface-alt);
}

.cn-pairing-head,
.cn-pairing-actions {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
}

.cn-pairing-head .cn-card-title { margin-bottom: 0; }
.cn-pairing-fields { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); margin-top: var(--space-5); }
.cn-pairing-fields .ui-password { width: 100%; }
.cn-pairing-help { color: var(--color-text-secondary); font-size: var(--font-size-eyebrow); line-height: 1.45; }
.cn-pairing-progress { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--color-stroke-subtle); }
.cn-pairing-steps { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-2); }
.cn-pairing-step { display: flex; align-items: center; gap: var(--space-2); color: var(--color-text-disabled); font-size: var(--font-size-eyebrow); }
.cn-pairing-step.reached { color: var(--color-text-secondary); }
.cn-pairing-step.current { color: var(--color-accent-text); font-weight: var(--font-weight-semibold); }
.cn-pairing-step-dot { width: 8px; height: 8px; flex: 0 0 auto; border-radius: 50%; background: var(--color-stroke); }
.cn-pairing-step.reached .cn-pairing-step-dot,
.cn-pairing-step.current .cn-pairing-step-dot { background: var(--color-accent); }
.cn-pairing-status { margin-top: var(--space-3); color: var(--color-text-secondary); font-size: var(--font-size-description); }
.cn-pairing-actions { align-items: center; justify-content: flex-end; margin-top: var(--space-5); }

@media (max-width: 980px) {
    .cn-pairing-fields { grid-template-columns: 1fr; }
    .cn-pairing-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.cn-card {
    background: var(--color-surface);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    margin-bottom: var(--space-4);
}

.cn-card.well { background: var(--color-surface-alt); }
.cn-card-title { font-size: var(--font-size-card-title); font-weight: var(--font-weight-semibold); margin-bottom: var(--space-3); }

.cn-field-label { font-size: var(--font-size-description); color: var(--color-text-secondary); margin: var(--space-3) 0 var(--space-2); }
.cn-field-label:first-child { margin-top: 0; }

.cn-wrap { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.cn-readout { font-family: var(--font-mono); font-size: var(--font-size-body); }
.cn-line-tuple { font-variant-numeric: tabular-nums; }
.cn-compatibility-field, .cn-transport-field, .cn-secret-field { min-width: 300px; flex: 2 1 360px; }
.cn-compatibility-note, .cn-transport-note, .cn-secret-note {
    max-width: 560px;
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
    line-height: 1.4;
    text-wrap: pretty;
}
.cn-compatibility-note.raised {
    color: var(--color-caution);
    font-weight: var(--font-weight-semibold);
    font-variant-numeric: tabular-nums;
}
.cn-transport-note.warning, .cn-secret-note {
    color: var(--color-caution);
    font-weight: var(--font-weight-semibold);
}
.cn-line-timing-metrics {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-5);
    margin-top: var(--space-2);
}
.cn-line-timing-metric {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-2);
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
}
.cn-line-timing-metric .cn-readout {
    color: var(--color-text);
    font-size: var(--font-size-description);
    font-variant-numeric: tabular-nums;
}
.cn-line-state {
    padding: var(--space-1) var(--space-2);
    border: 1px solid var(--color-stroke-subtle);
    border-radius: var(--radius-sm);
    color: var(--color-text-secondary);
    font-size: var(--font-size-eyebrow);
}
.cn-line-summary {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    margin-top: var(--space-3);
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
}

/* Numeric conversion pipeline (Tag panel · Conversion). */
.cn-stage {
    border: 1px solid var(--color-stroke-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
    margin-bottom: var(--space-3);
    background: transparent;
}

.cn-stage.on { background: var(--color-surface); }
.cn-stage.fault { border-color: var(--color-caution); }
.cn-stage-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.cn-stage-head-end { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-3); min-width: 0; }
.cn-stage-result { display: flex; align-items: center; gap: var(--space-2); }
.cn-stage-op { color: var(--color-text-disabled); font-size: var(--font-size-card-title); }
.cn-stage-value { font-family: var(--font-mono); font-weight: var(--font-weight-semibold); text-align: right; min-width: 70px; color: var(--color-accent-text); }
.cn-stage-value.bypassed { color: var(--color-text-disabled); }
.cn-stage-unit { font-size: var(--font-size-eyebrow); color: var(--color-text-secondary); min-width: 26px; }
.cn-stage-fields { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); margin-top: var(--space-3); }
.cn-stage-fields.one { grid-template-columns: 1fr; }

/* Two-point Scale / Calibration assistant. It extends the stage in place: the top
   hairline separates the occasional workflow without introducing another card. */
.cn-two-point-trigger,
.cn-two-point-capture {
    padding: var(--space-2) var(--space-3);
    font-size: var(--font-size-description);
}

.cn-two-point {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-stroke-subtle);
}

.cn-two-point-intro { margin-bottom: var(--space-4); }
.cn-two-point-title { font-size: var(--font-size-label); font-weight: var(--font-weight-semibold); }
.cn-two-point-description {
    margin-top: var(--space-1);
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
    line-height: 1.45;
}

.cn-two-point-points {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
}

.cn-two-point-point {
    min-width: 0;
    margin: 0;
    padding: var(--space-3);
    border: 1px solid var(--color-stroke-subtle);
    border-radius: var(--radius-md);
}

.cn-two-point-point legend {
    padding-inline: var(--space-2);
    color: var(--color-text);
    font-size: var(--font-size-description);
    font-weight: var(--font-weight-semibold);
}

.cn-two-point-fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
}

.cn-two-point-fields .cn-field-label { margin-top: 0; }
.cn-two-point-field-error {
    color: var(--color-critical);
    font-size: var(--font-size-eyebrow);
}

.cn-two-point-capture-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-3);
}

.cn-two-point-captured {
    color: var(--color-text-secondary);
    font-size: var(--font-size-eyebrow);
    font-variant-numeric: tabular-nums;
}

/* What the assistant makes of the draft, said the way the shared .ui-note-caution says it: a
   recessed surface with a thin rule for the tone. It is an observation about two numbers, not
   an alarm; the .error branch only swaps the rule's colour. */
.cn-two-point-message {
    margin-top: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
    border: 1px solid var(--color-stroke-subtle);
    box-shadow: inset 3px 0 0 var(--color-caution);
    color: var(--color-text-secondary);
    font-size: var(--font-size-description);
}

.cn-two-point-message.error {
    box-shadow: inset 3px 0 0 var(--color-critical);
}

.cn-two-point-preview-wrap {
    margin-top: var(--space-4);
    overflow-x: auto;
}

.cn-two-point-preview {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-description);
}

.cn-two-point-preview caption {
    padding-bottom: var(--space-2);
    color: var(--color-text-secondary);
    font-weight: var(--font-weight-semibold);
    text-align: left;
}

.cn-two-point-preview :is(th, td) {
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--color-stroke-subtle);
    text-align: right;
    white-space: nowrap;
}

.cn-two-point-preview th:first-child { text-align: left; }
.cn-two-point-preview thead th {
    color: var(--color-text-secondary);
    font-size: var(--font-size-eyebrow);
    font-weight: var(--font-weight-semibold);
}

.cn-two-point-value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

.cn-two-point-value.muted { color: var(--color-text-disabled); }
.cn-two-point-actions {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.cn-pipeline-end {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 var(--space-3); margin-bottom: var(--space-3);
}

.cn-pipeline-end .cn-eng-value { font-family: var(--font-mono); font-size: var(--font-size-readout); font-weight: var(--font-weight-bold); color: var(--color-accent-text); }
.cn-pipeline-end.muted .cn-eng-value { font-size: var(--font-size-body); font-weight: var(--font-weight-medium); color: var(--color-text-secondary); }

.cn-live-box {
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
}

.cn-live-value { font-size: var(--font-size-readout); font-weight: var(--font-weight-semibold); color: var(--color-accent-text); font-variant-numeric: tabular-nums; }

@media (max-width: 980px) {
    .cn-stage-head { align-items: flex-start; flex-wrap: wrap; }
    .cn-stage-head-end.has-action { flex: 1 1 100%; justify-content: space-between; }
    .cn-two-point-points { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
    .cn-two-point-fields { grid-template-columns: 1fr; }
}

/* Caution notes (fault / validation) use the shared .ui-note-caution. */

/* Discovery results card. */
.cn-discovery {
    margin-top: var(--space-4);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-lg);
    background: var(--color-surface-alt);
    padding: var(--space-4);
}

.cn-discovery-list { max-height: 340px; overflow-y: auto; margin-top: var(--space-3); }
.cn-discovered-card {
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    padding: var(--space-4);
    margin-bottom: var(--space-3);
}

/* Empty states use the shared .ui-empty-state (see the component library above). */

/* Fixed-width fields use the shared .w-* utilities (component library above). */

.cn-grid-secondary { color: var(--color-text-secondary); }

/* Tag grid: what the ticks are holding right now. The grid is virtualized, so a ticked row can sit
   well outside the viewport and the strip is the only place its mark is visible at all: it says how
   many rows the next cell edit would reach, and carries the one press that drops them. Absent while
   nothing is ticked, so the grid looks exactly as it did until there is something to report. */
.cn-tag-selection {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-stroke-subtle);
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
    font-size: var(--font-size-description);
    color: var(--color-text-secondary);
}

/* Tag grid: the whole grid scrolls horizontally as a unit (head + body together), so the
   many conversion columns stay aligned. The body keeps its own vertical scroll. */
.cn-tag-grid { overflow-x: auto; }
.cn-tag-grid .ui-grid-head,
.cn-tag-grid .ui-grid-body { min-width: max-content; }
.cn-tag-grid .ui-grid-body { overflow-x: visible; }

