/* Chart flows — the reader's row gutter and menus, and the developer's Flows
   panel.

   PALETTE IS THE APP'S, NOT MINE. PersivX's config panel is light-only:
   #ddd/#eee borders, #888 muted text, #6667ab accent. An earlier version of
   this file carried its own blue scale and a prefers-color-scheme dark block —
   the only one in the product — so on a machine set to dark the panel rendered
   a navy card inside a white sidebar. Nothing here sets a dark variant, and
   nothing here invents a colour the surrounding panel does not already use.
   The one exception is a button's own colour, which the developer picks. */

/* ── Reader: the flow gutter ────────────────────────────────────────────
   Its OWN sticky column, second after the row-number/comment gutter — not an
   icon crammed into that cell beside the row number. `left` is set inline by
   harbour (0 or 26px) because only it knows whether the first gutter exists.
   Mirrors .comment-gutter's own geometry so the two line up exactly. */
.table.table-viz > div.flow-gutter {
  position: sticky;
  z-index: 3;
  width: 26px;
  min-width: 26px;
  max-width: 26px;
  background: #fff;
  border-right: 1px solid #e2e8f0;
}
.table.table-viz > div.flow-gutter .body-container { overflow: hidden !important; }
.table.table-viz > div.flow-gutter .body-container::-webkit-scrollbar { width: 0; height: 0; }

/* Width is set inline by harbour from flowRowActions.gutterWidth() — it
   depends on how many buttons the chart carries, which CSS cannot know. */
.flow-gutter-cell {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Kept in step with GAP/PAD in flowRowActions.js's gutterWidth(). */
  gap: 2px;
  padding: 0 7px;
  box-sizing: border-box;
  font-size: 10px;
  color: #c0c4cc;
}

/* One button per flow, wearing the developer's own icon and colour. */
.fr-btn { position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border: none; border-radius: 4px;
  background: none; cursor: pointer; font-size: 12px; opacity: .78; }
.fr-btn:hover { opacity: 1; background: rgba(102,103,171,.10); }
.fr-btn.fr-busy { opacity: .4; cursor: progress; }
/* The last run's outcome, tucked on the button's corner rather than taking a
   column of its own — the button is already the thing it refers to. */
.fr-btn .fr-dot { position: absolute; right: 0; bottom: 0; margin: 0;
  width: 5px; height: 5px; border: 1px solid #fff; }
/* The overflow. A chart with eight flows would otherwise need an eight-icon
   column beside every row; two buttons and a count keep the column the same
   width whether the developer bound three flows or thirty. */
/* The stack: one slot standing in for every flow on the row. Styled as a
   button, not a chip, because it wears a real chosen icon now. */
.fr-more { position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border: none; border-radius: 4px;
  background: none; cursor: pointer; font-size: 12px; opacity: .78; }
.fr-more:hover { opacity: 1; background: rgba(0,0,0,.06); }
/* Black, not tinted: it stands for ALL the flows on the row, so borrowing any
   one of their colours would be picking a side. A single flow still wears its
   own chosen colour — that is the point of the colour picker. */
.fr-stack { color: #000; }
.fr-more .fr-dot { position: absolute; right: 0; bottom: 0; margin: 0;
  width: 5px; height: 5px; border: 1px solid #fff; }

/* The combined-run button, in the flow column's header. Filled rather than
   ghosted like the row buttons: it only appears once rows are selected, and
   it is the one control on the column that acts on more than one row. */
/* Column-header twin of .fr-tb-icon. Sized explicitly because it carries
   .no-special-class (see gutterHeader) and so inherits nothing from harbour;
   12px matches what the toolbar glyph resolves to at 0.85em. */
.fr-bulk-btn { display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; padding: 0; border: none; border-radius: 4px;
  background: none; color: #000; cursor: pointer; font-size: 12px; line-height: 1; }
.fr-bulk-btn:hover { background: rgba(0,0,0,.06); }
/* Outruns the button on a 3-digit selection; that is the one case worth a
   couple of px of bleed rather than a wider column on every chart. */



/* Last run's outcome. Colour never carries the meaning alone — every dot has
   a title, and the history table spells the status out. */
.fr-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%;
    margin-left: 3px; vertical-align: middle; background: #bbb; }
.fr-dot.fr-completed { background: #2e7d32; }
.fr-dot.fr-failed { background: #c62828; }
.fr-dot.fr-running, .fr-dot.fr-queued { background: #6667ab; }
.fr-dot.fr-waiting_approval { background: #ef6c00; }

/* ── Reader: menu ───────────────────────────────────────────────────── */
/* u.popover owns the positioning and the stacking now — this is just the
   card inside it, so no position/z-index of its own. The chrome (border,
   radius, shadow) stays here rather than moving to .uPopover, which u.css
   already styles for every other popover in the product. */
.fr-menu { min-width: 220px; max-width: 300px;
    background: #fff; border: thin solid #ddd; border-radius: 6px;
    box-shadow: 0 6px 20px rgba(0,0,0,.12); overflow: hidden; font-size: 12px; color: #333; }
/* u.popover sizes a bottom-anchored popover to its anchor; these anchors are
   18px icons, so the menu is anchored to the side instead and told to take
   its own content width. */
.uPopover.fr-menu-pop { width: max-content; padding: 0; background: none; border: none; box-shadow: none; }
.fr-menu-head { display: flex; align-items: center; gap: 8px;
  padding: 7px 7px 7px 11px; font-size: 10.5px; color: #888; border-bottom: thin solid #eee; }
.fr-menu-head > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fr-menu-close { display: flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; flex: 0 0 18px; padding: 0; border: none; border-radius: 4px;
  background: none; cursor: pointer; color: #888; font-size: 13px; line-height: 1; }
.fr-menu-close:hover { background: #f1f1f1; color: #1f1f1f; }
.fr-menu-item { display: flex; align-items: center; gap: 8px; padding: 8px 11px; cursor: pointer; }
.fr-menu-item:hover { background: #f6f6fa; }
.fr-menu-item.fr-disabled { opacity: .45; cursor: not-allowed; }
.fr-menu-item.fr-disabled:hover { background: none; }
.fr-menu-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fr-menu-note { font-size: 10px; color: #888; white-space: nowrap; }
.fr-menu-empty { padding: 11px; color: #888; font-style: italic; }
.fr-menu-foot { display: flex; align-items: center; gap: 6px; padding: 8px 11px;
    border-top: thin solid #eee; cursor: pointer; color: #6667ab; }
.fr-menu-foot:hover { background: #f6f6fa; }
.fr-chip { display: inline-flex; align-items: center; justify-content: center;
    width: 21px; height: 21px; border-radius: 5px; color: #fff; font-size: 10.5px; flex-shrink: 0; }
.persivx-selection-flow { cursor: pointer; }

/* ── Reader: history ────────────────────────────────────────────────── */
.fr-hist { width: 100%; border-collapse: collapse; font-size: 12px; }
.fr-hist th { text-align: left; font-size: 10px; color: #888; font-weight: 600;
    padding: 6px 8px; border-bottom: thin solid #ddd; }
.fr-hist td { padding: 7px 8px; border-bottom: thin solid #eee; vertical-align: top; }
.fr-err { color: #c62828; font-size: 11px; margin-top: 2px; }
.fr-linkbtn { background: none; border: none; color: #6667ab; cursor: pointer; font-size: 11.5px; padding: 0; }

/* ── Developer: Flows panel ─────────────────────────────────────────── */
.fb-key { display: flex; align-items: center; gap: 6px; margin: 0 0 8px;
    font-size: 11px; color: #888; }
.fb-key i { flex-shrink: 0; }
.fb-key span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-key b { color: #555; font-weight: 600; }

.fb-empty { font-size: 11.5px; color: #888; font-style: italic; padding: 4px 0 8px; }

.fb-item { border: thin solid #ddd; border-radius: 5px; margin-bottom: 6px; }
.fb-item.fb-open { border-color: #6667ab; }
.fb-head { display: flex; align-items: center; gap: 8px; padding: 7px 8px; cursor: pointer; }
.fb-head:hover { background: #f6f6fa; }
.fb-item.fb-open .fb-head { border-bottom: thin solid #eee; }
.fb-swatch { display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 5px; color: #fff; font-size: 10.5px; flex-shrink: 0; }
.fb-head-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.fb-head-text b { font-size: 12px; font-weight: 600; color: #333;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-head-text small { font-size: 10.5px; color: #888;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-caret { font-size: 10px; color: #888; flex-shrink: 0; }

.fb-body { padding: 8px; display: flex; flex-direction: column; gap: 9px; }
.fb-field { display: flex; flex-direction: column; gap: 3px; }
.fb-field > span { font-size: 11px; color: #555;
    display: flex; justify-content: space-between; align-items: baseline; }
.fb-field > span small { color: #888; }
.fb-field input[type="text"] { width: 100%; font-size: 12px; padding: 4px 6px;
    border: thin solid #ddd; border-radius: 4px; box-sizing: border-box; }
.fb-field input[type="text"]:focus { outline: none; border-color: #6667ab; }

.fb-color { width: 52px; height: 26px; padding: 0; border: thin solid #ddd;
    border-radius: 4px; background: none; cursor: pointer; }

/* Icon chooser: a grid you scan, not a name you have to already know.
   Full width of the panel, ~3 rows visible, scrolling for the rest. */
/* The icon selector: what the panel shows. The grid itself lives in a popup,
   because inline it was 28 buttons tall and pushed the rest of the card off
   the panel — while still being a fraction of the library. */
/* The toolbar twin of the gutter header's button. Sized to sit among
   .chartControllers' own 12px icons rather than to match the row buttons. */
/* The toolbar control carries NO size, padding, border or background of its
   own. It is a <i class="bi"> like the search and menu icons beside it, so
   whatever rule sizes them sizes it — harbour's 22px circle inside a
   .grid-stack-item, or nothing at all elsewhere. The only thing added is a
   positioning context for the count, which changes no dimension. */
/* Two deliberate departures from the neighbours, both asked for: black ink,
   and a slightly smaller glyph — the stack is a denser shape than a magnifier
   or three lines, so at the same font-size it reads heavier than them. The
   size is relative, so it stays proportional whatever the page sets. */
.fr-tb-icon { position: relative; cursor: pointer; color: #000; }
/* The idle state is NOT opacity. Fading the element fades its border and
   background with it, so the circle came out visibly lighter than the two
   beside it — and since it is idle whenever nothing is selected, that was
   most of the time. The class is kept as a hook; it deliberately changes
   nothing visual. What the control needs is to look like its neighbours;
   whether it currently has rows is what the tooltip is for. */
/* The smaller glyph applies ONLY where harbour draws the circle, scoped the
   same way harbour scopes that rule. Inside the circle the box is fixed, so
   shrinking the glyph costs nothing; on a page with no circle the glyph IS
   the box, and shrinking it would make this icon smaller than its neighbours
   — the exact mismatch this whole control was rebuilt to avoid. */
.grid-stack-item .fr-tb-icon { font-size: 0.85em; }
.fr-menu-hint { padding: 5px 9px 7px; font-size: 10px; color: #999; font-style: italic;
  border-top: 1px solid #f1f1f1; }

.fb-icon-sel { display: flex; align-items: center; gap: 7px; width: 100%;
  padding: 5px 8px; border: 1px solid #ddd; border-radius: 4px;
  background: #fff; cursor: pointer; font-size: 12px; color: #1f1f1f; text-align: left; }
.fb-icon-sel:hover { border-color: #6667ab; }
.fb-icon-sel > span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-icon-sel-caret { font-size: 9px; color: #888; }

/* The popup. Wider than the panel's own column and tall enough to scan, which
   is the whole reason the grid moved out of the card. */
.fb-iconpop { width: 264px; padding: 8px; background: #fff; }
.fb-iconpop .fb-icons { max-height: 184px; margin: 0; }
.fb-iconpop .fb-pick-note { padding: 5px 2px 0; }

/* Only reachable from a config saved before one-icon-per-button was enforced.
   Warned about rather than silently rewritten — it is the developer's chart,
   and quietly changing a saved icon on open is worse than saying so. */
.fb-warn { margin-top: 5px; padding: 5px 7px; border-radius: 4px;
  background: #fff8e6; border: 1px solid #f0e0b8; color: #7a5c12; font-size: 11px; line-height: 1.4; }

/* Taken by another button on this chart. Shown rather than hidden: "greyed
   out, and the tooltip says which button has it" answers the question, where
   a silently missing icon just looks like the library is incomplete. */
.fb-icon-taken { opacity: .32; cursor: not-allowed; }
.fb-icon-taken:hover { background: none; color: inherit; }

/* Searches the full ~2,050-icon library the Pictorial Bars chart uses. The
   grid below is the starting set until something is typed, so the common
   choice stays one click away. */
.fb-icon-search { width: 100%; margin: 4px 0 5px; padding: 4px 7px;
  border: 1px solid #ddd; border-radius: 4px; font-size: 11px; color: #1f1f1f; }
.fb-icon-search:focus { outline: none; border-color: #6667ab; }

.fb-icons { display: grid; grid-template-columns: repeat(auto-fill, minmax(28px, 1fr));
    gap: 4px; max-height: 96px; overflow-y: auto;
    border: thin solid #ddd; border-radius: 4px; padding: 5px; background: #fff; }
.fb-icon { display: flex; align-items: center; justify-content: center;
    height: 24px; border: thin solid transparent; border-radius: 4px;
    background: none; cursor: pointer; color: #555; font-size: 12.5px; padding: 0; }
.fb-icon:hover { background: #f6f6fa; color: #6667ab; }
.fb-icon-on { border-color: #6667ab; color: #6667ab; background: #f6f6fa; }

/* The bulk switch's explanation sits under the switch, indented to it. */
.fb-sub { margin: -5px 0 0 2.4em; }

/* An empty column list should not reserve 190px of nothing. */
.fb-map-empty { border: none; }

.fb-check { display: flex; gap: 7px; align-items: flex-start; cursor: pointer; }
.fb-check input { margin-top: 2px; flex-shrink: 0; }
.fb-check span { font-size: 11.5px; color: #555; line-height: 1.4; }
.fb-check small { display: block; font-size: 10.5px; color: #888; }

.fb-map { max-height: 168px; overflow-y: auto; border: thin solid #eee; border-radius: 4px; }
/* The panel's switches sit flush with its other rows. */
.fb-body .form-check.form-switch { display: flex; align-items: center;
    justify-content: space-between; gap: 8px; margin: 0; padding: 0; min-height: 0; }
.fb-body .form-check.form-switch .form-check-label { font-size: 11.5px; color: #555; margin: 0; }
.fb-body .form-check.form-switch .form-check-input { margin: 0; flex-shrink: 0; float: none; }
.fb-map-row { display: grid; grid-template-columns: 1fr 45%; gap: 6px; align-items: center;
    padding: 2px 5px; }
.fb-map-row + .fb-map-row { border-top: thin solid #f4f4f4; }
.fb-map-row label { font-size: 11px; color: #555;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-map-row input { font-size: 11px; padding: 2px 5px; border: thin solid #ddd;
    border-radius: 3px; width: 100%; box-sizing: border-box; }
.fb-map-row input:focus { outline: none; border-color: #6667ab; }

.fb-add { width: 100%; padding: 6px; border: thin dashed #bbb; border-radius: 5px;
    background: none; cursor: pointer; color: #6667ab; font-size: 11.5px; }
.fb-add:hover { border-color: #6667ab; background: #f6f6fa; }
.fb-remove { align-self: flex-start; background: none; border: none; cursor: pointer;
    color: #c62828; font-size: 11px; padding: 0; }

.fb-note { font-size: 11px; color: #888; line-height: 1.5; margin: 3px 0; }
.fb-error { font-size: 11.5px; color: #c62828; background: #fdf3f3; border: thin solid #f0c9c9;
    border-radius: 4px; padding: 7px 9px; margin-bottom: 8px; line-height: 1.5; }

/* Flow picker — search, because an org can hold thousands. */
.fb-picked { display: flex; align-items: center; gap: 6px; padding: 4px 7px;
    border: thin solid #ddd; border-radius: 4px; font-size: 11.5px; color: #333; }
.fb-picked span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-picked i { color: #2e7d32; }
.fb-picked button { background: none; border: none; cursor: pointer; color: #888;
    font-size: 15px; line-height: 1; padding: 0; }
.fb-pick-results { max-height: 160px; overflow-y: auto; margin-top: 3px; }
.fb-pick-results:not(:empty) { border: thin solid #ddd; border-radius: 4px; }
.fb-pick-item { padding: 5px 7px; cursor: pointer; }
.fb-pick-item + .fb-pick-item { border-top: thin solid #f4f4f4; }
.fb-pick-item:hover { background: #f6f6fa; }
.fb-pick-name { display: block; font-size: 12px; color: #333; }
.fb-pick-desc { display: block; font-size: 10.5px; color: #888;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-pick-note { padding: 6px 7px; font-size: 11px; color: #888; font-style: italic; }
