:host {
  display: block;
}

.swb-qe {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px;
  height: 100%;
}

// ── Toolbar ────────────────────────────────────────────────────────────────
// Each field is its own column (label row → control row → status-caption
// row). Aligning the columns to flex-start means every column's control row
// sits at the same vertical offset from the top — the same offset as every
// column's label row — regardless of how much status text is showing
// underneath any one of them, so nothing drifts or wraps unpredictably.
.swb-qe-toolbar {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  flex-wrap: wrap;
}

.swb-qe-field-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

// A field's control row: the box itself, plus any adjacent inline control
// (e.g. the Database field's refresh button, or the Actions column's buttons).
.swb-qe-field-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.swb-qe-label {
  font-size: 13px;
  font-weight: 500;
  color: #424242;
  white-space: nowrap;
  line-height: 1.3;

  // Invisible but still occupies a label-height line, so the Actions column's
  // button row lands at the same vertical offset as the Server/Database box rows.
  &--spacer {
    visibility: hidden;
  }
}

// gb-newpicklist renders its own "Server" label (the library's ".input_label" class,
// styled by its own global stylesheet) stacked above the input. That fights with the
// external .swb-qe-label used for Database — hiding the built-in label here (scoped
// to this toolbar only, via the leading .swb-qe-toolbar ancestor) lets the external
// .swb-qe-label added above <gb-newpicklist> in the template be the only one shown,
// so both fields line up the same way.
.swb-qe-toolbar ::ng-deep .input_label {
  display: none;
}

// Angular Material's mat-form-field (used by gb-newpicklist's box) always reserves
// space below itself for a hint/error line, even when empty — that reserved gap is
// what pushes the Server field's "Connected to …" caption further down than the
// Database field's, whose plain custom box has no such reserved area. Collapsing
// it here (scoped to this toolbar only) makes both captions sit at the same offset.
.swb-qe-toolbar ::ng-deep .mat-mdc-form-field-subscript-wrapper {
  display: none;
}

// ── Database search textbox — pulls the exact same design tokens the Server
// picklist's own box does (gbcommonstyle.scss ".Mat_Form_Field .mdc-text-field"),
// at the same fixed 320px width as serverPicklistConfig.Width, so the two boxes
// render pixel-equal instead of just similarly-shaped. ─────────────────────────
.swb-qe-search-wrap {
  position: relative;
  display: flex;
  align-items: center;
  width: 320px;

  &--disabled {
    opacity: 0.6;
  }
}

.swb-qe-search-input {
  width: 100%;
  height: calc(var(--field-height-m, 40) * 1px);
  padding: 0 calc(var(--space-m, 16) * 1px);
  padding-right: 44px;
  border: 1px solid var(--field-border-default, #e0e0e0);
  border-radius: calc(var(--size-radius-s, 4) * 1px);
  font-size: 14px;
  color: var(--field-text-default, #212121);
  background: var(--field-bg-default, #fff);
  box-sizing: border-box;

  &::placeholder {
    color: var(--field-text-placeholder, #9e9e9e);
    opacity: 1;
  }

  &:focus {
    outline: none;
    border-color: var(--field-border-focus, #1976d2);
  }

  &:disabled {
    background: var(--gb-surface-alt, #f5f5f5);
    cursor: not-allowed;
  }
}

// Same mat-icon, same "keyboard_arrow_down" ligature, same 24px size as the
// dropdown symbol gb-newpicklist renders on the Server field, so both fields
// show the identical glyph instead of two different-looking arrows.
.swb-qe-search-chevron {
  position: absolute;
  right: calc(var(--space-m, 16) * 1px);
  top: 50%;
  transform: translateY(-50%);
  font-size: 24px;
  width: 24px;
  height: 24px;
  color: var(--field-text-default, #212121);
  pointer-events: none;
}

.swb-qe-search-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 10;
  margin: 2px 0 0;
  padding: 4px 0;
  max-height: 240px;
  overflow-y: auto;
  list-style: none;
  background: var(--field-bg-default, #fff);
  border: 1px solid var(--field-border-default, #e0e0e0);
  border-radius: calc(var(--size-radius-s, 4) * 1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

.swb-qe-search-option {
  padding: 6px 10px;
  font-size: 14px;
  color: var(--field-text-default, #212121);
  cursor: pointer;
  white-space: nowrap;

  &:hover {
    background: var(--bg-subtle, #f5f5f5);
  }
}

.swb-qe-search-empty {
  padding: 6px 10px;
  font-size: 12px;
  color: var(--field-text-placeholder, #9e9e9e);
}

.swb-qe-refresh-btn {
  height: calc(var(--field-height-m, 40) * 1px);
  padding: 0 8px;
  border: 1px solid var(--gb-border-color, #e0e0e0);
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  box-sizing: border-box;

  &:hover:not(:disabled) {
    background: #f5f5f5;
  }

  &:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }
}

.swb-qe-loading-dot {
  font-size: 13px;
  color: var(--gb-text-secondary, #9e9e9e);
}

.swb-qe-connect-status {
  font-size: 12px;
  white-space: nowrap;

  &--pending { color: var(--gb-text-secondary, #9e9e9e); }
  &--ok      { color: #2e7d32; }
  &--err     { color: #c62828; }
}

.swb-qe-btn {
  height: calc(var(--field-height-m, 40) * 1px);
  padding: 0 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  box-sizing: border-box;

  &:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }

  &--primary {
    background: #1976d2;
    color: #fff;

    &:not(:disabled):hover {
      background: #1565c0;
    }
  }

  &--secondary {
    background: transparent;
    border: 1px solid var(--gb-border-color, #bdbdbd);
    color: #424242;

    &:hover {
      background: #f5f5f5;
    }
  }
}

// ── Editor toolbar — Monaco built-in-action icon strip ─────────────────────
.swb-qe-editor-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px;
  padding: 4px 6px;
  border: 1px solid var(--gb-border-color, #e0e0e0);
  border-bottom: none;
  border-radius: 4px 4px 0 0;
  background: var(--gb-surface-alt, #f5f5f5);
}

.swb-qe-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: #424242;
  cursor: pointer;
  line-height: 0;

  // Angular Material stamps its own ".mat-icon" class on every <mat-icon>,
  // and its theme styles set that class's own font-size/width/height/line-height
  // (24px by default) — a plain "mat-icon" element selector loses to that on
  // specificity, which is what was making every icon fall back to a mismatched
  // 24px box instead of this toolbar's 20px one. Matching the class here, plus
  // an explicit line-height equal to the font-size (so the glyph's baseline sits
  // centered instead of inside a taller default line box), fixes both the
  // inconsistent sizing and the vertical misalignment.
  ::ng-deep .mat-icon {
    font-size: 20px;
    width: 20px;
    height: 20px;
    line-height: 20px;
    overflow: hidden;
  }

  &:hover {
    background: #e0e0e0;
    border-color: var(--gb-border-color, #d0d0d0);
  }

  &:active {
    background: #d5d5d5;
  }
}

.swb-qe-toolbar-sep {
  flex: 0 0 auto;
  align-self: center;
  width: 1px;
  height: 20px;
  margin: 0 4px;
  background: var(--gb-border-color, #d0d0d0);
}

// ── Editor ────────────────────────────────────────────────────────────────
.swb-qe-editor {
  flex-shrink: 0;
}

// ── Results ───────────────────────────────────────────────────────────────
.swb-qe-results {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-height: 0;
}

.swb-qe-result-block {
  display: flex;
  flex-direction: column;
  gap: 6px;

  & + .swb-qe-result-block {
    border-top: 1px solid var(--gb-border-color, #e0e0e0);
    padding-top: 10px;
  }
}

.swb-qe-status {
  font-size: 13px;
  padding: 4px 0;
}

.swb-qe-status-ok  {
  color: #2e7d32;
  font-family: Consolas, 'Courier New', monospace;
}
.swb-qe-status-index { color: var(--gb-text-secondary, #757575); font-family: inherit; }
.swb-qe-status-err {
  color: #c62828;
  font-family: Consolas, 'Courier New', monospace;
}
.swb-qe-status-err-msg { white-space: pre-line; }

.swb-qe-grid-wrap {
  overflow: auto;
  max-height: 320px;
  border: 1px solid var(--gb-border-color, #e0e0e0);
  border-radius: 4px;
}

.swb-qe-grid {
  width: max-content;
  min-width: 100%;
  border-collapse: collapse;
  font-size: 13px;

  th, td {
    padding: 5px 10px;
    text-align: left;
    border-bottom: 1px solid var(--gb-border-color, #e0e0e0);
    white-space: nowrap;
  }

  th {
    position: sticky;
    top: 0;
    background: var(--gb-surface-alt, #f5f5f5);
    font-weight: 600;
    z-index: 1;
  }

  tr:hover td {
    background: #fafafa;
  }
}

// ── RTL ───────────────────────────────────────────────────────────────────
[dir="rtl"] {
  .swb-qe-toolbar { flex-direction: row-reverse; }
  .swb-qe-grid th,
  .swb-qe-grid td { text-align: right; }
}
