/*
 * castle-modal.css — A53 shared modal shell (single source of truth for the castle-modal-* classes).
 *
 * Loaded via <link> LAST in <head> on every page that uses window.castleModal, so it wins the cascade
 * over the legacy vNNN-layout-repair.css files on equal specificity (they target .castle-modal-overlay
 * without !important on position for the NEW component's pages). No !important here — if a page ever
 * needs it to beat an !important legacy rule, the correct fix is to remove that legacy rule, not to
 * escalate here (see the sequenced brief §1.7 and the M15 computed-value test).
 *
 * castle-modal.js injects an identical <style> ONLY as a fallback when this link is absent, so a page
 * that includes the JS but forgot the link still renders — but this file is the source of truth.
 */
/* §3.1: the leading `html body > .castle-modal-overlay` (specificity 0,1,3) self-defends against a
   blanket `html.castle-v219-ui body > *` (0,1,2) that sets position:relative/z-index:1 on every
   body-level element — the actual A53 cascade blocker. No !important; the bare selector is kept so
   the shell still works if ever mounted somewhere other than a direct child of <body>. box-sizing is
   set explicitly here (§3.3) since it was removed from the castle-v234 group. */
html body > .castle-modal-overlay,
.castle-modal-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:1000;background:rgba(0,0,0,.5);padding:20px;box-sizing:border-box;}
/* 3.1c — a caller may widen its card. The tie modal shows the SAME four options the results screen
   behind it shows at the content width, and 520px reformats two- and three-line descriptions into 44%
   of the space the facilitator just read them in. Opt-in, so every other modal keeps 520px. */
.castle-modal-card.castle-modal-card-content-width{max-width:var(--castle-content-max,1180px);}
.castle-modal-card{position:relative;max-width:520px;width:100%;max-height:90vh;overflow-y:auto;background:#fff;border-radius:14px;box-shadow:0 24px 60px rgba(0,0,0,.4);padding:24px 26px;font-family:inherit;box-sizing:border-box;}
.castle-modal-eyebrow{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:#0b6bcb;}
.castle-modal-title{font-size:20px;font-weight:800;margin:6px 0 4px;color:#1a1a18;}
.castle-modal-title.destructive{color:#c02b2b;}
.castle-modal-context{font-size:13px;color:#6b6b66;margin:8px 0;}
.castle-modal-copy{font-size:14px;line-height:1.55;color:#2b2f36;margin:8px 0;}
.castle-modal-field{margin-top:14px;}
/* DIRECT CHILD ONLY. This was `.castle-modal-field label`, and the choice field renders its rows as
   <label> elements nested inside the field — so every row inherited 9px uppercase monospace, and
   letter-spacing:.12em computed against 9px (1.08px) cascaded into children that had set their own
   font-size but not their own spacing. The tie modal shouted every option in mono caps as a result.
   Scoping to the direct child fixes it where it happens; every other caller's label IS a direct
   child, so nothing else changes. */
.castle-modal-field > label{display:block;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:#0b6bcb;margin-bottom:6px;}
.castle-modal-field input,.castle-modal-field textarea{width:100%;border:1px solid #c4c8ce;border-radius:9px;padding:10px 12px;font:inherit;box-sizing:border-box;}
.castle-modal-field .castle-modal-help{font-size:11px;color:#8a8f98;margin-top:4px;}
.castle-modal-confirm-row{font-size:14px;line-height:1.9;margin-top:6px;}
.castle-modal-confirm-row span{display:inline-block;width:150px;color:#6b6b66;}
.castle-modal-error{display:none;margin-top:12px;padding:10px 12px;border-radius:8px;background:rgba(192,43,43,.08);border:1px solid rgba(192,43,43,.3);color:#8a2a2a;font-size:13px;line-height:1.5;}
.castle-modal-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:20px;}
.castle-modal-btn{min-width:130px;padding:11px 18px;border-radius:9px;font-weight:700;font-size:14px;cursor:pointer;border:1px solid #c4c8ce;background:#fff;color:#2b2f36;}
.castle-modal-btn.primary{border:none;background:#0b6bcb;color:#fff;}
.castle-modal-btn.destructive{border:none;background:#c02b2b;color:#fff;}
.castle-modal-btn[disabled]{opacity:.55;cursor:not-allowed;}

/* Tie-break choice list. 22-09: CARD ROWS, styled by the results screen's own rules.
 *
 * The rows emit .result-row / .rr-top / .rr-badge / .rr-info / .rr-title / .rr-desc / .rr-pct, and the
 * list emits .result-list.result-stack-v145 — the container the grid in castle-v145-facilitator-polish
 * is scoped to. Everything the card looks like therefore comes from ONE set of rules, shared with the
 * screen behind the modal. That is the point: two stylesheets describing the same card is how the two
 * screens drifted in the first place.
 *
 * What is left here is only what the MODAL adds to that card: a clipped radio, a tied pill, and a list
 * that scrolls inside the dialog. The compact .cmc-main / .cmc-desc / .cmc-meta row is gone, and its
 * rules went with it rather than being left orphaned.
 */
/* THE LIST SCROLLS, THE CARD DOES NOT — and the cap is the space the card actually has, never a
   number. This was `max-height:min(52vh,460px)`, tuned against the OLD compact rows: at card size a
   row is 119px, four of them want 519px, and the list clipped 59px short while the card sat 437px
   below its own 90vh limit. A fixed pixel cap cannot know what a row costs, and nothing revisited it
   when the rows tripled in height — so it is replaced rather than re-tuned.
   The card becomes a flex column and the list takes what is left after the header and the actions.
   min-height:0 at every step is what makes that real: a flex item's default min-height is auto, which
   refuses to shrink below its content, and the chain silently reverts to overflowing without it.
   overflow-y:auto stays as the small-viewport fallback — at 768px the list scrolls inside the card,
   which is the point: the actions row is pinned and reachable at every height, rather than being
   somewhere below a scroll. Scoped to the content-width card, so no other modal's layout changes. */
.castle-modal-card.castle-modal-card-content-width{display:flex;flex-direction:column;overflow:hidden;}
.castle-modal-card-content-width .castle-modal-step-form{display:flex;flex-direction:column;min-height:0;flex:1 1 auto;}
.castle-modal-card-content-width .castle-modal-field{display:flex;flex-direction:column;min-height:0;flex:1 1 auto;}
.castle-modal-choice{display:flex;flex-direction:column;gap:10px;min-height:0;flex:1 1 auto;overflow-y:auto;}
/* NO TWO-COLUMN LAYOUT HERE, AND THIS NOTE IS WHY THE NEXT READER SHOULD NOT ADD ONE.
   A two-column grid was added on 22-09 to solve the height problem and then removed, and it is worth
   recording that it never took effect for a single second. This list carries `result-stack-v145`, and
   castle-v145-facilitator-polish.css:17 says
       .option-stack-v145,.result-stack-v145{display:grid!important;grid-template-columns:1fr!important;gap:14px!important}
   Specificity does not beat !important, so the rule here was inert from the moment it was written —
   and the test asserting it passed anyway, because the rule EXISTED in the file. That is the vacuity
   this repo keeps catching: a green assertion about a declaration that never reached a pixel.
   The height problem was solved properly instead, by collapsing the list to the tied options. That rule
   in castle-v145 is left exactly as it is; this file simply stops arguing with it. */
/* A STRAY "}" SAT HERE from 22-09 to 25-09, left when the two-column rule above was removed. A closing brace with no
   rule open makes the parser drop the NEXT rule — which was the collapse below, so every tie modal opened with all
   its options (CTC-27429 inject 2, on prod). scripts/css-balance.test.js now fails any stylesheet whose braces do
   not balance, and scripts/tie-modal-browser.test.js counts the rows a facilitator actually sees. */
/* COLLAPSED — the tied options only. The rest stay in the DOM so the radiogroup is never rebuilt and
   no selection can be lost on reveal; display:none is what removes them, which also takes them out of
   the tab order. A row a facilitator cannot see must not be reachable by keyboard either. */
.castle-modal-choice.is-collapsed .castle-modal-choice-row.is-hidden{display:none;}
/* THE PILL SHOWS WHEN THE LIST HAS OTHERS (James, 25 Sep, hotfix item 1: "show only the tied options, visibly
   marked as tied"). This replaces the 22-09 rule, which also hid it while collapsed: the tied rows are marked on
   open and stay marked when Other options reveals the rest. On a FOUR-WAY tie there are no others, and every row
   wearing a badge that repeats the heading distinguishes nothing, so it still never appears there.
   Hidden by rule rather than by re-rendering — revealing is a class change, not a rebuild. */
.castle-modal-choice .cmc-mark{display:none;}
.castle-modal-choice.has-others .cmc-mark{display:inline-block;}

/* WHAT IS NOT DECLARED HERE IS DELIBERATE. castle-v145 gives .result-row its card (padding:0, with the
   padding on .rr-top) and castle-v223 sets its border, background and shadow with !important. So the
   modal declares NEITHER — it takes the same card the results screen has, which is the point, and this
   file's standing rule is that it does not escalate to !important to beat a legacy rule.
   One casualty, recorded: the .is-marked row TINT cannot win against v223's !important background, so
   the tied rows are identified by the pill below rather than by a wash. The pill is the marker the
   spec asked to keep; the tint was never the thing being read. */
/* position:relative is what the clipped radio is positioned against — the row, not the card. */
.castle-modal-choice-row{position:relative;display:block;}
/* The radio is CLIPPED, never display:none or visibility:hidden: it has to stay focusable and stay a
   real radio for a screen reader. The visible state is the row's .selected card, and the focus ring is
   drawn on the row via :focus-within — otherwise keyboard focus would be invisible. */
.castle-modal-choice-row > input[type=radio]{position:absolute;width:1px;height:1px;margin:0;padding:0;
  opacity:0;pointer-events:none;}
.castle-modal-choice-row:focus-within{outline:2px solid #0b6bcb;outline-offset:2px;}
/* Every property the row needs is DECLARED, not inherited — the shell's field-label rule is scoped to
   a direct child, but declaring these means the next rule added to the shell cannot reintroduce the
   leak silently. */
.castle-modal-choice-row,.castle-modal-choice-row *{text-transform:none;letter-spacing:normal;}
/* The tied pill, re-homed into the title line: the card has no spare column, and this is the only
   thing identifying which rows the choice is actually between when the list is in option order.
   FILLED, NOT OUTLINED (22-09, James). It was a 10px/400 hairline — a 0.67px computed border in a
   colour on white — which is to say it was drawn as a whisper and had to read from the back of a
   room. The treatment is inverted rather than recoloured: same hue, fill and text swapped.
   THE HUE IS NOT A FREE CHOICE. Green, amber and red on an option row are how this platform signals
   rating-great through rating-weak, and a room that has seen the rating key reads a coloured row as a
   graded one — the §8 confusion arriving by the back door. #0b6bcb is the informational blue and sits
   outside that palette, and filled blue stays distinct from the teal selection accent, so "these two
   are level" and "I have picked this one" remain separate channels when they stack on one row.
   font-weight is DECLARED: the pill computed 400 inside a 700 title, so it cannot be left to inherit.
   White on #0b6bcb is ~5.2:1, above AA at 12px/700. */
/* No `display` here on purpose: this rule is the pill's LOOK and it sits below the two rules that
   decide whether it is shown at all. Both are single-class specificity, so declaring display here
   would win on document order and switch the pill back on in every state, including the four-way tie
   this was just fixed for. Look and visibility are kept in separate rules so neither can quietly
   overrule the other. */
.castle-modal-choice-row .cmc-mark{margin-left:8px;vertical-align:middle;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:#fff;background:#0b6bcb;border:0;border-radius:999px;
  padding:3px 9px;}

/* PR #16 (29 Sep), finding 3: the facilitator's "View inject narrative" panel drawn as the participant sees the inject
   (vote.html's .phone-card: phase label, title, time pill, narrative card, question), read-only. The values are the
   participant screen's own computed styles, measured on vote.html; scripts/narrative-display-browser.test.js holds the
   two to the same computed values, so a change to one without the other fails. Scoped under the panel, and !important
   where the facilitator page's own cascade styles h2 and p. */
.castle-modal-panel.castle-pcard-panel{background:rgb(245,244,240)!important;}
.castle-pcard-panel .castle-pcard{font-family:"Frutiger LT Pro","Helvetica Neue",Arial,sans-serif!important;color:rgb(17,17,16);
  background:rgba(255,255,255,.88);border:1px solid rgba(17,17,16,.086);border-radius:16px;padding:18px;margin:0 0 4px;}
.castle-pcard-panel .castle-pcard-kicker{font-family:inherit!important;font-size:11px!important;font-weight:900!important;line-height:16.5px!important;
  color:rgb(155,163,152)!important;text-transform:uppercase!important;letter-spacing:.07em!important;margin:0 0 6px!important;}
.castle-pcard-panel .castle-pcard-title{font-family:inherit!important;font-size:22px!important;font-weight:900!important;line-height:1.25!important;
  color:rgb(26,31,23)!important;margin:0 0 6px!important;padding:0 44px 0 0!important;letter-spacing:normal!important;text-transform:none!important;}
.castle-pcard-panel .castle-pcard-time{display:inline-flex;align-items:center;gap:6px;background:rgb(239,239,235);border:1px solid rgba(0,0,0,.08);
  border-radius:999px;padding:6px 12px;font-size:12px;line-height:18px;font-weight:400;color:rgb(107,107,102);margin:4px 0 10px;}
.castle-pcard-panel .castle-pcard-scenario{padding:18px!important;font-size:15px!important;line-height:1.75!important;font-weight:400!important;
  color:rgb(26,31,23)!important;background:rgb(255,255,255)!important;border:1px solid rgb(226,230,222)!important;border-radius:16px!important;
  white-space:pre-wrap!important;margin:0 0 16px!important;}
.castle-pcard-panel .castle-pcard-scenario p{margin:0 0 .85em!important;line-height:1.5!important;font-size:15px!important;color:rgb(26,31,23)!important;}
.castle-pcard-panel .castle-pcard-scenario p:last-child{margin-bottom:0!important;}
.castle-pcard-panel .castle-pcard-question{padding:18px 20px!important;background:rgb(232,247,245)!important;border:1px solid rgba(0,155,170,.28)!important;
  border-radius:16px!important;font-size:16px!important;font-weight:900!important;line-height:1.4!important;color:rgb(26,31,23)!important;margin:0 0 16px!important;}
.castle-pcard-panel .castle-pcard-media-label{font-size:11px;font-weight:900;line-height:16.5px;color:rgb(155,163,152);text-transform:uppercase;
  letter-spacing:.07em;margin:0 0 6px;}
.castle-pcard-panel .castle-pcard-chips{display:flex;flex-wrap:wrap;gap:8px;}
.castle-pcard-panel .castle-pcard-chip{display:inline-flex;align-items:center;gap:6px;background:rgb(239,239,235);border:1px solid rgba(0,0,0,.08);
  border-radius:999px;padding:6px 12px;font-size:12px;line-height:18px;color:rgb(26,31,23);}
