/* Shared asynchronous state. The router renders this before any lazy app
   stylesheet is available, so it belongs to the static feedback layer. */
.loading { display:flex; align-items:center; justify-content:center; gap:var(--sp-3);
  padding:var(--sp-10) var(--sp-4); color:var(--color-text-muted); font-size:var(--text-sm); }

/* Empty and unavailable states are feedback, not utility helpers. */
.empty { text-align:center; color:var(--color-text-muted); padding:var(--sp-12) var(--sp-4); }
.empty__title { margin:0; font-size:var(--fs-lg); color:var(--color-text); }
.empty__hint { margin:var(--sp-2) auto 0; max-width:44ch; font-size:var(--fs-sm); }
.empty__action { margin-top:var(--sp-5); }
.empty--unavailable { display:flex; align-items:center; justify-content:center; gap:var(--sp-2);
  padding:var(--sp-8) var(--sp-4); color:var(--color-error-text); background:var(--color-error-bg);
  border-radius:var(--radius-lg); text-align:left; }
.empty--unavailable .icon { flex:none; }
.empty--unavailable > span { min-width:0; overflow-wrap:anywhere; }

/* Notifications (notification.postcss:5-58) */
.notification { display:flex; position:relative; gap:var(--sp-3); align-items:flex-start; padding:var(--sp-2);
  border:0; border-radius:var(--radius); background:var(--color-gray-50); box-shadow:var(--shadow-lg); }
@media (min-width:480px) { .notification { padding:var(--sp-4); } }
@media (min-width:1024px){ .notification { padding:var(--sp-6); } }
@media (min-width:1544px){ .notification { padding:var(--sp-8); } }
/* `margin-right` is CD's own (`notification.postcss:78-83`: `mr-3 h-10 w-10
   flex-shrink-0 fill-current`) and was the one declaration missing here, so
   every notification in this portal set its icon 12px tighter against the text
   than the design system draws it — and than the tenant portal, which had the
   rule all along. */
.notification__icon { flex:none; margin-right:var(--sp-3); width:var(--sp-10); height:var(--sp-10); }
.notification__content { min-width:0; margin-block:var(--sp-2-5); }
@media (min-width:1280px){ .notification__content { margin-block:var(--sp-2); } }
.notification__content > p { margin:0; overflow-wrap:anywhere; }
/* CD rhythm: 4px below the FIRST child only (`> *:first-child { mb-1 }`,
   notification.postcss:85-87) — the former `p + p` variant spaced every
   pair; tenant-portal parity (2026-08 alignment D31). */
.notification__content > :first-child { margin-bottom:var(--sp-1); }
/* DS notification button spacing (notification.postcss:89-92): below lg the
   button drops under the copy, from lg it moves beside it. Was absent —
   buttons sat flush against the copy at every width. */
.notification .btn { margin-top:var(--sp-4); }
@media (min-width:640px)  { .notification .btn { margin-top:var(--sp-8); } }
@media (min-width:1024px) { .notification .btn { margin-top:0; margin-left:var(--sp-6); } }
.banner-host .notification .btn { margin-top:0; margin-left:0; }   /* (dead __actions selector removed, F-S30) */
/* …but the CD's `lg:ml-6` guarantee returns from lg (notification-banner.
   postcss:24-27): with a long copy line, space-between alone would let the
   text run into the button. 24px — the tenant banner's action offset
   (alignment D42). */
@media (min-width:1024px){ .banner-host .notification .btn { margin-left:var(--sp-6); } }
/* NO .notification__title rule: nothing emits the class, and CD's title anatomy
   is larger (__header + --with-title + __content-offset,
   notification.postcss:98-112). A partial implementation would be a trap; add
   it in full when a titled notification is needed. */
.notification--info    { background:var(--color-info-bg-subtle);    color:var(--color-info-text-subtle); }
.notification--success { background:var(--color-success-bg-subtle); color:var(--color-success-text); }
.notification--warning { background:var(--color-warning-bg-subtle); color:var(--color-warning-text); }
.notification--error   { background:var(--color-error-bg-subtle);   color:var(--color-error-text); }
.notification--hint    { background:var(--color-secondary-50);      color:var(--color-gray-700); }

/* Consent/banner variant follows the base notification in source order, so a
   single BEM class is enough; no doubled-class specificity bump is required. */
/* SHARED DELIBERATE DEVIATION from CD's py-4 sm:py-8 lg:py-10
   (notification-banner.postcss:8): held at 16 → 24 @640. The tenant portal
   documented the reason first — a bar that greets EVERY session of a dense
   application must not take 40px paddings — and both portals now render the
   same compact strip (2026-08 alignment D32). */
.notification-banner { padding:var(--sp-4) 0; font-size:var(--text-sm); box-shadow:none; }
@media (min-width:640px){ .notification-banner { padding:var(--sp-6) 0; } }
/* Full 1px white frame (CD `border border-t border-white`,
   notification-banner.postcss:13-17 — not only the top edge), and BELOW the
   toast layer: a confirmation toast must never hide behind the standing
   disclaimer (tenant-portal parity; 2026-08 alignment D31). */
.notification-banner--fixed { position:fixed; z-index:var(--z-overlay); right:0; bottom:0; left:0; width:100%;
  border:var(--stroke-1) solid var(--color-bg); box-shadow:var(--shadow-2xl); }
/* --alert (danger to life, notification.postcss:29-58) DELIBERATELY has NO
   portal consumer. The variant remains as CD canon because --color-alert-bg
   and the notification() role branch reference it; deleting it would orphan
   that chain (Design Review, C9 decision). */
.notification--alert   { background:var(--color-alert-bg);          color:var(--color-text-negative); }
/* EVERY interactive child of a notification inherits its color (currentColor)
   instead of brand primary: CD notification.postcss:11-21 (text-current, hover
   brightness-50). Covers <a>, button.link AND .btn; the former --alert special
   rule becomes a case of the general rule. Hover pins color again because
   .link:hover (0,2,0) would otherwise restore brand primary. */
.notification a, .notification .link { color:currentColor; text-decoration:underline; text-underline-offset:var(--stroke-2); }
.notification a:hover, .notification a:focus, .notification .link:hover, .notification .link:focus { color:currentColor; filter:brightness(.5); }
.notification .btn { color:currentColor; border-color:currentColor; }
.notification .btn:hover { color:currentColor; border-color:currentColor; filter:brightness(.5); }
/* Close button (CD notification.postcss): 44px hit area around the 2rem icon. */
.notification--dismissible { padding-right:var(--target-min); }
.notification__close { position:absolute; top:0; right:0; display:inline-flex; align-items:center; justify-content:center;
  min-width:var(--target-min); min-height:var(--target-min); padding:var(--sp-1-5); border:0; background:none; color:inherit; cursor:pointer; }
.notification__close .icon { width:var(--sp-8); height:var(--sp-8); }
.notification__close:hover { opacity:.7; }

/* Step indicator (step-indicator.postcss:5-23) */
/* row-gap is smaller than column-gap: at 320/390 the bar wraps, and the tighter
   row gap makes the wrap read as an intentional row. */
.steps { display:flex; gap:var(--sp-4); row-gap:var(--sp-3); list-style:none; margin:0 0 var(--sp-8); flex-wrap:wrap; padding:0; }
.steps li { display:flex; align-items:center; gap:var(--sp-2); font-size:var(--text-sm); color:var(--color-text-muted); }
.steps li[aria-current="step"] { color:var(--color-text); font-weight:var(--fw-bold); }
/* CD scopes every step rule under `.step__indicator`
   (step-indicator.postcss:5-24, StepIndicator.vue:2-9); current markup omits
   this wrapper. Therefore use the UNION of both forms: today's
   `<ol class="steps"><li><span …>` AND CD's wrapper, supplied by Item 3.10.
   Item 7.8 then removes the `.steps > li >` half, CD-verbatim without a broken
   intermediate state. Item 2.3 uses the same union form. */
/* Contrast (Item 2.3): the CD template itself is not AA-conformant here
   (step-indicator.postcss:6-24 uses gray-400). This is a deliberate deviation
   under BehiG/P028, but stays within CD's token vocabulary. Measured ratios:
     old  #9ca3af on white and white on #9ca3af  = 2.54:1  (target 4.5:1)
     old  white on --color-success #10b981       = 2.54:1  (target 3:1)
     new  --color-text-600 on white              = 7.56:1
     new  border --color-secondary-400           = 5.65:1 red / 4.58:1 intranet
     new  white on --color-primary-600           = 5.01:1 red / 5.17:1 intranet
     new  white on --color-success-text #065f46  = 7.68:1
   Current now uses primary-600 like .pipeline__step--active: ONE you-are-here
   color in the product. Previously the current step was weaker than completed
   steps. The primary-100 ring conveys state in addition to color (WCAG 1.4.1). */
/* Only CD's wrapper form remains (Item 7.8 fulfilled): stepIndicator() has
   rendered the .step__indicator wrapper since Item 3.10, so the
   `.steps > li >` halves were redundant. */
.step__indicator .step__indicator-step { display:inline-flex; align-items:center; justify-content:center;
  width:36px; height:36px; flex:none; border-radius:var(--radius-full);
  background:transparent; color:var(--color-text-600); border:var(--stroke-2) solid var(--color-secondary-400);
  font-size:var(--text-sm); font-weight:var(--fw-regular); }
.step__indicator .step__indicator-step--active { background:var(--color-primary-600); color:var(--color-text-negative); border:0;
  box-shadow:var(--state-ring-primary-soft); }
.step__indicator .step__indicator-step--confirmed { background:var(--color-success-text); color:var(--color-text-negative); border:0; }

/* Status pipeline / timeline (portal extension — no CD counterpart) */
.timeline { list-style:none; border-left:var(--stroke-2) solid var(--color-border); margin-left:var(--sp-2); }
.timeline li { position:relative; padding:0 0 var(--sp-4) var(--sp-5); }
.timeline li::before { content:""; position:absolute; left:calc(-1 * var(--sp-2)); top:var(--sp-1); width:var(--sp-3); height:var(--sp-3);
  border-radius:var(--radius-full); background:var(--color-gray-400); border:var(--stroke-2) solid var(--color-bg); }
.timeline li.done::before { background:var(--color-success-text); }
.timeline li.current::before { background:var(--color-gray-400); }
.timeline .when { font-size:var(--text-xs); color:var(--color-text-muted); }

/* Status stepper (C.pipeline): chevron segments use clip-path so arrows
   interlock without z-index tricks. Completed = green, current = primary,
   open = gray. Horizontally scrollable on narrow viewports. */
/* `position:relative` is the P0 fix here, not cosmetics: without a positioned
   ancestor, `<span class="sr-only">` markers in the steps resolve their
   containing block all the way to `#main-content{position:relative}`. Absolutely
   positioned descendants are NOT clipped by an unpositioned ancestor's
   overflow. One landed at x=338 and drove documentElement.scrollWidth to 339
   in a 320px viewport, making the entire case-detail page scroll sideways
   (WCAG 1.4.10). Measured live: 339 → 320. */
/* WRAP INSTEAD OF SIDEWAYS SCROLLING: flows with six or more steps never fit
   one row. Final steps sat behind a horizontal scrollbar and were effectively
   invisible, even though a process is precisely the information users need to
   see IN FULL. Segments now wrap while preserving the chevron treatment per row.

   `padding-left:var(--arrow)` offsets the negative margin used to interlock
   segments. Otherwise the first tile of EVERY following row protruded one
   arrow width to the left of the container. */
/* `--seg-gap` = visible gap between segments. Previously the chevrons
   interlocked exactly (overlap = full arrow width), so the chain looked like
   ONE bar and individual arrowheads disappeared. A few pixels reveal the
   lighter box background, making the arrow shape and reading direction visible.
   The overlap is reduced by exactly this gap; `padding-left` offsets the
   remaining negative margin so each row's first tile begins flush with the
   container. */
.pipeline {
  --arrow:var(--sp-3);
  --seg-gap:var(--sp-1);
  position:relative; display:flex; flex-wrap:wrap; list-style:none;
  margin:0; padding:0 0 0 calc(var(--arrow) - var(--seg-gap)); row-gap:var(--seg-gap);
}
.pipeline-wrap { position:relative; }
.pipeline__step {
  /* Segments fill the row (`1 1 auto`): the chain stays continuous to the
     right edge rather than ending with a gap. */
  flex:1 1 auto; max-width:100%;
  display:flex; align-items:center; justify-content:center; gap:var(--sp-2);
  min-height:var(--target-min); padding:var(--sp-2) var(--sp-4) var(--sp-2) calc(var(--sp-4) + var(--arrow));
  margin-left:calc(var(--seg-gap) - var(--arrow));
  background:var(--color-secondary-100); color:var(--color-text-muted);
  font-size:var(--fs-sm); font-weight:var(--fw-bold); line-height:1.2;
  /* No more `nowrap`: a long step title may wrap within its segment instead of
     breaking the row. */
  text-align:center; hyphens:auto;
  clip-path:polygon(0 0, calc(100% - var(--arrow)) 0, 100% 50%, calc(100% - var(--arrow)) 100%, 0 100%, var(--arrow) 50%);
}
/* Only the list's FIRST segment gets a straight left edge. The first segment in
   a following row keeps its notch, making it read as a continuation of the row above. */
.pipeline__step:first-child {
  clip-path:polygon(0 0, calc(100% - var(--arrow)) 0, 100% 50%, calc(100% - var(--arrow)) 100%, 0 100%); }
.pipeline__step:last-child {
  clip-path:polygon(0 0, 100% 0, 100% 100%, 0 100%, var(--arrow) 50%); }
.pipeline__step--done { background:var(--color-success-text); color:var(--color-text-negative); }
.pipeline__step--active { background:var(--color-primary-600); color:var(--color-text-negative); }
/* Two states a process can be IN rather than a position it has reached: a case
   returned with conditions, and one that ended in refusal. Ported from the
   tenant portal so both portals own the same pipeline vocabulary
   (docs/case-view-alignment.md V10). Neither replaces the badge — they keep the
   chain from claiming forward progress that did not happen. */
.pipeline__step--rueckfrage { background:var(--color-warning); color:var(--color-text); }
.pipeline__step--rejected { background:var(--color-error); color:var(--color-text-negative); }
/* pipeline() uses the shared CD `icon--md` tier: 20px on phones and 24px from
   768px. Keep sizing in that tier so every pipeline consumer stays aligned. */
.pipeline__glyph { flex:none; }

/* Accordion (accordion.postcss:5-78) */
.accordion { list-style:none; padding-left:0; margin:0; border:0; border-radius:var(--radius-none); background:transparent; }
.accordion__item { border-top:var(--stroke-1) solid var(--color-secondary-200); list-style:none; }
.accordion__item:last-of-type { border-bottom:var(--stroke-1) solid var(--color-secondary-200); }
.accordion__button { display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4); width:100%;
  padding:var(--sp-3) var(--sp-2); background:none; border:0; font:inherit; font-size:var(--fs-base); font-weight:var(--fw-bold);
  text-align:left; cursor:pointer; transition:color var(--duration); }
@media (min-width:1544px){ .accordion__button { padding:var(--sp-5) var(--sp-3); } }
.accordion__button:hover { background:none; color:var(--color-primary-500); }
/* Touch guard — no sticky hover colour after a tap (CD accordion.postcss:31-35
   `@media (hover:none)`; the tenant portal carries the same guard). */
@media (hover:none){ .accordion__button:hover { color:inherit; } }
.accordion__button:active { background:var(--color-secondary-50); color:var(--color-primary-700); }
.accordion__button:focus-visible { position:relative; z-index:var(--z-local-content);
  outline:var(--stroke-2) solid var(--color-focus-ring); outline-offset:calc(-1 * var(--stroke-2)); }
.accordion__button:is(:disabled, [aria-disabled="true"]) { cursor:not-allowed; opacity:.55; }
.accordion__button[aria-busy="true"] { cursor:progress; opacity:.7; }
.accordion__item[aria-invalid="true"] { border-color:var(--color-error); }
.accordion__item[aria-invalid="true"] > .accordion__heading > .accordion__button { color:var(--color-error-text); }
.accordion__item[data-empty="true"] > .accordion__heading > .accordion__button {
  cursor:default; color:var(--color-text-muted); }
/* Long, unbreakable compound UI terms must wrap, or text pushes the chevron out
   of the viewport at 320px. */
.accordion__button > span { min-width:0; overflow-wrap:anywhere; }
.accordion__heading { margin:0; font-size:inherit; font-weight:inherit; }
.accordion__title { font-size:var(--fs-base); text-align:left; padding:var(--sp-1) var(--sp-4) var(--sp-1) 0; margin:0; overflow-wrap:anywhere; }
/* CD accordion.postcss:75-78: pr-4 → lg:pr-6 → 2xl:pr-8 */
@media (min-width:1024px){ .accordion__title { padding-right:var(--sp-6); } }
@media (min-width:1544px){ .accordion__title { padding-right:var(--sp-8); } }
.accordion__button .icon { flex:none; transition:transform var(--duration); }
.accordion__button[aria-expanded="true"] .icon { transform:rotate(180deg); }
/* CD accordion.postcss:59-68: the drawer animates max-height 300ms ease-out
   (wireAccordion drives style.maxHeight from scrollHeight); [hidden] still
   collapses it hard for non-JS/print. The .icon rotation rule above also
   serves .accordion__arrow. */
.accordion__drawer { width:100%; max-height:none; overflow:hidden;
  transition:max-height var(--duration-slow) var(--ease-out); }
.accordion__content { width:100%; padding:var(--sp-4) var(--sp-2) var(--sp-10); }
/* CD accordion.postcss:70-73 2xl:px-3: keeps content aligned with the button,
   which also jumps to .75rem inline padding at 1544. */
@media (min-width:1544px){ .accordion__content { padding-inline:var(--sp-3); } }
/* right-hand cluster in an accordion header (format badge + chevron) */
.accordion__meta { display:flex; align-items:center; gap:var(--sp-3); flex:none; }

/* .data-rows/.data-row are DELETED: the parallel implementation of the
   key-value pattern (data catalogue + my-cases only) moved to the ONE recipe
   dl.kv (+ .kv--ruled for dividers). .kv itself disproves the old claim that a
   dl would need one grid per pair (Design Review C7). */

/* Detail page section rhythm (CD vertical-spacing between content blocks) */
/* Rhythm from --stack-gap: steps at 1544px like CD (spacings.postcss:7-8).
   Previously ONLY this rule stepped at 1024px, placing app detail sections 8px
   farther apart than every .vertical-spacing column between 1024 and 1544
   (Design Review C2). */
.detail-section { margin-top:var(--stack-gap); }
/* Space below the detail hero: ONE value for every sibling. Previously service,
   application and info pages used mt-6 (1.5rem), while only the dataset used
   the 3rem section rhythm: the same location with two spacing systems
   (Design Review, pages finding). Pages no longer carry mt-6. */
.hero + .container--grid, .hero + .measure-xl { margin-top:var(--stack-gap); }
/* The wrapper owns spacing below the hero; the first .detail-section child must
   not double it (6rem instead of 3rem, visible on application and dataset sheets). */
.container__main > .detail-section:first-child,
.measure-xl > .detail-section:first-child { margin-top:0; }
.detail-section__title { margin-bottom:var(--sp-4); }

