/*
 * public/m33-static/relay-prompt.css — Relay's ONE prompt and the four-view
 * frame it floats over (lib/views/htmls/relay-prompt.ejs,
 * lib/views/javascripts/shell/relay/relay-prompt.js; ADR 0082 D6, rule 10a):
 * the frame, header, middle band and busy veil every Relay view wears; the
 * bar fixed over the centre panel's floor; its close, note and tools; the
 * Ask Relay button; standing down under a modal; and the bottom padding a
 * scrolling band keeps clear of the bar.
 *
 * Served from /m33/ and linked right after the Relay composer chrome's
 * <style>, where lib/relay-surface-prompt.js styleRules() followed it in one
 * block. Generated from that function's source: the rules are its output in
 * order, byte for byte, and its comments are kept as comments.
 */

/* THE FOUR-VIEW FRAME. Header, frame inset, reading width and middle
   band are ONE set of numbers, not four copies — four views that must
   measure the same are otherwise four chances to drift (rule 11). A
   view wears .m33-relay-frame / -top / -main and adds only what is
   its own; it never restates these values. */
.m33-relay-frame { display:flex; flex-direction:column; height:100%; box-sizing:border-box; padding:18px 22px; max-width:1100px; margin:0 auto; }
.m33-relay-top { flex:none; display:flex; align-items:center; gap:6px; margin:0 0 10px; padding:0 0 8px; border-bottom:1px solid var(--m33-border,#2a2d3a); }
.m33-relay-top h2 { font-size:11px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; margin:0 6px 0 0; color:var(--m33-text-muted,#8b8fa3); }
.m33-relay-top .m33-subtoggle { margin:0; }
.m33-relay-main { position:relative; flex:1; min-height:0; display:flex; flex-direction:column; }
/* The busy veil covers the MIDDLE BAND only: a switch must never blink
   the header or the prompt, or the two fixed things in the frame stop
   reading as fixed. */
.m33-relay-busy { position:absolute; inset:0; z-index:20; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px; background:rgba(15,17,23,0.72); backdrop-filter:blur(2px); }
/* AN AUTHOR `display` DEFEATS THE `hidden` ATTRIBUTE. The veil is written
   as <div class="m33-relay-busy" hidden> and taken down by setting
   .hidden — but `[hidden]{display:none}` lives in the UA stylesheet, and
   ANY author rule that sets display outranks it. Without this reset the
   veil paints from first render and no amount of busy.hidden = true takes
   it off: Contacts showed the shell's switch loader and this one, both
   captioned "Loading view…", and the second never left. jsdom probes
   cannot see it — they read the .hidden property, which was always right. */
.m33-relay-busy[hidden] { display:none; }
/* The bar is opaque at its own floor and fades to nothing at its top,
   with a blur behind it: three of the four views scroll (Chat, Mail,
   Contacts), and their rows must pass UNDER the bar and dissolve there
   rather than stopping short of it. The trunk's original chat composer
   established that look; this is the same instrument, so it keeps it. */
.m33-rprompt { position:fixed; z-index:12000; box-sizing:border-box; left:var(--m33-rprompt-left,0px); width:var(--m33-rprompt-width,100%); bottom:var(--m33-rprompt-bottom,0px); padding:14px 22px 14px; background:linear-gradient(to top,var(--m33-bg,#0f1117) 0%,var(--m33-bg,#0f1117) 58%,rgba(15,17,23,0.72) 82%,rgba(15,17,23,0) 100%); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); }
/* A MODAL IS MODAL, AND THE BAR IS NOT ABOVE IT. The bar is fixed at
   z-index 12000 so it floats over the panel it hovers; the shell's modal
   backdrop sits at 300, so the bar painted straight through the dimmed
   sheet and cut the bottom off every dialog opened from a Relay view —
   first reported against Profile → Agency Settings, whose save row lives
   there. (The thread-reply panel once stood the bar down too; it now
   sits ABOVE the bar's floor instead, so the channel box stays usable
   while a thread is open — see trunk.js "One prompt, not two".)
   Raising each overlay's z-index instead would mean picking a number out
   of an application-wide scale that already runs past 2^31, and losing
   again the next time something floats higher; standing the bar DOWN is
   the claim that is actually true, and it is the same move the trunk
   makes when this bar takes over its box (one instrument at a time).
   
   DATA-M33-PROMPT-STAND-DOWN is the open contract, not a growing list of
   selectors: the shell modal is the one caller this file cannot avoid
   knowing about, but every OTHER same-page overlay that can end up under
   this bar — a side panel, a future picker, anything appended over the
   view while the bar stays mounted — declares itself by carrying this
   attribute on its own outermost element for as long as it is open. This
   file never learns a new overlay's name; the overlay author adds one
   attribute and the bar already knows to stand down for it. Grep
   `STAND_DOWN_ATTR` (exported below) for every current holder.
   
   VISIBILITY, NOT DISPLAY, for two reasons: .m33-rprompt also wears
   .m33-tc-composer (display:flex !important), and place() publishes the
   scrollers' floor from this element's OWN measured height — a display:none
   bar measures zero and would drop the page behind the overlay to the 96px
   fallback, so the view jumps as it closes. */
body:has(#m33-modal-backdrop.m33-open, [data-m33-prompt-stand-down]) .m33-rprompt { visibility:hidden; pointer-events:none; }
/* The button is the bar's other posture, so it obeys the same contract.
   Its own rule rather than a second selector in the one above: that rule
   is asserted as an exact string, and a clause added to it is the drift
   the assertion exists to catch. */
body:has(#m33-modal-backdrop.m33-open, [data-m33-prompt-stand-down]) .m33-rprompt-fab { visibility:hidden; pointer-events:none; }
/* THE SUMMONED POSTURE. The button sits in the host panel's bottom-right
   corner, inset by FAB.gap; place() measures the panel and writes the
   offsets, so it follows a rail collapse exactly as the bar does. Same
   z-index as the bar: above the view, below every modal (mail's own sit
   at 13700), which is what keeps it off the New message sheet. */
.m33-rprompt-fab { position:fixed; z-index:12000; box-sizing:border-box; right:var(--m33-rprompt-fab-right,20px); bottom:var(--m33-rprompt-fab-bottom,20px); width:48px; height:48px; padding:0; border:0; border-radius:50%; display:flex; align-items:center; justify-content:center; cursor:pointer; background:var(--m33-agent-accent,var(--m33-accent,#6366f1)); color:#fff; box-shadow:0 8px 24px rgba(0,0,0,0.45); transition:transform 0.12s ease, filter 0.12s ease; }
.m33-rprompt-fab:hover { filter:brightness(1.12); transform:translateY(-1px); }
.m33-rprompt-fab:focus-visible { outline:2px solid var(--m33-text,#e1e4ed); outline-offset:3px; }
/* An author display outranks [hidden] (see .m33-relay-busy above). */
.m33-rprompt-fab[hidden] { display:none; }
/* The close row is the writing column's width, so the ✕ lands over the
   box's right edge on any panel width instead of in the panel corner. */
.m33-rprompt-head { display:flex; justify-content:flex-end; width:100%; max-width:var(--m33-read-col,760px); margin:0 auto; }
.m33-rprompt-head[hidden] { display:none; }
.m33-rprompt-close { display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px; padding:0; border:1px solid var(--m33-border,#2a2d3a); border-radius:50%; background:var(--m33-card,#14161f); color:var(--m33-text-muted,#8b8fa3); cursor:pointer; }
.m33-rprompt-close:hover { color:var(--m33-text,#e1e4ed); background:rgba(255,255,255,0.08); }
.m33-rprompt-close:focus-visible { outline:2px solid var(--m33-agent-accent,var(--m33-accent,#6366f1)); outline-offset:2px; }
/* THE COMPOSER IS AS WIDE AS VEGA'S, not as wide as the page. The bar
   spans its panel (it is a blurred floor rows dissolve under), but the
   writing box inside it is the SHARED reading column — the same
   --m33-read-col the Vega chat composer and stream use. It said 1100
   here, which is the page frame's width, so one prompt was two
   different widths depending on which door you came through.
   `width:100%` IS LOAD-BEARING, and its absence is why this bar was 330px
   wide for months while its rule claimed 1100. `.m33-rprompt` also wears
   .m33-tc-composer, which is `display:flex !important` — so the form is a
   FLEX ITEM, and a cross-axis `margin:auto` overrides `align-items:stretch`
   per spec. The item therefore fell back to shrink-to-fit, sized to its own
   content, and a max-width is only a ceiling: a box that never reaches it
   renders the same whatever the number says. Both properties are needed —
   width to fill, max-width to stop at the reading column, auto margins to
   centre what is left. */
.m33-rprompt > form { width:100%; max-width:var(--m33-read-col,760px); margin:0 auto; position:relative; }
/* The chip strip is a row of the form above the box; the chips' own look
   is the trunk's (.m33-tc-staged*, rule 11) and only the seat is here. */
.m33-rprompt [data-relay-prompt-staged] { margin:0 0 6px; }
/* Reserves its own height whether or not anyone is typing, so the box
   does not hop up and down as names arrive and expire — visibility, not
   display, for the same reason the bar itself uses it. */
.m33-rprompt [data-relay-prompt-typing] { width:100%; max-width:var(--m33-read-col,760px); margin:0 auto 4px; min-height:15px; line-height:15px; font-size:11px; color:#8a8fa3; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; visibility:hidden; }
/* THE PLACEHOLDER IS PER-VIEW, BUT THE EDITOR IS NOT REBUILT PER VIEW.
   Tiptap's Placeholder extension is configured once at create() and
   re-asserts its own data-placeholder on every update, so a view switch
   cannot change it by touching the DOM — and tearing the editor down four
   times a session would throw away the draft this bar exists to keep.
   The text therefore arrives as a custom property the script sets, and
   this rule (more specific than the editor's own) reads it. */
.m33-rprompt .m33-rte-surface .ProseMirror p.is-editor-empty:first-child::before { content:var(--m33-rprompt-ph,attr(data-placeholder)); }
/* Same flex-item trap as the form above: without a width it hugs its own
   text and sits narrower than the box it captions. */
.m33-rprompt-note { width:100%; max-width:var(--m33-read-col,760px); margin:0 auto 6px; padding:7px 10px; border-radius:7px; background:var(--m33-card,#14161f); border:1px solid var(--m33-border,#2a2d3a); color:var(--m33-text-muted,#8b8fa3); font-size:11px; }
.m33-rprompt-tools { position:absolute; left:0; bottom:calc(100% + 6px); z-index:5; min-width:280px; max-width:420px; max-height:min(480px,50vh); overflow-y:auto; padding:4px; border:1px solid rgba(255,255,255,0.1); border-radius:8px; background:var(--m33-card,#141a28); box-shadow:0 8px 32px rgba(0,0,0,0.5); font:400 13px/1.3 system-ui,sans-serif; }
.m33-rprompt-tools [data-relay-prompt-row] { display:flex; align-items:center; gap:10px; padding:7px 10px; border-radius:6px; cursor:pointer; border:0; width:100%; background:transparent; color:inherit; text-align:left; font:inherit; }
.m33-rprompt-tools [data-relay-prompt-row]:hover,
.m33-rprompt-tools [data-relay-prompt-row][data-active="true"] { background:rgba(74,134,255,0.18); }
.m33-rprompt-tools [data-relay-prompt-row-icon] { flex:none; color:#8a93a6; display:inline-flex; align-items:center; }
.m33-rprompt-tools [data-relay-prompt-row-name] { flex:none; font-weight:600; }
.m33-rprompt-tools [data-relay-prompt-row-desc] { flex:1; color:#8a93a6; font-size:11px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.m33-rprompt-tools [data-relay-prompt-row-kind] { flex:none; font-size:11px; color:#8a93a6; }
.m33-rprompt-tools-empty { padding:8px 12px; color:#8a93a6; font-size:12px; }
/* WHERE THE FLOOR GOES, and why it is not each view's business.
   A view that pads its own BAND short stops its content above the bar,
   which is the opposite of scrolling under it. The reservation belongs
   INSIDE the scroller instead: the scroller runs to the panel floor so
   rows travel under the bar, and its bottom padding lets the last row
   clear it. A view marks its scroller once and this rule does the rest,
   so the measurement lives in one place (rule 11). The fallback value
   only covers the frame before the script measures the real height. */
body[data-relay-prompt="on"] { --m33-relay-prompt-h:96px; }
body[data-relay-prompt="on"] [data-relay-scroll] { padding-bottom:var(--m33-relay-prompt-h,96px) !important; scroll-padding-bottom:var(--m33-relay-prompt-h,96px); }
/* A band that declared a floor of its own would shorten the column and
   reintroduce the gap this rule exists to close. */
body[data-relay-prompt="on"] [data-relay-band][data-relay-scroll] { padding-bottom:var(--m33-relay-prompt-h,96px) !important; }
