/*
 * Reltrax app styles.
 *
 * Every rule is prefixed `.rtx-app` — not for tidiness but for specificity.
 * The app renders inside whatever the client's theme and Breakdance put around
 * it, and a bare `.rtx-table` (0,1,0) loses to a theme's `.page table`. Two
 * classes deep wins those fights without reaching for !important.
 *
 * Deliberately plain: this is a tool agents use for hours, not a landing page.
 * Everything sizes in relative units so it survives whatever base font size
 * the theme sets.
 */

.rtx-app {
	/*
	 * Taken from the logo: the blue of the wordmark, the orange of the roof,
	 * the green of the house. Blue carries navigation and anything primary,
	 * orange means "this wants you", green means "this went well". Three
	 * jobs, three colours — a fourth would start meaning nothing.
	 */
	--rtx-blue: #1b75bb;
	--rtx-blue-dark: #145d95;
	--rtx-blue-soft: #e8f2fa;
	--rtx-blue-ink: #10537f;

	--rtx-orange: #f26722;
	--rtx-orange-soft: #fdeee4;
	--rtx-orange-ink: #a2400d;

	--rtx-green: #6faf2f;
	--rtx-green-soft: #eff7e5;
	--rtx-green-ink: #47701c;

	--rtx-ink: #1a2230;
	--rtx-muted: #616b7a;
	--rtx-line: #e2e6ec;
	--rtx-bg: #fff;
	--rtx-soft: #f5f7fa;
	--rtx-faint: #97a0ae;

	--rtx-accent: var(--rtx-blue);
	--rtx-accent-soft: var(--rtx-blue-soft);
	--rtx-accent-ink: var(--rtx-blue-ink);
	--rtx-warn: #c0392b;
	--rtx-ok: var(--rtx-green-ink);

	color: var(--rtx-ink);
	font-size: 15px;
	line-height: 1.5;
	max-width: 1200px;
	margin: 0 auto;
	padding: 0 0 32px;
	text-align: left;
}

.rtx-app *,
.rtx-app *::before,
.rtx-app *::after {
	box-sizing: border-box;
}

.rtx-app a {
	color: var(--rtx-accent);
}

/* -- Chrome --------------------------------------------------------------- */

.rtx-app .rtx-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 16px;
	flex-wrap: wrap;
	padding: 12px 0;
	border-bottom: 1px solid var(--rtx-line);
	margin-bottom: 16px;
}

.rtx-app .rtx-nav {
	display: flex;
	gap: 18px;
	margin: 0;
	padding: 0;
}

.rtx-app .rtx-nav a {
	text-decoration: none;
	font-weight: 600;
	font-size: 15px;
	padding-bottom: 4px;
	border-bottom: 2px solid transparent;
}

.rtx-app .rtx-nav a.is-active {
	border-bottom-color: var(--rtx-accent);
	color: var(--rtx-ink);
}

.rtx-app .rtx-who {
	color: var(--rtx-muted);
	font-size: 13px;
	display: flex;
	gap: 6px;
	align-items: center;
}

.rtx-app .rtx-role,
.rtx-app .rtx-env,
.rtx-app .rtx-tag {
	display: inline-block;
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	border-radius: 3px;
	padding: 0 6px;
	font-size: 11px;
	line-height: 1.7;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--rtx-muted);
	vertical-align: middle;
}

.rtx-app .rtx-env {
	background: #fcf9e8;
	border-color: #dba617;
	color: #8a6116;
}

/*
 * Impersonation has to be impossible to forget: full width, high contrast,
 * and present at the top of every screen for the whole session.
 */
.rtx-app .rtx-impersonating {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	background: #8a2424;
	color: #fff;
	padding: 10px 14px;
	border-radius: 4px;
	margin-bottom: 12px;
	font-size: 14px;
}

.rtx-app .rtx-notice {
	padding: 10px 14px;
	border: 1px solid var(--rtx-line);
	border-left: 4px solid var(--rtx-faint);
	border-radius: 6px;
	background: var(--rtx-soft);
	margin-bottom: 12px;
	font-size: 14px;
}

.rtx-app .rtx-notice-success {
	border-left-color: var(--rtx-green);
	border-color: #cfe4b4;
	background: var(--rtx-green-soft);
	color: var(--rtx-green-ink);
}

/*
 * Information, not a problem. Used where something is still in progress and
 * the reader has nothing to do about it — styling that as an error trains
 * people to ignore the errors that do matter.
 */
.rtx-app .rtx-notice-info {
	border-left-color: #2271b1;
	border-color: #c5d9ea;
	background: #f0f6fb;
	color: #1d4f7c;
}

.rtx-app .rtx-notice-error {
	border-left-color: var(--rtx-warn);
	border-color: #edc3bd;
	background: #fbecea;
	color: #8f2a1e;
}

/* -- Controls ------------------------------------------------------------- */

/*
 * One button, four skins.
 *
 * Sized to a 38px control height across the app so a button, a select and a
 * text input sitting on the same row line up without anyone nudging margins.
 * That single number is what separates a screen that looks assembled from one
 * that looks arranged.
 */
.rtx-app .rtx-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	min-height: 38px;
	background: linear-gradient(180deg, #fff, #f7f9fb);
	border: 1px solid var(--rtx-line);
	border-radius: 8px;
	padding: 8px 15px;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.2;
	font-family: inherit;
	cursor: pointer;
	text-decoration: none;
	white-space: nowrap;
	color: var(--rtx-ink);
	text-transform: none;
	letter-spacing: normal;
	box-shadow: 0 1px 2px rgba(26, 34, 48, .06);
	transition: background-color .13s ease, border-color .13s ease, box-shadow .13s ease, transform .13s ease;
}

.rtx-app .rtx-btn:hover {
	background: #fff;
	border-color: #cfd6e0;
	color: var(--rtx-ink);
	box-shadow: 0 2px 6px rgba(26, 34, 48, .1);
	transform: translateY(-1px);
}

/* Pressed state returns it to the page, so a click feels like one. */
.rtx-app .rtx-btn:active {
	transform: translateY(0);
	box-shadow: inset 0 1px 2px rgba(26, 34, 48, .12);
}

/*
 * :focus-visible, not :focus — a mouse click on a button should not leave a
 * ring behind it, but a keyboard tab must always show where it landed.
 */
.rtx-app .rtx-btn:focus-visible,
.rtx-app input:focus-visible,
.rtx-app select:focus-visible,
.rtx-app textarea:focus-visible {
	outline: 2px solid var(--rtx-accent);
	outline-offset: 2px;
}

.rtx-app .rtx-btn .rtx-icon {
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
	opacity: .85;
}

.rtx-app .rtx-btn-primary {
	background: linear-gradient(180deg, #2384cf, var(--rtx-accent));
	border-color: var(--rtx-blue-dark);
	color: #fff;
	box-shadow: 0 1px 2px rgba(16, 83, 127, .3);
}

.rtx-app .rtx-btn-primary:hover {
	background: linear-gradient(180deg, var(--rtx-accent), var(--rtx-blue-dark));
	border-color: var(--rtx-blue-dark);
	color: #fff;
	box-shadow: 0 3px 10px rgba(27, 117, 187, .32);
}

.rtx-app .rtx-btn-primary .rtx-icon {
	opacity: 1;
}

/* Quiet enough to sit above a heading without competing with it. */
.rtx-app .rtx-btn-ghost {
	background: none;
	border-color: transparent;
	box-shadow: none;
	color: var(--rtx-muted);
	font-weight: 600;
}

.rtx-app .rtx-btn-ghost:hover {
	background: var(--rtx-soft);
	border-color: var(--rtx-line);
	color: var(--rtx-ink);
	box-shadow: none;
}

.rtx-app .rtx-btn-danger {
	color: var(--rtx-warn);
	border-color: #e7c9c5;
	background: linear-gradient(180deg, #fff, #fdf6f5);
}

.rtx-app .rtx-btn-danger:hover {
	background: var(--rtx-warn);
	border-color: var(--rtx-warn);
	color: #fff;
}

.rtx-app .rtx-btn-sm {
	min-height: 30px;
	padding: 5px 10px;
	font-size: 13px;
	border-radius: 7px;
}

/* Square, for an icon with no label — a title attribute carries the meaning. */
.rtx-app .rtx-btn-icon {
	padding: 8px;
	width: 38px;
}

.rtx-app .rtx-btn-icon .rtx-icon {
	width: 17px;
	height: 17px;
}

.rtx-app .rtx-btn-block {
	width: 100%;
}

.rtx-app .rtx-btn-light {
	background: #fff;
	border-color: #fff;
	color: #8a2424;
}

.rtx-app .rtx-link {
	background: none;
	border: 0;
	padding: 0;
	color: var(--rtx-accent);
	cursor: pointer;
	font-size: 13px;
	font-family: inherit;
	text-decoration: underline;
}

.rtx-app input[type="text"],
.rtx-app input[type="email"],
.rtx-app input[type="search"],
.rtx-app input[type="date"],
.rtx-app select,
.rtx-app textarea {
	border: 1px solid #d6dce5;
	border-radius: 8px;
	padding: 8px 11px;
	min-height: 38px;
	font-size: 14px;
	line-height: 1.4;
	font-family: inherit;
	color: var(--rtx-ink);
	background: var(--rtx-bg);
	max-width: 100%;
	height: auto;
	margin: 0;
	/* A hairline of depth, so a field reads as a well rather than an outline. */
	box-shadow: inset 0 1px 2px rgba(26, 34, 48, .05);
	transition: border-color .13s ease, box-shadow .13s ease;
}

.rtx-app input[type="text"]:hover,
.rtx-app input[type="email"]:hover,
.rtx-app input[type="search"]:hover,
.rtx-app select:hover,
.rtx-app textarea:hover {
	border-color: #bdc7d4;
}

.rtx-app input[type="text"]:focus,
.rtx-app input[type="email"]:focus,
.rtx-app input[type="search"]:focus,
.rtx-app input[type="date"]:focus,
.rtx-app select:focus,
.rtx-app textarea:focus {
	border-color: var(--rtx-accent);
	box-shadow: 0 0 0 3px rgba(27, 117, 187, .14);
	outline: none;
}

.rtx-app ::placeholder {
	color: var(--rtx-faint);
	opacity: 1;
}

/*
 * A select styled like the rest needs its own arrow: once the border and
 * padding are ours, the platform triangle sits in the wrong place and at the
 * wrong weight. Inline SVG so it costs no request.
 */
.rtx-app select {
	appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5l5-5' fill='none' stroke='%23616b7a' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 11px center;
	padding-right: 32px;
}

.rtx-app textarea {
	width: 100%;
	display: block;
	margin-bottom: 10px;
	min-height: 72px;
	resize: vertical;
}

.rtx-app .rtx-filters {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	align-items: center;
	margin-bottom: 12px;
}

.rtx-app .rtx-search {
	min-width: 240px;
	flex: 1 1 240px;
}

.rtx-app .rtx-clear {
	font-size: 13px;
}

.rtx-app .rtx-count {
	color: var(--rtx-muted);
	font-size: 13px;
	margin: 0 0 8px;
}

.rtx-app .rtx-muted {
	color: var(--rtx-muted);
}

/*
 * A button that reads as a link. For an action inside a table cell where a
 * real button would be a lump and a real link would lie about navigating.
 */
.rtx-app .rtx-linkish {
	background: none;
	border: 0;
	padding: 0;
	margin-left: 8px;
	font: inherit;
	color: var(--rtx-blue-ink);
	text-decoration: underline;
	cursor: pointer;
}

/*
 * `.rtx-table` is nowrap, which is right for dates and badges and wrong for a
 * blog title: one long headline pushed the whole table sideways and everything
 * after it — the date, and now the button that removes the post — off the edge
 * of the scroller. Only the first column wraps, and it keeps a floor so the
 * title does not end up one word per line.
 */
.rtx-app .rtx-blog-table th:first-child,
.rtx-app .rtx-blog-table td:first-child {
	white-space: normal;
	min-width: 260px;
}

/*
 * The same button at the end of a table row, where there is no sentence for it
 * to sit inside. The left margin is what separates it from the words before it
 * and is wrong when it is the only thing in the cell.
 */
.rtx-app .rtx-row-form {
	display: inline;
	margin: 0;
}

.rtx-app .rtx-row-form .rtx-linkish {
	margin-left: 0;
}

.rtx-app .rtx-linkish-danger {
	color: var(--rtx-warn);
}

/* -- Homes a lead keeps coming back to ----------------------------------- */

.rtx-app .rtx-viewed {
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	gap: .65rem;
}

.rtx-app .rtx-viewed-item {
	display: flex;
	gap: .85rem;
	align-items: flex-start;
	padding: .7rem;
	border: 1px solid var(--rtx-line);
	border-radius: 10px;
	background: var(--rtx-bg);
}

/*
 * Fixed box, photo fills it. Listing photos arrive at whatever shape the
 * photographer left them, and a portrait shot would otherwise set the height
 * of its whole row.
 */
.rtx-app .rtx-viewed-photo {
	flex: 0 0 104px;
	position: relative;
	aspect-ratio: 4 / 3;
	border-radius: 7px;
	overflow: hidden;
	background: color-mix(in srgb, currentColor 8%, transparent);
}

.rtx-app .rtx-viewed-photo img {
	position: absolute;
	inset: 0;
	display: block;
	inline-size: 100%;
	block-size: 100%;
	max-inline-size: none;
	object-fit: cover;
}

.rtx-app .rtx-viewed-body { min-width: 0; flex: 1 1 auto; }
.rtx-app .rtx-viewed-title { margin: 0; font-weight: 650; overflow-wrap: anywhere; }
.rtx-app .rtx-viewed-facts { margin: .15rem 0 0; font-size: .88rem; opacity: .75; }

/* The count is the signal, so it is the loudest thing on the row. */
.rtx-app .rtx-viewed-when {
	margin: .35rem 0 0;
	font-size: .88rem;
	font-weight: 600;
}

/*
 * The "not one of yours" note rides on the end of the count line, so it is
 * `rtx-inline-tight` — the name this file already uses for that — rather than
 * a second rule called `rtx-inline`, which here means a flex row and would
 * have broken the line in half. Weight is reset because the line it sits on
 * is deliberately bold and the note is not part of what gets read out.
 */
.rtx-app .rtx-viewed-when .rtx-hint { font-weight: 400; }

@media (max-width: 520px) {
	.rtx-app .rtx-viewed-photo { flex-basis: 76px; }
}

/*
 * A panel heading with an action parked at its right-hand end. Wraps rather
 * than squeezing, because the button carries words and a narrow column would
 * otherwise crush the heading to fit it on one line.
 */
.rtx-app .rtx-panel-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	margin-block-end: .4rem;
}

.rtx-app .rtx-panel-head h3 { margin: 0; }
.rtx-app .rtx-resync { margin: 0; }

/*
 * An icon-only action sitting inside a heading. Inline-flex so it sits on the
 * text baseline rather than dropping the h2's line box, and sized off the
 * heading so it stays proportionate wherever it is used.
 */
.rtx-app .rtx-title-action {
	display: inline;
	margin: 0 0 0 .4em;
}

.rtx-app .rtx-iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	vertical-align: middle;
	inline-size: 1.5em;
	block-size: 1.5em;
	padding: 0;
	border: 0;
	border-radius: 6px;
	background: none;
	color: inherit;
	opacity: .5;
	cursor: pointer;
	transition: opacity .15s ease, background-color .15s ease;
}

.rtx-app .rtx-iconbtn svg {
	inline-size: 1em;
	block-size: 1em;
}

.rtx-app .rtx-iconbtn:hover,
.rtx-app .rtx-iconbtn:focus-visible {
	opacity: 1;
	background: color-mix(in srgb, currentColor 10%, transparent);
}

/* -- Sharing a published post -------------------------------------------- */

/*
 * A row of ordinary buttons. The share destinations are links rather than
 * integrations — see `Content\Share` for why — so they need nothing here
 * beyond wrapping sensibly on a narrow screen.
 */
.rtx-app .rtx-share {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 14px;
}

.rtx-app .rtx-share-heading {
	margin: 24px 0 6px;
}

.rtx-app .rtx-share-caption summary {
	cursor: pointer;
	font-weight: 600;
}

.rtx-app .rtx-share-caption textarea {
	width: 100%;
	margin-top: 8px;
	font: inherit;
	line-height: 1.5;
	padding: 10px;
	border: 1px solid var(--rtx-line);
	border-radius: 6px;
	background: var(--rtx-soft);
}

/* -- Table ---------------------------------------------------------------- */

/*
 * The table scrolls inside its own box rather than stretching the page.
 * Agents work on phones between showings, and a horizontally scrolling body
 * makes every tap land somewhere unintended.
 *
 * The scroll lives on a wrapper and not on the table, which is the correction.
 * `display: block` on a `<table>` gets the scrolling right and throws the table
 * layout away with it: the rows re-form as an anonymous table sized to their
 * content, so `width: 100%` applies to the block box while the columns inside
 * stop wherever the text does. On a wide screen with few columns that reads as
 * a table that gave up two hundred pixels short of the panel it sits in.
 */
.rtx-app .rtx-table-scroll {
	overflow-x: auto;
	margin: 0 0 8px;
	background: var(--rtx-bg);
}

.rtx-app .rtx-table {
	width: 100%;
	border-collapse: collapse;
	white-space: nowrap;
	background: var(--rtx-bg);
}

.rtx-app .rtx-table th,
.rtx-app .rtx-table td {
	text-align: left;
	padding: 8px 12px;
	border-bottom: 1px solid var(--rtx-line);
	vertical-align: top;
	background: transparent;
}

.rtx-app .rtx-table th {
	font-size: 11.5px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .05em;
	color: var(--rtx-blue-ink);
	background: var(--rtx-soft);
	border-bottom: 2px solid var(--rtx-line);
}

.rtx-app .rtx-table th:first-child { border-top-left-radius: 6px; }
.rtx-app .rtx-table th:last-child { border-top-right-radius: 6px; }

.rtx-app .rtx-table tbody tr:hover td {
	background: var(--rtx-soft);
}

.rtx-app .rtx-table tr.is-archived td {
	color: var(--rtx-muted);
}

.rtx-app .rtx-contact {
	font-size: 13px;
	white-space: normal;
}

.rtx-app .rtx-stage {
	display: inline-block;
	font-size: 12px;
	padding: 2px 8px;
	border-radius: 10px;
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
}

.rtx-app .rtx-stage-new {
	background: var(--rtx-blue-soft);
	border-color: #a9cee9;
	color: var(--rtx-blue-ink);
}

.rtx-app .rtx-stage-working {
	background: var(--rtx-green-soft);
	border-color: #b6d894;
	color: var(--rtx-green-ink);
}

.rtx-app .rtx-stage-appt {
	background: var(--rtx-orange-soft);
	border-color: #f3b98e;
	color: var(--rtx-orange-ink);
}

.rtx-app .rtx-stage-client {
	background: #e9f6ec;
	border-color: #62a970;
}

.rtx-app .rtx-stage-lost {
	background: #fbeaea;
	border-color: #d9a1a1;
}

.rtx-app .rtx-pager {
	display: flex;
	gap: 16px;
	align-items: center;
	padding: 14px 0;
	font-size: 14px;
}

.rtx-app .rtx-empty {
	border: 1px dashed #cfd8e3;
	border-radius: 8px;
	padding: 26px;
	text-align: center;
	color: var(--rtx-muted);
	background: linear-gradient(180deg, var(--rtx-soft) 0%, #fff 100%);
}

.rtx-app .rtx-empty strong {
	color: var(--rtx-ink);
}

.rtx-app .rtx-empty p {
	margin: 0 0 6px;
}

/* -- Lead detail ---------------------------------------------------------- */

.rtx-app .rtx-back {
	font-size: 13px;
	margin: 0 0 10px;
}

.rtx-app .rtx-lead {
	display: grid;
	gap: 14px;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	align-items: start;
}

.rtx-app .rtx-lead-head {
	grid-column: 1 / -1;
}

.rtx-app .rtx-panel {
	border: 1px solid var(--rtx-line);
	border-radius: 12px;
	padding: 16px 18px;
	background: var(--rtx-bg);
}

.rtx-app .rtx-panel h2 {
	margin: 0 0 10px;
	font-size: 20px;
	line-height: 1.3;
}

/*
 * Two shadows, not one: a tight dark line that reads as the card's edge, and a
 * wide soft one that lifts it off the page. A single blurred shadow gives you
 * one or the other and always looks slightly muddy.
 */
.rtx-app .rtx-panel {
	box-shadow: 0 1px 2px rgba(26, 34, 48, .05), 0 4px 14px rgba(26, 34, 48, .05);
}

.rtx-app .rtx-panel h3 {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 10px;
	font-size: 13px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .05em;
	color: var(--rtx-ink);
}

/* A short brand tick, not a full rule — enough to break up the white. */
.rtx-app .rtx-panel h3::before {
	content: "";
	flex: 0 0 auto;
	width: 3px;
	height: 13px;
	border-radius: 2px;
	background: var(--rtx-blue);
}

.rtx-app .rtx-cols > .rtx-panel:nth-child(2n) h3::before { background: var(--rtx-orange); }
.rtx-app .rtx-cols > .rtx-panel:nth-child(3n) h3::before { background: var(--rtx-green); }

.rtx-app .rtx-facts {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 4px 16px;
	margin: 0;
	font-size: 14px;
}

.rtx-app .rtx-facts dt {
	color: var(--rtx-muted);
	font-weight: 400;
}

.rtx-app .rtx-facts dd {
	margin: 0;
}

.rtx-app .rtx-alt {
	font-size: 13px;
	color: var(--rtx-muted);
	margin: 12px 0 0;
}

.rtx-app .rtx-ident {
	display: inline-block;
	margin-right: 10px;
}

/*
 * "Unconfirmed", not "wrong". Red made an imported phone number look like an
 * error when it is simply a number nobody has verified — muted says the same
 * thing without the alarm.
 */
.rtx-app .rtx-ident abbr {
	cursor: help;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 15px;
	height: 15px;
	border-radius: 50%;
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	color: var(--rtx-muted);
	font-size: 10px;
	font-weight: 700;
	text-decoration: none;
	vertical-align: 1px;
}

.rtx-app .rtx-inline {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	align-items: center;
	margin-bottom: 10px;
}

.rtx-app .rtx-inline-tight {
	display: inline;
}

.rtx-app .rtx-timeline {
	list-style: none;
	margin: 0;
	padding: 0;
}

.rtx-app .rtx-timeline li {
	border-left: 2px solid var(--rtx-line);
	padding: 0 0 14px 14px;
	margin-left: 4px;
	list-style: none;
}

.rtx-app .rtx-timeline-meta {
	font-size: 12px;
	color: var(--rtx-muted);
	margin-bottom: 2px;
}

.rtx-app .rtx-timeline-body {
	font-size: 14px;
}

.rtx-app .rtx-tasks {
	list-style: none;
	margin: 0 0 12px;
	padding: 0;
	font-size: 14px;
}

.rtx-app .rtx-tasks li {
	display: flex;
	gap: 10px;
	align-items: baseline;
	flex-wrap: wrap;
	padding: 6px 0;
	margin: 0;
	border-bottom: 1px solid var(--rtx-line);
	list-style: none;
}

.rtx-app .rtx-tasks li.is-done {
	color: var(--rtx-muted);
	text-decoration: line-through;
}

.rtx-app .rtx-tasks li.is-overdue .rtx-due {
	color: var(--rtx-warn);
	font-weight: 600;
}

.rtx-app .rtx-task-body {
	flex: 1 1 auto;
}

.rtx-app .rtx-due {
	min-width: 52px;
	color: var(--rtx-muted);
	font-size: 13px;
}

.rtx-app .rtx-task-lead {
	font-size: 13px;
}

.rtx-app .rtx-secondary {
	background: var(--rtx-soft);
}

@media (max-width: 600px) {
	.rtx-app .rtx-facts {
		grid-template-columns: 1fr;
	}

	.rtx-app .rtx-facts dt {
		margin-top: 8px;
	}
}

/* -- Shell: sidebar + main ------------------------------------------------ */

.rtx-app .rtx-shell {
	display: grid;
	grid-template-columns: 228px minmax(0, 1fr);
	gap: 28px;
	align-items: start;
}

/*
 * The sidebar is a quiet surface, not a coloured slab. Agents look at the
 * content beside it for hours; a heavy nav competes with the thing they came
 * to read. One hairline rule, generous padding, and colour reserved entirely
 * for the active item.
 */
.rtx-app .rtx-side {
	position: sticky;
	top: 16px;
	display: flex;
	flex-direction: column;
	gap: 18px;
	padding: 4px 16px 14px 0;
	border-right: 1px solid var(--rtx-line);
	min-height: 320px;
}

.rtx-app .rtx-side-nav {
	display: flex;
	flex-direction: column;
	gap: 18px;
}

.rtx-app .rtx-side-group h4 {
	margin: 0 0 6px;
	padding: 0 10px;
	font-size: 10.5px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .09em;
	color: var(--rtx-faint);
}

.rtx-app .rtx-side ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 1px;
}

.rtx-app .rtx-side li {
	margin: 0;
	list-style: none;
}

.rtx-app .rtx-side a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 7px 10px;
	border-radius: 7px;
	text-decoration: none;
	color: var(--rtx-ink);
	font-size: 14px;
	line-height: 1.3;
	transition: background-color .12s ease, color .12s ease;
}

.rtx-app .rtx-side a:hover {
	background: var(--rtx-soft);
}

/*
 * Active is a filled pill rather than a left bar: the pill reads at a glance
 * from anywhere in the list, and it does not shift the label by a pixel, which
 * a border would.
 */
.rtx-app .rtx-side a.is-active {
	background: var(--rtx-blue-soft);
	color: var(--rtx-blue-ink);
	font-weight: 600;
}

.rtx-app .rtx-side-label {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* The icon carries the mood: muted at rest, full colour only when active. */
.rtx-app .rtx-icon {
	flex: 0 0 auto;
	color: var(--rtx-faint);
	transition: color .12s ease;
}

.rtx-app .rtx-side a:hover .rtx-icon {
	color: var(--rtx-muted);
}

.rtx-app .rtx-side a.is-active .rtx-icon {
	color: var(--rtx-blue);
}

/* Group headings get the brand blue so the sidebar is not all grey. */
.rtx-app .rtx-side-group h4 {
	color: var(--rtx-blue);
	opacity: .75;
}

.rtx-app .rtx-soon {
	flex: 0 0 auto;
	font-size: 9.5px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .06em;
	color: var(--rtx-orange-ink);
	background: var(--rtx-orange-soft);
	border-radius: 9px;
	padding: 1px 6px;
}

.rtx-app .rtx-side-who {
	display: flex;
	align-items: center;
	gap: 9px;
	margin-top: auto;
	padding: 10px;
	border-radius: 8px;
	background: var(--rtx-soft);
}

.rtx-app .rtx-avatar {
	flex: 0 0 auto;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: linear-gradient(135deg, var(--rtx-blue) 0%, var(--rtx-blue-dark) 100%);
	color: #fff;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: .02em;
	display: flex;
	align-items: center;
	justify-content: center;
}

.rtx-app .rtx-side-who-text {
	min-width: 0;
	display: flex;
	flex-direction: column;
	line-height: 1.3;
}

.rtx-app .rtx-side-who-text strong {
	font-size: 13px;
	font-weight: 600;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.rtx-app .rtx-side-who-text small {
	font-size: 11px;
	color: var(--rtx-muted);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.rtx-app .rtx-main {
	min-width: 0;
	padding-top: 8px;
}

.rtx-app .rtx-page-title {
	position: relative;
	margin: 0 0 14px;
	padding-bottom: 9px;
	font-size: 23px;
	line-height: 1.25;
	font-weight: 700;
	letter-spacing: -.01em;
}

.rtx-app .rtx-page-title::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 34px;
	height: 3px;
	border-radius: 2px;
	background: var(--rtx-orange);
}

/* When a hint follows the title, close the gap the underline opened. */
.rtx-app .rtx-page-title + .rtx-hint {
	margin-top: -6px;
}

.rtx-app .rtx-hint {
	color: var(--rtx-muted);
	font-size: 13px;
	margin: 0 0 12px;
}

.rtx-app .rtx-lead-in {
	font-size: 16px;
	margin: 0 0 14px;
}

/* -- Dashboard ------------------------------------------------------------ */

.rtx-app .rtx-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 10px;
	margin: 12px 0 18px;
}

/*
 * Each tile owns a colour, and the colour is the meaning — blue for what has
 * arrived, orange for what is late, green for what is in hand. An agent should
 * be able to read this row from across a desk without reading the labels.
 */
.rtx-app .rtx-stat {
	position: relative;
	display: block;
	border: 1px solid var(--rtx-line);
	border-radius: 8px;
	padding: 14px 16px 13px;
	text-decoration: none;
	background: var(--rtx-bg);
	color: var(--rtx-ink);
	overflow: hidden;
	transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}

.rtx-app .rtx-stat::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 3px;
	background: var(--tile, var(--rtx-blue));
}

.rtx-app .rtx-stat:hover {
	border-color: var(--tile, var(--rtx-blue));
	box-shadow: 0 2px 10px rgba(26, 34, 48, .07);
	transform: translateY(-1px);
}

.rtx-app .rtx-stat-n {
	display: block;
	font-size: 28px;
	line-height: 1.1;
	font-weight: 700;
	color: var(--tile, var(--rtx-blue));
	letter-spacing: -.01em;
}

.rtx-app .rtx-stat-new { --tile: var(--rtx-blue); }
.rtx-app .rtx-stat-late { --tile: var(--rtx-orange); }
.rtx-app .rtx-stat-open { --tile: #8a6bbf; }
.rtx-app .rtx-stat-total { --tile: var(--rtx-green); }

/* Nothing overdue is not worth shouting about; grey it down. */
.rtx-app .rtx-stat-late.is-zero { --tile: var(--rtx-faint); }

/*
 * A count that represents a gap rather than an achievement. Used on the alerts
 * screen for "have none" — the number worth acting on, and the one that should
 * not read as a score.
 */
.rtx-app .rtx-stat.is-warn { --tile: var(--rtx-orange); }

.rtx-app .rtx-stat-l {
	display: block;
	font-size: 12px;
	color: var(--rtx-muted);
	margin-top: 2px;
}

.rtx-app .rtx-cols {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: 14px;
	align-items: start;
}

.rtx-app .rtx-list {
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: 14px;
}

.rtx-app .rtx-list li {
	display: flex;
	gap: 8px;
	align-items: baseline;
	flex-wrap: wrap;
	padding: 6px 0;
	margin: 0;
	border-bottom: 1px solid var(--rtx-line);
	list-style: none;
}

.rtx-app .rtx-list li:last-child {
	border-bottom: 0;
}

.rtx-app .rtx-list li.is-overdue .rtx-due {
	color: var(--rtx-warn);
	font-weight: 600;
}

.rtx-app .rtx-when {
	margin-left: auto;
	font-size: 12px;
	color: var(--rtx-muted);
	white-space: nowrap;
}

/* -- Lead page ------------------------------------------------------------ */

.rtx-app .rtx-back {
	margin: 0 0 12px;
	padding-left: 8px;
}

.rtx-app .rtx-back .rtx-icon {
	width: 15px;
	height: 15px;
}

.rtx-app .rtx-lead-bar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 16px;
	flex-wrap: wrap;
	margin-bottom: 14px;
}

.rtx-app .rtx-lead-id {
	display: flex;
	align-items: center;
	gap: 14px;
	min-width: 0;
}

.rtx-app .rtx-avatar-lg {
	width: 52px;
	height: 52px;
	font-size: 18px;
	font-weight: 700;
	letter-spacing: .03em;
	box-shadow: 0 2px 8px rgba(16, 83, 127, .28);
}

.rtx-app .rtx-lead-id-text {
	min-width: 0;
}

/*
 * The title's orange underline earns its keep on a page heading, but here the
 * avatar already anchors the block and a second mark just crowds it.
 */
.rtx-app .rtx-lead-id-text .rtx-page-title {
	margin: 0 0 5px;
	padding-bottom: 0;
	display: flex;
	align-items: center;
	gap: 9px;
	flex-wrap: wrap;
}

.rtx-app .rtx-lead-id-text .rtx-page-title::after {
	display: none;
}

.rtx-app .rtx-lead-sub {
	margin: 0;
	font-size: 13.5px;
	color: var(--rtx-muted);
	display: flex;
	align-items: center;
	gap: 7px;
	flex-wrap: wrap;
}

.rtx-app .rtx-sub-sep {
	color: var(--rtx-faint);
}

.rtx-app .rtx-lead-quick {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	align-items: center;
}

/*
 * Stage and owner are settings, not actions, so they sit below the header in
 * their own tray rather than competing with Call and Email for the eye.
 */
.rtx-app .rtx-lead-controls {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	align-items: center;
	margin-bottom: 16px;
}

.rtx-app .rtx-controlgroup {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	border-radius: 10px;
	padding: 6px 8px 6px 12px;
}

.rtx-app .rtx-controlgroup-label {
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .05em;
	color: var(--rtx-muted);
}

.rtx-app .rtx-controlgroup select {
	min-width: 140px;
}

/* Input and button fused into one control, for "type a thing, add the thing". */
.rtx-app .rtx-addrow {
	display: flex;
	margin: 0;
}

.rtx-app .rtx-addrow input[type="text"] {
	flex: 1 1 auto;
	min-width: 0;
	border-radius: 8px 0 0 8px;
	border-right-color: transparent;
}

.rtx-app .rtx-addrow input[type="text"]:focus {
	border-right-color: var(--rtx-accent);
	position: relative;
	z-index: 1;
}

.rtx-app .rtx-addrow .rtx-btn {
	border-radius: 0 8px 8px 0;
	margin-left: -1px;
}

.rtx-app .rtx-addrow .rtx-btn:hover {
	transform: none;
}

/* -- Logging a call ------------------------------------------------------- */

.rtx-app .rtx-callpanel {
	margin-top: 14px;
}

.rtx-app .rtx-callpanel h3 .rtx-icon {
	width: 15px;
	height: 15px;
	color: var(--rtx-green-ink);
}

/*
 * The note and the button on one line, because at full width a block button
 * under a full-width textarea is a very long way to travel for one click.
 */
.rtx-app .rtx-callform-row {
	display: flex;
	gap: 10px;
	align-items: flex-start;
}

.rtx-app .rtx-callform-row textarea {
	flex: 1 1 auto;
	margin-bottom: 0;
	min-height: 56px;
}

.rtx-app .rtx-callform-row .rtx-btn {
	flex: 0 0 auto;
	min-height: 56px;
	padding-left: 20px;
	padding-right: 20px;
}

@media (max-width: 620px) {
	.rtx-app .rtx-callform-row {
		flex-direction: column;
	}

	.rtx-app .rtx-callform-row .rtx-btn {
		width: 100%;
		min-height: 42px;
	}
}

.rtx-app .rtx-calllog {
	margin-top: 18px;
	border-top: 1px solid var(--rtx-line);
	padding-top: 14px;
}

.rtx-app .rtx-calllog h4 {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 10px;
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .05em;
	color: var(--rtx-muted);
}

/*
 * A fixed viewport onto an unbounded history.
 *
 * Capped in `rem` rather than by a row count, so the panel keeps its height
 * whatever the theme's base font size does — a log measured in rows is a log
 * that swallows the page on someone's 20px body text.
 */
.rtx-app .rtx-calllog-scroll {
	list-style: none;
	margin: 0;
	padding: 0;
	max-height: 22rem;
	overflow-y: auto;
	overscroll-behavior: contain;
	border: 1px solid var(--rtx-line);
	border-radius: 10px;
	background: var(--rtx-bg);
}

/* Focusable, because a scroll region a keyboard cannot reach is a trap. */
.rtx-app .rtx-calllog-scroll:focus-visible {
	outline: 2px solid var(--rtx-accent);
	outline-offset: 2px;
}

.rtx-app .rtx-calllog-scroll li {
	padding: 11px 13px;
	font-size: 14px;
	border-bottom: 1px solid var(--rtx-line);
}

/* No trailing rule — a separator after the last entry is a line to nowhere. */
.rtx-app .rtx-calllog-scroll li:last-child {
	border-bottom: 0;
}

.rtx-app .rtx-calllog-head {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
}

.rtx-app .rtx-calllog-when {
	color: var(--rtx-muted);
	font-size: 13px;
	white-space: nowrap;
}

.rtx-app .rtx-calllog-who {
	color: var(--rtx-faint);
	font-size: 12px;
}

/* Pushed to the right so the row's meaning is read before its controls. */
.rtx-app .rtx-calllog-del {
	margin: 0 0 0 auto;
}

.rtx-app .rtx-calllog-note {
	margin: 6px 0 0;
	color: var(--rtx-ink);
	line-height: 1.45;
}

.rtx-app .rtx-calllog-empty {
	margin: 14px 0 0;
	font-size: 13px;
}

/*
 * A destructive control that stays quiet until you are on the row. Always-red
 * delete icons down a list read as a column of warnings and pull the eye away
 * from the content they belong to.
 */
.rtx-app .rtx-iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 1px solid transparent;
	border-radius: 7px;
	background: none;
	color: var(--rtx-faint);
	cursor: pointer;
	font-family: inherit;
	transition: background-color .13s ease, color .13s ease, border-color .13s ease;
}

.rtx-app .rtx-calllog-scroll li:hover .rtx-iconbtn {
	color: var(--rtx-muted);
}

.rtx-app .rtx-iconbtn:hover {
	background: #fbeceb;
	border-color: #e7c9c5;
	color: var(--rtx-warn);
}

.rtx-app .rtx-iconbtn:focus-visible {
	outline: 2px solid var(--rtx-accent);
	outline-offset: 1px;
}

.rtx-app .rtx-iconbtn .rtx-icon {
	width: 15px;
	height: 15px;
}

/* -- RelScore ------------------------------------------------------------- */

.rtx-app .rtx-score-col {
	width: 46px;
	text-align: center;
}

/*
 * A filled disc, not a bar or a star rating. The number is the content and a
 * whole page of them has to be comparable at a glance, in the same position on
 * every row — which is what a fixed-width disc buys and a bar does not.
 */
.rtx-app .rtx-score {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	font-size: 13px;
	font-weight: 700;
	background: var(--rtx-soft);
	color: var(--rtx-faint);
}

.rtx-app .rtx-scorepanel .rtx-hint {
	margin: 4px 0 0;
}

.rtx-app .rtx-scorehead {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-bottom: 12px;
}

.rtx-app .rtx-scoredial {
	flex: 0 0 auto;
	width: 58px;
	height: 58px;
	border-radius: 50%;
	display: flex;
	align-items: baseline;
	justify-content: center;
	gap: 1px;
	background: var(--rtx-soft);
	color: var(--rtx-faint);
}

.rtx-app .rtx-scoredial strong {
	font-size: 24px;
	font-weight: 700;
	line-height: 1;
}

.rtx-app .rtx-scoredial span {
	font-size: 11px;
	opacity: .75;
}

/*
 * The working, not just the answer. This list is the difference between a
 * score an agent argues with and one they ignore.
 */
.rtx-app .rtx-scorewhy {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 1px;
}

.rtx-app .rtx-scorewhy li {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 12px;
	padding: 5px 8px;
	border-radius: 6px;
	font-size: 13.5px;
}

.rtx-app .rtx-scorewhy li:nth-child(odd) {
	background: var(--rtx-soft);
}

.rtx-app .rtx-scorewhy strong {
	color: var(--rtx-green-ink);
	font-size: 13px;
	white-space: nowrap;
}

.rtx-app .rtx-scoreat,
.rtx-app .rtx-scorepartial {
	margin: 10px 0 0;
	font-size: 12px;
	color: var(--rtx-faint);
}

.rtx-app .rtx-scorepartial {
	color: var(--rtx-orange-ink);
}

/* -- Listings ------------------------------------------------------------- */

/*
 * One per line.
 *
 * Two columns fits more on screen and reads worse: an agent scanning inventory
 * is comparing price and address down a column, and a two-up grid makes that a
 * zigzag. A row is also wide enough to carry the share controls inline instead
 * of stacking them under every card.
 */
.rtx-app .rtx-listings {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-bottom: 18px;
}

.rtx-app .rtx-listing {
	display: flex;
	gap: 0;
	border: 1px solid var(--rtx-line);
	border-radius: 12px;
	background: var(--rtx-bg);
	overflow: hidden;
	box-shadow: 0 1px 2px rgba(26, 34, 48, .05), 0 4px 14px rgba(26, 34, 48, .05);
}

/*
 * A fixed photo column rather than a full-bleed image on top. A listing card is
 * read for its price and address; the photo is recognition, not the content,
 * and giving it the top half pushes the facts below the fold of the card.
 */
.rtx-app .rtx-listing-photo {
	flex: 0 0 150px;
	width: 150px;
	min-height: 112px;
	object-fit: cover;
	align-self: stretch;
	background: var(--rtx-soft);
}

/*
 * A photo is recognition, not content: at a narrow width the address has to
 * win, so the thumbnail shrinks rather than the text wrapping to nothing.
 */
@media (max-width: 640px) {
	.rtx-app .rtx-listing-photo {
		flex-basis: 96px;
		width: 96px;
		min-height: 88px;
	}
}

.rtx-app .rtx-listing-body {
	min-width: 0;
	padding: 12px 14px;
	flex: 1 1 auto;
}

.rtx-app .rtx-listing-head {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	margin-bottom: 4px;
}

.rtx-app .rtx-listing-head strong {
	font-size: 17px;
	letter-spacing: -.01em;
}

.rtx-app .rtx-listing-address {
	margin: 0 0 4px;
	font-size: 14px;
	line-height: 1.4;
}

.rtx-app .rtx-listing-town {
	display: block;
	color: var(--rtx-muted);
	font-size: 13px;
}

.rtx-app .rtx-listing-facts {
	margin: 0 0 6px;
	color: var(--rtx-muted);
	font-size: 13px;
}

.rtx-app .rtx-listing-sold {
	margin: 0 0 6px;
	color: var(--rtx-green-ink);
	font-size: 13px;
	font-weight: 600;
}

.rtx-app .rtx-listing-notes {
	margin: 0 0 6px;
	padding-left: 9px;
	border-left: 2px solid var(--rtx-line);
	color: var(--rtx-muted);
	font-size: 13px;
}

.rtx-app .rtx-listing-meta {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	margin: 0;
	font-size: 12px;
}

.rtx-app .rtx-alertform {
	margin: 0;
}

/* -- Training and tips ---------------------------------------------------- */

.rtx-app .rtx-guides {
	display: grid;
	gap: 8px;
}

.rtx-app .rtx-guide {
	display: flex;
	gap: 13px;
	align-items: flex-start;
	padding: 13px 14px;
	border: 1px solid var(--rtx-line);
	border-radius: 10px;
	background: var(--rtx-bg);
	text-decoration: none;
	color: var(--rtx-ink);
	transition: border-color .13s ease, box-shadow .13s ease, transform .13s ease;
}

.rtx-app .rtx-guide:hover {
	border-color: #cfd6e0;
	box-shadow: 0 2px 8px rgba(26, 34, 48, .08);
	transform: translateY(-1px);
	color: var(--rtx-ink);
}

/*
 * A numbered disc, because in training the order is the content — "read these
 * four in this order" is a different instruction from "here are four articles".
 */
.rtx-app .rtx-guide-step {
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	border-radius: 50%;
	background: var(--rtx-accent-soft);
	color: var(--rtx-accent-ink);
	font-size: 13px;
	font-weight: 700;
	display: flex;
	align-items: center;
	justify-content: center;
}

.rtx-app .rtx-guide-text {
	min-width: 0;
	display: block;
}

.rtx-app .rtx-guide-text strong {
	display: block;
	font-size: 15px;
	margin-bottom: 3px;
}

.rtx-app .rtx-guide-excerpt {
	display: block;
	color: var(--rtx-muted);
	font-size: 13.5px;
	line-height: 1.45;
}

.rtx-app .rtx-guide-topics {
	display: block;
	margin-top: 7px;
}

/*
 * Prose, not app chrome. Narrower measure and looser leading than the rest of
 * the interface, because this is the one place in the product someone reads
 * rather than scans.
 */
.rtx-app .rtx-article {
	max-width: 44rem;
}

.rtx-app .rtx-article p,
.rtx-app .rtx-article li {
	font-size: 15.5px;
	line-height: 1.65;
}

.rtx-app .rtx-article h2:not(.rtx-page-title),
.rtx-app .rtx-article h3,
.rtx-app .rtx-article h4 {
	margin: 26px 0 8px;
	line-height: 1.3;
}

.rtx-app .rtx-article h3::before {
	display: none;
}

.rtx-app .rtx-article-meta {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	margin: -4px 0 16px;
	color: var(--rtx-muted);
	font-size: 13px;
}

.rtx-app .rtx-article-image {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 10px;
	margin: 0 0 18px;
}

.rtx-app .rtx-article blockquote {
	margin: 18px 0;
	padding: 2px 0 2px 16px;
	border-left: 3px solid var(--rtx-orange);
	color: var(--rtx-muted);
}

/* -- Communication plans -------------------------------------------------- */

.rtx-app .rtx-stepform {
	margin-top: 16px;
	padding-top: 16px;
	border-top: 1px solid var(--rtx-line);
}

.rtx-app .rtx-stepform h4 {
	margin: 0 0 12px;
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .05em;
	color: var(--rtx-muted);
}

/*
 * The wording a step actually sends, under its label. Indented and quieter
 * than the label because it is the detail you check, not the thing you scan.
 */
.rtx-app .rtx-steppreview {
	display: block;
	margin-top: 5px;
	padding-left: 10px;
	border-left: 2px solid var(--rtx-line);
	font-size: 13px;
	color: var(--rtx-muted);
	white-space: pre-wrap;
}

.rtx-app .rtx-steppreview-warn {
	border-left-color: var(--rtx-orange);
	color: var(--rtx-orange-ink);
}

/* -- Website activity ----------------------------------------------------- */

.rtx-app .rtx-day + .rtx-day {
	margin-top: 18px;
}

.rtx-app .rtx-day-head {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 8px;
	padding-bottom: 7px;
	border-bottom: 1px solid var(--rtx-line);
	font-size: 13px;
	font-weight: 700;
	color: var(--rtx-ink);
}

.rtx-app .rtx-act-link {
	font-size: 12px;
	margin-left: 8px;
	white-space: nowrap;
}

/* -- Badges --------------------------------------------------------------- */

.rtx-app .rtx-badge {
	display: inline-flex;
	align-items: center;
	border-radius: 20px;
	padding: 3px 11px;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .01em;
	line-height: 1.5;
	white-space: nowrap;
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	color: var(--rtx-muted);
}

.rtx-app .rtx-badge-muted {
	text-transform: uppercase;
	font-size: 11px;
	letter-spacing: .05em;
}

/*
 * Stage colours run cold to warm: a new lead is neutral, one being worked is
 * live, one that converted is green, one that went nowhere fades out. The
 * agent should be able to read the pipeline without reading the words.
 */
.rtx-app .rtx-badge-stage {
	background: var(--rtx-blue-soft);
	border-color: transparent;
	color: var(--rtx-blue-ink);
}

.rtx-app .rtx-stage-working,
.rtx-app .rtx-stage-nurturing {
	background: var(--rtx-orange-soft);
	color: var(--rtx-orange-ink);
}

.rtx-app .rtx-stage-won,
.rtx-app .rtx-stage-closed {
	background: var(--rtx-green-soft);
	color: var(--rtx-green-ink);
}

.rtx-app .rtx-stage-lost,
.rtx-app .rtx-stage-dead {
	background: var(--rtx-soft);
	color: var(--rtx-faint);
}

/*
 * Call outcomes read at a glance: green means you reached them, amber means you
 * tried, grey means the number is no good. Scanning a log for "when did I last
 * actually speak to this person" should not require reading four words a row.
 */
.rtx-app .rtx-outcome {
	background: var(--rtx-soft);
	border-color: transparent;
	color: var(--rtx-muted);
	font-size: 11.5px;
}

.rtx-app .rtx-outcome-connected {
	background: var(--rtx-green-soft);
	color: var(--rtx-green-ink);
}

.rtx-app .rtx-outcome-voicemail,
.rtx-app .rtx-outcome-no_answer {
	background: var(--rtx-orange-soft);
	color: var(--rtx-orange-ink);
}

.rtx-app .rtx-outcome-bad_number {
	background: #fbeceb;
	color: #8a2b20;
}

/*
 * Website activity, coloured by what it means rather than where it came from.
 *
 * Looking is neutral, viewing a specific home is warm, saving anything is blue
 * — a saved search or a saved home is the lead asking to be contacted again,
 * and it should not carry the same weight as a page view in a list you are
 * scanning for a reason to call.
 *
 * These live in this block, after `.rtx-badge`, rather than beside the rest of
 * the activity styles. Same specificity as `.rtx-badge`, so whichever is
 * written later wins — and defined earlier they silently lost their colour.
 */
.rtx-app .rtx-act {
	font-size: 11px;
	background: var(--rtx-soft);
	border-color: transparent;
	color: var(--rtx-muted);
}

.rtx-app .rtx-act-idx-search-saved,
.rtx-app .rtx-act-idx-property-saved {
	background: var(--rtx-blue-soft);
	color: var(--rtx-blue-ink);
}

.rtx-app .rtx-act-traffic-property-view {
	background: var(--rtx-green-soft);
	color: var(--rtx-green-ink);
}

/*
 * Who performs a plan step. Automatic is blue because it is the one that acts
 * without anyone watching, and that is the fact worth spotting when a broker
 * scans a plan they are about to turn loose on the whole book.
 *
 * Here rather than beside the plan styles, for the same reason as the others:
 * these tie with `.rtx-badge` on specificity, so they must be written after it.
 */
.rtx-app .rtx-mode {
	font-size: 11px;
	background: var(--rtx-soft);
	border-color: transparent;
	color: var(--rtx-muted);
}

.rtx-app .rtx-mode-auto {
	background: var(--rtx-blue-soft);
	color: var(--rtx-blue-ink);
}

/*
 * Listing status. Green is available, amber is spoken for, grey is gone —
 * the same cold-to-warm logic as the lead stages, so one glance across the
 * grid says what is sellable without reading a word.
 */
.rtx-app .rtx-lstatus {
	font-size: 11px;
	background: var(--rtx-soft);
	border-color: transparent;
	color: var(--rtx-muted);
}

.rtx-app .rtx-lstatus-active {
	background: var(--rtx-green-soft);
	color: var(--rtx-green-ink);
}

.rtx-app .rtx-lstatus-pending,
.rtx-app .rtx-lstatus-contingent,
.rtx-app .rtx-lstatus-coming {
	background: var(--rtx-orange-soft);
	color: var(--rtx-orange-ink);
}

.rtx-app .rtx-lstatus-sold {
	background: var(--rtx-blue-soft);
	color: var(--rtx-blue-ink);
}

/*
 * Score bands. Warm-to-cold, matching stages and call outcomes so the whole
 * app teaches one colour language rather than four.
 */
.rtx-app .rtx-score-hot {
	background: var(--rtx-orange);
	color: #fff;
}

.rtx-app .rtx-score-warm {
	background: var(--rtx-orange-soft);
	color: var(--rtx-orange-ink);
}

.rtx-app .rtx-score-cool {
	background: var(--rtx-blue-soft);
	color: var(--rtx-blue-ink);
}

.rtx-app .rtx-score-cold {
	background: var(--rtx-soft);
	color: var(--rtx-faint);
}

/*
 * Sharing a listing.
 *
 * Three ways out, in the order an agent reaches for them: look at it, copy the
 * link, hand it to somebody. The address sits in a readonly field rather than
 * behind the copy button alone — the button is hidden until the JavaScript that
 * makes it work has run, and a link you can select by hand is the floor.
 */
/*
 * A label, one field and a button on one line — the shape of every "do this
 * one thing now" control in the app. Wraps rather than shrinking the input on
 * a narrow screen, because an MLS number typed into a 40px box is a typo
 * waiting to happen.
 */
.rtx-app .rtx-inline-form {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin: 4px 0 6px;
}

.rtx-app .rtx-inline-form input[type="text"] {
	min-width: 160px;
}

.rtx-app .rtx-share {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px solid var(--rtx-line);
}

.rtx-app .rtx-share-url {
	flex: 1 1 180px;
	min-width: 0;
	font-size: 12px;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	color: var(--rtx-muted);
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	border-radius: 6px;
	padding: 5px 8px;
}

.rtx-app .rtx-share-off {
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px solid var(--rtx-line);
}

/* The summary is styled as a button, so it must not also show a marker. */
.rtx-app .rtx-share-send > summary {
	list-style: none;
	cursor: pointer;
}

.rtx-app .rtx-share-send > summary::-webkit-details-marker {
	display: none;
}

.rtx-app .rtx-share-form {
	display: grid;
	gap: 6px;
	margin-top: 8px;
	padding: 10px;
	background: var(--rtx-soft);
	border-radius: 8px;
}

.rtx-app .rtx-share-label {
	font-size: 12px;
	font-weight: 600;
	color: var(--rtx-muted);
}

/*
 * Texting permission. Green is a yes, red is a recorded no, grey is nobody has
 * asked — and grey is the common case, so it must not read as an alarm.
 *
 * The distinction between "they said stop" and "we never asked" is the point of
 * having three states rather than two: only one of them is something an agent
 * can do anything about.
 *
 * After `.rtx-badge`, like every other variant: same specificity, source order.
 */
.rtx-app .rtx-cons {
	font-size: 11px;
	background: var(--rtx-soft);
	border-color: transparent;
	color: var(--rtx-muted);
}

.rtx-app .rtx-cons-granted {
	background: var(--rtx-green-soft);
	color: var(--rtx-green-ink);
}

.rtx-app .rtx-cons-withdrawn {
	background: #fbeceb;
	color: #8a2b20;
}

.rtx-app .rtx-consent {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin: 14px 0 0;
	padding-top: 14px;
	border-top: 1px solid var(--rtx-line);
}

.rtx-app .rtx-consent-detail {
	color: var(--rtx-muted);
	font-size: 12.5px;
}

.rtx-app .rtx-consent-form {
	margin-left: auto;
}

.rtx-app .rtx-consent-hint {
	margin-top: 6px;
}

/*
 * What happened to an email after it left.
 *
 * Read is the only good outcome and gets the warm colour; bounced and
 * complained are red because both are things the agent has to act on rather
 * than merely notice — a bounce means the address is wrong and a complaint
 * means stop. Delivered is deliberately quiet: it is the expected case, and
 * colouring the normal thing trains people to ignore colour.
 *
 * After `.rtx-badge` for the usual reason: same specificity, source order wins.
 */
.rtx-app .rtx-dstate {
	font-size: 11px;
	background: var(--rtx-soft);
	border-color: transparent;
	color: var(--rtx-muted);
}

.rtx-app .rtx-dstate-opened,
.rtx-app .rtx-dstate-clicked {
	background: var(--rtx-green-soft);
	color: var(--rtx-green-ink);
}

.rtx-app .rtx-dstate-soft_bounced {
	background: var(--rtx-orange-soft);
	color: var(--rtx-orange-ink);
}

.rtx-app .rtx-dstate-bounced,
.rtx-app .rtx-dstate-complained {
	background: #fbeceb;
	color: #8a2b20;
}

/*
 * Tabs as a segmented bar rather than an underline.
 *
 * The active tab is a raised white card inside a recessed track, which says
 * "one of these is selected" at a glance and from across a desk. An underline
 * says it too, but only once you are already reading.
 */
.rtx-app .rtx-tabs {
	display: flex;
	gap: 3px;
	flex-wrap: wrap;
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	border-radius: 11px;
	padding: 4px;
	margin-bottom: 18px;
}

.rtx-app .rtx-tabs a {
	display: flex;
	gap: 7px;
	align-items: center;
	padding: 7px 14px;
	border-radius: 8px;
	text-decoration: none;
	color: var(--rtx-muted);
	font-size: 14px;
	font-weight: 600;
	border: 1px solid transparent;
	transition: background-color .13s ease, color .13s ease, box-shadow .13s ease;
}

.rtx-app .rtx-tabs a:hover {
	color: var(--rtx-ink);
	background: rgba(255, 255, 255, .7);
}

.rtx-app .rtx-tabs a.is-active {
	color: var(--rtx-ink);
	background: var(--rtx-bg);
	border-color: var(--rtx-line);
	box-shadow: 0 1px 3px rgba(26, 34, 48, .1);
}

.rtx-app .rtx-count-pill {
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	border-radius: 20px;
	padding: 1px 7px;
	font-size: 11px;
	font-weight: 700;
	color: var(--rtx-muted);
}

/*
 * "See what it finds" sits on the end of the search's own description, which
 * now carries its price band and bedroom count — so it needs a gap, or the
 * link runs straight into "1 city" and reads as part of it.
 */
.rtx-app .rtx-alert-open {
	margin-left: 8px;
	white-space: nowrap;
}

/*
 * A repeat count on a folded timeline line. Tinted rather than grey: it is
 * the one number on that row an agent is looking for, and the day head beside
 * it already wears the plain pill for the day's total.
 */
.rtx-app .rtx-count-times {
	background: var(--rtx-accent-soft);
	border-color: transparent;
	color: var(--rtx-accent);
}

/* On the selected tab the pill has to invert, or it disappears into the card. */
.rtx-app .rtx-tabs a.is-active .rtx-count-pill {
	background: var(--rtx-accent-soft);
	border-color: transparent;
	color: var(--rtx-accent-ink);
}

.rtx-app .rtx-radios {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: 10px;
	font-size: 14px;
}

.rtx-app .rtx-radios label {
	display: flex;
	gap: 4px;
	align-items: center;
}

/*
 * Segmented control.
 *
 * Still radio inputs underneath — that is what makes it work with JavaScript
 * off and announce correctly to a screen reader. The input is hidden visually
 * but never with `display: none`, which would take it out of the tab order and
 * leave a keyboard user with no way to choose an outcome at all.
 */
/*
 * A grid, not flex-wrap. With four options in a narrow column, wrapping gives
 * you one full-width item, then two, then one — a ragged shape that reads as a
 * mistake. auto-fit lands on two even columns here and one row when there is
 * space, without anyone counting the options.
 */
.rtx-app .rtx-segmented {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
	gap: 3px;
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	border-radius: 10px;
	padding: 3px;
	margin-bottom: 12px;
}

.rtx-app .rtx-seg {
	margin: 0;
	position: relative;
}

.rtx-app .rtx-seg input {
	position: absolute;
	opacity: 0;
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	margin: 0;
	cursor: pointer;
}

.rtx-app .rtx-seg span {
	display: block;
	text-align: center;
	padding: 7px 10px;
	border-radius: 7px;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--rtx-muted);
	border: 1px solid transparent;
	transition: background-color .13s ease, color .13s ease, box-shadow .13s ease;
}

.rtx-app .rtx-seg input:hover + span {
	color: var(--rtx-ink);
	background: rgba(255, 255, 255, .7);
}

.rtx-app .rtx-seg input:checked + span {
	background: var(--rtx-bg);
	border-color: var(--rtx-line);
	color: var(--rtx-ink);
	box-shadow: 0 1px 3px rgba(26, 34, 48, .1);
}

/* The ring goes on the visible label, since the input itself is transparent. */
.rtx-app .rtx-seg input:focus-visible + span {
	outline: 2px solid var(--rtx-accent);
	outline-offset: 1px;
}

/* -- Tags ----------------------------------------------------------------- */

.rtx-app .rtx-tagrow {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0 0 10px;
}

.rtx-app .rtx-chip {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	background: var(--rtx-blue-soft);
	border: 1px solid #a9cee9;
	border-radius: 12px;
	padding: 1px 3px 1px 10px;
	font-size: 13px;
	line-height: 1.7;
	color: var(--rtx-blue-ink);
	white-space: nowrap;
}

/*
 * The remove button lives in its own form (it is a POST), and a form defaults
 * to a block-level flex item — which pushed the × out of the pill and onto the
 * next one. Making it an inline-flex item keeps it inside its own chip.
 */
.rtx-app .rtx-chip form {
	display: inline-flex;
	margin: 0;
}

.rtx-app .rtx-chip-x {
	background: none;
	border: 0;
	cursor: pointer;
	color: var(--rtx-blue-ink);
	font-size: 15px;
	line-height: 1;
	padding: 0 4px;
}

.rtx-app .rtx-chip-x:hover {
	color: var(--rtx-warn);
}

/* -- Forms ---------------------------------------------------------------- */

.rtx-app .rtx-field {
	display: block;
	margin-bottom: 12px;
	min-width: 0;
}

.rtx-app .rtx-field > span,
.rtx-app .rtx-field > label {
	display: block;
	font-size: 13px;
	font-weight: 600;
	color: var(--rtx-ink);
	margin-bottom: 5px;
}

.rtx-app .rtx-field > small {
	display: block;
	font-size: 12px;
	color: var(--rtx-faint);
	margin-top: 4px;
	line-height: 1.4;
}

.rtx-app .rtx-field input[type="text"],
.rtx-app .rtx-field input[type="email"],
.rtx-app .rtx-field input[type="url"],
.rtx-app .rtx-field input[type="tel"],
.rtx-app .rtx-field textarea,
.rtx-app .rtx-field select {
	width: 100%;
}

/*
 * A long settings form as a stack of cards rather than one wall of inputs.
 * The account screen has upwards of forty fields on it; grouped into headed
 * panels it reads as five short forms, which is the difference between a page
 * someone fills in and one they close.
 */
.rtx-app .rtx-formsheet {
	display: grid;
	gap: 14px;
	margin-bottom: 26px;
}

.rtx-app .rtx-fieldgrid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
	gap: 0 16px;
}

/* A textarea wants the full width whatever the grid is doing around it. */
.rtx-app .rtx-fieldgrid .rtx-field:has(textarea) {
	grid-column: 1 / -1;
}

/*
 * A save bar that follows you down a long form.
 *
 * Opaque and bordered rather than faded into a gradient: sticky content that
 * is partly transparent overlaps whatever scrolls beneath it and reads as a
 * rendering fault. It needs to look like a bar that belongs there.
 */
.rtx-app .rtx-formsheet-save {
	position: sticky;
	bottom: 0;
	z-index: 2;
	display: flex;
	justify-content: flex-end;
	padding: 12px 14px;
	background: var(--rtx-bg);
	border: 1px solid var(--rtx-line);
	border-radius: 12px;
	box-shadow: 0 -2px 10px rgba(26, 34, 48, .07);
}

/* -- Merge field reference ------------------------------------------------ */

/*
 * Wider columns than the default card grid. A token and its description on one
 * line needs the room; squeezed into a third of the page the description wraps
 * to four lines and the list stops being scannable, which is the only thing a
 * reference list is for.
 */
/*
 * The token list where it is typed rather than a page away.
 *
 * Folded shut, because an agent writing their fourth step already knows the
 * fields and a forty-row table above the Add button would be in the way every
 * time. Open, it wants to read as reference and not as more form.
 */
/*
 * The call script on a task.
 *
 * Folded shut so a list of ten tasks stays a list; open, it is what a new agent
 * reads while the phone rings. Set in the reading face rather than the UI one,
 * because it is meant to be spoken from.
 */
.rtx-app .rtx-script > summary {
	cursor: pointer;
	font-size: 12px;
	color: var(--rtx-faint);
}

.rtx-app .rtx-script-body {
	margin-top: 6px;
	padding: 10px 12px;
	border-left: 3px solid var(--rtx-line);
	background: var(--rtx-soft);
	border-radius: 0 8px 8px 0;
	font-size: 14px;
	line-height: 1.55;
	max-width: 62ch;
	white-space: normal;
}

.rtx-app .rtx-tokens-inline > summary {
	cursor: pointer;
	font-weight: 600;
	padding: 6px 0;
}

.rtx-app .rtx-tokens-inline h4 {
	margin: 12px 0 4px;
	font-size: 13px;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--rtx-faint);
}

.rtx-app .rtx-cols-wide {
	display: grid;
	gap: 14px;
	grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
	align-items: start;
	margin-bottom: 18px;
}

.rtx-app .rtx-tokens {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 6px 14px;
	margin: 0;
	font-size: 13px;
	align-items: baseline;
}

.rtx-app .rtx-tokens dt {
	margin: 0;
}

.rtx-app .rtx-tokens dd {
	margin: 0;
	color: var(--rtx-muted);
}

.rtx-app .rtx-tokens code {
	background: var(--rtx-soft);
	border: 1px solid var(--rtx-line);
	border-radius: 5px;
	padding: 1px 6px;
	font-size: 12px;
	color: var(--rtx-accent-ink);
	white-space: nowrap;
}

.rtx-app .rtx-pair {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: 0 12px;
}

.rtx-app .rtx-check {
	display: flex;
	gap: 8px;
	align-items: center;
	margin-bottom: 8px;
	font-size: 14px;
}

.rtx-app .rtx-row-actions {
	display: flex;
	gap: 10px;
	white-space: nowrap;
}

/* -- Reports -------------------------------------------------------------- */

.rtx-app .rtx-bars {
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: 13px;
}

.rtx-app .rtx-bars li {
	display: grid;
	grid-template-columns: 110px minmax(0, 1fr) 48px;
	gap: 8px;
	align-items: center;
	margin: 0 0 5px;
	list-style: none;
}

.rtx-app .rtx-bar-l {
	color: var(--rtx-muted);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.rtx-app .rtx-bar {
	display: block;
	background: var(--rtx-soft);
	border-radius: 3px;
	height: 14px;
	overflow: hidden;
}

.rtx-app .rtx-bar i {
	display: block;
	height: 100%;
	background: linear-gradient(90deg, var(--rtx-blue) 0%, #3d95d8 100%);
	border-radius: 3px;
}

.rtx-app .rtx-bar-n {
	text-align: right;
	color: var(--rtx-muted);
}

.rtx-app .rtx-spark {
	list-style: none;
	margin: 10px 0;
	padding: 0;
	display: flex;
	align-items: flex-end;
	gap: 2px;
	height: 90px;
}

.rtx-app .rtx-spark li {
	flex: 1 1 auto;
	height: 100%;
	display: flex;
	align-items: flex-end;
	margin: 0;
	list-style: none;
}

.rtx-app .rtx-spark i {
	display: block;
	width: 100%;
	background: linear-gradient(180deg, #3d95d8 0%, var(--rtx-blue) 100%);
	border-radius: 2px 2px 0 0;
}

.rtx-app .rtx-soon-panel {
	max-width: 640px;
}

@media (max-width: 782px) {
	/*
	 * `minmax(0, 1fr)` and not `1fr`. A bare `1fr` track takes an automatic
	 * minimum of min-content, and the min-content of a `white-space: nowrap`
	 * table is the whole table — so the column grew to the widest row and the
	 * page itself scrolled sideways on a phone, which is the exact thing the
	 * table's own scroll box exists to prevent. The desktop rule above always
	 * had the `minmax`; this one did not.
	 */
	.rtx-app .rtx-shell {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * On a phone the sidebar becomes a scrolling row of pills. Agents use this
	 * between showings with one hand, so the targets stay full size and the
	 * group headings go away rather than stacking into a wall of labels.
	 */
	.rtx-app .rtx-side {
		position: static;
		min-height: 0;
		border-right: 0;
		border-bottom: 1px solid var(--rtx-line);
		padding: 0 0 10px;
		gap: 10px;
	}

	.rtx-app .rtx-side-nav {
		flex-direction: row;
		gap: 0;
		overflow-x: auto;
		scrollbar-width: none;
	}

	.rtx-app .rtx-side-nav::-webkit-scrollbar {
		display: none;
	}

	.rtx-app .rtx-side-group h4 {
		display: none;
	}

	.rtx-app .rtx-side ul {
		flex-direction: row;
		gap: 4px;
	}

	.rtx-app .rtx-side a {
		white-space: nowrap;
	}

	.rtx-app .rtx-soon {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.rtx-app .rtx-side a,
	.rtx-app .rtx-icon {
		transition: none;
	}
}

/* -- Sign in / out -------------------------------------------------------- */

.rtx-app .rtx-signin {
	max-width: 380px;
	margin: 32px auto;
	padding: 28px 28px 22px;
	border: 1px solid var(--rtx-line);
	border-radius: 10px;
	background: var(--rtx-bg);
	box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 8px 24px rgba(16, 24, 40, .05);
}

.rtx-app .rtx-signin h2 {
	margin: 0 0 4px;
	font-size: 20px;
}

.rtx-app .rtx-signin .rtx-hint {
	margin-bottom: 18px;
}

.rtx-app .rtx-btn-wide {
	width: 100%;
	text-align: center;
	padding: 9px 12px;
	font-size: 15px;
}

.rtx-app .rtx-signin-foot {
	margin: 14px 0 0;
	text-align: center;
	font-size: 13px;
}

.rtx-app .rtx-signout {
	margin-left: auto;
	display: flex;
}

.rtx-app .rtx-signout button {
	background: none;
	border: 0;
	padding: 4px;
	border-radius: 5px;
	cursor: pointer;
	color: var(--rtx-faint);
	display: flex;
	transition: color .12s ease, background-color .12s ease;
}

.rtx-app .rtx-signout button:hover {
	color: var(--rtx-warn);
	background: #fff;
}

/* Reduced motion: the tile lift is decoration, not information. */
@media (prefers-reduced-motion: reduce) {
	.rtx-app .rtx-stat {
		transition: none;
	}

	.rtx-app .rtx-stat:hover {
		transform: none;
	}
}

.rtx-app .rtx-inline-label {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 13px;
	color: var(--rtx-muted);
}

/* -- Bulk actions --------------------------------------------------------- */

.rtx-app .rtx-bulkbar {
	display: flex;
	gap: 8px;
	align-items: center;
	flex-wrap: wrap;
	padding: 9px 12px;
	margin-bottom: 8px;
	border: 1px solid var(--rtx-line);
	border-radius: 7px;
	background: var(--rtx-soft);
}

.rtx-app .rtx-bulk-count {
	font-size: 13px;
	font-weight: 600;
	color: var(--rtx-muted);
	min-width: 96px;
}

.rtx-app .rtx-bulk-warn {
	font-size: 12px;
	color: var(--rtx-warn);
	font-weight: 600;
}

.rtx-app .rtx-check-col {
	width: 30px;
	padding-right: 0;
}

.rtx-app .rtx-check-col input[type="checkbox"] {
	margin: 2px 0 0;
	vertical-align: top;
}
