/**
 * Resolve — the shared component layer (§7).
 *
 * WHY THIS FILE EXISTS
 * --------------------
 * §7 asks for "one consistent design system for all roles and pages". There
 * were two. resolve-platform.css defined the components the counterparty
 * surfaces use; resolve-panel.css defined a parallel, differently-named and
 * differently-styled set for the administration panel; resolve-admin.css a
 * third for the wp-admin screens. The same idea existed three times under three
 * class names, and they had drifted in ways that were visible on screen:
 *
 *   - a status pill carried a ✓/!/✕ glyph on an investor's dashboard and no
 *     glyph at all in the verification queue, so the panel — the screen where
 *     statuses are actually decided — was relying on colour alone;
 *   - page titles were a high-contrast serif on the front end and a plain
 *     grotesque in the panel, so the two halves of one product did not look
 *     like one product;
 *   - the panel had tabs, filters, tables and pagination and no help
 *     component; the front end had a help component and no tabs, filters or
 *     pagination. Each surface hand-wrote whatever the other one had.
 *
 * Everything in this file is a component whose appearance must NOT depend on
 * which surface it is rendered into. It is attached to every Resolve
 * stylesheet at runtime by Shell::attach_tokens(), so it loads exactly once,
 * after resolve-tokens.css and before the surface sheets — which are therefore
 * still free to override where they have a real reason to.
 *
 * WHAT IS *NOT* HERE
 * ------------------
 * Anything genuinely specific to one surface: the panel's sidebar, the
 * marketplace's filter rail, the shell's header. Those stay where they are.
 * The test for belonging here is "would it be a bug if this looked different
 * in the panel?".
 *
 * DIRECTION
 * ---------
 * Logical properties throughout — `padding-inline-start`, `border-inline-start`,
 * `margin-inline-end` — so this mirrors for Arabic without a single rule in
 * resolve-rtl.css. The four places a physical property is unavoidable are
 * marked where they occur.
 */


/* ===================================================================
 * 0. VISUALLY HIDDEN TEXT.
 *
 * Defined here because a component in this file DEPENDS on it: the help
 * trigger's accessible name is real text inside its <summary>, hidden
 * visually, rather than an aria-label — see Fields::help() for why. If this
 * class is not styled, that name becomes visible and every "?" on the page
 * grows the words "About: Disclosure level" beside it.
 *
 * It was defined in resolve-platform.css and again in resolve-panel.css, and
 * in neither of the two places that a shared component could rely on. A
 * component layer whose accessibility affordance only works when a DIFFERENT
 * stylesheet happens to be loaded is precisely the coupling this file exists
 * to remove, so it is declared here as well. The duplicate declarations in
 * those two files are harmless — the rule is identical and idempotent.
 *
 * `clip-path` alongside the legacy `clip`: `clip` is deprecated but still what
 * older engines honour, and the two together are the combination that keeps
 * the text reachable by screen readers on all of them.
 * =================================================================== */

.screen-reader-text {
	position: absolute !important;
	inline-size: 1px;
	block-size: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * …but it must become visible when focused, or a skip link is a link nobody
 * can see they have reached.
 */
.screen-reader-text:focus {
	position: static !important;
	inline-size: auto;
	block-size: auto;
	margin: 0;
	overflow: visible;
	clip: auto;
	clip-path: none;
	white-space: normal;
}


/* ===================================================================
 * 1. FOCUS — one ring, everywhere.
 *
 * Every focusable thing in the system gets the same ring, defined once. It is
 * an `outline` rather than a `box-shadow` because an outline is not clipped by
 * `overflow: hidden` (a table inside a scroll region would otherwise swallow
 * it) and because outlines survive forced-colours/high-contrast mode, where
 * box-shadows are discarded.
 *
 * :focus-visible rather than :focus, so a mouse user clicking a button does not
 * get a ring they did not ask for, while a keyboard user always does.
 * =================================================================== */

.resolve-platform :focus-visible,
.resolve-panel :focus-visible,
.resolve-shell :focus-visible,
.resolve-app :focus-visible {
	outline: var(--resolve-focus-width, 2px) solid var(--resolve-focus, #5A68C4);
	outline-offset: var(--resolve-focus-offset, 2px);
}

/* On the black header and footer the accent ring has too little contrast
 * against the ground; the brand periwinkle is 7.30:1 there. */
.resolve-shell__header :focus-visible,
.resolve-shell__footer :focus-visible,
.resolve-onblack :focus-visible {
	outline-color: var(--resolve-focus-dark, #8493E6);
}


/* ===================================================================
 * 2. STATUS (§7)
 *
 * "Status must be communicated by text AND visual treatment… never rely on
 * color alone."
 *
 * Three signals on every pill, and the colour is the third of them:
 *
 *   TEXT    the status word, always present, supplied by the component.
 *   SHAPE   a glyph per tone, below. This is what survives greyscale
 *           printing and every form of colour vision deficiency.
 *   COLOUR  the tone.
 *
 * The glyph is generated content and `aria-hidden` by nature — a screen
 * reader is already reading the word, and "check mark Approved" is noise. It
 * is also given an explicit `speak: never` where supported.
 *
 * The border is a fourth signal and does real work: at 1px solid in the tone's
 * own colour it distinguishes a pill from a plain label even when the soft
 * background fails to print.
 * =================================================================== */

.resolve-pill {
	display: inline-flex;
	/*
	 * `flex-start`, not `center`. A pill may now wrap at any width (see
	 * `white-space` below), and centring the glyph against two lines of text
	 * drops it into the gutter between them, where it reads as belonging to
	 * neither. On the one-line case, which is still most of them, flex-start
	 * and center are indistinguishable because the glyph and the text are the
	 * same height.
	 */
	align-items: flex-start;
	gap: 0.4em;
	padding-block: 3px;
	padding-inline: 8px;
	border: 1px solid currentColor;
	border-radius: var(--resolve-radius, 0);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-label, 0.6875rem);
	line-height: var(--resolve-type-label-lh, 1.4);
	font-weight: 600;
	letter-spacing: var(--resolve-type-label-tracking, 3px);
	text-transform: uppercase;
	/*
	 * A PILL WRAPS AT EVERY WIDTH. This was `nowrap`, released only below
	 * 782px by the media query that used to follow.
	 *
	 * The gate was the wrong shape. A pill does not overflow because the
	 * VIEWPORT is narrow, it overflows because the BOX IT IS IN is narrow, and
	 * a status column in a nine-column table is a narrow box at 1920px. With
	 * nowrap above 782px, "Anonymous Teaser Published" — 26 characters,
	 * uppercase, 3px tracking — set the minimum width of its column to 307px on
	 * a desktop, and every table carrying a Status column paid for it. That is
	 * the single widest column in the panel and there is no data in it.
	 *
	 * Wrapping is safe everywhere BECAUSE of `max-inline-size: 100%` below: a
	 * pill still occupies one line wherever its container has room for one,
	 * which is every header, badge and toolbar it appears in. It takes a second
	 * line only where the alternative was overflowing or being clipped, and §7
	 * is explicit that a status cut in half is the failure — "status must be
	 * communicated by text", and half a word is not the text.
	 *
	 * Nothing about the pill got smaller: 11px, uppercase, 3px tracking, before
	 * and after.
	 */
	white-space: normal;
	/*
	 * A STATUS WORD IS NEVER BROKEN. This pair is not optional.
	 *
	 * Section 16 of this file sets `overflow-wrap: break-word` on
	 * .resolve-platform, .resolve-panel and .resolve-shell as the last line of
	 * defence against a long reference or filename forcing a page sideways.
	 * That is inherited, and while the pill was `nowrap` it could never apply.
	 * The moment the pill was allowed to wrap it did: in a narrow Status column
	 * "Confidential Information Access" came out as CONFIDENTIA / L INFORMATION
	 * ACCESS — a status cut in half, which is precisely what §7 forbids and
	 * what the wrap was introduced to prevent.
	 *
	 * So the inheritance is refused here. A pill wraps BETWEEN words and never
	 * inside one, which means a status column's floor is the longest word in
	 * the vocabulary and not one pixel narrower — an honest floor, and the one
	 * this component is prepared to defend.
	 */
	overflow-wrap: normal;
	word-break: normal;
	vertical-align: middle;
	/*
	 * A pill may never be wider than what contains it.
	 *
	 * The brand's eyebrow treatment — uppercase at 3px tracking — is expensive
	 * in width, and the platform's status vocabulary contains some long ones.
	 * "Anonymous Teaser Published" set this way measures 337px, and on a 390px
	 * phone inside a card with 16px padding it ran 4px past the viewport and
	 * made every page of the marketplace scroll sideways.
	 *
	 * This is the cap, and it is what makes `white-space: normal` above safe at
	 * every width: a pill wraps only once it has run out of container, so it is
	 * still one line everywhere there is room for one line.
	 */
	max-inline-size: 100%;
}

/*
 * A WRAPPED PILL, AT EVERY WIDTH.
 *
 * These two rules were inside `@media (max-width: 782px)` and are now
 * unconditional, because a pill can wrap at any viewport now that the wrap
 * itself is unconditional. They are not cosmetic:
 *
 *   - `align-items: flex-start` — the base rule centres the glyph against a
 *     single line of text. On two lines, centring puts it in the gutter
 *     between them, which reads as a bullet belonging to neither.
 *   - the glyph must not stretch or be pushed down by the second line, hence
 *     `flex: 0 0 auto` and the small optical nudge onto the first line's
 *     baseline.
 *
 * Leaving them behind the media query would have meant every pill that wraps
 * on a desktop — which is the whole point of the change — wrapping with its
 * glyph misaligned. `align-items` moved up into the base rule rather than
 * being re-declared here, so there is one place a pill's cross-axis alignment
 * is decided.
 */
.resolve-pill::before {
	flex: 0 0 auto;
	margin-block-start: 0.15em;
}

/*
 * The glyph. `content` is set per tone so that the shape and the colour can
 * never disagree — there is no way to write a green pill with a cross.
 */
.resolve-pill::before {
	font-family: var(--resolve-sans);
	font-size: 1em;
	line-height: 1;
	font-weight: 700;
	speak: never;
}

.resolve-pill--success {
	color: var(--resolve-status-approved, #2f6b46);
	background: var(--resolve-status-approved-soft, #ecf3ef);
}
.resolve-pill--success::before { content: "\2713"; }   /* ✓ approved, verified, active */

.resolve-pill--warning {
	color: var(--resolve-status-pending, #7a6033);
	background: var(--resolve-status-pending-soft, #f7f2e8);
}
.resolve-pill--warning::before { content: "\0021"; }   /* ! pending, needs attention */

.resolve-pill--danger,
.resolve-pill--error {
	color: var(--resolve-status-blocked, #8c2f2f);
	background: var(--resolve-status-blocked-soft, #f7edec);
}
.resolve-pill--danger::before,
.resolve-pill--error::before { content: "\2715"; }     /* ✕ blocked, revoked, rejected */

.resolve-pill--neutral {
	color: var(--resolve-status-inactive, #565f6b);
	background: var(--resolve-status-inactive-soft, #eeedea);
}
.resolve-pill--neutral::before { content: "\25CB"; }   /* ○ inactive, not applicable */

/* Stage is where a transaction has reached, not a judgement about anybody. */
.resolve-pill--stage {
	color: var(--resolve-status-stage, #48559f);
	background: var(--resolve-status-stage-soft, #eef0fa);
}
.resolve-pill--stage::before { content: "\25C6"; }     /* ◆ stage reached */

.resolve-pill--info {
	color: var(--resolve-status-stage, #48559f);
	background: var(--resolve-status-stage-soft, #eef0fa);
}
.resolve-pill--info::before { content: "\2139"; }      /* ℹ information */

/*
 * RESTRICTED — withheld, deliberately.
 *
 * The seventh tone, and the one that was missing rather than wanted.
 * Domain\ContactRelease::STATE_RESTRICTED is the default state of every pair of
 * parties on every transaction: correspondence runs through Resolve and the
 * counterparty's contact details are not shown. It had no entry in
 * Fields::status_tones() and no keyword match, so it resolved to `neutral` and
 * came out in the same grey as "Withdrawn" and "Cancelled" — which reads as an
 * inactive leftover, when it is the live rule the platform is enforcing.
 *
 * It is neither red nor amber on purpose. Red would say a decision had been
 * taken against the reader, and none has: the two parties simply have not been
 * introduced. Amber would put a call to action on the settled default state of
 * every transaction on the platform. resolve-tokens.css documents the pair —
 * 7.03:1 on white, 5.99:1 on its own soft ground, both clear of AA at body
 * size, and a hue nothing else on the platform uses, so a restricted pill is
 * distinguishable from all six others rather than a shade of one of them.
 *
 * The glyph is ⊘ (circled solidus), which is the convention for "withheld" and
 * shares no silhouette with ○ neutral, ◆ stage or ✕ blocked — the three it
 * would otherwise be confused with in greyscale, which is the test §7 sets.
 */
.resolve-pill--restricted {
	color: var(--resolve-status-restricted, #6a5540);
	background: var(--resolve-status-restricted-soft, #f1ece6);
}
.resolve-pill--restricted::before { content: "\2298"; } /* ⊘ withheld */

/*
 * FORCED COLOURS. In Windows high-contrast mode the system replaces every
 * colour, so the tone is gone and the glyph becomes the only visual signal
 * left. Keep the border so the pill is still a discrete object.
 */
@media (forced-colors: active) {
	.resolve-pill {
		border: 1px solid CanvasText;
	}
}

/* A pill and its explanation. Flow container — it holds a <details>. */
.resolve-pillwrap {
	display: flex;
	align-items: center;
	gap: var(--resolve-space-2, 8px);
	flex-wrap: wrap;
}


/* ===================================================================
 * 3. ALERTS AND NOTICES
 *
 * One block, four tones, and a leading rule rather than a full box: an
 * application screen that boxes every message ends up looking like a form of
 * shouting. The rule is `border-inline-start`, so it moves to the right-hand
 * edge in Arabic with no extra rule.
 *
 * The tone words match the status tones deliberately — an amber notice and an
 * amber pill mean the same class of thing.
 * =================================================================== */

.resolve-notice {
	padding: var(--resolve-space-3, 12px) var(--resolve-space-4, 16px);
	border-inline-start: 3px solid var(--resolve-line-strong, #c2c2d2);
	background: var(--resolve-ground, #f7f7fa);
	border-radius: var(--resolve-radius, 0);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	line-height: var(--resolve-type-support-lh, 1.5);
	color: var(--resolve-ink-2, #3c4653);
}

.resolve-notice + .resolve-notice { margin-block-start: var(--resolve-space-2, 8px); }

.resolve-notice--success {
	border-inline-start-color: var(--resolve-status-approved, #2f6b46);
	background: var(--resolve-status-approved-soft, #ecf3ef);
	color: var(--resolve-status-approved, #2f6b46);
}

.resolve-notice--warning {
	border-inline-start-color: var(--resolve-status-pending, #7a6033);
	background: var(--resolve-status-pending-soft, #f7f2e8);
	color: var(--resolve-status-pending, #7a6033);
}

.resolve-notice--error {
	border-inline-start-color: var(--resolve-status-blocked, #8c2f2f);
	background: var(--resolve-status-blocked-soft, #f7edec);
	color: var(--resolve-status-blocked, #8c2f2f);
}

.resolve-notice--info {
	border-inline-start-color: var(--resolve-accent, #5A68C4);
	background: var(--resolve-accent-soft, #eef0fa);
	color: var(--resolve-accent-2, #48559f);
}

.resolve-notice--quiet {
	border-inline-start-color: var(--resolve-line-strong, #c2c2d2);
	background: var(--resolve-ground, #f7f7fa);
	color: var(--resolve-ink-3, #515b68);
}

/*
 * Colour is not the only signal here either. A notice carries its tone as a
 * WORD before its message — "Error", "Warning", "Success" — and the word is
 * real markup emitted by Fields::notice() rather than CSS generated content.
 *
 * That distinction matters twice over: generated content cannot be translated,
 * and this platform is half Arabic; and `content` is announced inconsistently
 * across screen readers, so a blind reader could lose the only signal that
 * distinguishes a confirmation from a failure. The glyph beside it IS
 * generated content, because it is decoration that duplicates the word.
 */
.resolve-notice__label {
	display: block;
	margin-block-end: 2px;
	font-size: var(--resolve-type-label, 0.6875rem);
	font-weight: 700;
	letter-spacing: var(--resolve-type-label-tracking, 3px);
	text-transform: uppercase;
}

.resolve-notice__label::before {
	margin-inline-end: 0.4em;
	speak: never;
}

.resolve-notice--success .resolve-notice__label::before { content: "\2713"; }
.resolve-notice--warning .resolve-notice__label::before { content: "\0021"; }
.resolve-notice--error   .resolve-notice__label::before { content: "\2715"; }
.resolve-notice--info    .resolve-notice__label::before { content: "\2139"; }


/* ===================================================================
 * 4. "WHY IS IT UNAVAILABLE?" (§7)
 *
 * The component Fields::unavailable() renders. It is deliberately the most
 * prominent block on any screen that shows one, because a reader who has hit
 * it cannot do the thing they came to do and the next step is the only content
 * on the page that matters to them.
 *
 * Structure, top to bottom: a status pill; a heading naming the specific
 * state; a two-row definition list captioned "Why" and "What happens next";
 * and, where there is one, a single primary action. The definition list is
 * real <dl> markup, so the two captions are announced as the terms they are
 * rather than being bold text that happens to sit above a paragraph.
 * =================================================================== */

.resolve-unavailable {
	max-width: var(--resolve-prose, 68ch);
	margin-block: var(--resolve-space-5, 24px);
	padding: var(--resolve-space-5, 24px);
	border: 1px solid var(--resolve-line, #dcdce6);
	border-inline-start: 3px solid var(--resolve-status-stage, #48559f);
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-paper, #fff);
}

.resolve-unavailable--warning { border-inline-start-color: var(--resolve-status-pending, #7a6033); }
.resolve-unavailable--error   { border-inline-start-color: var(--resolve-status-blocked, #8c2f2f); }
.resolve-unavailable--info    { border-inline-start-color: var(--resolve-status-stage, #48559f); }

.resolve-unavailable__state { margin: 0 0 var(--resolve-space-3, 12px); }

.resolve-unavailable__title {
	margin: 0 0 var(--resolve-space-4, 16px);
	font-family: var(--resolve-display);
	font-size: var(--resolve-type-page, 1.5rem);
	line-height: var(--resolve-type-page-lh, 1.25);
	font-weight: 700;
	color: var(--resolve-ink, #181818);
}

.resolve-unavailable__body { margin: 0; }

.resolve-unavailable__row + .resolve-unavailable__row { margin-block-start: var(--resolve-space-4, 16px); }

.resolve-unavailable__row dt {
	margin: 0 0 2px;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-label, 0.6875rem);
	font-weight: 700;
	letter-spacing: var(--resolve-type-label-tracking, 3px);
	text-transform: uppercase;
	color: var(--resolve-ink-3, #515b68);
}

.resolve-unavailable__row dd {
	margin: 0;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-body, 1rem);
	line-height: var(--resolve-type-body-lh, 1.6);
	color: var(--resolve-ink-2, #3c4653);
}

.resolve-unavailable__detail {
	margin-block: var(--resolve-space-4, 16px) 0;
	padding: var(--resolve-space-3, 12px);
	background: var(--resolve-ground, #f7f7fa);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	color: var(--resolve-ink-2, #3c4653);
}

.resolve-unavailable__actions { margin-block: var(--resolve-space-5, 24px) 0; }


/* ===================================================================
 * 5. BUTTONS
 *
 * The brand's button, adapted for contrast. From the capture: zero radius,
 * 46px tall, 0 30px padding, uppercase, 1px tracking, and a transition of
 * `background-color 0.3s ease, border-color 0.3s ease` — all carried over
 * verbatim as tokens.
 *
 * The one change is the colour pairing, and it is not optional: Panacea sets
 * white text on a #8493E6 fill, which is 2.88:1 and fails AA outright. The
 * primary button therefore uses the accent ink (#5A68C4) with white text at
 * 4.99:1, and the variant that wants the LITERAL brand fill takes near-black
 * text on it instead of white, at 6.17:1. Same identity; legible.
 *
 * `-webkit-appearance: none` and an explicit font are set because this class is
 * used on <button>, <a> and <input type=submit>, and the three do not agree
 * about any of it by default.
 * =================================================================== */

.resolve-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--resolve-space-2, 8px);
	min-height: var(--resolve-btn-height, 46px);
	padding-block: 0;
	padding-inline: var(--resolve-btn-pad, 30px);
	border: 1px solid transparent;
	border-radius: var(--resolve-radius, 0);
	font-family: var(--resolve-sans);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: var(--resolve-track-button, 1px);
	text-transform: uppercase;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	appearance: none;
	-webkit-appearance: none;
	transition: var(--resolve-transition);
}

.resolve-btn--primary {
	background: var(--resolve-accent, #5A68C4);
	border-color: var(--resolve-accent, #5A68C4);
	color: var(--resolve-accent-ink, #fff);
}

.resolve-btn--primary:hover,
.resolve-btn--primary:focus-visible {
	background: var(--resolve-accent-2, #48559f);
	border-color: var(--resolve-accent-2, #48559f);
	color: var(--resolve-accent-ink, #fff);
}

/* The literal brand fill, with legible text on it. */
.resolve-btn--brand {
	background: var(--resolve-brand, #8493E6);
	border-color: var(--resolve-brand, #8493E6);
	color: var(--resolve-on-light, #181818);
}

.resolve-btn--brand:hover,
.resolve-btn--brand:focus-visible {
	background: var(--resolve-brand-hover, #7a88d6);
	border-color: var(--resolve-brand-hover, #7a88d6);
	color: var(--resolve-on-light, #181818);
}

.resolve-btn--outline {
	background: transparent;
	border-color: var(--resolve-accent, #5A68C4);
	color: var(--resolve-accent, #5A68C4);
}

.resolve-btn--outline:hover,
.resolve-btn--outline:focus-visible {
	background: var(--resolve-accent, #5A68C4);
	color: var(--resolve-accent-ink, #fff);
}

.resolve-btn--ghost {
	background: var(--resolve-paper, #fff);
	border-color: var(--resolve-line-strong, #c2c2d2);
	color: var(--resolve-ink, #181818);
}

.resolve-btn--ghost:hover,
.resolve-btn--ghost:focus-visible {
	border-color: var(--resolve-ink, #181818);
	background: var(--resolve-ground, #f7f7fa);
}

.resolve-btn--danger {
	background: var(--resolve-status-blocked, #8c2f2f);
	border-color: var(--resolve-status-blocked, #8c2f2f);
	color: #fff;
}

/*
 * The pressed darkening of danger, named rather than left as a literal.
 * resolve-panel.css carried #742727 for the identical state on the identical
 * control; both now read one token and both keep their present colour until
 * --resolve-danger-pressed is declared in resolve-tokens.css, at which point
 * the two converge. That token is a NEW VALUE somebody has to decide; it is
 * not in this change's scope.
 */
.resolve-btn--danger:hover,
.resolve-btn--danger:focus-visible {
	background: var(--resolve-danger-pressed, #6f2525);
	border-color: var(--resolve-danger-pressed, #6f2525);
}

.resolve-btn--sm {
	min-height: var(--resolve-btn-height-sm, 34px);
	padding-inline: var(--resolve-btn-pad-sm, 16px);
	font-size: 0.75rem;
	letter-spacing: var(--resolve-track-button-sm, 0.8px);
}

.resolve-btn--lg { min-height: 54px; padding-inline: 40px; }

.resolve-btn--block { display: flex; inline-size: 100%; }

/*
 * A disabled control must say WHY it is disabled, which markup cannot enforce
 * — but it can at least stop looking clickable and stop being a hover target.
 */
.resolve-btn[disabled],
.resolve-btn[aria-disabled="true"] {
	opacity: 0.55;
	cursor: not-allowed;
	pointer-events: none;
}

/*
 * Action groups. §7's "unclear action placement": actions were sometimes above
 * the thing they acted on, sometimes below, sometimes in a table cell. This is
 * the one arrangement — a row at the end of the block, primary first in
 * reading order, wrapping rather than overflowing on a narrow screen.
 */
.resolve-actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--resolve-space-3, 12px);
	align-items: center;
	margin-block-start: var(--resolve-space-5, 24px);
}

.resolve-actions--end { justify-content: flex-end; }
.resolve-actions--between { justify-content: space-between; }


/* ===================================================================
 * 6. CARDS
 *
 * One card. A hairline, square corners, no shadow — the brand has no shadows
 * and gets its depth from the 12px frame and from deliberate collisions, so a
 * drop shadow here would be a borrowed idiom.
 *
 * `display: flex; flex-direction: column` with the actions pushed to the end is
 * what fixes the brief's "inconsistent cards": in a grid, cards stretch to the
 * tallest in the row and their actions line up along the bottom edge instead of
 * floating at whatever height their own text happened to end.
 * =================================================================== */

.resolve-card {
	display: flex;
	flex-direction: column;
	padding: var(--resolve-space-5, 24px);
	border: 1px solid var(--resolve-line, #dcdce6);
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-paper, #fff);
	box-shadow: var(--resolve-shadow, none);
}

.resolve-card__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--resolve-space-3, 12px);
	margin-block-end: var(--resolve-space-4, 16px);
}

.resolve-card__title {
	margin: 0;
	font-family: var(--resolve-display);
	font-size: var(--resolve-type-section, 1.125rem);
	line-height: var(--resolve-type-section-lh, 1.35);
	font-weight: 700;
	color: var(--resolve-ink, #181818);
}

.resolve-card__body { flex: 1 1 auto; }

/* The actions row of a card always sits on its bottom edge. */
.resolve-card__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--resolve-space-3, 12px);
	margin-block-start: auto;
	padding-block-start: var(--resolve-space-4, 16px);
}

/*
 * The grid cards sit in. `align-items: stretch` is the default and is what
 * makes equal heights work; it is stated because it is load-bearing and a
 * future edit setting `align-items: start` would silently undo the fix.
 */
.resolve-cardgrid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: var(--resolve-space-4, 16px);
	align-items: stretch;
}


/* ===================================================================
 * 7. TABLES
 *
 * Dense, quiet and legible: an application table, not a marketing one. Row
 * separation is a hairline rather than zebra striping, because striping fights
 * the status colours that are the point of most of these tables.
 *
 * The wrapper is focusable and scrollable so a wide table on a narrow screen
 * can be reached by keyboard — `tabindex="0"` on an overflow container is the
 * accepted pattern and it is already in use on this platform. `overflow-x` on
 * the wrapper rather than the page is also what stops a table forcing a
 * horizontal scrollbar onto the whole document at 390px.
 * =================================================================== */

.resolve-tablewrap {
	overflow-x: auto;
	border: 1px solid var(--resolve-line, #dcdce6);
	background: var(--resolve-paper, #fff);
	-webkit-overflow-scrolling: touch;
}

.resolve-table {
	inline-size: 100%;
	border-collapse: collapse;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-table, 0.8125rem);
	line-height: var(--resolve-type-table-lh, 1.45);
}

/*
 * 12px INLINE, NOT 16px — the same gutter the administration panel's tables
 * have always used.
 *
 * These were the only tables on the platform at 16px a side, which on the data
 * room's six columns is 192px of blank margin inside cells and on the
 * marketplace's ten columns is 320px. The data room needed 742px in a 732px box
 * and the investor dashboard's access table 451px in a 449px box: both were
 * over by less than the gutter reduction alone returns, so both were scrolling
 * sideways on a desktop to make room for padding.
 *
 * The block padding is untouched at 12px. Row height is what makes a dense
 * table scannable and is not something to trade for width; the horizontal
 * gutter, at this size, is not carrying any information at all.
 */
.resolve-table th,
.resolve-table td {
	padding: var(--resolve-space-3, 12px);
	text-align: start;              /* logical: becomes right in Arabic */
	vertical-align: top;
	border-block-end: 1px solid var(--resolve-line, #dcdce6);
}

/*
 * COLUMN HEADINGS WRAP. THIS RULE USED TO SAY `white-space: nowrap`.
 *
 * Same defect as .resolve-panel__table thead th in resolve-panel.css, and worse
 * here, because these headings carry the brand eyebrow treatment: uppercase at
 * 3px tracking, which is the most expensive way the design system has of
 * setting a word. The marketplace table is ten columns of it, and its
 * HEADER-ONLY floor measured 1,040px against the 988px the app shell gives it —
 * so it scrolled sideways with no data in it at all, on a desktop, which is not
 * a data-density problem that more screen would solve.
 *
 * A heading here is one or two words. Wrapping the longest onto a second line
 * costs one row of 11px text at the top of the table and gives back the
 * difference on every row below. Nothing is truncated and nothing is
 * shrunk — 11px headings and 13px cells, unchanged.
 *
 * `overflow-x: auto` on .resolve-tablewrap STAYS, for viewports genuinely too
 * narrow for the content. It is the fallback again rather than the norm.
 *
 * AND THE TRACKING IS NOW PROPORTIONAL, WHICH IS THE THIRD CAUSE
 * -------------------------------------------------------------
 * Wrapping alone did not bring the marketplace back inside its box: measured
 * after the change above, its ten headings still totalled 1,272px against the
 * 838px the marketplace layout gives them, because `--resolve-type-label-tracking`
 * is a FLAT 3px and this text is 11px. Three pixels between every pair of
 * letters on an 11-pixel glyph is roughly a quarter of the type size again per
 * character — "TRANSACTION" pays 33px of pure tracking, "OPPORTUNITY" 33px, and
 * across ten headings of eight to eleven characters it is very nearly 300px of
 * the table's width spent on air between letters.
 *
 * 0.06em is the same figure resolve-panel.css has always used on the panel's own
 * column headings, so this is the two surfaces agreeing rather than a new value
 * invented here: at 11px it computes to 0.66px, it still reads as the brand's
 * eyebrow treatment, and it is the difference between a heading row that fits
 * and one that does not.
 *
 * THIS IS NOT SHRINKING THE TEXT, which the specification forbids and which
 * there is no headroom for anyway. The font-size above is untouched at 11px and
 * the cells remain 13px. Letter-spacing is the space BETWEEN glyphs, not the
 * glyphs; every character is drawn at exactly the size it was before. The
 * heading is if anything easier to read — 3px tracking on 11px uppercase is
 * past the point where tracking helps legibility and into the point where it
 * costs word shape.
 *
 * Scoped to `thead th` deliberately. `.resolve-pill` keeps its 3px, because a
 * pill is a badge whose whole job is to look like one, it now wraps (see the
 * `white-space` note in section 3), and its width is no longer a floor under
 * any column.
 */
.resolve-table thead th {
	position: sticky;
	inset-block-start: 0;
	z-index: 1;
	background: var(--resolve-ground, #f7f7fa);
	border-block-end: 1px solid var(--resolve-line-strong, #c2c2d2);
	font-size: var(--resolve-type-label, 0.6875rem);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--resolve-ink-3, #515b68);
	white-space: normal;
	overflow-wrap: break-word;
	hyphens: manual;
	min-inline-size: 5ch;
}

.resolve-table tbody tr:last-child td { border-block-end: 0; }

.resolve-table tbody tr:hover { background: var(--resolve-ground, #f7f7fa); }

/* The primary identifier in a row. */
.resolve-table__primary {
	font-weight: 600;
	color: var(--resolve-ink, #181818);
}

.resolve-table__secondary {
	display: block;
	margin-block-start: 2px;
	font-size: var(--resolve-type-label, 0.6875rem);
	color: var(--resolve-ink-4, #626c79);
}

/*
 * The actions column. Right-aligned in LTR and left-aligned in RTL via `end`,
 * and always last — one place for the verb on every row of every table.
 */
.resolve-table__actions { text-align: end; white-space: nowrap; }

/* A numeric column reads correctly only if it is aligned and tabular. */
.resolve-table__num {
	text-align: end;
	font-variant-numeric: tabular-nums;
}


/* ===================================================================
 * 8. EMPTY, LOADING, ERROR AND NO-PERMISSION STATES (§7)
 *
 * Four states that are each a real answer rather than an absence. The brief
 * lists them together and they share a shape deliberately: a mark, a sentence
 * saying what is true, and — where there is one — the action that changes it.
 *
 * "Empty" is not "broken". The panel dashboard already gets this right in
 * words ("These queues exist and currently hold nothing. They are listed so
 * that empty is visibly different from missing") and this is that idea given a
 * component.
 * =================================================================== */

.resolve-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--resolve-space-3, 12px);
	padding: var(--resolve-space-7, 48px) var(--resolve-space-5, 24px);
	border: 1px dashed var(--resolve-line-strong, #c2c2d2);
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-ground, #f7f7fa);
	text-align: center;
}

.resolve-empty__mark {
	font-size: 1.25rem;
	line-height: 1;
	color: var(--resolve-ink-4, #626c79);
}

.resolve-empty__title {
	margin: 0;
	font-family: var(--resolve-display);
	font-size: var(--resolve-type-section, 1.125rem);
	font-weight: 700;
	color: var(--resolve-ink, #181818);
}

.resolve-empty__body {
	margin: 0;
	max-width: 46ch;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	line-height: var(--resolve-type-support-lh, 1.5);
	color: var(--resolve-ink-3, #515b68);
}

/*
 * Loading. The animation is suppressed under prefers-reduced-motion, where it
 * becomes a static bar — a person who has asked the system to stop moving
 * things has asked for that here too.
 */
.resolve-loading {
	display: flex;
	align-items: center;
	gap: var(--resolve-space-3, 12px);
	padding: var(--resolve-space-5, 24px);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	color: var(--resolve-ink-3, #515b68);
}

.resolve-loading::before {
	content: "";
	inline-size: 14px;
	block-size: 14px;
	border: 2px solid var(--resolve-line-strong, #c2c2d2);
	border-top-color: var(--resolve-accent, #5A68C4);   /* physical: a spinner has a top */
	border-radius: 50%;                                  /* the one round thing: it must be */
	animation: resolve-spin 0.8s linear infinite;
}

@keyframes resolve-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
	.resolve-loading::before {
		animation: none;
		border-top-color: var(--resolve-line-strong, #c2c2d2);
	}
}


/* ===================================================================
 * 9. TABS
 *
 * Underline tabs, one treatment. The panel had these; the counterparty
 * surfaces had nothing and hand-rolled toggles instead, so the same idea
 * appeared as an underline in one place and a filled pill in another on the
 * SAME screen (the investors section showed both, stacked).
 *
 * These are links, not the ARIA tab pattern: each is a separate page load, and
 * the tab pattern promises arrow-key movement between panels already in the
 * document. `aria-current="page"` is the honest way to mark the active one.
 * =================================================================== */

.resolve-tabs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--resolve-space-5, 24px);
	margin-block-end: var(--resolve-space-5, 24px);
	padding: 0;
	border-block-end: 1px solid var(--resolve-line, #dcdce6);
	list-style: none;
}

.resolve-tabs__item { margin: 0; }

.resolve-tabs__link {
	display: inline-flex;
	align-items: center;
	gap: var(--resolve-space-2, 8px);
	padding-block: var(--resolve-space-3, 12px);
	border-block-end: 2px solid transparent;
	margin-block-end: -1px;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	font-weight: 600;
	color: var(--resolve-ink-3, #515b68);
	text-decoration: none;
}

.resolve-tabs__link:hover { color: var(--resolve-ink, #181818); }

/*
 * The current tab is marked three ways — weight, colour and a 2px rule —
 * because an underline alone disappears on a low-quality screen and colour
 * alone is the thing §7 forbids.
 */
.resolve-tabs__link[aria-current="page"] {
	border-block-end-color: var(--resolve-accent, #5A68C4);
	color: var(--resolve-ink, #181818);
	font-weight: 700;
}

/* The count beside a tab. A badge, not a pill: it carries a number, not a
 * status, so it gets no glyph and no tone. */
.resolve-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 18px;
	padding-inline: 5px;
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-ink, #181818);
	color: var(--resolve-paper, #fff);
	font-family: var(--resolve-sans);
	font-size: 0.6875rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1.6;
}

.resolve-badge--quiet {
	background: var(--resolve-ground-2, #eeeef4);
	color: var(--resolve-ink-2, #3c4653);
}

.resolve-badge--attention {
	background: var(--resolve-status-pending, #7a6033);
	color: #fff;
}


/* ===================================================================
 * 10. BREADCRUMBS (§7 — "missing breadcrumbs")
 *
 * The front-end shell had these and the panel had none, so half the product
 * told you where you were and half did not. One component now.
 *
 * The separator is generated content rather than a character in the markup, so
 * it is not read out as "slash" by a screen reader, and it is a logical
 * `padding-inline` pair so the trail reverses correctly in Arabic.
 * =================================================================== */

.resolve-crumbs {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--resolve-space-2, 8px);
	margin: 0 0 var(--resolve-space-3, 12px);
	padding: 0;
	list-style: none;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	color: var(--resolve-ink-3, #515b68);
}

.resolve-crumbs__item { display: flex; align-items: center; gap: var(--resolve-space-2, 8px); }

.resolve-crumbs__item + .resolve-crumbs__item::before {
	content: "/";
	color: var(--resolve-ink-4, #626c79);
	speak: never;
}

.resolve-crumbs__link { color: var(--resolve-accent, #5A68C4); text-decoration: none; }
.resolve-crumbs__link:hover { text-decoration: underline; }

.resolve-crumbs__item[aria-current="page"],
.resolve-crumbs__current { color: var(--resolve-ink, #181818); font-weight: 600; }


/* ===================================================================
 * 11. CONTEXTUAL HELP
 *
 * A native <details>. See Fields::help() for the full reasoning — briefly: a
 * title="" tooltip is unreachable by keyboard and touch and read
 * inconsistently by screen readers, and <details> is a real disclosure widget
 * that works with scripting off.
 *
 * The marker is removed on both engines' spellings and replaced with a "?" in
 * the markup, so the trigger is a consistent size and does not jump between
 * a triangle and a chevron.
 * =================================================================== */

.resolve-help { display: inline-block; }

.resolve-help__trigger {
	display: inline-flex;
	align-items: center;
	cursor: pointer;
	list-style: none;
}

.resolve-help__trigger::-webkit-details-marker { display: none; }
.resolve-help__trigger::marker { content: ""; }

.resolve-help__mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 16px;
	block-size: 16px;
	border: 1px solid var(--resolve-line-strong, #c2c2d2);
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-paper, #fff);
	color: var(--resolve-ink-3, #515b68);
	font-family: var(--resolve-sans);
	font-size: 0.625rem;
	font-weight: 700;
	line-height: 1;
}

.resolve-help[open] .resolve-help__mark,
.resolve-help__trigger:hover .resolve-help__mark {
	border-color: var(--resolve-accent, #5A68C4);
	color: var(--resolve-accent, #5A68C4);
}

.resolve-help__body {
	margin-block-start: var(--resolve-space-2, 8px);
	padding: var(--resolve-space-3, 12px);
	border: 1px solid var(--resolve-line, #dcdce6);
	border-inline-start: 3px solid var(--resolve-accent, #5A68C4);
	background: var(--resolve-ground, #f7f7fa);
	max-inline-size: 42ch;
}

.resolve-help__row + .resolve-help__row { margin-block-start: var(--resolve-space-3, 12px); }

.resolve-help__term {
	margin: 0 0 2px;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-label, 0.6875rem);
	font-weight: 700;
	letter-spacing: var(--resolve-type-label-tracking, 3px);
	text-transform: uppercase;
	color: var(--resolve-ink-3, #515b68);
}

.resolve-help__def {
	margin: 0;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	line-height: var(--resolve-type-support-lh, 1.5);
	color: var(--resolve-ink-2, #3c4653);
}

/* A heading and its help, side by side. Flow container — see
 * Fields::heading_with_help() for why this cannot be a <p>. */
.resolve-headrow {
	display: flex;
	align-items: baseline;
	gap: var(--resolve-space-2, 8px);
	flex-wrap: wrap;
}


/* ===================================================================
 * 12. SEARCH, FILTERS AND PAGINATION (§7)
 *
 * Standardised because they were not: the marketplace had a 2,500px filter
 * rail, the panel had inline chips, and neither looked like the other.
 * =================================================================== */

.resolve-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--resolve-space-3, 12px);
	margin-block-end: var(--resolve-space-4, 16px);
}

.resolve-toolbar__spacer { margin-inline-start: auto; }

.resolve-chip {
	display: inline-flex;
	align-items: center;
	gap: var(--resolve-space-2, 8px);
	min-height: var(--resolve-btn-height-sm, 34px);
	padding-inline: var(--resolve-space-3, 12px);
	border: 1px solid var(--resolve-line-strong, #c2c2d2);
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-paper, #fff);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
	color: var(--resolve-ink-2, #3c4653);
	text-decoration: none;
	transition: var(--resolve-transition);
}

.resolve-chip:hover { border-color: var(--resolve-ink, #181818); }

.resolve-chip[aria-current="true"],
.resolve-chip[aria-pressed="true"],
.resolve-chip.is-current {
	background: var(--resolve-ink, #181818);
	border-color: var(--resolve-ink, #181818);
	color: var(--resolve-paper, #fff);
	font-weight: 600;
}

.resolve-pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--resolve-space-2, 8px);
	margin-block-start: var(--resolve-space-5, 24px);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
}

.resolve-pagination__count {
	margin-inline-end: auto;
	color: var(--resolve-ink-3, #515b68);
}

.resolve-pagination__link,
.resolve-pagination__current {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 34px;
	min-block-size: 34px;
	padding-inline: var(--resolve-space-2, 8px);
	border: 1px solid var(--resolve-line, #dcdce6);
	border-radius: var(--resolve-radius, 0);
	text-decoration: none;
	font-variant-numeric: tabular-nums;
}

.resolve-pagination__link { color: var(--resolve-accent, #5A68C4); background: var(--resolve-paper, #fff); }
.resolve-pagination__link:hover { border-color: var(--resolve-accent, #5A68C4); }

.resolve-pagination__current {
	background: var(--resolve-ink, #181818);
	border-color: var(--resolve-ink, #181818);
	color: var(--resolve-paper, #fff);
	font-weight: 700;
}


/* ===================================================================
 * 13. DOCUMENT LISTS AND AUDIT HISTORY (§7)
 *
 * Both are "a list of things that happened or exist, each with a time, an
 * actor and a state". They are given one shape because they are one idea, and
 * because a company reading its document list and an administrator reading the
 * audit log should not have to learn two layouts.
 * =================================================================== */

.resolve-doclist,
.resolve-history {
	margin: 0;
	padding: 0;
	list-style: none;
	border-block-start: 1px solid var(--resolve-line, #dcdce6);
}

.resolve-doclist__item,
.resolve-history__item {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--resolve-space-2, 8px) var(--resolve-space-4, 16px);
	padding-block: var(--resolve-space-3, 12px);
	border-block-end: 1px solid var(--resolve-line, #dcdce6);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-support, 0.875rem);
}

.resolve-doclist__name,
.resolve-history__what {
	flex: 1 1 18ch;
	font-weight: 600;
	color: var(--resolve-ink, #181818);
}

.resolve-doclist__meta,
.resolve-history__meta {
	color: var(--resolve-ink-4, #626c79);
	font-variant-numeric: tabular-nums;
}

/*
 * A timestamp and a reference are Latin runs even inside an Arabic line.
 * `direction: ltr` with `unicode-bidi: isolate` keeps "2026-09-18 14:03" and
 * "RES-4741" from being reordered by the bidi algorithm mid-sentence.
 */
.resolve-ltr-run {
	direction: ltr;
	unicode-bidi: isolate;
}


/* ===================================================================
 * 14. MODALS AND CONFIRMATION DIALOGS (§7)
 *
 * A native <dialog>. The browser gives focus trapping, Escape-to-close, inert
 * background content and the `::backdrop` pseudo-element for free, and every
 * one of those is a thing a hand-rolled modal gets subtly wrong.
 *
 * The one shadow in the system is here, because a dialog is the only surface
 * that genuinely floats above another.
 * =================================================================== */

.resolve-modal {
	max-inline-size: min(560px, calc(100vw - 2 * var(--resolve-gutter, 21px)));
	padding: var(--resolve-space-6, 32px);
	border: 1px solid var(--resolve-line-strong, #c2c2d2);
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-paper, #fff);
	box-shadow: var(--resolve-shadow-raised);
	color: var(--resolve-ink, #181818);
}

.resolve-modal::backdrop { background: rgba(0, 0, 0, 0.55); }

.resolve-modal__title {
	margin: 0 0 var(--resolve-space-3, 12px);
	font-family: var(--resolve-display);
	font-size: var(--resolve-type-page, 1.5rem);
	line-height: var(--resolve-type-page-lh, 1.25);
	font-weight: 700;
}

.resolve-modal__body {
	margin: 0;
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-body, 1rem);
	line-height: var(--resolve-type-body-lh, 1.6);
	color: var(--resolve-ink-2, #3c4653);
}

/*
 * A destructive confirmation names the consequence in the body and colours
 * only the confirming button. Colouring the whole dialog red makes every
 * confirmation feel like an error, and readers stop reading them.
 */
.resolve-modal--destructive .resolve-modal__title { color: var(--resolve-status-blocked, #8c2f2f); }


/* ===================================================================
 * 15. SECTION RHYTHM — the application's, not the marketing site's (§7)
 *
 * The brand's verified rhythm is 130px between sections. That is correct for a
 * page read once while scrolling and wrong for a queue of access requests,
 * where it means four rows per screen. Application sections use the app scale;
 * the marketing surfaces keep 130px (see the theme stylesheet).
 * =================================================================== */

.resolve-section + .resolve-section { margin-block-start: var(--resolve-stack, 32px); }

.resolve-sectionhead {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--resolve-space-3, 12px);
	margin-block-end: var(--resolve-space-4, 16px);
	padding-block-end: var(--resolve-space-3, 12px);
	border-block-end: 1px solid var(--resolve-line, #dcdce6);
}

.resolve-sectionhead__title {
	margin: 0;
	font-family: var(--resolve-display);
	font-size: var(--resolve-type-section, 1.125rem);
	line-height: var(--resolve-type-section-lh, 1.35);
	font-weight: 700;
	color: var(--resolve-ink, #181818);
}

/* The eyebrow. Uppercase, 3px tracking — the brand's only display tracking,
 * and zeroed for Arabic by the token. */
.resolve-eyebrow {
	display: block;
	margin: 0 0 var(--resolve-space-2, 8px);
	font-family: var(--resolve-sans);
	font-size: var(--resolve-type-label, 0.6875rem);
	font-weight: 700;
	letter-spacing: var(--resolve-track-eyebrow, 3px);
	text-transform: uppercase;
	color: var(--resolve-ink-3, #515b68);
}


/* ===================================================================
 * 16. NARROW SCREENS
 *
 * §7's "poor responsive behaviour". One rule matters more than the rest: the
 * page must never scroll horizontally. Anything that can be wider than its
 * container — a table, a long reference, a code span — is made to scroll
 * inside its own box instead of pushing the document wide.
 * =================================================================== */

@media (max-width: 782px) {
	.resolve-card { padding: var(--resolve-space-4, 16px); }

	.resolve-unavailable { padding: var(--resolve-space-4, 16px); }

	.resolve-table th,
	.resolve-table td { padding: var(--resolve-space-2, 8px) var(--resolve-space-3, 12px); }

	/* A button that is the only action in its block goes full width rather
	 * than sitting orphaned at 30px padding on a 390px screen. */
	.resolve-actions > .resolve-btn { flex: 1 1 auto; }

	.resolve-tabs { gap: var(--resolve-space-4, 16px); }
}

/*
 * The last line of defence against horizontal overflow. A long unbroken
 * string — a reference, an email address, a filename — is the usual cause,
 * and `overflow-wrap` is the only property that breaks one without also
 * hyphenating ordinary prose.
 */
.resolve-platform,
.resolve-panel,
.resolve-shell {
	overflow-wrap: break-word;
}


/* ===================================================================
 * 17. PRINT AND GREYSCALE
 *
 * The greyscale check §7 asks for is not only a design review step — some of
 * these screens are printed, and an audit trail printed in black and white is
 * a document somebody relies on. Backgrounds are forced to print so the pill
 * grounds survive, and where a printer drops them the glyph and the word are
 * still there.
 * =================================================================== */

@media print {
	.resolve-pill,
	.resolve-notice {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
	}

	.resolve-help[open] .resolve-help__body { display: block; }

	/* A link's destination is invisible on paper. --resolve-ink-2 rather than
	 * the bare #444 it was: a printed URL is secondary text, and the palette
	 * already has a value for secondary text. #444 was neither that value nor
	 * any other on the platform. */
	.resolve-prose a[href^="http"]::after {
		content: " (" attr(href) ")";
		font-size: 0.75em;
		color: var(--resolve-ink-2, #3c4653);
	}
}

/* ============================================================
 * 18. The notification bell (1.5.1 §2)
 *
 * One component, two shells. The counterparty header calls it
 * `rs-bell`, the administration panel calls it
 * `resolve-panel__bell`, and both selectors are listed on every
 * rule rather than the markup being given a second class — a
 * component whose appearance depends on which page it is on is
 * the thing the 1.5.0 component layer exists to prevent.
 *
 * It is a <details> disclosure, so everything below is layout:
 * there is no open/closed state to keep in sync and no script.
 * Logical properties throughout, so it mirrors for Arabic with
 * no RTL rule.
 * ============================================================ */

.rs-bell,
.resolve-panel__bell {
	position: relative;
	flex: 0 0 auto;
}

.rs-bell__trigger,
.resolve-panel__bell__trigger {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 2px;
	inline-size: 34px;
	block-size: 34px;
	padding: 0;
	border: 1px solid var(--resolve-line, #dcdce6);
	border-radius: var(--resolve-radius, 0);
	background: transparent;
	color: inherit;
	cursor: pointer;
	list-style: none;
}

.rs-bell__trigger::-webkit-details-marker,
.resolve-panel__bell__trigger::-webkit-details-marker {
	display: none;
}

.rs-bell__trigger:focus-visible,
.resolve-panel__bell__trigger:focus-visible {
	outline: var(--resolve-focus-width, 2px) solid var(--resolve-focus, #5A68C4);
	outline-offset: var(--resolve-focus-offset, 2px);
}

.rs-bell__glyph,
.resolve-panel__bell__glyph {
	font-size: 11px;
	line-height: 1;
	opacity: 0.75;
}

/*
 * The count. Absolutely positioned at the logical-start top corner
 * so it mirrors in Arabic, and capped at "99+" in PHP rather than
 * here — a badge that changes width with the number pushes the
 * header around.
 */
.rs-bell__count,
.resolve-panel__bell__count {
	position: absolute;
	inset-block-start: -6px;
	inset-inline-start: -6px;
	min-inline-size: 18px;
	padding: 0 4px;
	border-radius: var(--resolve-radius, 0);
	background: var(--resolve-accent, #5A68C4);
	color: #fff;
	font-size: 10px;
	font-weight: 700;
	line-height: 18px;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

.rs-bell__panel,
.resolve-panel__bell__panel {
	position: absolute;
	inset-block-start: calc(100% + var(--resolve-space-2, 8px));
	inset-inline-end: 0;
	z-index: 40;
	inline-size: max-content;
	min-inline-size: 300px;
	max-inline-size: min(400px, calc(100vw - 24px));
	padding: var(--resolve-space-3, 12px);
	background: var(--resolve-paper, #fff);
	color: var(--resolve-ink, #181818);
	border: 1px solid var(--resolve-line, #dcdce6);
	border-radius: var(--resolve-radius, 0);
	box-shadow: var(--resolve-shadow-raised, none);
	text-align: start;
}

.rs-bell__head,
.resolve-panel__bell__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--resolve-space-2, 8px);
	padding-block-end: var(--resolve-space-2, 8px);
	border-block-end: 1px solid var(--resolve-line, #dcdce6);
}

.rs-bell__title,
.resolve-panel__bell__title {
	font-weight: 600;
	font-size: 13px;
}

/*
 * The list inside the disclosure is capped and scrolls. The cap is
 * a height rather than a row count because a notification with a
 * long body is two lines tall and eight of those would cover the
 * page the bell is supposed to sit above.
 */
.rs-bell__list,
.resolve-panel__bell__list {
	max-block-size: 50vh;
	overflow-y: auto;
}

.rs-bell__empty,
.resolve-panel__bell__empty,
.rs-notiflist__empty,
.resolve-panel__notiflist__empty {
	margin: var(--resolve-space-3, 12px) 0;
	font-size: 13px;
}

.rs-bell__more,
.resolve-panel__bell__more {
	display: block;
	padding-block-start: var(--resolve-space-2, 8px);
	font-size: 12px;
	text-align: center;
}

/*
 * The row itself, shared by the disclosure and both full lists.
 * `.resolve-notifications` already carries the row styling from
 * the platform stylesheet; these are the two things that were
 * missing from it — a focus ring, and a hover that tells the
 * reader the whole row is the link.
 */
.resolve-notifications__link {
	display: grid;
	gap: 2px;
	padding: var(--resolve-space-3, 12px) 0;
	color: inherit;
	text-decoration: none;
}

.resolve-notifications__link:hover {
	background: var(--resolve-ground-2, #f2f2f7);
}

.resolve-notifications__link:focus-visible {
	outline: var(--resolve-focus-width, 2px) solid var(--resolve-focus, #5A68C4);
	outline-offset: -2px;
}

.resolve-notifications__meta {
	display: flex;
	align-items: baseline;
	gap: var(--resolve-space-2, 8px);
	flex-wrap: wrap;
}

/*
 * The event type. Quiet by design: it is a scanning aid beneath the
 * subject, not a second heading competing with it.
 */
.resolve-notifications__type {
	font-size: 11px;
	letter-spacing: var(--resolve-track-button-sm, 0.8px);
	text-transform: uppercase;
	color: var(--resolve-accent, #5A68C4);
}

[dir="rtl"] .resolve-notifications__type {
	text-transform: none;
	letter-spacing: 0;
}
