/* GetEYT tables layer, styles.

   Everything here is namespaced tx- because eleven agents are live in
   this tree and .cap already cost this codebase 85 unrelated capability
   dots. The only two selectors that reach outside that namespace are
   `.tbl th.tx-th` and `.tbl th.num .tx-sort`, and both are scoped to an
   element this file marked itself. Nothing here can restyle a table it
   did not adopt.

   Loads last, so it never needs !important. */

/* ================================================================
   1. the sortable header

   The button has to be the whole cell or the hit target is a word,
   which on a two letter header like TT is unclickable. So the th
   gives up its padding to the button and gets it back on the inside,
   and the header keeps the exact metrics it had before.
   ================================================================ */

.tbl th.tx-th {
  padding: 0;
}

.tx-sort {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 10px 14px;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: inherit;
  cursor: pointer;
  border-radius: 0;
  transition:
    color 0.12s,
    background 0.12s;
}
.tbl th.num .tx-sort {
  justify-content: flex-end;
}
.tx-sort:hover {
  color: var(--ink);
  background: var(--surface-2);
}
.tx-sort:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: -2px;
  color: var(--ink);
}
.tbl th.tx-on {
  color: var(--ink);
}

/* Two stacked chevrons at rest, one when the column is the sorted one.
   Drawn in CSS rather than as a glyph so it inherits colour and stays
   crisp at 11.5px, where a text arrow is a smudge. */
.tx-sort__i {
  position: relative;
  flex: none;
  width: 8px;
  height: 12px;
  opacity: 0.34;
  transition: opacity 0.12s;
}
.tx-sort__i::before,
.tx-sort__i::after {
  content: "";
  position: absolute;
  left: 0;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  transition: opacity 0.12s;
}
.tx-sort__i::before {
  top: 1px;
  border-bottom: 4px solid currentColor;
}
.tx-sort__i::after {
  bottom: 1px;
  border-top: 4px solid currentColor;
}
.tx-sort:hover .tx-sort__i {
  opacity: 0.6;
}
.tx-sort[data-tx-dir="asc"] .tx-sort__i,
.tx-sort[data-tx-dir="desc"] .tx-sort__i {
  opacity: 1;
  color: var(--plum);
}
.tx-sort[data-tx-dir="asc"] .tx-sort__i::after,
.tx-sort[data-tx-dir="desc"] .tx-sort__i::before {
  opacity: 0.18;
}

/* ================================================================
   2. the empty state

   Grafana's rule, moved from a stat to a table: the empty answer sits
   where the real answer sat, at the same padding as a data row, so
   nothing on the screen moves between populated, empty and populated
   again. It is a row inside the tbody with the right colspan, not a
   block bolted underneath, for exactly that reason.
   ================================================================ */

.tbl tr.tx-zero:hover {
  background: none;
}
.tbl td.tx-zero__c {
  padding: 34px 20px 36px;
  border-bottom: none;
  text-align: center;
}
.tx-zero__h {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  letter-spacing: -0.01em;
}
.tx-zero__w {
  display: block;
  margin-top: 5px;
  font-size: 12.5px;
  color: var(--muted);
  max-width: 46ch;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.5;
}
.tx-zero__hint {
  display: block;
  margin-top: 9px;
  font-size: 12px;
  color: var(--muted);
}
.btn.tx-zero__b {
  margin-top: 13px;
}

/* ================================================================
   3. batch select

   Cloudscape's variant. The bar is visible and disabled before there
   is a selection, so the actions a selection would unlock are legible
   without making one. It stays a single 34px line so ten of these
   across a screen do not read as chrome.
   ================================================================ */

.tx-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  min-height: 34px;
  flex-wrap: wrap;
}
.tx-bar--on {
  background: var(--plum-050);
  border-bottom-color: #ddd0e8;
}
/* sentence case, no tracking. An uppercase tracked micro-label is the
   house's named anti-pattern, and this one sits above a table rather
   than inside its header row, where the uppercase belongs. */
.tx-bar__n {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  margin-right: 2px;
  font-variant-numeric: tabular-nums;
}
.tx-bar--on .tx-bar__n {
  color: var(--plum);
}
.btn.tx-bar__a {
  background: var(--surface);
}
.btn.tx-bar__a:disabled {
  opacity: 0.45;
  cursor: default;
  background: transparent;
  border-style: dashed;
}
.tx-bar__x {
  margin-left: auto;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.tx-bar__x:hover {
  color: var(--ink);
}
.tx-bar__x[hidden] {
  display: none;
}

.tbl th.tx-cb,
.tbl td.tx-cb {
  width: 1px;
  padding-right: 0;
  white-space: nowrap;
}
.tbl th.tx-cb {
  padding-top: 0;
  padding-bottom: 0;
}
.tx-cb__i {
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--plum);
  cursor: pointer;
  vertical-align: middle;
}
.tx-cb__i:disabled {
  cursor: default;
  opacity: 0.4;
}
.tx-cb__i:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: 2px;
}

/* ================================================================
   4. finding a record
   ================================================================ */

.tx-cue {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  gap: 2px;
  align-items: center;
  border: 0;
  background: none;
  padding: 2px;
  cursor: pointer;
  border-radius: 6px;
}
.tx-cue:hover kbd {
  border-color: var(--plum);
  color: var(--plum);
}
.tx-cue:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: 1px;
}
/* the room for .tx-cue is written inline by tables.js when it injects
   the cue, not from here. `.nav-search input` would tie this file to
   the stylesheet order, and tables.css currently loads before motion.css
   and orgtree.css rather than last. Inline wins regardless. */
.app.rail .tx-cue {
  display: none;
}

.tx-cue kbd,
.tx-find kbd {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
  padding: 3px 4px;
  min-width: 15px;
  text-align: center;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--line-2);
  border-bottom-width: 2px;
  border-radius: 6px;
}

.tx-find {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 900;
  background: rgba(36, 28, 43, 0.36);
  backdrop-filter: blur(2px);
  padding: 12vh 20px 20px;
  justify-content: center;
  align-items: flex-start;
}
.tx-find.on {
  display: flex;
  animation: tx-fade 0.14s ease-out;
}
@keyframes tx-fade {
  from {
    opacity: 0;
  }
}
.tx-find__box {
  width: min(660px, 100%);
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: tx-rise 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes tx-rise {
  from {
    transform: translateY(-8px);
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .tx-find.on,
  .tx-find__box {
    animation: none;
  }
}

.tx-find__top {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.tx-find__top svg {
  width: 17px;
  height: 17px;
  flex: none;
  color: var(--muted);
}
.tx-find__q {
  flex: 1;
  border: 0;
  background: none;
  font-family: var(--font-ui);
  font-size: 16px;
  color: var(--ink);
  min-width: 0;
}
.tx-find__q:focus {
  outline: none;
}
.tx-find__q::placeholder {
  color: var(--muted);
}
.tx-find__q::-webkit-search-cancel-button {
  display: none;
}
.tx-find__c {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.tx-find__x {
  border: 1px solid var(--line-2);
  border-bottom-width: 2px;
  background: var(--surface-2);
  border-radius: 6px;
  font: inherit;
  font-size: 11px;
  font-weight: 650;
  color: var(--muted);
  padding: 3px 5px;
  cursor: pointer;
}

.tx-find__list {
  overflow-y: auto;
  padding: 6px;
}
.tx-find__tip {
  margin: 0;
  padding: 22px 14px 26px;
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.55;
}
.tx-find__r {
  display: grid;
  /* both tracks must be allowed to shrink below their content or the
     location label sizes the column it is then clamped to a percentage
     of, and every one of them renders as "Stu..." */
  grid-template-columns: minmax(0, 1fr) minmax(0, max-content);
  gap: 2px 14px;
  padding: 9px 12px;
  border-radius: var(--r-sm);
  cursor: pointer;
}
.tx-find__r.on {
  background: var(--plum-050);
}
.tx-find__t {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
}
.tx-find__w {
  grid-row: 1;
  grid-column: 2;
  font-size: 11px;
  color: var(--muted);
  align-self: center;
  white-space: nowrap;
  max-width: 30ch;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tx-find__d {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tx-find__r b {
  color: var(--plum);
  background: #efe4f7;
  border-radius: 2px;
  font-weight: 700;
}
.tx-find__r.on b {
  background: #e2d2ee;
}

.tx-find__foot {
  display: flex;
  gap: 16px;
  padding: 9px 16px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
  font-size: 11px;
  color: var(--muted);
  flex-wrap: wrap;
}
.tx-find__foot span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* the row you were sent to, held long enough to find with your eye */
.tbl tr.tx-hit > td {
  animation: tx-hit 2.2s ease-out;
}
@keyframes tx-hit {
  0%,
  62% {
    background: var(--plum-050);
  }
  100% {
    background: transparent;
  }
}
@media (prefers-reduced-motion: reduce) {
  .tbl tr.tx-hit > td {
    animation: none;
    background: var(--plum-050);
  }
}

/* ================================================================
   5. the live region

   Off screen, never display:none, because a hidden live region is
   never read. The sort state, the selection count and the empty state
   all announce through this one node.
   ================================================================ */

.tx-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 720px) {
  .tx-find {
    padding: 6vh 12px 12px;
  }
  .tx-find__w {
    display: none;
  }
  .tx-bar {
    padding: 7px 12px;
  }
}
