/* =============================================================================
   ics-messager — the paint layer of the notification surfaces: the message /
   confirm / prompt box, the framed child-page dialog, and the toast stack. The
   behaviour lives in js/components/ics-messager.js.
   PUBLIC classes: .messager-body (page stylesheets override its padding, so the
   name is part of the contract) and .messager-icon +
   .messager-{warning|error|info|question}.
   OWN classes: .ics-messager .ics-messager__msg .ics-messager__btn (+ --yes /
   --no) .ics-messager__input .messager-button .ics-modal-dialog
   .ics-modal-dialog__frame .ics-toast-host .ics-toast (+ --success / --error /
   --warning / --info / --pre / --out / --clickable) .ics-toast__icon
   .ics-toast__body .ics-toast__title .ics-toast__msg .ics-toast__close.
   CUSTOM PROPERTIES published on the toast card: --ics-toast-sev ·
   --ics-toast-sev-bg (the severity slots the four modifiers re-point) ·
   --ics-toast-ink (the ONE ink variable the title and the × read).
   Severity glyphs of the BOX are CSS-DRAWN, no sprite and no emoji: the SHAPES
   stay distinguishable at 32px with colour removed - warning = triangle + !,
   error = circle + X, info = circle + i, question = circle + ?. Their fills
   ride the semantic tokens, so the tokens own the colour.
   DEPENDENCIES. The box is an ics window (ics-window.css must precede this sheet);
   its buttons are ics buttons (ics-button.css paints face, height and glyph); the
   toast glyph is an ics-icons element. Link after tokens.css, ics-window.css and
   ics-button.css. Linked by _Meta, _MobileLayout, _AuthMeta and the two GUProduction
   device heads.
   ============================================================================= */

/* ---- THE MESSAGE / CONFIRM / PROMPT BOX -------------------------------------
   An ics window frame (flat brand-gold title bar with no corner chip - the box
   opens closable:false, so it is answered rather than dismissed), the message on
   the surface, and a footer BAND: soft surface-alt fill under a rule, buttons
   right-aligned. The box source div IS the window body, so its frame inset is
   cancelled here and the band runs edge to edge.
   Width comes from the window (380 message / 400 confirm+prompt); height follows
   the content. */
.ics-messager > .ics-window__bodysrc { margin: 0; }

/* content element - .messager-body is public, so page-level overrides land */
.messager-body {
  padding: var(--space-6) var(--space-5) var(--space-6) var(--space-5);
  overflow: auto;
  color: var(--ics-text);
  font-family: var(--ics-font);
  font-size: var(--ics-font-size);
  line-height: var(--lh-base);
  white-space: pre-line;                         /* server messages carry line breaks */
}
.ics-messager__msg { overflow-wrap: break-word; }

/* 32x32 icon floated left, 10px gap. A box called without a severity renders NO
   icon element at all, so there is no empty gutter to reserve here */
.messager-icon {
  float: left;
  width: 32px;
  height: 32px;
  margin: 0 10px 10px 0;
  position: relative;
  border-radius: 50%;
  color: #fff;
}
.messager-icon::after {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font: 700 20px/1 system-ui, sans-serif;
}
.messager-warning {
  border-radius: 0;
  background: var(--ics-warning);
  clip-path: polygon(50% 4%, 98% 96%, 2% 96%);
}
.messager-warning::after { content: '!'; padding-top: 8px; }
.messager-error   { background: var(--ics-danger); }
.messager-error::after   { content: '\00d7'; }              /* multiplication x */
.messager-info    { background: var(--ics-info); }
.messager-info::after    { content: 'i'; font-style: italic; }
.messager-question { background: var(--ics-info); }
.messager-question::after { content: '?'; }

/* footer band: buttons right-aligned, own ics-buttons (face, height and glyph
   come from ics-button.css and the button engine); the first button (Ok/Yes) is
   auto-focused, and that focus must stay VISIBLE.
   ORDER: affirmative FIRST - Ok / Yes on the LEFT, No / Cancel to its right;
   the band itself stays right-aligned. That order is DOM order, set by the
   caller's `buttons` array in ics-messager.js - never re-order it here with
   `order:` or `row-reverse`, or the tab ring and the DOM stop agreeing. */
.messager-button {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-4);
  clear: both;
  padding: var(--space-4) var(--space-5);
  background: var(--ics-surface-alt);
  border-top: var(--border-1) solid var(--ics-border);
}
.ics-messager__btn { min-width: 64px; }          /* short captions (OK / No) still read as buttons */
.ics-messager__btn:focus-visible,
.ics-messager__btn:focus {
  outline: 2px solid var(--ics-focus-ring);
  outline-offset: 1px;
}

/* prompt input - present only on a box that asks for a typed value */
.ics-messager__input {
  width: 100%;
  box-sizing: border-box;
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-4);
  border: var(--border-1) solid var(--ics-border);
  border-radius: var(--radius-1);
  background: var(--ics-surface);
  color: inherit;
  font: inherit;
}
.ics-messager__input:focus {
  outline: 2px solid var(--ics-focus-ring);
  outline-offset: 1px;
}

/* ---- the two answer buttons -------------------------------------------------
   Yes/OK and No render the ONE bordered button design the .ics-messager__btn
   base already takes from the tokens - there is no emphasised tier here. The
   single exception is DANGER (a destructive Yes), and that is severity, not
   emphasis: do not reintroduce a face for the affirmative answer. */
.ics-messager__btn--yes,
.ics-messager__btn--no { font-weight: var(--fw-semibold); }
/* the one red face: a destructive Yes (severity at the point of no return - the
   exception the button face contract in ics-button.css itself names).
   SPECIFICITY CONTRACT: that face contract paints every .ics-btn at 2-1-0 with
   !important, so this rule repeats the same :is(#\9, …) form and adds the two box
   classes (2-3-0 !important) in order to be the rule that wins. Weaken either side
   of that pair and the destructive answer silently repaints as a normal button. */
.ics-btn:is(#\9, .ics-btn):is(#\9, .ics-btn).ics-messager__btn--yes.ics-danger,
.ics-btn:is(#\9, .ics-btn):is(#\9, .ics-btn).ics-messager__btn--yes.ics-danger:hover {
  background: var(--ics-danger) !important;
  color: #fff !important;
  border-color: var(--danger-500) !important;
}
.ics-btn.ics-messager__btn--yes.ics-danger .ics-btn__icon { filter: brightness(0) invert(1); }   /* white glyph on the red face */

/* the framed child-page dialog: another page running inside a modal window.
   The source div is the window body (flex child and scroll owner); it carries NO
   padding so the frame fills the body edge to edge, and the frame itself has no
   border. The window is resizable and the frame follows, because both are 100%. */
.ics-modal-dialog {
  min-height: 0;
  padding: 0;
  overflow: hidden;
  display: flex;                                     /* the frame is the one flex child: it takes ALL the body height */
  flex-direction: column;
}
.ics-modal-dialog__frame {
  display: block;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  border: 0;
  background: var(--ics-surface, #fff);
}

/* ---- THE TOAST ---------------------------------------------------------------------
   The product's one passive-notice card: a WHITE surface card inside the brand's gold-500
   hairline frame - the same frame every panel and window wears - with the severity carried
   by a 4px accent stripe on the LEFT edge, by the glyph badge's tint, and by the bold title
   word; never by a solid coloured face. The glyph is the own ics-icons set (success =
   ok-check, error = back-undo, warning = notify, info = info) on a badge tinted with the
   severity's -100 token and ringed with its -500. Ink is the body ink on every face, so the
   card reads like the message box and the panel headers around it instead of a foreign
   accent block, and AA holds (see the ink block). Cards stack in a fixed column at the
   viewport's BOTTOM-RIGHT corner - the newest nearest the corner, older ones above it.
   Geometry is fixed here: 300px wide, content-high. The × shows on hover; the card fades
   and slides in and out (200 ms, none under reduced motion). */
.ics-toast-host {
  position: fixed;
  right: 12px;
  bottom: 12px;
  z-index: var(--ics-z-toast, 7000);
  display: flex;
  flex-direction: column;                        /* newest appended = nearest the corner */
  align-items: flex-end;
  gap: 6px;
  width: 300px;
  max-width: calc(100vw - 24px);
  pointer-events: none;                          /* the gaps never block the page */
}
.ics-toast {
  pointer-events: auto;
  position: relative;
  box-sizing: border-box;
  width: 300px;
  max-width: 100%;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 28px 10px 12px;                  /* right room for the × */
  border-radius: var(--radius-2);
  box-shadow: var(--shadow-md);
  /* the product's card: white surface, gold-500 hairline (the brand's standard line), and
     the severity on the LEFT EDGE only - a 4px stripe reading the severity token.
     --ics-toast-sev / --ics-toast-sev-bg are the card's two severity slots; the four
     modifier classes below re-point them and nothing else. */
  --ics-toast-sev:    var(--ics-info);
  --ics-toast-sev-bg: var(--ics-info-bg);
  --ics-toast-ink:    var(--ics-text);
  background: var(--ics-surface);
  border: var(--border-1) solid var(--ics-border);
  border-left: 4px solid var(--ics-toast-sev);
  color: var(--ics-toast-ink);
  font-family: var(--ics-font);
  font-size: var(--ics-font-size);
  line-height: var(--lh-base);
  opacity: 1;                                    /* full contrast at rest: the fade lives in --pre/--out */
  transition: opacity .2s ease, transform .2s ease, box-shadow .15s ease;
}
.ics-toast:hover { box-shadow: var(--shadow-lg); }
.ics-toast--success { --ics-toast-sev: var(--ics-success); --ics-toast-sev-bg: var(--ics-success-bg); }
.ics-toast--error   { --ics-toast-sev: var(--ics-danger);  --ics-toast-sev-bg: var(--ics-danger-bg); }
.ics-toast--warning { --ics-toast-sev: var(--ics-warning); --ics-toast-sev-bg: var(--ics-warning-bg); }
.ics-toast--info    { --ics-toast-sev: var(--ics-info);    --ics-toast-sev-bg: var(--ics-info-bg); }

/* ---- THE INK IS TOAST-SCOPED -------------------------------------------------------
   WCAG AA wants 4.5:1 for this text size. The face is the SURFACE token (white) on every
   severity, so the ink is the body ink: title = --ics-text (#2F2B26, 12.6:1), message =
   --ics-text-soft (#57514A, 7.4:1). The severity lives on the stripe, the badge and the
   title word, none of which carry text, so no per-face ink override exists or is needed.
   `--ics-toast-ink` is the ONE ink variable the × chip and the title read, so a re-skin
   of the surface changes it here and nowhere else. The contrast gate MEASURES all four
   ratios against the resolved surface token: a surface re-pointed to a dark value is the
   one thing that could break this. Never hardcode a colour on this card. */
.ics-toast--pre,
.ics-toast--out     { opacity: 0; transform: translateX(24px); }
.ics-toast--clickable { cursor: pointer; }

/* the glyph: an ics-icons element (.ics-icon-<name> paints the SVG background) in its OWN
   colours, on a 26px badge tinted with the severity's -100 token and ringed with its -500 -
   the same glyph the recall list shows, so the two read as one. The tint is the card's
   second severity cue (the stripe is the first); it stays pale so the multi-tone glyph keeps
   its own colours (the info disc keeps its counter). background-origin keeps the SVG inside
   the badge's padding. */
.ics-toast__icon,
.ics-toast .ics-toast__icon[class*="ics-icon-"] {
  flex: 0 0 26px;
  width: 26px;
  height: 26px;
  margin-top: 0;
  padding: 4px;
  box-sizing: border-box;
  vertical-align: top;
  border-radius: 50%;
  background-color: var(--ics-toast-sev-bg);
  background-origin: content-box;
  background-clip: border-box;
  box-shadow: 0 0 0 1px var(--ics-toast-sev);
}

.ics-toast__body  { flex: 1 1 auto; min-width: 0; }
.ics-toast__title { font-weight: var(--fw-bold); margin-bottom: 2px; overflow-wrap: break-word; color: var(--ics-toast-ink); }
.ics-toast__msg   { white-space: pre-line; overflow-wrap: break-word; color: var(--ics-text-soft); }
.ics-toast__close {
  position: absolute;
  top: 3px;
  right: 6px;
  padding: 0 4px;
  border: 0;
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--ics-toast-ink);       /* follows the card's ink, never a fixed white */
  opacity: 0;
  cursor: pointer;
  font: 700 18px/1 system-ui, sans-serif;
  transition: opacity .15s;
}
.ics-toast:hover .ics-toast__close,
.ics-toast__close:focus-visible { opacity: .9; }
.ics-toast__close:hover { background: var(--ics-btn-face-hover); }   /* the window close chip's gold-tint hover cue */
.ics-toast__close:focus-visible { outline: 2px solid var(--ics-focus-ring); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) {
  .ics-toast, .ics-toast__close { transition: none; }
}
