  /* ============================== TYPE-AWARE CONDITION RULES ==============================
     DESIGN-SPEC (typed-rules) §8.3. ONE rule row — the condition node, the side panel
     (253px, narrower than the node itself), the analytics filter bar and the community
     invite modal all render the exact same DOM (public/js/builder/rule-editor.js
     nfRuleHtml()), and differ only through this file's ONE container query (§1b). No other
     layout branching exists anywhere in the feature.

     THE TRUNCATION BAR (§5), kept here so it does not recur: a <select> in a node body is
     a craft violation the moment its selected option's text is clipped by its own box —
     the author can no longer read the state of the rule without opening the menu, so the
     control has stopped reporting. Rules that follow from that:
       1. Minimum <select> width 136px (~18 chars at 11.5px Inter + padding + chevron).
          Below that, change the layout, not the control — hence the grid's 140px track min.
       2. No <select> may be a shrinking flex item (no flex:1;min-width:88px — that produced
          four 89.3px selects in the old 410px rule row; see 04-canvas-nodes.css's deleted
          .rule-row select).
       3. Proper-noun content (question labels, row/column/option labels, chip labels) is
          truncated in JS with '…', never machine-clipped — full string always in `title`.
       4. Structural strings (operator labels, quantifier labels, "and"/"above", the
          read-back's operator + value spans) are NEVER truncated. If they don't fit, the
          layout is wrong, not the label. */

  /* ---- §1a: the read-back sentence — the default state of a complete rule. ---- */
  .nf-rule{container-type:inline-size; background:var(--surface-default);
    border:1px solid var(--border-strong); border-radius:var(--r-control); font-size:11.5px; position:relative;
    display:flex; align-items:stretch; margin-bottom:6px;}
  /* Guardian C1 — two classes, two meanings. .expanded is LAYOUT (an incomplete rule can't
     collapse); .editing is the one-at-a-time focus ring. Painting the ring for both reasons
     put it on three cards at once, and a focus signal on three things is no signal. */
  .nf-rule.expanded{display:block;}
  .nf-rule.expanded:not(.editing){border-color:var(--border-strong); box-shadow:none;}
  .nf-rule.editing{border-color:var(--brand-600); box-shadow:0 0 0 1px var(--brand-600);}
  .nf-rule-read{display:flex; gap:6px; padding:7px 8px; width:100%; background:transparent; border:none;
    font:inherit; font-size:11.5px; line-height:1.4; color:var(--text-secondary); text-align:left; cursor:pointer;}
  .nf-rule-read:hover{background:var(--surface-subtle);}
  /* Guardian fix 1.9 — 2 -> 3 lines. Together with the JS-side truncation (24 chars per
     value, rule-editor.js's collapsed branch) this clamp is now a safety net that only
     ever ends a line in an authored "…", never a machine mid-glyph clip. */
  .nf-rule-read .s{display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; flex:1;}
  .nf-rule-read .q, .nf-rule-read .v{color:var(--text-primary); font-weight:600;}
  .nf-rule-read .q{display:inline-block; vertical-align:bottom; max-width:60%; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  /* Guardian fix 2.6 — 27x17px hit target (no coarse-pointer bump, unlike .nf-chip-x). */
  .nf-rule-rm{flex:none; align-self:center; margin-right:4px; background:transparent; border:none;
    color:var(--text-muted); padding:2px 7px; line-height:1; cursor:pointer; border-radius:var(--r-control); /* Guardian C3 — no opacity: the token alone is 3.90:1, opacity .75 dragged it to 2.60:1 */
    min-height:24px; min-width:24px;}
  .nf-rule-rm:hover{color:var(--error-fg); border:none; background:var(--surface-sunken);}
  .nf-rule-rm:focus-visible{color:var(--error-fg);}

  /* ---- §1b: expanded — auto-fit grid, no breakpoints below 620px. ---- */
  .nf-rule-grid{display:grid; grid-template-columns:repeat(auto-fit, minmax(140px,1fr)); gap:6px; padding:8px;}
  .nf-rule-q, .nf-rule-vals, .nf-rule-foot, .nf-rule-hint{grid-column:1/-1;}
  /* Guardian fix 1.10 — a rule with no scope control (star_rating, number, date, text,
     nps, ranked_above's read-back... any type minus matrix/ranked_top_n/ranked_above) put
     .nf-rule-op alone into the auto-fit grid's first track, leaving the second 140px+
     track of that row empty — a orphan cell exactly .nf-rule-op's own width. Default op to
     full width; when a scope cell DOES precede it (matrix, ranked_top_n, ranked_above —
     scope always renders before op in the DOM, see nfRuleHtml), put it back to auto so the
     two sit side by side as designed. */
  .nf-rule-op{grid-column:1/-1;}
  .nf-rule-scope + .nf-rule-op{grid-column:auto;}
  .nf-rule select, .nf-rule input{width:100%; min-width:0; height:28px; font:inherit; font-size:11.5px;
    background:var(--surface-default); border:1px solid var(--border-control);
    color:var(--text-primary); border-radius:var(--r-control); padding:5px 6px;}
  .nf-rule select:focus-visible, .nf-rule input:focus-visible{outline:2px solid var(--brand-600); outline-offset:1px;}
  .nf-and{font-size:11.5px; color:var(--text-muted); align-self:center; padding:0 2px; white-space:nowrap;}
  /* Guardian fix 2.1 — .nf-rule-vals was a plain block, so a `between`/`date_between`/nps
     `between`/`ranked_above`-style two-control-plus-connective row stacked full width with
     a flush-left "and" instead of sitting on one line. */
  .nf-rule-vals{display:flex; flex-wrap:wrap; align-items:center; gap:6px;}
  .nf-rule-vals > input, .nf-rule-vals > select{flex:1 1 136px; width:auto;}
  .nf-rule-vals > .nf-vals{flex:1 1 100%;}
  /* Guardian fix 2.3 — the OR-hint is now its own top-level grid/flex cell (a sibling of
     .nf-rule-vals, not nested inside it — see nfRuleHintCellHtml in rule-editor.js), so it
     stops inheriting .nf-rule-vals's narrow flex-basis in the filter bar and stops
     drifting out of vertical alignment with the row's controls. */
  .nf-rule-hint{font-size:11.5px; color:var(--text-secondary); line-height:1.45;} /* Guardian C5 — 6.19:1; --text-muted was 3.90:1 at 10.5px, and condition-split §3b already ruled this */
  .nf-rule-foot{display:flex; gap:8px; align-items:center;}
  /* §7.7 — Done commits nothing (edits are already live); ghost treatment, brand fill is
     reserved for actions that actually commit something. */
  .nf-rule-rm-txt, .nf-rule-done{font-size:11.5px; padding:5px 10px; height:auto;}
  .nf-rule-rm-txt{margin-right:auto; color:var(--text-secondary);} /* Guardian C6 — 11px text needs 4.5:1 */
  .nf-rule-rm-txt:hover{color:var(--error-fg);}
  /* Guardian fix 3.3 — with no Remove-rule button to push against (ctx.removable=false,
     the invite modal's single filter), Done had nothing forcing it right and sat flush
     left instead of in its usual bottom-right corner. */
  .nf-rule-done{margin-left:auto;}
  @container (min-width:620px){
    .nf-rule-grid{display:flex; flex-wrap:wrap; align-items:center;}
    .nf-rule-grid > *{flex:0 1 auto; width:auto;}
    .nf-rule-q select{max-width:320px;}
    .nf-rule-scope select, .nf-rule-op select{min-width:136px;}
    .nf-rule-vals{flex:1 1 220px; align-self:center;}
    /* Guardian fix 2.3 — force the hint onto its own full-width line rather than crowding
       the last control on the row (the source of the 1500px filter-bar's 27px vertical
       misalignment: the hint and the selects disagreed about their own top offset once
       they were forced to share a line). */
    .nf-rule-hint{flex:1 1 100%; order:9;}
    .nf-rule-foot{margin-left:auto;}
  }

  /* ---- §2: the multi-value picker — chips + one trigger + a fixed popover. ---- */
  .nf-vals{display:flex; flex-wrap:wrap; gap:4px; align-items:center; min-height:28px;
    background:var(--surface-default); border:1px solid var(--border-control);
    border-radius:var(--r-control); padding:3px 4px;}
  .nf-vals-none{font-size:11.5px; color:var(--text-secondary); padding:4px 2px;} /* Guardian C4 — light-tier text on the sunken fill was 3.43:1; secondary is 5.46:1 */
  .nf-chip{display:inline-flex; align-items:center; gap:2px; height:22px; max-width:146px;
    font-size:11.5px; line-height:1; padding:0 3px 0 9px; border-radius:var(--r-chip);
    background:var(--surface-default); border:1px solid var(--border-control); color:var(--text-primary);}
  .nf-chip-lb{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .nf-chip-x{width:18px; height:18px; display:inline-flex; align-items:center; justify-content:center;
    border:none; background:transparent; color:var(--text-muted); border-radius:50%; cursor:pointer; padding:0;}
  .nf-chip-x:hover{background:var(--surface-sunken); color:var(--error-fg);}
  .nf-chip-x:focus-visible{color:var(--error-fg); outline:2px solid var(--brand-600); outline-offset:1px;}
  .nf-vals-add{height:22px; padding:0 10px; font-size:11.5px; border-radius:var(--r-chip); cursor:pointer;
    border:1px dashed var(--border-strong); background:transparent; color:var(--brand-700);}
  .nf-vals.is-empty .nf-vals-add{border-style:solid; border-color:var(--brand-200); background:var(--brand-50);}
  /* Guardian fix 2.6 — coarse-pointer bump .nf-chip-x already gets, .nf-rule-rm didn't. */
  @media (pointer:coarse){ .nf-chip{height:32px;} .nf-chip-x{width:28px; height:28px;} .nf-vals-add{height:32px;} .nf-rule-rm{width:32px; height:32px;} }

  /* ---- §2c: the popover — .cmt-pop geometry verbatim, zero new colour tokens. ---- */
  /* Guardian fix 1.2 — .cmt-pop is z-index:158, under .app-modal (180). Opened from the
     invite modal, a hit-test on a popover checkbox landed on the modal's Cancel button
     instead — clicking "+ add" there looked like it did nothing. 190 clears .app-modal
     (180) and its backdrop (185), stays under the toast (200). */
  .nf-vals-pop{width:260px; overflow:hidden; z-index:190;}
  /* Guardian fix 3.2 — inside a wrapping flex header, margin-left:auto with nothing after
     it on the line just pushed the question label to the far right of its OWN wrapped
     line, not the header's. flex-basis:100% forces it onto its own line predictably. */
  .nf-vals-pop-q{font-size:11.5px; color:var(--text-muted); flex-basis:100%; margin-left:0;}
  .nf-vals-filter{width:100%; height:28px; font:inherit; font-size:11.5px; background:var(--surface-default);
    border:1px solid var(--border-control); color:var(--text-primary); border-radius:var(--r-control); padding:5px 8px; margin:8px 0 4px;}
  /* Guardian fix 2.4 — .nf-rule select/input:focus-visible is scoped to .nf-rule; this
     popover lives on document.body, outside it, so its filter input and checkboxes fell
     back to the browser's default black focus ring. */
  .nf-vals-pop input:focus-visible{outline:2px solid var(--brand-600); outline-offset:1px;}
  .nf-vals-pop-list{max-height:280px; overflow-y:auto; padding:2px 6px;}
  .nf-vals-opt{display:flex; align-items:center; gap:8px; height:32px; padding:0 6px; font-size:12px;
    color:var(--text-primary); border-radius:var(--r-control); cursor:pointer;}
  .nf-vals-opt:hover{background:var(--brand-50);}
  .nf-vals-opt input{margin:0; accent-color:var(--brand-600); flex:none;}
  .nf-vals-opt span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  /* Guardian fix 3.1 — the list scrolls (max-height:280px) with no boundary marking where
     it ends and the Clear-all footer begins. */
  .nf-vals-pop-foot{padding:6px 12px 10px; border-top:1px solid var(--border-default);}
  .nf-vals-clear{font-size:11.5px; padding:0; height:auto; border:none; background:transparent; color:var(--text-secondary); text-decoration:underline;} /* Guardian C6 */
  .nf-vals-clear:hover{color:var(--error-fg); background:transparent; border:none;}
