/* Blazor's <ValidationMessage>, still used next to inputs that Fluent's own field does not wrap. */
.validation-message {
    color: var(--app-intent-danger-fg);
}

.validation-message::before {
    position: relative;
    content: "!";
    font-weight: var(--fontWeightBold);
    padding: 0 var(--spacingHorizontalXS);
}

/* Fills its column. Fluent inputs take the class on their field wrapper, buttons on the element itself. */
.block {
    width: 100%;
}

.ignore-min-width,
.ignore-min-width fluent-dropdown {
    min-width: 0;
}

/* FocusOnNavigate (Routes.razor) focuses the page's h1 after each navigation so a screen reader announces the new
   page. The heading is not something to act on, so it shows no focus ring. */
h1:focus {
    outline: none;
}

/* fluent-tooltip ships with `contain: layout`, which makes it the containing block of its fixed-position
   panel. Inside a scrolling dialog the panel is then clipped by that scroll container, cutting off the top of
   a tall tooltip. Without it the panel is placed against the viewport again. */
fluent-tooltip.coverage-validity-tooltip {
    contain: none;
}

/* A partner autocomplete shows its selected value as a badge whose width grows with the text, expanding the
   Fact/PropertyBox value wrapper past its column and bleeding into the neighbouring field. Clip only the innermost
   wrapper that directly holds a .partner-field (:has) so the badge stays put; every other value keeps its default
   wrapping. */
.fact-value:has(> .partner-field),
.property-box-value:has(> .partner-field) {
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
}

/* A v5 listbox is a flex column of fixed height, and its options set min-height: 32px, which also lets them shrink to
   it: a long autocomplete list squeezed every two-line option (a customer's name and number) into one line's height
   and the lines ran into the next option. Options keep their own height; the list scrolls instead. */
fluent-listbox > fluent-option {
    flex-shrink: 0;
}

/* An autocomplete with nothing to list yet (the customer search, before anything is typed) opened as an empty box under
   the field, which app.js now does as soon as Tab reaches it. The list shows once it has something in it. */
fluent-popover-b:has(> .fluent-stack-vertical:only-child:empty) {
    display: none;
}

/* A v5 listbox picks an option only when the click lands on the <fluent-option> itself, so a click on an option
   template's content (a logo, a customer's name, a badge) picked nothing. Clicks pass through the template to the
   option, as in Fluent's own templated example. */
fluent-option > * {
    pointer-events: none;
}

.hidden {
    display: none !important; /* theming-allow: important — utility must beat component display rules */
}

.h-100-percent {
    height: 100%;
}

pre {
    margin: 0;
}

/* FluentText As="H1"…"H6"/"Paragraph" renders that tag inside its own element, and reboot.css gives the tag a bottom
   margin (12px for a heading, 16px for a paragraph) that FluentText's Margin parameter cannot reach. Without this the
   spacing after every such text was Margin plus reboot's; with it, Margin and the surrounding stack's gap are the only
   spacing, as with v4's FluentLabel. */
fluent-text > :is(h1, h2, h3, h4, h5, h6, p) {
    margin: 0;
}

/* FluentDialogBody puts an ActionTemplate in one wrapper, and v5's action row right-aligns that wrapper at its own
   width, so a FluentSpacer or a summary meant for the footer's left end (bulk assign) had no room and sat against the
   buttons. The wrapper takes the row; its content stays at the right end unless something takes the space. */
fluent-dialog-body > div[slot=action] {
    flex: 1;
    justify-content: flex-end;
}

/* Opt-in (FluentDialogBody Class="scroll-content"): a long dialog that scrolls its content, not itself. v5's <dialog>
   scrolls as a whole, title and actions with the content, so a sticky header in the content (the compare dialog's
   grid) stuck to the dialog's top edge, over its title. The body is held to the dialog's height (the screen's) and
   its content part takes the rows the title and the actions leave, scrolling within them. Not for every dialog: set
   on all of them, the coverage groups dialog (tabs of coverage tables) hung the page while it was open. */
fluent-dialog-body.scroll-content {
    box-sizing: border-box;
    max-height: 100dvh;
    grid-template-rows: auto minmax(0, 1fr) auto;
}

fluent-dialog-body.scroll-content::part(content) {
    min-height: 0;
    overflow-y: auto;
}

/* Opt-in (FluentDialogBody Class="fill-content"), for a dialog given a height: the content part is a flex column of
   exactly the height its title and actions leave, so a child that fills (Tabs Fill, an UpGrid FillHeight) has a
   definite height to fill and scrolls within it, a grid's pager in view under its rows. */
fluent-dialog-body.fill-content {
    box-sizing: border-box;
    height: 100%;
    grid-template-rows: auto minmax(0, 1fr) auto;
}

fluent-dialog-body.fill-content::part(content) {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* FluentDialogBody puts the content in one wrapper div; it takes the content part's height and hands it on. */
fluent-dialog-body.fill-content > div:not([slot]) {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
}

/* A badge is one line. Squeezed (a contact flow's name in its picker's selection) it wrapped, and the field clipped
   the second line. FluentBadge has no nowrap parameter. */
fluent-badge {
    white-space: nowrap;
}

.gradient-text-accent {
    color: transparent;
    background-clip: text;
    background-image: linear-gradient(to right, var(--colorNeutralForeground1), var(--colorBrandForeground1));
}

/*
 * A just-deleted policy is tombstoned client-side (see PolicyGrid.razor): the policies grid is served through Atlas
 * Search, which is eventual-consistent and can keep returning the row for a few seconds after deletion. The row's
 * Actions cell renders a [data-policy-deleting] marker; this rule hides that whole FluentDataGrid row so the deleted
 * policy disappears immediately. Global (not scoped) CSS because the <tr> is rendered by the shared
 * UpGrid/FluentDataGrid child, which a scoped ::deep rule cannot reliably reach with :has().
 */
tr[role="row"]:has([data-policy-deleting]) {
    display: none;
}
