/* Home tables + page chrome (TRA-1298 visual-fidelity pass).
   Ports the design mock's .pt table layer + page chrome from
   _scratch/tra-1298-design/src/plays2.css + plays4-tables-visual.css as a
   scoped `.htbl*` layer, because the tables use bespoke markup (the
   design-system-rules escape hatch for a surface that fights the primitives).

   NOT verbatim on type. The mock's half-pixel sizes (9.5/10.5/11.5/12.5px)
   were ported literally at first and made this sheet a second, unthemed type
   system; every size is now a step off the LOCKED ramp in
   `packages/shared/src/styles/typography.css`, referenced as --fs-* / --lh-*.
   Match the ramp, not the mock's literal size. The half-pixel WEIGHTS
   (650/680/550/450) do stay — they have no Tailwind scale step and no ramp
   governs weight.

   Colors are all tokens; there are no raw hex/rgba here, and a value that
   needs a per-theme arm belongs in tokens.css (see --surface-chip-warm), not
   in a hand-written `.dark` rule. Token map: --fg-1→text-primary,
   --fg-2→text-secondary, --fg-3→text-muted, --line→border-subtle,
   --line-strong→border-strong, --bg-card→surface-card, --bg-well→surface-well,
   --bg-card-hover→surface-row, --accent→accent-brand. */

/* ---------------- page chrome ---------------- */
/* Wraps like the shared PageHeader (and the Lists/Sequences title rows): on a
   narrow viewport the blurb drops to its own line instead of being squeezed
   beside the title. Without `wrap` the blurb stays on the title's flex line and
   its second line makes that line box taller, which drags the centered mobile
   nav burger below the title's center. Row gap matches Lists' `gap-y-1`. */
.htbl-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
}
.htbl-h1 {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: 680;
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
.htbl-sub {
  font-size: var(--text-dense);
  color: var(--text-muted);
}

.htbl-card {
  border: 1px solid var(--border-subtle);
  border-radius: 14px;
  background: var(--surface-card);
}

/* live-onboarding banner: slim accent strip above the toolbar while the
   discovery burst is still landing (mirrors the newsfeed's discovering bar) */
.htbl-live-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 18px;
  font-size: var(--text-xs);
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent-brand) 7%, var(--surface-card));
  border-bottom: 1px solid var(--border-subtle);
}

/* toolbar band: white (card), hairline under, seats below the folder tabs */
.htbl-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: var(--surface-card);
  border-bottom: 1px solid var(--border-subtle);
  flex-wrap: wrap;
  row-gap: 6px;
  flex-shrink: 0;
}

/* Search field with in-pill trailing count (Linear/Notion pattern):
   outer width stays max-w-[380px]; count lives inside the pill. */
.htbl-search {
  position: relative;
  width: 100%;
  max-width: 380px;
}
.htbl-search-trail {
  pointer-events: none;
  position: absolute;
  top: 50%;
  right: 6px;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 4px;
  transform: translateY(-50%);
}
.htbl-search-trail > button {
  pointer-events: auto;
}

.htbl-result-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 18px;
  padding: 0 7px;
  border-radius: 9999px;
  background: color-mix(in srgb, var(--text-muted) 9%, transparent);
  font-size: var(--text-caption);
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  line-height: var(--lh-none);
}

/* Room for the count chip (~"3 of 209") + optional clear/spinner */
.htbl-search .htbl-search-pad {
  padding-right: 5rem;
}
.htbl-search .htbl-search-pad-clear {
  padding-right: 6.75rem;
}

/* ---------------- folder tabs (seated on the card edge) ---------------- */
.htbl-tabs {
  display: flex;
  align-items: stretch;
  align-self: flex-start;
  gap: 6px;
  /* seats on the card's top edge (-1px), flush with the card's left edge */
  margin: 0 0 -1px;
  position: relative;
  z-index: 6;
}
/* The first tab seats flush on the card's corner, so the corner squares off —
   a 14px radius would curve away underneath the tab and leave a shell-colored
   notch. Scoped via sibling selector: the Lists page reuses .htbl-card without
   tabs and keeps all four rounded corners. */
.htbl-tabs + .htbl-card {
  border-top-left-radius: 0;
}
.htbl-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  /* All four sides, INCLUDING the bottom, so an inactive tab reads as a closed
     box. The strip seats -1px onto the card's top border, but each tab paints
     an OPAQUE shell-blend fill at `z-index: 6` — so that rule is covered right
     where the tab sits, and a tab with no bottom edge of its own looked
     open-bottomed. Mirrors `TAB_TRIGGER_CLS` in
     packages/shared/src/components/signals/SignalDetailPane.tsx, which hit the
     same thing; the two tab strips have to stay in agreement. */
  border: 1px solid var(--border-subtle);
  border-radius: 10px 10px 0 0;
  padding: 9px 14px 10px 13px;
  background: color-mix(in srgb, var(--surface-well) 62%, var(--surface-shell));
  font-size: var(--text-dense);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
}
.htbl-tab svg {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
}
.htbl-tab-count {
  font-style: normal;
  font-size: var(--text-caption);
  font-weight: 650;
  color: var(--text-muted);
  background: color-mix(in srgb, var(--text-muted) 9%, transparent);
  border-radius: 9999px;
  padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}
.htbl-tab.is-on {
  background: var(--surface-card);
  color: var(--text-primary);
  /* Transparent, NOT zero-width. Dropping the edge would change the content-box
     height between states and shift the icon and label by half a pixel every
     time you switch tabs. A transparent edge keeps every tab's box model
     identical, and since backgrounds paint under the border box the tab's own
     `--surface-card` shows through it — covering the card's top border exactly
     as a removed border did, so the active tab still merges into the card. */
  border-bottom-color: transparent;
}
.htbl-tab.is-on .htbl-tab-count {
  color: var(--accent-text);
  background: var(--accent-soft);
}
.htbl-tab.is-on::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--accent-brand);
}
/* On phones the three tabs — glyph, label and count each — outgrow the strip
   and push the page into a horizontal scroll. The glyph is the first thing to
   go: it is decorative (the label already names the tab, and it carries no
   aria text), while the count is live data and the label is the control. Done
   in CSS rather than a rendered condition so it reflows on rotate with no
   re-render. 480px sits one tier below the 640px mobile breakpoint used in
   `packages/shared/src/components/event-card/sizes.css` and clears the widest
   phone in portrait (430px) with headroom. */
/* The audience bar is fixed below md, so it floats over the end of the list.
   `:has()` keeps the clearance to cards that actually carry one. */
@media (max-width: 767px) {
  .htbl-card:has(.hdw-ab-wrap) {
    padding-bottom: 76px;
  }
}

@media (max-width: 480px) {
  .htbl-tab svg {
    display: none;
  }
  /* With the glyph gone this gap only ever separates the label from its count,
     and at 7px the count read as a loose second element rather than part of
     the tab. Tightening it also buys back a few px per tab. */
  .htbl-tab {
    gap: 4px;
  }
  /* Matches the shell gutter's own step down, so the card chrome stops being
     more generous than the page around it. The 16px it returns is also what
     the People toolbar needs: its two filter chips (140 + 143) leave 81px for
     an import button that wants 104, which is why that button was landing on
     a third row of its own. */
  .htbl-tools {
    padding-left: 8px;
    padding-right: 8px;
  }
  /* Same trade as the folder tabs: the chips' leading glyphs are decorative
     (the label names the filter) and each costs 14px plus its 6px gap, so
     dropping both returns 40px — enough for "Import CSV" to join the chips'
     row with slack to spare instead of taking a third row of its own.

     Scoped to the leading icon only: it is the first svg INSIDE the trigger's
     content wrapper, whereas the chevron and the clear button are siblings of
     that wrapper and keep working. */
  .htbl-tools [data-slot='popover-trigger'] > :first-child > svg:first-child {
    display: none;
  }
}

/* Below ~400px the three tabs no longer fit even with the ≤480px trims (label
   + count + side pads ≈ 350px against a ~344px content column at 360), and the
   strip pushed the page into a horizontal scroll. So the strip stops sizing to
   content: it stretches to the row and the tabs split it evenly, giving up
   side padding they no longer need. The tabs' existing `overflow: hidden`
   absorbs any residual squeeze inside the tab instead of widening the page. */
@media (max-width: 400px) {
  .htbl-tabs {
    align-self: stretch;
    gap: 4px;
  }
  .htbl-tab {
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
    padding-left: 10px;
    padding-right: 10px;
  }
  /* With the strip stretched across the row the card reads as a full-width
     band, so the remaining rounded corners just leave shell-colored notches
     against the stretched tabs — square the card off entirely. */
  .htbl-card {
    border-radius: 0;
  }
}

/* ---------------- table ---------------- */
.htbl {
  --htbl-header-height: 35px;
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

/* Horizontal-scroll floors (TRA-1428). `table-layout: fixed` ignores per-cell
   min-widths, so without an explicit floor the auto-width column collapses to
   absorb any shortfall and the table silently squeezes instead of overflowing
   — which is why the hidden-column affordance had nothing to count. Each floor
   is that surface's fixed column sum plus room for its auto column; below the
   floor the wrapping TableScrollRegion scrolls and shows the `N more` badge.
   Mirrors the shared DataTable's `tableClassName="min-w-[…]"` convention. */
.htbl-w-signals { min-width: 900px; }   /* 44+214+98+150+36 fixed + Details */
.htbl-w-accounts { min-width: 1176px; } /* 44+230+96+96+100+81+93+69+135+36 fixed + 196 HQ floor */
.htbl-w-people { min-width: 1008px; }   /* 44+167+319+246+92+104+36 — all fixed */
.htbl-w-lists { min-width: 1040px; }    /* 300+200+240+36 fixed + People */
.htbl-w-outreach { min-width: 998px; } /* 266+172+60+80+86+128+36 fixed + People */

/* column widths (table-layout: fixed) */
.htbl-c-check {
  width: 44px;
}
/* Signal carries two stacked lines (pill + account), so it runs wider than the
   other identity columns; When widened, "Where it fits" trimmed; the auto-width
   Details column absorbs the net delta (table-layout: fixed). */
.htbl-c-sig {
  width: 214px;
}
/* "Where it fits" column (replaces People); trimmed so the freed width
   flows to the auto-width Details column. */
.htbl-c-fit {
  width: 150px;
}
.htbl-c-when {
  width: 98px;
}
.htbl-c-tw {
  width: 36px;
}
.htbl-c-num {
  width: 96px;
}
.htbl-c-num-sm {
  width: 81px;
}
.htbl-c-score {
  width: 69px;
}
.htbl-c-acctmain {
  width: 230px;
}
.htbl-c-type {
  width: 100px;
}
.htbl-c-cts {
  width: 93px;
}

/* Signals / Contacts / Score are sized to their own HEADER, not their data:
   the values are 1-3 centered digits but the labels are 41-65px, and an active
   column also has to fit the 16px sort chevron. Trimming the side padding to
   6px is the only lever that actually buys width back, so these three carry
   less padding than the rest of the row. */
.htbl-c-num-sm,
.htbl-c-cts,
.htbl-c-score {
  padding-left: 6px;
  padding-right: 6px;
}
.htbl thead th.htbl-c-num-sm,
.htbl thead th.htbl-c-cts,
.htbl thead th.htbl-c-score {
  padding-left: 6px;
  padding-right: 6px;
}
/* People: the name column was wider than the names needed while role and
   account — the two fields that actually get truncated — were cramped. Person
   gives up 15% (196 -> 167) and the dropped Email column gives up all 168; the
   365px freed is split evenly between Role (+99) and Account (+98). The total
   is unchanged at 1046px, so the min-width floor and the horizontal-scroll
   affordance stay exactly as they were. */
.htbl-c-role {
  width: 319px;
}
.htbl-c-co {
  width: 246px;
}
.htbl-c-person {
  width: 167px;
}
.htbl-c-enriched {
  width: 92px;
}
.htbl-c-last {
  width: 104px;
}
/* Accounts runs a wider "Last outreach" than People: its HQ column is the one
   fluid column in that table, so the extra width is taken from HQ rather than
   from the layout. People has no slack column to borrow from, hence the scope. */
.htbl-w-accounts .htbl-c-last {
  width: 135px;
}
/* Lists page: the List-name column absorbs the slack (long names benefit),
   Accounts + People are snug so their avatar strips sit tight together with no
   awkward gap. Accounts: 8 stacked 22px logos (16px/step) + the +N chip;
   People: up to 14 faces + chip. */
.htbl-c-listname {
  width: auto;
}
.htbl-c-logos {
  width: 200px;
}
.htbl-c-people {
  width: 260px;
}
.htbl-c-acts {
  width: 240px;
}

/* Danger tone for the Outreach status pill. There is no soft/line danger token
   pair (unlike success/warning), so the tint is mixed over the destructive
   token rather than reaching for the shadcn `bg-destructive/10` semantics that
   feature code is not allowed to use. */
.htbl-pill-bad {
  border-color: color-mix(in srgb, var(--destructive) 32%, transparent);
  background: color-mix(in srgb, var(--destructive) 10%, transparent);
  color: var(--destructive);
}

/* Outreach page: the sequence name absorbs the slack (names are the long
   field); the rest are sized to their own headers, since the values are short
   counts and dates. Sent runs wider than People because it carries "12 of 30". */
/* The name column is sized to its content, not left to absorb the page: the
   widest thing it holds is ~150px of text and it had been taking 468. Every
   other column here is at its own content width, so the two preview strips
   take the slack instead — they are strips of faces, and air around them reads
   as a gutter between WHO the outreach went to and HOW it is going.
   Both strip classes are shared with the Lists table, hence the scoping.

   Only PEOPLE takes the slack, not both strips: sharing it stranded the
   account logo alone in the middle of its cell. Tight name, tight logos,
   tight faces, then one gutter before the numbers. */
.htbl-w-outreach .htbl-c-listname {
  width: 266px;
}
.htbl-w-outreach .htbl-c-logos {
  width: 172px;
}
.htbl-w-outreach .htbl-c-people {
  width: auto;
}

/* Every one of these is sized to its own content, not to a round number: the
   table has seven columns and a 1280px laptop gives it under 1000px, so slack
   anywhere pushed Status behind a horizontal scroll. */
.htbl-c-seqppl {
  width: 80px;
}
.htbl-c-seqsent {
  width: 60px;
}
.htbl-c-seqdate {
  width: 86px;
}
.htbl-c-seqstatus {
  width: 128px;
}

/* Lists page (UserLists): shorter list name; People absorbs slack. Lives here
   (not drawer.css) because the table renders before the drawer mounts. */
.htbl.hl-table .htbl-c-listname {
  width: 300px;
}
.htbl.hl-table .htbl-c-people {
  width: auto;
}
.htbl.hl-table td:first-child {
  overflow: hidden;
  max-width: 300px;
}

/* header: sticky cream band */
.htbl thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  height: var(--htbl-header-height);
  background: var(--surface-well);
  text-align: left;
  /* --text-2xs, NOT --text-caption. These labels were 10.5px, and the columns below are
     width-tuned to them: measured at the 1176px min-width, Employees had 0.9px
     of slack, Score 0.4px, and Signals 0.4px once its sort chevron is showing.
     Rounding UP to 11 spilled all three (-2.2 / -1.3 / -1.8px) — with nowrap,
     fixed layout and no ellipsis that is a visible overrun into the neighbour,
     not a clip. 10 is the nearest step in the other direction and is a
     sanctioned size (--text-2xs), so it stays on the ramp and buys slack back.
     Verified by comparing each header's inline-flex label box against its
     cell's content box, in both themes, with each sortable column active.
     (scrollWidth is NOT a usable probe here: `overflow: visible` cells clamp
     it, and it reported no overflow while the labels were spilling.) */
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 9px 12px;
  border-bottom: 1px solid var(--border-subtle);
  white-space: nowrap;
}
.htbl thead th:first-child {
  padding-left: 18px;
}
.htbl thead th.htbl-sortable {
  cursor: pointer;
  user-select: none;
}
.htbl thead th.htbl-th-center {
  text-align: center;
}

/* day-bucket rows: quiet accent wash, distinct from the cream header — the
   WASH is the distinction, not the type. This band carries the same 700 weight,
   0.06em tracking and uppercase as `.htbl thead th`, and shared its size too,
   so it tracks the header's step rather than being sized on its own. It has
   room for more (full-width band, 18px side padding); staying at 11 while the
   header dropped to 10 would leave the band reading LARGER than the column
   header stacked above it, inverting the hierarchy. */
.htbl-day td {
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent-brand) 6%, var(--surface-card));
  padding: 6px 18px;
  border-bottom: 1px solid var(--border-subtle);
}

.htbl-selection-scope td {
  position: sticky;
  top: var(--htbl-header-height);
  z-index: 4;
  padding: 7px 14px 7px 16px;
  border-bottom: 1px solid var(--border-subtle);
  background: color-mix(in srgb, var(--accent-brand) 5%, var(--surface-card));
  box-shadow: 0 1px 2px color-mix(in srgb, var(--text-primary) 8%, transparent);
}

.htbl-selection-scope td > span {
  margin-right: 10px;
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 600;
}

.htbl-selection-status-count {
  color: var(--text-primary);
  font-weight: 700;
}

.htbl-selection-status-separator {
  color: var(--text-muted);
  font-weight: 400;
}

.htbl-selection-status-detail {
  color: var(--text-muted);
  font-weight: 400;
}

.htbl-selection-scope td > button + button {
  margin-left: 4px;
}

/* rows */
.htbl-row {
  cursor: pointer;
  transition: background 0.1s;
}
.htbl-row td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: middle;
}
.htbl-row td:first-child {
  padding-left: 18px;
}
.htbl-row:hover {
  background: var(--surface-row);
}
.htbl-row.is-sel {
  background: color-mix(in srgb, var(--accent-brand) 9%, transparent);
}
.htbl-row.is-sel:hover {
  background: color-mix(in srgb, var(--accent-brand) 13%, transparent);
}
/* Open row: must read differently from is-sel. Sibling signals often share
   suggested contacts; is-sel used to use this same tint, so opening one row
   looked like another "lit up" (false id-collision). Keep the border (drawer
   is a side panel, not docked under the row), strengthen the tint, and add a
   left accent bar on the first cell. */
.htbl-row.is-open > td {
  background: color-mix(in srgb, var(--accent-brand) 14%, transparent);
}
.htbl-row.is-open:hover > td {
  background: color-mix(in srgb, var(--accent-brand) 18%, transparent);
}
.htbl-row.is-open > td:first-child {
  box-shadow: inset 3px 0 0 var(--accent-brand);
}
/* Select cell (TRA-1429): the whole cell is the hit target. The Radix checkbox
   renders a <button>, and the UA stylesheet resets `cursor` on buttons — so
   `.htbl-row { cursor: pointer }` does NOT reach it and the pointer flipped to
   an arrow exactly over the box. Cursor only: the cell deliberately paints NO
   background of its own — an accent hover wash here reads as a per-cell
   "selected" state on the checkbox column — so the row-level hover/is-sel/
   is-open tints are the only background feedback. */
.htbl-row td.htbl-cell-select,
.htbl-row td.htbl-cell-select [data-slot='checkbox'] {
  cursor: pointer;
}
.htbl-row td.htbl-cell-select:has([data-slot='checkbox']:disabled),
.htbl-row td.htbl-cell-select [data-slot='checkbox']:disabled {
  /* Beats the rule above; the shared Checkbox's own
     `disabled:cursor-not-allowed` loses on specificity here. */
  cursor: not-allowed;
}

.htbl-cell-center { text-align: center; }

/* account cell */
.htbl-acct {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}
.htbl-acct-t {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.htbl-acct-name {
  font-size: var(--text-dense);
  font-weight: 650;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The second line under a name. Truncates like the name above it: left to
   wrap, a long one grows the row to three lines and drags the whole table
   taller, which is what "Copy each message into LinkedIn" used to do. */
/* Size and colour come from the `.text-meta` role in the markup — this rule
   only owns the truncation, which is what it exists for. */
.htbl-acct-sub {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Signal identity cell: the signal pill and account line share both their icon
   and text rails. The smaller account logo is indented so its center matches
   the signal glyph while the account name starts under the signal label. */
.htbl-sig-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
  max-width: 100%;
}
.htbl-sig-account-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.htbl-sig-account {
  display: flex;
  align-items: center;
  gap: 5px;
  padding-left: 6px;
  min-width: 0;
  max-width: 100%;
  font-size: var(--text-xs);
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.htbl-sig-pill.htbl-sig-cell-pill {
  gap: 7px;
}
/* Double class beats .htbl-pill's later flex-shrink: 0, so the pill actually
   shrinks inside the fixed signal column instead of overflowing into the
   account cell. */
.htbl-pill.htbl-sig-pill {
  flex-shrink: 1;
  min-width: 0;
  /* Wrapping pill: the glyph stays on line 1, and the stadium radius is
     softened to a corner radius so a 2-line pill doesn't read as a blob. */
  align-items: flex-start;
  white-space: normal;
  border-radius: 10px;
}
.htbl-sig-pill .htbl-sig-pill-t {
  min-width: 0;
  overflow-wrap: anywhere;
}
/* Signal pills are colored by their TYPE (news / job listing / career change).
   The component sets --sig-hue from the type's design token (--dot-news /
   --dot-job / --dot-career, the same hues the signal editor and the events
   views use); everything below derives from it, so there is one hue per pill
   and no per-signal palette.

   The INK is a deep shade of that hue rather than the token itself: the tokens
   are mid-tone dot colors, and at 11px/550 on the cream card the raw token
   reads washed out. Light mode mixes the hue toward the page ink; dark mode
   uses the token, which is already light enough against the dark shell. */
.htbl-pill.htbl-sig-pill {
  background: color-mix(in srgb, var(--sig-hue) 20%, transparent);
  border-color: color-mix(in srgb, var(--sig-hue) 42%, transparent);
  color: light-dark(
    color-mix(in srgb, var(--sig-hue) 58%, var(--text-primary)),
    var(--sig-hue)
  );
}
.htbl-row:hover .htbl-pill.htbl-sig-pill {
  background: color-mix(in srgb, var(--sig-hue) 30%, transparent);
  border-color: color-mix(in srgb, var(--sig-hue) 55%, transparent);
}
/* The glyph takes the pill's ink. Double class + descendant beats the later
   `.htbl-pill svg` rule, which otherwise repaints every glyph brand-lavender
   at 0.75 opacity (equal specificity, and it comes later in this file). */
.htbl-pill.htbl-sig-pill svg {
  color: inherit;
  opacity: 1;
  /* Optical: align the glyph to the cap-height of the first text line. */
  margin-top: 1.5px;
}
/* Block, not inline: as the cell's sole content it must clip to the fixed
   column width (an inline span sizes to its text and overflows the cell). */
.htbl-headline {
  display: block;
  max-width: 100%;
  font-size: var(--text-dense);
  font-weight: 450;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* signal pill: accent-tinted, deepens when the row is hovered */
.htbl-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  border-radius: 9999px;
  padding: 2px 9px 2px 7px;
  font-size: var(--text-caption);
  font-weight: 550;
  line-height: var(--lh-snug);
  white-space: nowrap;
  background: color-mix(in srgb, var(--accent-brand) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-brand) 10%, transparent);
  color: var(--accent-text);
  transition:
    background 0.1s,
    border-color 0.1s;
}
.htbl-pill svg {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  color: var(--accent-text);
  opacity: 0.75;
}
.htbl-row:hover .htbl-pill {
  background: color-mix(in srgb, var(--accent-brand) 16%, transparent);
  border-color: color-mix(in srgb, var(--accent-brand) 28%, transparent);
}

/* picked "N of M" chip */
.htbl-picked {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}
.htbl-picked svg {
  width: 12px;
  height: 12px;
}

/* numeric / when / muted cells */
.htbl-num {
  font-size: var(--text-dense);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.htbl-when {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  /* As an inline, this 11.5px text sat on the CELL's strut — a taller line box
     than its own — which dropped it ~4px below the first line of the columns
     either side of it in the tall signal rows. Block with a line box measured
     to match those neighbours (their first lines land at 237-240; this puts it
     at 238). */
  display: block;
  line-height: var(--lh-snug);
}
/* email cell text - size only; color comes from a token class in the markup */
.htbl-muted {
  font-size: var(--text-dense);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: block;
}

/* score chip */
.htbl-score {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 7px;
  font-size: var(--text-xs);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  background: var(--surface-well);
  color: var(--text-secondary);
}
.htbl-score.is-hot {
  background: color-mix(in srgb, var(--accent-brand) 12%, transparent);
  color: var(--accent-text);
}

/* row-end chevron (opens a drawer) */
.htbl-tw {
  display: inline-flex;
  color: var(--text-muted);
}
.htbl-tw svg {
  width: 14px;
  height: 14px;
  transform: rotate(-90deg);
}

/* empty / loading rows */
.htbl-empty td {
  padding: 64px 12px;
  text-align: center;
  font-size: var(--text-dense);
  color: var(--text-muted);
}

/* ---------------- signals: beefy row-density variants (TRA-1359) ----------
   Same sortable table + columns; each variant just draws a richer Details cell
   so a signal shows the work behind it (what happened, why it matters, when +
   where it came from, who to reach). A tall row top-aligns its cells so the
   signal pill / when / checkbox sit on line 1. `original` stays compact. */
.htbl-row.is-tall > td {
  vertical-align: top;
  padding-top: 11px;
  padding-bottom: 11px;
}

/* Details cell: stacked lines. Line 1 is the event summary (a touch heavier),
   then the "why it matters" prose and the suggested-contact pills. */
.htbl-det {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.htbl-det .htbl-l1 {
  font-weight: 550;
  color: var(--text-primary);
}

/* the "Where it fits" column that replaces People - shows just the
   offering name (else the source line), styled like the When column (11.5px
   muted) and top-aligned like every other cell. */
.htbl-fit-name {
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: var(--lh-snug);
  /* Wrap to a second line on overflow (was single-line nowrap), then clamp. */
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* the "why it matters" prose, clamped to 2 lines */
.htbl-det-why {
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: var(--lh-normal);
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* source meta line: publication · date + a "Source" link */
.htbl-src-meta {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: var(--text-caption);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.htbl-src-link {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: var(--accent-text);
}
.htbl-src-link svg {
  width: 11px;
  height: 11px;
}

/* story: horizontal strip of avatar + name pill chips (stakeholders inline) */
.htbl-facechips {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}
.htbl-facechip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  padding: 1px 9px 1px 2px;
  border-radius: 9999px;
  /* Fill only, no outline: the row already carries enough hairlines, and the
     chips read as a group off the shared background alone. */
  background: var(--surface-well);
}
.htbl-facechip-n {
  font-size: var(--text-xs);
  font-weight: 550;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 140px;
}

/* story: the "+N" overflow chip after the last inline name chip */
.htbl-contact-more {
  font-size: var(--text-caption);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* The Signals row layout: restyled to sit closer to the Accounts/People tables.
   Name chips in secondary ink, a 650-weight headline to match .htbl-acct-name,
   and the "Where it fits" value at the muted 12.5px used by the HQ/Role value
   columns. Chips keep Story's pill wrapper with a soft warm-paper fill instead
   of the neutral surface-well. */
.htbl-v-storyx .htbl-facechips {
  gap: 14px;
}
/* Warm paper in light, the neutral well in dark — one token that flips itself,
   replacing the hex + hand-written `.dark` arm that used to sit here. Needing
   a per-theme patch was the tell that the value belonged in tokens.css. */
.htbl-v-storyx .htbl-facechip {
  background: var(--surface-chip-warm);
}
.htbl-v-storyx .htbl-facechip-n {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-secondary);
  max-width: 160px;
}
.htbl-v-storyx .htbl-l1 {
  font-weight: 650;
}
.htbl-v-storyx .htbl-fit-name {
  font-size: var(--text-dense);
}

/* ── "Available to add" group (discovery rows) ───────────────────────────────
   Search returns two kinds of row in ONE table: records the tenant already owns
   and directory matches it does not. The product constraint is a single table
   with one set of column headers, so the split has to be carried by cues that
   survive scrolling — a band that parks under the header, and a rail that runs
   the whole group. A cue that only appears once at the top of the group is the
   failure mode being fixed here. */

/* Where the band parks: under everything else that is sticky above it. The
   real value is MEASURED and written here by `useExternalBandOffset` — the
   header's rendered height differs from `--htbl-header-height`, and the
   selection row's height follows a button size, so any declared offset was
   wrong. This is only the pre-measurement fallback. */
.htbl {
  --htbl-band-top: var(--htbl-header-height);
}

.htbl-ext-band td {
  position: sticky;
  top: var(--htbl-band-top);
  /* Under the column header (5) AND under the selection row (4), so if the two
     ever meet the band slides beneath rather than over them. */
  z-index: 3;
  /* The SAME accent wash as the `IN THIS LIST` bucket bands. It was on the
     cream `--surface-well`, which reads as another header strip and made the
     one persistent cue the least noticeable thing on screen. Matching the
     established band language is what makes it register as a section break.
     Slightly stronger than `.htbl-day` (9% vs 6%) because this seam separates
     two KINDS of row, not two time buckets. */
  background: color-mix(in srgb, var(--accent-brand) 9%, var(--surface-card));
  color: var(--accent-text);
  border-top: 1px solid color-mix(in srgb, var(--accent-brand) 22%, transparent);
  border-bottom: 1px solid var(--border-subtle);
  /* The air above the seam is padding on the band itself. A spacer ROW read as
     a stray half-row hanging under the last owned record. */
  padding: 12px 18px 7px;
  font-size: var(--text-caption);
  font-weight: 650;
  letter-spacing: 0.01em;
  text-transform: none;
}

/* The rail: one continuous accent edge down the whole group. Drawn as an inset
   shadow on the first cell of each row, which reads as continuous because the
   rows are contiguous — a per-row border would leave hairline gaps at the row
   boundaries. Deliberately not an indent: shifting the cells would break column
   alignment with the owned rows above and read as a rendering bug. */
.htbl-row.htbl-ext td:first-child {
  /* Per-theme alpha: 38% of the brand hue reads fine on the cream surface but
     nearly disappears on the dark shell, and this is meant to be one of the two
     cues that survive scrolling. Same light-dark() treatment the signal pill
     ink uses for the same reason. */
  box-shadow: inset 3px 0 0
    light-dark(
      color-mix(in srgb, var(--accent-brand) 45%, transparent),
      color-mix(in srgb, var(--accent-brand) 85%, transparent)
    );
}
/* The group reads as a REGION, not as a set of degraded rows. A faint wash over
   the whole block does the work that per-row text dimming was doing badly:
   stacking opacity on already-muted role/account tokens washed them out on the
   cream surface until they were hard to read, and an unreadable row is a worse
   outcome than an under-differentiated one. A repeated per-row label was worse
   still — twenty-five copies of the same sentence is noise, not signal.
   Deliberately faint: at this strength it reads as a shaded region rather than
   the highlight/error state a saturated tint would suggest. */
/* NEUTRAL, not accent. The brand tint is already the language of selection
   (`.is-sel` is accent 9%, hover 13%) and of the open row (14%) — an accent
   wash here landed within two points of "selected", so a block of unowned rows
   read as a block of picked ones. A neutral shade says "another region"
   without claiming a state. It derives from `--text-primary`, so it darkens
   the cream surface and lifts the dark one without a per-theme rule. */
/* `.htbl-row` sets `cursor: pointer` because an owned row opens its drawer on
   click. A directory row has no drawer and does not add on click — adding is
   deliberate, via the checkbox or the button — so the row must not advertise a
   click it will not honour. The two controls restate `pointer` themselves
   (`.htbl-cell-select` below, and the Button). */
.htbl-row.htbl-ext {
  cursor: default;
}
/* While the add is running the checkbox is replaced by a spinner, so the
   `:has(checkbox:disabled)` not-allowed rule below cannot match and the cell
   kept advertising `pointer` for the several hundred ms the click is ignored. */
.htbl-row td.htbl-cell-select:has(.htbl-ext-pending) {
  cursor: default;
}
.htbl-row.htbl-ext td {
  background: color-mix(in srgb, var(--text-primary) 5%, transparent);
}
/* Hover still lifts, so the rows feel every bit as live as the owned ones —
   and stays neutral, so hovering never impersonates selection either. */
.htbl-row.htbl-ext:hover td {
  background: color-mix(in srgb, var(--text-primary) 9%, transparent);
}
.htbl-row.htbl-ext .htbl-acct-name {
  font-weight: 550;
  color: var(--text-secondary);
}
/* Role and account step back by blending toward the surface — ONE explicit
   value, not an opacity stacked on an already-muted token. That stacking is
   what made them hard to read on the cream background; 12% is a perceptible
   softening that leaves the text fully legible at either theme. */
.htbl-row.htbl-ext .htbl-muted {
  color: color-mix(in srgb, var(--text-muted) 88%, var(--surface-card));
}
/* Softer avatar: an outlined ring instead of a solid fill, so the eye picks up
   "not yours yet" at the left edge without a badge repeated on every row. */
.htbl-row.htbl-ext .htbl-acct > :first-child {
  box-shadow: 0 0 0 1.5px var(--surface-card), 0 0 0 3px
    color-mix(in srgb, var(--accent-brand) 22%, transparent);
}

/* Spinner occupying the checkbox slot while the create-and-add runs, so the
   control does not jump position between states. */
.htbl-ext-pending {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  color: var(--text-muted);
}

/* "No people in your workspace match X" — the owned-side empty state, which
   still renders when the external group below has content. */
.htbl-ext-none td {
  padding: 14px 18px;
  font-size: var(--text-dense);
  color: var(--text-muted);
  border-bottom: 1px solid var(--border-subtle);
}
