/* ============================================================================
   OI — Wheel Admin, ruleset editor (.oi-*)

   Scope: an INTERNAL OPS tool, not a patient or clinician-chart surface. It is
   NOT on patient-tokens.css and must never be: parity.html governs patient
   surfaces and this is not one.

   COLOUR: Wheel green, matched to the real screen. This was built on ClearCare
   teal first, on the reasoning that ClearCare is Wheel's clinician-side system —
   wrong call. Wheel Admin is Wheel's OWN internal tool and the screenshot wears
   Wheel green: a green solid on the primary action, green-filled ALL/ANY pills,
   light-green chips with dark-green ink. ClearCare's teal belongs to the EMR
   product, not to Wheel's back office. The primary ramp below is built around
   brand green #2E4F25; the NEUTRAL and SEMANTIC ramps stay ClearCare's, because
   those are generic greys and fixed status colours, not brand.

   Everything is scoped under .oi-shell, the same way the Generic API demo scopes
   its palette: this prototype mounts INLINE in app-b's tree, so writing
   documentElement would repaint the sales demo behind it.
   ============================================================================ */

.oi-shell {
  /* Wheel green, around brand #2E4F25 (--oi-p-700). Same ramp shape as before so
     nothing downstream had to change: 50/100 are tints, 200 is a chip border,
     400 a focus ring, 600 a bar fill, 700 the brand, 800 the pressed state. */
  --oi-p-50: rgb(241,245,239);
  --oi-p-100: rgb(227,235,223);
  --oi-p-200: rgb(198,216,191);
  --oi-p-400: rgb(127,165,116);
  --oi-p-600: rgb(61,102,49);
  --oi-p-700: rgb(46,79,37);
  --oi-p-800: rgb(37,64,30);
  /* neutrals */
  --oi-n-50: rgb(242,244,245);
  --oi-n-100: rgb(229,232,235);
  --oi-n-200: rgb(208,213,217);
  --oi-n-300: rgb(182,189,195);
  --oi-n-400: rgb(155,164,172);
  --oi-n-500: rgb(131,140,147);
  --oi-n-600: rgb(108,116,123);
  --oi-n-700: rgb(87,94,100);
  --oi-n-800: rgb(67,73,77);
  --oi-n-900: rgb(48,52,55);
  /* semantic — fixed, never brand-coloured (same rule as the patient system) */
  --oi-err-50: rgb(255,239,237);
  --oi-err-200: rgb(255,195,189);
  --oi-err-700: rgb(157,51,48);
  --oi-warn-50: rgb(255,242,220);
  --oi-warn-200: rgb(246,206,137);
  --oi-warn-400: rgb(211,151,0);
  --oi-warn-700: rgb(122,86,0);
  --oi-ok-50: rgb(227,251,234);
  --oi-ok-200: rgb(165,230,186);
  --oi-ok-700: rgb(0,112,61);
  --oi-info-50: rgb(237,244,255);
  --oi-info-200: rgb(186,214,255);
  --oi-info-700: rgb(33,91,171);
  /* surfaces + type */
  --oi-page: var(--oi-n-50);
  --oi-card: #fff;
  --oi-line: var(--oi-n-200);
  --oi-line-soft: var(--oi-n-100);
  --oi-ink: var(--oi-n-900);
  --oi-ink-2: var(--oi-n-700);
  --oi-ink-3: var(--oi-n-600);
  --oi-r-sm: 4px; --oi-r-md: 6px; --oi-r-lg: 8px; --oi-r-pill: 999px;
  --oi-s1: 4px; --oi-s2: 8px; --oi-s3: 12px; --oi-s4: 16px; --oi-s5: 20px; --oi-s6: 24px; --oi-s8: 32px;
  --oi-t-xs: 12px; --oi-t-sm: 13px; --oi-t-md: 14px; --oi-t-lg: 16px; --oi-t-xl: 20px; --oi-t-2xl: 26px;

  display: flex;
  min-height: calc(100vh - 0px);
  background: var(--oi-page);
  color: var(--oi-ink);
  font-family: "Inter", system-ui, -apple-system, sans-serif;
  font-size: var(--oi-t-md);
  line-height: 1.45;
}
.oi-shell *, .oi-shell *::before, .oi-shell *::after { box-sizing: border-box; }
.oi-shell button { font-family: inherit; cursor: pointer; }

/* ---- sidebar ------------------------------------------------------------- */
.oi-side { flex: 0 0 232px; background: var(--oi-card); border-right: 1px solid var(--oi-line); padding: var(--oi-s6) 0; display: flex; flex-direction: column; }
.oi-who { padding: 0 var(--oi-s5) var(--oi-s5); }
.oi-who-name { font-family: "Source Serif 4", Georgia, serif; font-size: 19px; font-weight: 600; color: var(--oi-ink); }
.oi-who-role { font-size: var(--oi-t-xs); color: var(--oi-ink-3); margin-top: 2px; }
.oi-nav { display: flex; flex-direction: column; gap: 1px; }
.oi-nav-i { display: flex; align-items: center; gap: var(--oi-s3); width: 100%; padding: 9px var(--oi-s5); border: none; background: none; text-align: left; font-size: var(--oi-t-md); color: var(--oi-ink-2); }
.oi-nav-i:hover { background: var(--oi-n-50); color: var(--oi-ink); }
.oi-nav-i .material-icons-round { font-size: 19px; color: var(--oi-n-500); flex: 0 0 19px; }
/* Selected: a teal rail plus a tint. The rail is what makes it readable at a
   glance in a 14-item list; colour alone is not enough (the patient app learned
   this the hard way on its own nav). */
.oi-nav-i.is-on { background: var(--oi-n-50); color: var(--oi-ink); font-weight: 600; box-shadow: inset 3px 0 0 var(--oi-p-700); }
.oi-nav-i.is-on .material-icons-round { color: var(--oi-p-700); }
.oi-side { font-feature-settings: normal; }

/* ---- page frame --------------------------------------------------------- */
.oi-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.oi-top { background: var(--oi-card); border-bottom: 1px solid var(--oi-line); padding: var(--oi-s5) var(--oi-s6) 0; }
.oi-crumb { display: flex; align-items: center; gap: var(--oi-s1); font-size: var(--oi-t-sm); color: var(--oi-ink-3); }
.oi-crumb button { border: none; background: none; padding: 0; font-size: inherit; color: var(--oi-p-700); text-decoration: underline; }
.oi-top-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--oi-s6); margin-top: var(--oi-s2); }
.oi-h1 { font-size: var(--oi-t-2xl); font-weight: 600; letter-spacing: -0.01em; margin: 0; }
.oi-top-actions { display: flex; align-items: center; gap: var(--oi-s2); flex: 0 0 auto; }

/* Draft state is the highest-stakes fact on this screen: these rules gate who
   can take work. It was an 11px grey line under the title; it is a banded strip
   with the change count and the publish action in it. */
.oi-draft { display: flex; align-items: center; gap: var(--oi-s3); flex-wrap: wrap; margin-top: var(--oi-s4); padding: var(--oi-s3) var(--oi-s4); border-radius: var(--oi-r-md) var(--oi-r-md) 0 0; background: var(--oi-warn-50); border: 1px solid var(--oi-warn-200); border-bottom: none; font-size: var(--oi-t-sm); color: var(--oi-ink); }
.oi-draft.is-clean { background: var(--oi-ok-50); border-color: var(--oi-ok-200); }
.oi-draft .material-icons-round { font-size: 18px; color: var(--oi-warn-700); }
.oi-draft.is-clean .material-icons-round { color: var(--oi-ok-700); }
.oi-draft-b { font-weight: 600; }
.oi-draft-sp { margin-left: auto; display: flex; gap: var(--oi-s2); }

.oi-body { flex: 1 1 auto; display: grid; grid-template-columns: minmax(0,1fr) 336px; gap: var(--oi-s6); align-items: start; padding: var(--oi-s6); max-width: 1440px; }

/* ---- buttons ------------------------------------------------------------ */
.oi-btn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: var(--oi-r-md); border: 1px solid var(--oi-n-300); background: #fff; color: var(--oi-n-800); font-size: var(--oi-t-md); font-weight: 500; }
.oi-btn:hover { background: var(--oi-n-50); }
.oi-btn-primary { background: var(--oi-p-700); border-color: var(--oi-p-700); color: #fff; }
.oi-btn-primary:hover { background: var(--oi-p-800); border-color: var(--oi-p-800); }
.oi-btn-ghost { border-color: transparent; background: none; color: var(--oi-p-700); }
.oi-btn-ghost:hover { background: var(--oi-p-50); }
.oi-btn:disabled { background: var(--oi-n-100); border-color: var(--oi-n-200); color: var(--oi-n-500); cursor: default; }
.oi-btn-sm { padding: 5px 10px; font-size: var(--oi-t-sm); }
.oi-btn .material-icons-round { font-size: 17px; }

/* ---- group container ---------------------------------------------------- */
/* A group is a CONTAINER, not an indent. The original conveyed nesting with
   ~30px of left padding and nothing else, so a group and a rule read as peers
   and you could not see where a branch ended. */
.oi-group { background: var(--oi-card); border: 1px solid var(--oi-line); border-radius: var(--oi-r-lg); }
.oi-group + .oi-group { margin-top: var(--oi-s4); }
.oi-group-head { display: flex; align-items: center; gap: var(--oi-s3); padding: var(--oi-s4); border-bottom: 1px solid var(--oi-line-soft); flex-wrap: wrap; }
.oi-group-name { font-size: var(--oi-t-lg); font-weight: 600; }
.oi-group-sub { font-size: var(--oi-t-sm); color: var(--oi-ink-3); }
.oi-group-acts { margin-left: auto; display: flex; align-items: center; gap: var(--oi-s1); }
.oi-group-body { padding: var(--oi-s4); display: flex; flex-direction: column; gap: var(--oi-s3); }
/* Nested groups sit on a rail so the branch is traceable without counting pixels. */
.oi-sub { border-left: 2px solid var(--oi-p-200); border-radius: 0 var(--oi-r-lg) var(--oi-r-lg) 0; background: var(--oi-n-50); border-top: 1px solid var(--oi-line-soft); border-right: 1px solid var(--oi-line-soft); border-bottom: 1px solid var(--oi-line-soft); }
.oi-sub > .oi-group-head { border-bottom-color: var(--oi-line); }
/* ink-3 clears 4.5:1 on white but only reaches 4.3 on the nested tint. */
.oi-sub > .oi-group-head .oi-group-sub { color: var(--oi-ink-2); }
.oi-sub .oi-rule { background: #fff; }

.oi-chev { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: none; background: none; border-radius: var(--oi-r-sm); color: var(--oi-ink-3); flex: 0 0 24px; }
.oi-chev:hover { background: var(--oi-n-100); color: var(--oi-ink); }
.oi-chev .material-icons-round { font-size: 20px; }

/* ---- boolean toggle ----------------------------------------------------- */
/* ALL / ANY was two adjacent pills with no selected state, so the meaning had
   to be carried by trailing prose ("every one of the following"). One control,
   one selected half, and the prose becomes a subtitle instead of the answer.
   Two-letter pills inside a segmented control are the legitimate all-caps case;
   no heading here uses them. */
.oi-bool { display: inline-flex; padding: 2px; background: var(--oi-n-100); border-radius: var(--oi-r-pill); flex: 0 0 auto; }
/* --oi-ink-2, not ink-3: the unselected half is clickable, not disabled, and ink-3 on
   the n-100 track measures 3.86:1. */
.oi-bool button { padding: 3px 12px; border: none; background: none; border-radius: var(--oi-r-pill); font-size: var(--oi-t-xs); font-weight: 700; letter-spacing: 0.04em; color: var(--oi-ink-2); }
.oi-bool button.is-on { background: var(--oi-p-700); color: #fff; }

/* ---- rule card ---------------------------------------------------------- */
/* Each rule is its own card with the rule TYPE as a label above the sentence.
   In the original the type and the sentence ran together on one line, so at six
   controls the grammar broke down and you could not tell where one rule ended. */
.oi-rule { position: relative; border: 1px solid var(--oi-line); border-radius: var(--oi-r-md); background: var(--oi-card); padding: var(--oi-s3) var(--oi-s4); }
.oi-rule:hover { border-color: var(--oi-n-300); }
.oi-rule.is-focus { border-color: var(--oi-p-400); box-shadow: 0 0 0 2px var(--oi-p-100); }
.oi-rule-head { display: flex; align-items: center; gap: var(--oi-s2); }
.oi-rule-type { font-size: var(--oi-t-sm); font-weight: 600; color: var(--oi-ink-2); }
.oi-rule-acts { margin-left: auto; display: flex; align-items: center; gap: 2px; opacity: 0; }
.oi-rule:hover .oi-rule-acts, .oi-rule:focus-within .oi-rule-acts { opacity: 1; }
.oi-ia { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; background: none; border-radius: var(--oi-r-sm); color: var(--oi-ink-3); }
.oi-ia:hover { background: var(--oi-n-100); color: var(--oi-ink); }
.oi-ia.is-danger:hover { background: var(--oi-err-50); color: var(--oi-err-700); }
.oi-ia .material-icons-round { font-size: 18px; }
.oi-grip { cursor: grab; }

/* The sentence. Wraps as a phrase list, so a long rule reads as clauses rather
   than a paragraph with holes in it. */
.oi-sent { display: flex; align-items: center; flex-wrap: wrap; gap: 6px var(--oi-s1); margin-top: 6px; font-size: var(--oi-t-md); color: var(--oi-ink); line-height: 2.1; }
.oi-w { color: var(--oi-ink-2); }
.oi-clause { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px var(--oi-s1); padding: 2px 0; }
/* A secondary clause (a cap, a qualifier) is dimmed so the primary condition
   survives. Everything was one weight before, so "at least 12 hours" competed
   with "crediting accepted assignments". */
.oi-clause.is-aside { color: var(--oi-ink-3); }
.oi-clause.is-aside .oi-w { color: var(--oi-ink-3); }

/* ---- inline controls ---------------------------------------------------- */
.oi-num { width: 68px; padding: 4px 8px; border: 1px solid var(--oi-n-300); border-radius: var(--oi-r-sm); background: #fff; font: inherit; font-variant-numeric: tabular-nums; text-align: right; color: var(--oi-ink); }
.oi-num:focus { outline: 2px solid var(--oi-p-600); outline-offset: -1px; border-color: var(--oi-p-600); }
/* An unfilled optional input read identically to an unfilled REQUIRED one in
   the original. Optional blanks now say what blank means. */
.oi-num.is-empty { border-style: dashed; border-color: var(--oi-n-400); text-align: left; }
.oi-num.is-wide { width: 96px; }
.oi-sel { padding: 4px 26px 4px 8px; border: 1px solid var(--oi-n-300); border-radius: var(--oi-r-sm); background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236C747B'%3E%3Cpath d='M4 6l4 4 4-4z'/%3E%3C/svg%3E") no-repeat right 6px center; background-size: 14px; font: inherit; color: var(--oi-ink); appearance: none; }
.oi-sel:focus { outline: 2px solid var(--oi-p-600); outline-offset: -1px; }

.oi-chips { display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--oi-s1); }
.oi-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 6px 3px 10px; border-radius: var(--oi-r-pill); background: var(--oi-p-50); border: 1px solid var(--oi-p-200); color: var(--oi-p-800); font-size: var(--oi-t-sm); font-weight: 500; }
.oi-chip-x { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border: none; background: none; border-radius: var(--oi-r-pill); color: var(--oi-p-700); padding: 0; }
.oi-chip-x:hover { background: var(--oi-p-200); }
.oi-chip-x .material-icons-round { font-size: 14px; }
.oi-chip-add { display: inline-flex; align-items: center; gap: 3px; padding: 3px 10px; border-radius: var(--oi-r-pill); border: 1px dashed var(--oi-n-400); background: none; color: var(--oi-ink-2); font-size: var(--oi-t-sm); }
.oi-chip-add:hover { border-color: var(--oi-p-600); color: var(--oi-p-700); background: var(--oi-p-50); }
.oi-chip-add .material-icons-round { font-size: 15px; }

/* ---- no-data policy ----------------------------------------------------- */
/* This line appeared under all eight rules, at low contrast, saying the same
   thing seven times. The one rule that differed was the hardest to spot. It is
   a ruleset-level default now, and a rule only speaks up when it DISAGREES. */
.oi-nodata { display: inline-flex; align-items: center; gap: 5px; margin-top: 6px; padding: 2px 8px; border-radius: var(--oi-r-pill); background: var(--oi-info-50); border: 1px solid var(--oi-info-200); font-size: var(--oi-t-xs); color: var(--oi-ink); }
.oi-nodata .material-icons-round { font-size: 14px; color: var(--oi-info-700); }
.oi-nodata select { border: none; background: none; font: inherit; color: var(--oi-info-700); font-weight: 600; padding: 0 2px; }

.oi-add-row { display: flex; gap: var(--oi-s2); padding-top: var(--oi-s1); }

/* ---- evaluation panel --------------------------------------------------- */
/* The real gap in the original: nothing on screen said what the ruleset DOES.
   Eight sentences, no aggregate, so you edited an eligibility gate blind. */
.oi-eval { position: sticky; top: var(--oi-s6); display: flex; flex-direction: column; gap: var(--oi-s4); }
.oi-panel { background: var(--oi-card); border: 1px solid var(--oi-line); border-radius: var(--oi-r-lg); padding: var(--oi-s4); }
.oi-panel-h { font-size: var(--oi-t-md); font-weight: 600; margin: 0 0 var(--oi-s1); }
.oi-panel-sub { font-size: var(--oi-t-xs); color: var(--oi-ink-3); margin: 0 0 var(--oi-s3); }
.oi-match { display: flex; align-items: baseline; gap: var(--oi-s2); }
.oi-match-n { font-size: 34px; font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.oi-match-of { font-size: var(--oi-t-sm); color: var(--oi-ink-3); }
.oi-delta { display: inline-flex; align-items: center; gap: 3px; margin-top: var(--oi-s2); padding: 2px 8px; border-radius: var(--oi-r-pill); font-size: var(--oi-t-xs); font-weight: 600; }
.oi-delta.is-down { background: var(--oi-err-50); color: var(--oi-err-700); }
.oi-delta.is-up { background: var(--oi-ok-50); color: var(--oi-ok-700); }
.oi-delta.is-flat { background: var(--oi-n-100); color: var(--oi-ink-3); }
.oi-delta .material-icons-round { font-size: 14px; }

.oi-funnel { display: flex; flex-direction: column; gap: var(--oi-s3); }
.oi-fn { display: grid; grid-template-columns: 1fr auto; gap: 2px var(--oi-s2); align-items: baseline; }
.oi-fn-k { font-size: var(--oi-t-sm); color: var(--oi-ink-2); min-width: 0; }
.oi-fn-v { font-size: var(--oi-t-sm); font-variant-numeric: tabular-nums; color: var(--oi-ink); }
.oi-fn-bar { grid-column: 1 / -1; height: 6px; border-radius: var(--oi-r-pill); background: var(--oi-n-100); overflow: hidden; }
/* display:block is load-bearing. This is an empty span: as display:inline it discards
   width AND height and collapses to nothing, so every bar in the funnel rendered 0x0
   over a grey track. The track itself looked fine because .oi-fn-bar is a grid item
   and blockifies, which is exactly what made the bug hard to see. */
.oi-fn-fill { display: block; height: 100%; border-radius: var(--oi-r-pill); background: var(--oi-p-600); }
/* The binding constraint. With eight rules in an ALL, one of them is doing most
   of the filtering and that is the only number anyone actually wants. */
.oi-fn.is-binding .oi-fn-fill { background: var(--oi-warn-400); }
.oi-fn.is-binding .oi-fn-k { font-weight: 600; color: var(--oi-ink); }
.oi-fn-tag { display: inline-flex; align-items: center; gap: 3px; font-size: var(--oi-t-xs); font-weight: 600; color: var(--oi-warn-700); }
.oi-fn-tag .material-icons-round { font-size: 13px; }

.oi-changes { display: flex; flex-direction: column; gap: var(--oi-s2); }
.oi-change { display: grid; grid-template-columns: 18px 1fr; gap: var(--oi-s2); font-size: var(--oi-t-sm); color: var(--oi-ink-2); }
.oi-change .material-icons-round { font-size: 16px; color: var(--oi-warn-700); }
.oi-change b { color: var(--oi-ink); font-weight: 600; }
.oi-empty { font-size: var(--oi-t-sm); color: var(--oi-ink-3); }

/* ---- ruleset list ------------------------------------------------------- */
.oi-list { display: flex; flex-direction: column; gap: var(--oi-s2); }
.oi-lrow { display: grid; grid-template-columns: 1fr auto auto auto; gap: var(--oi-s4); align-items: center; width: 100%; text-align: left; padding: var(--oi-s4); background: var(--oi-card); border: 1px solid var(--oi-line); border-radius: var(--oi-r-md); }
.oi-lrow:hover { border-color: var(--oi-p-600); background: var(--oi-p-50); }
.oi-lrow-name { font-size: var(--oi-t-lg); font-weight: 600; }
.oi-lrow-meta { font-size: var(--oi-t-sm); color: var(--oi-ink-3); margin-top: 2px; }
.oi-lrow-n { font-size: var(--oi-t-md); font-variant-numeric: tabular-nums; color: var(--oi-ink-2); }
.oi-pill { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px; border-radius: var(--oi-r-pill); font-size: var(--oi-t-xs); font-weight: 600; }
.oi-pill.is-draft { background: var(--oi-warn-50); color: var(--oi-warn-700); border: 1px solid var(--oi-warn-200); }
.oi-pill.is-live { background: var(--oi-ok-50); color: var(--oi-ok-700); border: 1px solid var(--oi-ok-200); }

/* The head wraps its actions onto a second line below ~980px, which is fine; it
   just should not carry a full row gap when it does. */
@media (max-width: 980px) {
  .oi-group-head { gap: var(--oi-s2) var(--oi-s3); padding: var(--oi-s3) var(--oi-s4); }
  .oi-group-acts { margin-left: 0; }
}

@media (max-width: 1180px) {
  .oi-body { grid-template-columns: minmax(0,1fr); }
  .oi-eval { position: static; }
}
@media (max-width: 900px) {
  .oi-side { display: none; }
}
