/**
 * Tribal Order Vault — Trading Post messaging.
 * =============================================================================
 * "The Vault Ledger" applied to a conversation: gold leaf on obsidian, sharp
 * corners, hairline rules. A thread reads as an entry in a bound ledger rather
 * than a chat app — the messages here are the record if a trade goes wrong, and
 * the surface should feel like it knows that.
 *
 * TWO SCOPES, DELIBERATELY SEPARATE:
 *   .tov-msg   member-facing, inside the dark Trading Post shell.
 *   .tov-modq  the wp-admin moderation queue, on WordPress's own light chrome.
 * They share a vocabulary, not a palette. Dropping obsidian into wp-admin would
 * make the queue look like a different product bolted on.
 *
 * NO PALETTE IS DECLARED HERE. marketplace.css puts the Vault Ledger tokens on
 * `.tov-mkt`, which wraps every surface this file styles (the hub shell and the
 * listing single alike), so they arrive by inheritance. Restating them would be
 * a second palette to keep in sync, and the first one to drift. Only genuinely
 * new values are declared, namespaced `--tov-msg-*` / `--tov-modq-*`. The one
 * exception is `--tov-text-xs`, which exists in database.css's scale but was not
 * carried into marketplace.css.
 *
 * Buttons, notices, and empty states are `.tov-mkt__*` components owned by
 * marketplace.css. This file adds no second button.
 *
 * A URL in a message is inert text (the PHP never emits an anchor). It is styled
 * to LOOK unclickable on purpose: a member who can see that this platform never
 * makes links is a member who notices when something else does.
 * =============================================================================
 */

/* ---------------------------------------------------------------------------
 * Member surface
 * ------------------------------------------------------------------------- */
.tov-msg {
	/* New to this component. Status colors join the token set rather than being
	 * spelled out at each use. Only the warm plate behind a member's own message
	 * is a genuinely new value; the rest point back at the Ledger palette. */
	--tov-msg-own-bg: #1d1810;
	--tov-msg-own-edge: rgba(212, 162, 78, 0.42);
	--tov-msg-other-bg: var(--tov-surface-2);
	--tov-msg-other-edge: rgba(244, 241, 234, 0.12);
	/* Alert red since 0.17.0, matching .tov-mkt__pip on the hub's tabs — the
	   two count pips are one notification language and recolor together. */
	--tov-msg-unread: var(--tov-alert);
	--tov-msg-inert: #b9b3a7;

	width: 100%;
}

/* AA note for everything below: --tov-text-dim clears 4.5:1 only on the darkest
 * plate (--tov-bg), so it is used for text sitting directly on the page.
 * Anything on a raised surface uses --tov-text-muted, which holds ~6.3:1 there. */

.tov-msg a:focus-visible,
.tov-msg button:focus-visible,
.tov-msg summary:focus-visible,
.tov-msg textarea:focus-visible {
	outline: 2px solid var(--tov-focus);
	outline-offset: 2px;
}

/* ---------------------------------------------------------- conversation list */

.tov-msg__list {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--tov-line);
}

.tov-msg__row {
	border-bottom: 1px solid var(--tov-line);
	/* The spine every row reserves and only an unread one lights up (see
	   .is-unread below). Held transparent on all rows so lighting it never
	   shunts a row's text 3px off the rail its neighbours sit on. */
	border-left: 3px solid transparent;
}

.tov-msg__row-link {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: var(--tov-space-1) var(--tov-space-4);
	padding: var(--tov-space-4) var(--tov-space-3);
	color: inherit;
	text-decoration: none;
	transition: background var(--tov-dur-fast) var(--tov-ease-out);
}

.tov-msg__row-link:hover,
.tov-msg__row-link:focus-visible {
	background: var(--tov-surface);
}

.tov-msg__row-head {
	grid-column: 1 / -1;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--tov-space-2);
}

.tov-msg__row-handle {
	font-family: var(--tov-font-display);
	font-size: var(--tov-text-lg);
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var(--tov-text);
}

.tov-msg__row-time {
	font-size: var(--tov-text-xs);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--tov-text-dim);
}

.tov-msg__row-context {
	grid-column: 1 / -1;
	font-size: var(--tov-text-sm);
	color: var(--tov-gold);
}

.tov-msg__row-snippet {
	grid-column: 1;
	overflow: hidden;
	font-size: var(--tov-text-sm);
	color: var(--tov-text-muted);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.tov-msg__row.is-unread .tov-msg__row-snippet {
	color: var(--tov-text);
}

/* "NEEDS YOU" IS ONE LANGUAGE PRODUCT-WIDE. A deal waiting on this member wears
   a gold spine and a warm wash (.tov-deal-row.is-actionable). An unread thread
   is the same claim on the same member's attention, and it was saying so only by
   un-dimming its own snippet — a difference you can only see by comparing two
   rows. Same spine, same wash, so the two lists read alike from across a room. */
.tov-msg__row.is-unread {
	border-left-color: var(--tov-gold);
	background: linear-gradient(90deg, rgba(212, 162, 78, 0.06), transparent 40%),
		var(--tov-surface);
}

/* The link's own hover paints an opaque plate that would erase the wash beneath
   it, so an unread row carries the wash into its hover — over the brighter
   surface, exactly as a deal row brightens on hover. */
.tov-msg__row.is-unread .tov-msg__row-link:hover,
.tov-msg__row.is-unread .tov-msg__row-link:focus-visible {
	background: linear-gradient(90deg, rgba(212, 162, 78, 0.06), transparent 40%),
		var(--tov-surface-2);
}

/* Squared up with .tov-mkt__pip, the count badge on the hub's tabs: same alert
   plate, the same --tov-alert-ink token (dark gold-ink fails 4.5:1 on the red
   plate at this size), the same 700 weight, and tabular numerals because this
   one leads with a number too. The display face and tracking stay —
   .tov-mkt__pip is a bare numeral, and this one reads "3 NEW", which is the
   uppercase micro-label treatment. The unread row's gold spine and wash stay
   gold on purpose: they are row emphasis, not a notification count. */
.tov-msg__pip {
	grid-column: 2;
	align-self: center;
	padding: 2px var(--tov-space-2);
	border-radius: var(--tov-r-pill);
	background: var(--tov-msg-unread);
	color: var(--tov-alert-ink);
	font-family: var(--tov-font-display);
	font-size: var(--tov-text-xs);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------- thread view */

.tov-msg__back {
	margin: 0 0 var(--tov-space-4);
	font-size: var(--tov-text-sm);
}

/* 44px, the house minimum. As a bare inline anchor this was a ~17px-tall target
   — under even WCAG 2.2's 24px floor, and the way back out of a thread is not
   the control to make people aim at. */
.tov-msg__back a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--tov-gold);
	text-decoration: none;
}

.tov-msg__back a:hover {
	color: var(--tov-gold-bright);
	text-decoration: underline;
}

.tov-msg__context {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--tov-space-4);
	padding: var(--tov-space-4);
	margin-bottom: var(--tov-space-5);
	border: 1px solid var(--tov-line);
	border-left: 3px solid var(--tov-gold);
	border-radius: var(--tov-r-sm);
	background: var(--tov-surface);
}

.tov-msg__context-tile {
	flex: 0 0 96px;
	max-width: 96px;
}

.tov-msg__context-tile img {
	display: block;
	width: 100%;
	height: auto;
}

.tov-msg__context-body {
	flex: 1 1 200px;
}

.tov-msg__context-eyebrow {
	margin: 0;
	font-family: var(--tov-font-display);
	font-size: var(--tov-text-xs);
	font-weight: 500;
	letter-spacing: 0.28em;
	text-transform: uppercase;
	color: var(--tov-gold);
}

.tov-msg__context-handle {
	margin: 0;
	font-family: var(--tov-font-display);
	/* Was 1.4rem — the only off-scale type size on any member-facing marketplace
	   surface. Snapped to the nearest step; the scale is the whole point of
	   having one. */
	font-size: var(--tov-text-xl);
	font-weight: 600;
	line-height: 1.15;
	color: var(--tov-text);
}

.tov-msg__context-meta {
	margin: var(--tov-space-1) 0 0;
	font-size: var(--tov-text-sm);
}

/* The link back to the listing this thread is about — 44px, same as every other
   target. It sat at ~17px inside a panel with 16px of padding around it. */
.tov-msg__context-meta a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--tov-text-muted);
}

.tov-msg__context-meta a:hover {
	color: var(--tov-gold-bright);
}

/* ----------------------------------------------------------------- messages */

.tov-msg__stream {
	display: flex;
	flex-direction: column;
	gap: var(--tov-space-4);
	margin: 0 0 var(--tov-space-5);
	padding: 0;
	list-style: none;
	/* The record rises as one document — deliberately not per-bubble, so a long
	   thread never becomes a parade. */
	animation: tov-mkt-rise var(--tov-dur-slow) var(--tov-ease-out) both;
}

.tov-msg__stream-empty {
	margin: var(--tov-space-6) 0;
	color: var(--tov-text-muted);
	text-align: center;
}

.tov-msg__item {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--tov-space-1);
	max-width: 46rem;
}

.tov-msg__item--own {
	align-items: flex-end;
	margin-left: auto;
}

.tov-msg__bubble {
	padding: var(--tov-space-3) var(--tov-space-4);
	border: 1px solid var(--tov-msg-other-edge);
	border-radius: var(--tov-r-md);
	background: var(--tov-msg-other-bg);
	/* Square off the corner nearest the speaker — the only "chat" affordance
	 * this design borrows, and enough to read direction without color alone. */
	border-bottom-left-radius: var(--tov-r-sm);
}

.tov-msg__item--own .tov-msg__bubble {
	border-color: var(--tov-msg-own-edge);
	background: var(--tov-msg-own-bg);
	border-radius: var(--tov-r-md);
	border-bottom-right-radius: var(--tov-r-sm);
}

.tov-msg__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--tov-space-2);
	margin: 0 0 var(--tov-space-2);
}

.tov-msg__author {
	font-family: var(--tov-font-display);
	font-size: var(--tov-text-sm);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--tov-gold);
}

.tov-msg__time {
	font-size: var(--tov-text-xs);
	letter-spacing: 0.06em;
	color: var(--tov-text-muted);
}

.tov-msg__body {
	margin: 0;
	color: var(--tov-text);
	/* Bodies are plain text: a long unbroken payment handle or serial must wrap
	 * rather than widen the bubble past the column. */
	overflow-wrap: anywhere;
	white-space: normal;
}

/* An inert URL. Not a link, and styled so that is obvious at a glance:
 * monospaced, muted, dotted underline, default cursor. Deliberately outside the
 * .tov-msg scope — the moderation queue renders bodies through the same PHP, so
 * the fallback color is the one it uses on wp-admin's light chrome. */
.tov-msg__inert-url {
	color: var(--tov-msg-inert, #50575e);
	font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
	font-size: 0.95em;
	text-decoration: underline dotted;
	text-underline-offset: 2px;
	cursor: default;
	word-break: break-all;
}

/* ------------------------------------------------------------------- report */

.tov-msg__report {
	margin: 0;
	font-size: var(--tov-text-sm);
}

/* inline-flex + 44px: reporting a message is the safety control on this surface,
   and it was a ~21px sliver of uppercase micro-type. It keeps its quiet
   styling — quiet is not the same as small. */
.tov-msg__report-toggle {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 2px var(--tov-space-2);
	color: var(--tov-text-dim);
	font-size: var(--tov-text-xs);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	cursor: pointer;
	list-style: none;
}

.tov-msg__report-toggle::-webkit-details-marker {
	display: none;
}

.tov-msg__report-toggle:hover,
.tov-msg__report[open] .tov-msg__report-toggle {
	color: var(--tov-danger);
}

.tov-msg__report form {
	display: flex;
	flex-direction: column;
	gap: var(--tov-space-2);
	align-items: flex-start;
	max-width: 34rem;
	padding: var(--tov-space-3);
	margin-top: var(--tov-space-2);
	border: 1px solid var(--tov-msg-other-edge);
	border-radius: var(--tov-r-sm);
	background: var(--tov-surface);
}

.tov-msg__report-label {
	font-size: var(--tov-text-sm);
	color: var(--tov-text-muted);
}

.tov-msg__report-reason,
.tov-msg__textarea {
	width: 100%;
	padding: var(--tov-space-2) var(--tov-space-3);
	border: 1px solid var(--tov-msg-other-edge);
	border-radius: var(--tov-r-sm);
	background: var(--tov-bg);
	color: var(--tov-text);
	font-family: var(--tov-font-body);
	font-size: var(--tov-text-base);
	line-height: 1.5;
	resize: vertical;
}

.tov-msg__report-reason:focus,
.tov-msg__textarea:focus {
	border-color: var(--tov-line-strong);
	outline: none;
}

.tov-msg__reported {
	margin: 0;
	font-size: var(--tov-text-xs);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--tov-text-dim);
}

/* ----------------------------------------------------------------- composer */

/* A reply is answered at the measure it is answering. Bubbles cap at 46rem
   (.tov-msg__item); the composer ran the full 1280px column, so the box you type
   into was roughly three times the width of every message above it — the thread
   read as a transcript with a form bolted under it. Same cap, one document.
   .tov-msg__closed takes it too: it stands in the composer's slot, and a
   full-bleed plate where a capped one just was would jump the layout. */
.tov-msg__composer,
.tov-msg__closed {
	max-width: 46rem;
}

.tov-msg__composer {
	padding: var(--tov-space-4);
	border: 1px solid var(--tov-line);
	border-radius: var(--tov-r-sm);
	background:
		linear-gradient(var(--tov-line-strong), var(--tov-line-strong)) top left / 14px 1px,
		linear-gradient(var(--tov-line-strong), var(--tov-line-strong)) top left / 1px 14px,
		linear-gradient(var(--tov-line-strong), var(--tov-line-strong)) bottom right / 14px 1px,
		linear-gradient(var(--tov-line-strong), var(--tov-line-strong)) bottom right / 1px 14px,
		var(--tov-surface);
	background-repeat: no-repeat;
	box-shadow: var(--tov-shadow-md);
	animation: tov-mkt-rise var(--tov-dur-slow) var(--tov-ease-out) 80ms both;
}

.tov-msg__composer-label {
	display: block;
	margin-bottom: var(--tov-space-2);
	font-family: var(--tov-font-display);
	font-size: var(--tov-text-xs);
	font-weight: 500;
	letter-spacing: 0.28em;
	text-transform: uppercase;
	color: var(--tov-gold);
}

.tov-msg__composer-foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--tov-space-3);
	margin-top: var(--tov-space-3);
}

.tov-msg__composer-hint {
	flex: 1 1 18rem;
	margin: 0;
	font-size: var(--tov-text-xs);
	color: var(--tov-text-muted);
}

.tov-msg__closed {
	padding: var(--tov-space-3) var(--tov-space-4);
	border: 1px dashed var(--tov-line);
	border-radius: var(--tov-r-sm);
	color: var(--tov-text-muted);
	text-align: center;
}

/* ------------------------------------------------------------------ tablet */

/* This file had exactly one breakpoint, at 600px, so a thread on a 768px tablet
   or an 1100px laptop window was served the full desktop treatment: 1280px of
   column, desktop padding on every plate, and no step in between. This is that
   step — the chrome tightens one notch while the layout itself holds. */
@media (max-width: 900px) {
	.tov-msg__context {
		gap: var(--tov-space-3);
		padding: var(--tov-space-3);
	}

	.tov-msg__composer {
		padding: var(--tov-space-3);
	}

	.tov-msg__row-link {
		padding: var(--tov-space-3) var(--tov-space-2);
	}

	/* The stream loses its widest measure before the bubbles start touching the
	   gutters, so a long thread keeps a readable line length on the way down. */
	.tov-msg__item {
		max-width: 40rem;
	}
}

/* ------------------------------------------------------------------ narrow */

@media (max-width: 600px) {
	.tov-msg__item,
	.tov-msg__item--own {
		max-width: 100%;
	}

	.tov-msg__context-tile {
		flex-basis: 72px;
		max-width: 72px;
	}

	.tov-msg__row-link {
		grid-template-columns: 1fr;
	}

	.tov-msg__pip {
		grid-column: 1;
		justify-self: start;
	}
}

/* ---------------------------------------------------------------------------
 * Moderation queue (wp-admin)
 *
 * Light chrome, because it lives inside WordPress's. The identity column is the
 * one place a real email address renders anywhere in this module — it is marked
 * so it never reads as an accident.
 * ------------------------------------------------------------------------- */
.tov-modq {
	--tov-modq-flag: #8a5a00;
	--tov-modq-report: #a12d18;
	--tov-modq-hidden: #6b6b76;
	--tov-modq-plate: #f6f7f7;
	--tov-modq-line: #dcdcde;
}

.tov-modq__lede {
	max-width: 70ch;
	color: #3c434a;
}

.tov-modq__empty {
	padding: var(--tov-space-4, 16px);
	border: 1px dashed var(--tov-modq-line);
	background: var(--tov-modq-plate);
	color: var(--tov-modq-hidden);
}

.tov-modq__table {
	margin-top: 12px;
}

.tov-modq__table th,
.tov-modq__table td {
	vertical-align: top;
}

.tov-modq__body {
	max-width: 46ch;
	padding: 8px 10px;
	border-left: 3px solid var(--tov-modq-line);
	background: var(--tov-modq-plate);
	overflow-wrap: anywhere;
}

.tov-modq__meta {
	margin: 6px 0 0;
	color: #50575e;
	font-size: 12px;
}

.tov-modq__state {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 6px;
	border: 1px solid var(--tov-modq-hidden);
	border-radius: 2px;
	color: var(--tov-modq-hidden);
	font-size: 11px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.tov-modq__row--hidden .tov-modq__body {
	border-left-color: var(--tov-modq-hidden);
	opacity: 0.75;
}

/* Identity column: dotted rule + label styling so the "admins only" heading is
 * visibly attached to the data underneath it. */
.tov-modq__identity-col {
	border-left: 1px dotted var(--tov-modq-report);
	color: #3c434a;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 12px;
	overflow-wrap: anywhere;
}

th.tov-modq__identity-col {
	color: var(--tov-modq-report);
	font-family: inherit;
	font-size: inherit;
}

.tov-modq__reason {
	margin: 0 0 6px;
	font-size: 12px;
}

.tov-modq__flag,
.tov-modq__report-tag {
	display: inline-block;
	margin-right: 4px;
	padding: 1px 6px;
	border-radius: 2px;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: #fff;
}

.tov-modq__flag {
	background: var(--tov-modq-flag);
}

.tov-modq__report-tag {
	background: var(--tov-modq-report);
}

.tov-modq__match {
	display: inline-block;
	margin-right: 4px;
	padding: 0 4px;
	background: #fff5d6;
	color: #4b3200;
	font-size: 12px;
}

.tov-modq__report-reason {
	display: block;
	margin-top: 2px;
	color: #50575e;
	font-style: italic;
}

.tov-modq__actions form {
	display: inline-block;
	margin: 0 4px 4px 0;
}

.tov-modq__keywords {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ---------------------------------------------------------------------------
 * Reduced motion — every transition here is decorative, so all of it goes.
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.tov-msg *,
	.tov-msg *::before,
	.tov-msg *::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
	}
}
