/*
 * Forum UI. Colours come from the theme's tokens rather than being restated here,
 * so retinting the site in theme.json retints the forum with it.
 */

/* box-sizing is load-bearing, not tidiness. These are direct children of a constrained
   layout, so WordPress gives them `max-width: <content size>` and `margin-inline: auto`.
   Under content-box the 24px padding and 1px border are ADDED to that max-width: the box
   comes out 1650px wide inside a 1600px column, the auto margins have nothing left to
   distribute, and it sits 25px LEFT of every heading beside it. Cost an afternoon on the
   front-page gallery panel and both of the join/login forms. */
.l200-panel,
.l200-board,
.l200-reply,
.l200-form {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 14px;
	box-shadow: var(--wp--preset--shadow--panel);
	box-sizing: border-box;
	padding: var(--wp--preset--spacing--30);
}

.l200-boards {
	display: grid;
	gap: var(--wp--preset--spacing--20);
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.l200-board__title {
	font-size: var(--wp--preset--font-size--x-large);
	margin: 0 0 0.35rem;
}

.l200-board__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.l200-board__title a:hover {
	color: var(--wp--preset--color--accent-bright);
}

.l200-board__desc {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	margin: 0 0 0.75rem;
}

.l200-board__meta {
	border-top: 1px solid var(--wp--preset--color--line);
	color: var(--wp--preset--color--muted);
	display: flex;
	flex-wrap: wrap;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.75rem;
	margin: 0;
	padding-top: 0.75rem;
}

/* --- Forms --- */

.l200-form {
	display: grid;
	gap: var(--wp--preset--spacing--20);
	margin-block: var(--wp--preset--spacing--30);
}

.l200-field {
	display: grid;
	gap: 0.35rem;
	margin: 0;
}

.l200-field label {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
}

/* Exactly two flex children: the box and a span holding the whole sentence. Without the
   span, each link and each run of text became its own column. align-items: flex-start so
   the box sits against the first line when the sentence wraps, not floating in the middle. */
.l200-field--check label {
	align-items: flex-start;
	display: flex;
	font-weight: 400;
	gap: 0.6rem;
	line-height: 1.5;
}

.l200-field--check input[type="checkbox"] {
	flex: 0 0 auto;
	height: 1.15rem;
	margin-top: 0.12rem;
	width: 1.15rem;
}

.l200-field--check label > span {
	min-width: 0;
}

/* Signup: intro, reassurance and the perks panel that gives a short page a bottom. */
.l200-intro {
	color: var(--wp--preset--color--muted);
	margin: 0 0 var(--wp--preset--spacing--20);
	max-width: 60ch;
}

.l200-join-perks {
	border-top: 2px solid var(--wp--preset--color--accent);
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--30);
}

.l200-join-perks__title {
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--large);
	margin: 0 0 0.75rem;
}

.l200-join-perks ul {
	display: grid;
	gap: 0.6rem;
	list-style: none;
	margin: 0;
	max-width: 70ch;
	padding: 0;
}

.l200-join-perks li {
	color: var(--wp--preset--color--muted);
	padding-left: 1.6rem;
	position: relative;
}

/* A navy tick drawn in CSS rather than an emoji: emoji render at wildly different sizes
   across Android and iOS and would not sit on the baseline. */
.l200-join-perks li::before {
	border-bottom: 2px solid var(--wp--preset--color--accent);
	border-left: 2px solid var(--wp--preset--color--accent);
	content: "";
	height: 0.36rem;
	left: 0.15rem;
	position: absolute;
	top: 0.45rem;
	transform: rotate(-45deg);
	width: 0.7rem;
}

/* On a phone the primary action should be a full-width target, not a small pill. */
@media (max-width: 600px) {
	.l200-submit .l200-btn {
		width: 100%;
	}
}

.l200-field input[type="text"],
.l200-field input[type="email"],
.l200-field input[type="password"],
.l200-field input[type="number"],
.l200-field select,
.l200-field textarea {
	background: var(--wp--preset--color--deep);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 10px;
	color: var(--wp--preset--color--contrast);
	font: inherit;
	padding: 0.7rem 0.85rem;
	width: 100%;
}

.l200-field input:focus-visible,
.l200-field select:focus-visible,
.l200-field textarea:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent-bright);
	outline-offset: 2px;
}

.l200-hint {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

/* The honeypot must be reachable by bots but never seen or tabbed by people. */
.l200-hp {
	height: 0;
	left: -9999px;
	overflow: hidden;
	position: absolute;
	width: 0;
}

/* This class is worn by both <button> and <a>, which do NOT agree by default: a button
   does not inherit the page font, and an anchor inherits the body's 1.6 line-height while
   a button uses `normal`. Left alone, "Save profile" and "Log out" sat side by side at
   visibly different sizes. font: inherit, a fixed line-height and inline-flex centring
   make the two elements produce the same box. The transparent border is load-bearing too
   — the ghost variant only recolours it, so adding an outline cannot change the height. */
.l200-btn {
	align-items: center;
	background: var(--wp--preset--gradient--accent-button);
	border: 1px solid transparent;
	border-radius: 999px;
	box-shadow: var(--wp--preset--shadow--button);
	box-sizing: border-box;
	color: var(--wp--preset--color--accent-ink);
	cursor: pointer;
	display: inline-flex;
	font: inherit;
	font-weight: 700;
	justify-content: center;
	line-height: 1.2;
	padding: 0.85rem 1.75rem;
	text-align: center;
	text-decoration: none;
}

.l200-btn--ghost {
	background: transparent;
	border-color: var(--wp--preset--color--line);
	box-shadow: none;
	color: var(--wp--preset--color--contrast);
}

/* A row of buttons: an explicit gap rather than the whitespace between inline elements,
   which collapses differently depending on how the PHP happens to be indented. */
.l200-btn-row {
	align-items: stretch;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

.l200-btn:hover {
	filter: brightness(1.06);
}

/* --- Replies --- */

.l200-replies {
	display: grid;
	gap: var(--wp--preset--spacing--20);
	margin-top: var(--wp--preset--spacing--40);
}

.l200-replies__title {
	font-size: var(--wp--preset--font-size--x-large);
	margin: 0;
}

.l200-reply__by {
	align-items: center;
	border-bottom: 1px solid var(--wp--preset--color--line);
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
	margin-bottom: 0.85rem;
	padding-bottom: 0.6rem;
}

/* The avatar, and ONLY the avatar. Written as `.l200-reply__by img` this also caught the
   profile banner sitting in the same header — and 50% on a wide, short image is not a
   rounded rectangle, it is an ellipse, which is exactly what members saw. The banner's own
   `border-radius: 6px` lost because one class plus one element (0,1,1) beats one class
   (0,1,0). Same shape of mistake as `.l200-truck img` stretching the owner avatar: a rule
   meant for one image in a component quietly claiming every image in it. */
.l200-reply__by img:not(.l200-reply__banner) {
	border-radius: 50%;
}

.l200-reply__author {
	font-weight: 700;
}

.l200-reply__truck,
.l200-reply__date {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

.l200-reply__truck::before {
	content: "· ";
}

.l200-reply__date {
	margin-left: auto;
}

.l200-reply__body > :first-child {
	margin-top: 0;
}

.l200-reply__body > :last-child {
	margin-bottom: 0;
}

/* --- Notices --- */

.l200-notice {
	border-left: 3px solid var(--wp--preset--color--accent-bright);
	border-radius: 8px;
	background: var(--wp--preset--color--surface-raised);
	margin-block: var(--wp--preset--spacing--20);
	padding: 0.85rem 1rem;
}

.l200-notice--error {
	border-left-color: var(--wp--preset--color--contrast);
}

.l200-notice--success {
	border-left-color: var(--wp--preset--color--muted);
}

.l200-meta {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	margin: 0;
}

/* --- Badges --- */

.l200-badges {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	vertical-align: middle;
}

.l200-badge {
	align-items: center;
	background: var(--wp--preset--color--surface-raised);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 999px;
	color: var(--wp--preset--color--muted);
	display: inline-flex;
	font-size: 0.72rem;
	font-weight: 600;
	gap: 0.25rem;
	line-height: 1;
	padding: 0.22rem 0.55rem;
	white-space: nowrap;
}

.l200-badge__icon {
	font-size: 0.85em;
}

/* Role badges carry authority, so they are the only ones that use the accent. */
.l200-badge--role {
	background: color-mix(in srgb, var(--wp--preset--color--accent) 22%, transparent);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent-bright);
}

.l200-badge--rank {
	color: var(--wp--preset--color--contrast);
}

.l200-badge--manual {
	border-color: color-mix(in srgb, var(--wp--preset--color--accent-bright) 55%, transparent);
	color: var(--wp--preset--color--accent-bright);
}

/* --- Chips (helpful / accept answer) --- */

.l200-inline-form {
	display: inline;
	margin: 0;
}

.l200-chip {
	background: transparent;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 999px;
	color: var(--wp--preset--color--muted);
	cursor: pointer;
	font: inherit;
	font-size: 0.78rem;
	padding: 0.3rem 0.7rem;
}

.l200-chip:hover {
	border-color: var(--wp--preset--color--accent-bright);
	color: var(--wp--preset--color--contrast);
}

.l200-chip.is-on {
	background: color-mix(in srgb, var(--wp--preset--color--accent) 20%, transparent);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent-bright);
}

.l200-chip.is-static {
	cursor: default;
}

.l200-chip__count {
	font-weight: 700;
}

.l200-reply__actions {
	border-top: 1px solid var(--wp--preset--color--line);
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin-top: 0.9rem;
	padding-top: 0.7rem;
}

.l200-reply__ident {
	align-items: center;
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.l200-reply__author {
	color: var(--wp--preset--color--contrast);
	font-weight: 700;
	text-decoration: none;
}

.l200-reply__author:hover {
	color: var(--wp--preset--color--accent-bright);
}

/* --- Accepted answer --- */

.l200-reply.is-solution {
	border-color: var(--wp--preset--color--contrast);
	box-shadow: 0 0 0 1px var(--wp--preset--color--contrast) inset;
}

.l200-reply__solved {
	color: var(--wp--preset--color--contrast);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	margin: 0 0 0.6rem;
	text-transform: uppercase;
}

.l200-solved-flag {
	color: var(--wp--preset--color--contrast);
	font-weight: 700;
}

/* --- Pagination --- */

.l200-pagination {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	justify-content: center;
	margin-top: var(--wp--preset--spacing--20);
}

.l200-pagination a,
.l200-pagination__current {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	padding: 0.35rem 0.7rem;
	text-decoration: none;
}

.l200-pagination__current {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent-ink);
	font-weight: 700;
}

/* --- Members --- */

/* --- Member directory --------------------------------------------------------
   ONE definition for this component. Earlier versions of this file redefined
   .l200-member in three separate places and whichever came last won by accident.
   Change a member card here and nowhere else.
   ----------------------------------------------------------------------------- */

/* Count and note sit together on the left. Pushing the note to the far right with
   space-between strands it 1,300px from the number it belongs to on a wide screen. */
.l200-directory__bar {
	align-items: baseline;
	border-bottom: 2px solid var(--wp--preset--color--accent);
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem 1.5rem;
	margin-bottom: var(--wp--preset--spacing--30);
	padding-bottom: 0.8rem;
}

.l200-directory__count {
	align-items: baseline;
	display: flex;
	gap: 0.55rem;
	margin: 0;
}

.l200-directory__num {
	color: var(--wp--preset--color--accent);
	font-size: clamp(2.1rem, 4vw, 2.9rem);
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1;
}

.l200-directory__unit {
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.l200-directory__note,
.l200-directory__more {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	margin: 0;
}

.l200-directory__more {
	margin-top: var(--wp--preset--spacing--30);
}

/* Capped tracks, left-aligned — NOT stretched. With three members a `1fr` grid leaves
   four empty tracks and reads as a broken layout; capped tracks read as a deliberate
   row at three members and tile edge to edge at three thousand. */
.l200-members {
	display: grid;
	gap: var(--wp--preset--spacing--20);
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 360px));
	justify-content: start;
}

/* auto / 1fr / auto: the truck line absorbs the slack, so the stats rule sits on the
   bottom edge of every card and the row of cards reads as one band. */
.l200-member {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	border-top: 2px solid rgba(0, 41, 79, 0.18);
	display: grid;
	gap: 0.6rem;
	grid-template-rows: auto 1fr auto;
	padding: 0.95rem 1rem 0.8rem;
	text-decoration: none;
	transition: border-color .15s ease;
}

.l200-member:hover {
	border-color: var(--wp--preset--color--accent);
}

.l200-member__head {
	align-items: center;
	display: flex;
	gap: 0.7rem;
	min-width: 0;
}

.l200-member img,
.l200-member .l200-avatar-initial {
	border-radius: 50%;
	flex: 0 0 auto;
}

/* Initials badge that stands in for a missing profile picture. Sized inline in PHP from
   whatever size the avatar call asked for, so it matches the <img> it replaces. */
.l200-avatar-initial {
	align-items: center;
	background: var(--wp--preset--color--accent);
	border-radius: 50%;
	color: #fff;
	display: inline-flex;
	flex: 0 0 auto;
	font-weight: 700;
	justify-content: center;
	letter-spacing: 0.01em;
	line-height: 1;
	overflow: hidden;
	user-select: none;
	vertical-align: middle;
}

.l200-member__ident {
	display: grid;
	gap: 0.35rem;
	min-width: 0;
}

/* Long single-word usernames WRAP rather than truncate: "StaffordshireTruck…" tells a
   visitor less than two tidy lines do. The min-width: 0 above is what stops the long
   word from widening its grid track. */
.l200-member__name {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
	line-height: 1.25;
	overflow-wrap: anywhere;
}

.l200-member__truck {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

.l200-member__truck--none {
	opacity: 0.65;
}

.l200-member__stats {
	border-top: 1px solid var(--wp--preset--color--line);
	color: var(--wp--preset--color--muted);
	display: flex;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 1.1rem;
	padding-top: 0.65rem;
}

.l200-member__stats strong {
	color: var(--wp--preset--color--contrast);
}

/* --- Profile --- */

.l200-profile__head {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--20);
}

.l200-profile__head img {
	border-radius: 50%;
}

.l200-profile__name {
	margin: 0 0 0.4rem;
}

.l200-profile__meta {
	color: var(--wp--preset--color--muted);
	display: flex;
	flex-wrap: wrap;
	font-size: var(--wp--preset--font-size--small);
	gap: 0.75rem;
	margin: 0.5rem 0 0;
}

.l200-profile__stats {
	border-block: 1px solid var(--wp--preset--color--line);
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
	margin-block: var(--wp--preset--spacing--30);
	padding-block: var(--wp--preset--spacing--20);
}

.l200-profile__stats strong {
	color: var(--wp--preset--color--accent-bright);
	font-size: var(--wp--preset--font-size--x-large);
}

.l200-profile__topics {
	display: grid;
	gap: 0.4rem;
	list-style: none;
	padding: 0;
}

.l200-board__when {
	color: var(--wp--preset--color--muted);
	display: block;
}

/* ==========================================================================
   Monochrome refinement
   Black and white only. Hierarchy comes from weight, fill and space rather
   than hue, so nothing depends on colour to be understood.
   ========================================================================== */

.l200-panel,
.l200-board,
.l200-reply,
.l200-form {
	border-radius: 12px;
	box-shadow: none;
}

.l200-board,
.l200-latest__item {
	transition: border-color .15s ease, transform .15s ease;
}

.l200-board:hover {
	border-color: var(--wp--preset--color--contrast);
}

/* --- Badges: one filled, the rest quiet --- */

.l200-badge {
	background: transparent;
	border-radius: 6px;
	font-size: 0.7rem;
	letter-spacing: 0.02em;
	padding: 0.2rem 0.5rem;
	text-transform: none;
}

/* Role is the only badge that earns a fill — it is the one carrying authority. */
.l200-badge--role {
	background: var(--wp--preset--color--contrast);
	border-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.l200-badge--rank {
	background: var(--wp--preset--color--surface-raised);
	border-color: transparent;
	color: var(--wp--preset--color--contrast);
}

.l200-badge--achievement,
.l200-badge--manual {
	border-color: var(--wp--preset--color--line);
	color: var(--wp--preset--color--muted);
}

/* --- Chips --- */

/* Edited in place rather than appended as a fourth `.l200-chip` block. There are already
   three in this file and the later one silently wins; adding another would make the next
   person's job worse.

   These were a transparent box with a hairline border and muted grey text, sitting on the
   grey card ground — so Delete, Helpful and "Mark as answer" all but disappeared, and the
   only one anybody could see was the like, because being "on" gave it a colour. They are
   controls, and a control the reader cannot find is a control that does not exist.

   The fix is a white fill against the grey card plus ink text: the chip becomes an object
   sitting on the card rather than an outline drawn on it. The border is mixed from the ink
   rather than using `line`, which at #DCE4EC is a hairline meant for dividing things, not
   for describing the edge of something clickable. */
.l200-chip {
	background: var(--wp--preset--color--base);
	border-color: color-mix(in srgb, var(--wp--preset--color--contrast) 30%, transparent);
	border-radius: 6px;
	color: var(--wp--preset--color--contrast);
	font-size: 0.82rem;
	font-weight: 600;
	padding: 0.42rem 0.85rem;
	transition: border-color .15s ease, background .15s ease, color .15s ease;
}

/* A real hover state, so the row reads as interactive before it is clicked. */
.l200-chip:hover {
	background: color-mix(in srgb, var(--wp--preset--color--accent) 8%, var(--wp--preset--color--base));
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent);
}

.l200-chip.is-on {
	background: var(--wp--preset--color--contrast);
	border-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.l200-chip:focus-visible,
.l200-btn:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 2px;
}

/* --- Accepted answer: a solid rule, not a colour --- */

.l200-reply.is-solution {
	border-color: var(--wp--preset--color--contrast);
	border-left-width: 3px;
	box-shadow: none;
}

.l200-reply__solved {
	font-size: 0.7rem;
	letter-spacing: 0.1em;
}

/* --- Reading comfort: forum posts are long-form text --- */

.l200-reply__body {
	font-size: 1.02rem;
	line-height: 1.75;
}

/* Member-typed text is the one place on this site with genuinely unbounded content, and a
   pasted URL is a single unbreakable token. One Facebook permalink in a reply measured 535px
   of min-content inside a 375px phone, which pushed the reply, the main column and the whole
   document out to 609px — so the page scrolled sideways and every other element sat in a
   narrow strip with a white gutter beside it. It reads as "the theme is broken on mobile"
   rather than "someone pasted a link".

   `anywhere`, NOT `break-word`. They look interchangeable and are not: only `anywhere`
   affects the intrinsic min-content width, which is the measurement doing the damage here.
   `break-word` would wrap the visible text and leave the container just as wide.

   Applied to both bodies because the opening post and the replies are the same card and take
   the same paste. */
.l200-reply__body,
.l200-topic-post__body {
	overflow-wrap: anywhere;
}

/* Belt and braces for anything a member can put in a post that has its own intrinsic width.
   Photos already carry max-width, but this catches whatever gets added next. */
.l200-reply__body img,
.l200-topic-post__body img,
.l200-reply__body pre,
.l200-topic-post__body pre {
	max-width: 100%;
}

.l200-reply__body pre,
.l200-topic-post__body pre {
	overflow-x: auto;
}

.l200-reply {
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--30);
}

.l200-replies {
	gap: var(--wp--preset--spacing--30);
}

/* --- Forms --- */

.l200-field input[type="text"],
.l200-field input[type="email"],
.l200-field input[type="password"],
.l200-field input[type="number"],
.l200-field select,
.l200-field textarea {
	background: var(--wp--preset--color--base);
	border-radius: 8px;
	transition: border-color .15s ease;
}

.l200-field input:hover,
.l200-field textarea:hover {
	border-color: var(--wp--preset--color--muted);
}

.l200-field input:focus-visible,
.l200-field select:focus-visible,
.l200-field textarea:focus-visible {
	border-color: var(--wp--preset--color--contrast);
	outline: 1px solid var(--wp--preset--color--contrast);
	outline-offset: 0;
}

.l200-btn {
	border-radius: 8px;
	box-shadow: none;
	padding: 0.8rem 1.5rem;
	transition: opacity .15s ease;
}

.l200-btn:hover {
	filter: none;
	opacity: 0.85;
}

.l200-btn--ghost:hover {
	border-color: var(--wp--preset--color--contrast);
	opacity: 1;
}

/* --- Notices: weight and a rule, no colour --- */

.l200-notice {
	background: var(--wp--preset--color--surface-raised);
	border-left-width: 3px;
	border-radius: 0 8px 8px 0;
	font-size: 0.95rem;
}

.l200-notice--error {
	font-weight: 600;
}

/* Member card rules live in one place now — see "Member directory" above. */

.l200-profile__stats strong {
	color: var(--wp--preset--color--contrast);
}

.l200-pagination__current {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* --- Club palette ---------------------------------------------------------
   Green and red return, but only where they carry meaning: an accepted answer
   and an error. Everything else stays navy or neutral.
   -------------------------------------------------------------------------- */

.l200-reply.is-solution {
	border-color: var(--wp--preset--color--club-green);
	border-left-width: 3px;
}

.l200-reply__solved,
.l200-solved-flag {
	color: var(--wp--preset--color--club-green);
}

.l200-notice--success {
	border-left-color: var(--wp--preset--color--club-green);
}

.l200-notice--error {
	border-left-color: var(--wp--preset--color--club-red);
}

.l200-badge--role {
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

.l200-chip.is-on {
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

.l200-chip:hover {
	border-color: var(--wp--preset--color--accent);
}

.l200-btn {
	background: var(--wp--preset--color--accent);
}

.l200-btn--ghost {
	background: transparent;
	color: var(--wp--preset--color--accent);
}

.l200-pagination__current {
	background: var(--wp--preset--color--accent);
}

.l200-profile__stats strong,
.l200-latest__board {
	color: var(--wp--preset--color--accent);
}

.l200-field input:focus-visible,
.l200-field select:focus-visible,
.l200-field textarea:focus-visible {
	border-color: var(--wp--preset--color--accent);
	outline-color: var(--wp--preset--color--accent);
}

/* A long unbroken username (StaffordshireTruckCompany) sets its grid track's min-content
   width and used to stretch one card wider than the rest. The card rules above solve it
   with min-width: 0 plus overflow-wrap, so the name wraps instead of truncating — the
   override block that used to sit here has been folded into that one definition. */

/* Same guard in reply headers, where the author name sits beside the badges. */
.l200-reply__ident {
	min-width: 0;
}

.l200-reply__author {
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* --- Badge emoji ----------------------------------------------------------
   Emoji ignore `color`, so they keep their own hues on both the navy-filled role
   pill and the pale ones. Sized slightly below the label and given a fixed
   line-height so a tall glyph cannot stretch the pill taller than its neighbours.
   -------------------------------------------------------------------------- */

.l200-badge__icon {
	font-size: 0.9em;
	font-style: normal;
	line-height: 1;
}

.l200-badge {
	gap: 0.3rem;
}

/* --- Club admin panel ------------------------------------------------------ */

.l200-admin-stats {
	display: grid;
	gap: 0.75rem;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	margin-bottom: var(--wp--preset--spacing--40);
}

.l200-admin-stat {
	background: var(--wp--preset--color--surface-raised);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	display: grid;
	gap: 0.2rem;
	padding: var(--wp--preset--spacing--20);
}

/* Anything waiting on a moderator should be impossible to scroll past. */
.l200-admin-stat.is-flagged {
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

.l200-admin-stat.is-flagged .l200-admin-stat__value,
.l200-admin-stat.is-flagged .l200-admin-stat__label {
	color: var(--wp--preset--color--base);
}

.l200-admin-stat__value {
	color: var(--wp--preset--color--accent);
	font-size: 1.9rem;
	font-weight: 800;
	line-height: 1;
}

.l200-admin-stat__label {
	color: var(--wp--preset--color--muted);
	font-size: 0.72rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.l200-admin-heading {
	border-bottom: 1px solid var(--wp--preset--color--line);
	font-size: var(--wp--preset--font-size--x-large);
	margin: var(--wp--preset--spacing--50) 0 var(--wp--preset--spacing--20);
	padding-bottom: 0.5rem;
}

.l200-admin-item {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	margin-bottom: 0.75rem;
	padding: var(--wp--preset--spacing--20);
}

.l200-admin-item__head {
	align-items: baseline;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	justify-content: space-between;
}

.l200-admin-item__meta {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

.l200-admin-item__body {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	margin-top: 0.5rem;
}

.l200-admin-item__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin-top: 0.75rem;
}

.l200-chip.is-approve:hover {
	background: var(--wp--preset--color--club-green);
	border-color: var(--wp--preset--color--club-green);
	color: var(--wp--preset--color--base);
}

.l200-chip.is-danger:hover {
	background: var(--wp--preset--color--club-red);
	border-color: var(--wp--preset--color--club-red);
	color: var(--wp--preset--color--base);
}

.l200-admin-badges {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 0.75rem;
}

.l200-admin-badge-toggle {
	align-items: center;
	display: inline-flex;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.3rem;
}

.l200-admin-link {
	margin-top: var(--wp--preset--spacing--30);
}

/* Admin-only nav link. Marked out from the member-facing items so it is obvious it is
   a staff control, without competing with the Join button beside it. */
.l200-admin-nav a {
	border: 1px solid var(--wp--preset--color--accent);
	border-radius: 8px;
	color: var(--wp--preset--color--accent) !important;
	padding: 0.4rem 0.8rem;
}

/* --- Search ---------------------------------------------------------------- */

.l200-search {
	display: flex;
	gap: 0.5rem;
	margin-bottom: var(--wp--preset--spacing--30);
}

.l200-search input[type="search"] {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	box-sizing: border-box;
	color: var(--wp--preset--color--contrast);
	flex: 1 1 auto;
	font: inherit;
	min-width: 0;
	padding: 0.7rem 0.85rem;
}

.l200-search input[type="search"]:focus-visible {
	border-color: var(--wp--preset--color--accent);
	outline: 1px solid var(--wp--preset--color--accent);
}

.l200-search .l200-btn {
	flex: 0 0 auto;
}

.l200-search-results .l200-latest__item {
	margin-bottom: 0.6rem;
}

.l200-search-excerpt {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

/* Solved threads are the most useful search results, so say so. */
.l200-search-solved {
	color: var(--wp--preset--color--club-green);
	font-weight: 700;
}

/* --- Gallery --------------------------------------------------------------- */

.l200-gallery {
	display: grid;
	gap: var(--wp--preset--spacing--20);
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	margin-bottom: var(--wp--preset--spacing--40);
}

.l200-truck {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	display: block;
	overflow: hidden;
	text-decoration: none;
	transition: border-color .15s ease;
}

.l200-truck:hover {
	border-color: var(--wp--preset--color--accent);
}

/* Fixed aspect so a portrait phone photo and a landscape one sit in the same grid
   without one card towering over its neighbours. */
/* DIRECT CHILD only. As `.l200-truck img` this also caught the owner's avatar nested in
   the card body and stretched a 26px portrait to the full 260px width of the card at a
   4:3 crop. The thumbnail is the anchor's own child; the avatar never is. */
.l200-truck > img {
	aspect-ratio: 4 / 3;
	display: block;
	height: auto;
	object-fit: cover;
	width: 100%;
}

.l200-truck__body {
	display: grid;
	gap: 0.2rem;
	padding: 0.75rem 0.85rem;
}

.l200-truck__title {
	color: var(--wp--preset--color--contrast);
	font-weight: 700;
	line-height: 1.3;
}

.l200-truck__owner {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

.l200-field input[type="file"] {
	background: var(--wp--preset--color--base);
	border: 1px dashed var(--wp--preset--color--line);
	border-radius: 8px;
	box-sizing: border-box;
	font: inherit;
	padding: 0.7rem 0.85rem;
	width: 100%;
}

/* --- Moderation controls --------------------------------------------------- */

.l200-mod-controls {
	align-items: center;
	border-top: 1px solid var(--wp--preset--color--line);
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin-top: 0.75rem;
	padding-top: 0.75rem;
}

.l200-mod-status {
	border-radius: 6px;
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	padding: 0.2rem 0.5rem;
	text-transform: uppercase;
}

.l200-mod-status.is-banned {
	background: var(--wp--preset--color--club-red);
	color: var(--wp--preset--color--base);
}

.l200-mod-status.is-timeout {
	background: var(--wp--preset--color--surface-raised);
	color: var(--wp--preset--color--contrast);
}

/* --- Photos attached to replies -------------------------------------------- */

.l200-reply__photo {
	display: block;
	margin-top: 0.85rem;
	max-width: 520px;
}

.l200-reply__photo img {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 10px;
	display: block;
	height: auto;
	max-width: 100%;
}

.l200-reply__photo:hover img {
	border-color: var(--wp--preset--color--accent);
}

/* --- Profile picture field ------------------------------------------------- */

.l200-avatar-row {
	align-items: center;
	display: flex;
	gap: 0.85rem;
}

.l200-avatar-row img {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 50%;
	flex: 0 0 auto;
	height: 72px;
	object-fit: cover;
	width: 72px;
}

.l200-avatar-row input[type="file"] {
	flex: 1 1 auto;
	min-width: 0;
}

/* Avatars are round everywhere they appear. */
.l200-reply__by img,
.l200-member img,
.l200-profile__head img {
	object-fit: cover;
}

/* --- Delete controls --------------------------------------------------------
   Gallery cards keep the delete button beside the card rather than inside it: a
   form nested in an anchor is invalid markup, and clicking it would follow the
   link instead of submitting.
   -------------------------------------------------------------------------- */

.l200-truck-wrap {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.l200-truck-wrap .l200-truck {
	flex: 1 1 auto;
}

.l200-truck__actions {
	display: flex;
	justify-content: flex-end;
}

.l200-topic-actions {
	display: flex;
	justify-content: flex-end;
	margin-top: var(--wp--preset--spacing--20);
}

/* --- Section headings inside the forum index ---------------------------------
   The board grid and the member topics below it are two different things, so each
   gets a labelled head. These h2s also repair the heading order on /forum/: board
   titles are h3, and before this there was no h2 between them and the page h1.
   ----------------------------------------------------------------------------- */

.l200-section-head {
	align-items: baseline;
	border-bottom: 2px solid var(--wp--preset--color--accent);
	display: flex;
	flex-wrap: wrap;
	gap: 0.3rem 1.25rem;
	margin-bottom: var(--wp--preset--spacing--30);
	padding-bottom: 0.7rem;
}

.l200-section-head--spaced {
	margin-top: var(--wp--preset--spacing--50);
}

.l200-section-title {
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--x-large);
	line-height: 1.2;
	margin: 0;
}

.l200-section-note {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	margin: 0;
}

/* ==========================================================================
   Photo picker and cropper
   The native control prints "Choose file" next to the raw filename, which on a
   phone is a truncated string like magnific_make-this-a-hero-banner_vQFew1Ya47.jpeg
   and tells the member nothing useful. The real input stays in the DOM and in the
   tab order — it is only moved out of sight — so the form still works with
   JavaScript off and the <label> association is untouched.
   ========================================================================== */

.l200-upload {
	display: grid;
	gap: 0.6rem;
	justify-items: start;
}

/* Not display:none — that would take the input out of the tab order and break the
   label. Clipped instead, so it stays focusable and operable. */
.l200-upload__input {
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* Focus lands on the hidden input, so the visible twin has to show it. */
.l200-upload__input:focus-visible + .l200-upload__pick {
	outline: 2px solid var(--wp--preset--color--accent-bright);
	outline-offset: 2px;
}

.l200-upload__status {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

.l200-upload__status:empty {
	display: none;
}

.l200-upload__done {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

.l200-upload__thumb {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 10px;
	height: auto;
	max-width: 96px;
}

.l200-upload__ready {
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.l200-crop {
	background: var(--wp--preset--color--surface-raised);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	display: grid;
	gap: 0.75rem;
	max-width: 480px;
	padding: 0.9rem;
	width: 100%;
}

/* touch-action: none so a drag inside the stage repositions the photo instead of
   scrolling the page on a phone. */
.l200-crop__stage {
	background: var(--wp--preset--color--contrast);
	border-radius: 8px;
	cursor: grab;
	overflow: hidden;
	position: relative;
	touch-action: none;
	user-select: none;
	width: 100%;
}

.l200-crop__stage.is-dragging {
	cursor: grabbing;
}

.l200-crop__img {
	left: 0;
	max-width: none;
	position: absolute;
	top: 0;
	transform-origin: 0 0;
	will-change: transform;
}

.l200-crop__hint {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	margin: 0;
}

.l200-crop__controls {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}

.l200-crop__zoom {
	align-items: center;
	display: flex;
	flex: 1 1 160px;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.5rem;
	font-weight: 600;
}

.l200-crop__zoom input[type="range"] {
	accent-color: var(--wp--preset--color--accent);
	flex: 1 1 auto;
	min-width: 0;
}

.l200-crop__apply,
.l200-crop__cancel {
	font-size: var(--wp--preset--font-size--small);
	padding: 0.6rem 1.1rem;
}

@media (max-width: 600px) {
	.l200-crop__controls {
		align-items: stretch;
		flex-direction: column;
	}

	.l200-crop__apply,
	.l200-crop__cancel {
		width: 100%;
	}
}

/* The `hidden` attribute is only `display: none` at user-agent strength, so ANY class rule
   that sets display beats it — .l200-crop is display:grid and .l200-upload__done is
   display:flex, which meant hiding them in JS did nothing and the crop stage and the
   finished preview showed at the same time. */
.l200-crop[hidden],
.l200-upload[hidden],
.l200-upload__done[hidden] {
	display: none;
}

/* ==========================================================================
   Glowing names
   Hand-granted from the club admin panel. A gradient clipped to the text plus a
   soft halo — no layout shift, because nothing here changes the box: no size, no
   weight, no spacing. A name that resized when it lit up would nudge every card
   it sits in.
   ========================================================================== */

.l200-glow {
	animation: l200-glow-sweep 6s linear infinite;
	background: linear-gradient(
		100deg,
		var(--wp--preset--color--accent) 0%,
		var(--wp--preset--color--accent-bright) 25%,
		#4FA3E3 40%,
		var(--wp--preset--color--accent-bright) 55%,
		var(--wp--preset--color--accent) 80%
	);
	background-clip: text;
	background-size: 220% auto;
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	color: var(--wp--preset--color--accent-bright);
	text-shadow: 0 0 14px rgba(79, 163, 227, 0.35);
}

@keyframes l200-glow-sweep {
	from { background-position: 0% center; }
	to   { background-position: 220% center; }
}

/* On navy the same trick needs a lighter ramp or it disappears into the background. */
.wp-site-blocks > header .l200-glow,
.l200-hero .l200-glow {
	background: linear-gradient(100deg, #9FD0FF 0%, #FFFFFF 40%, #9FD0FF 70%, #FFFFFF 100%);
	background-clip: text;
	background-size: 220% auto;
	-webkit-background-clip: text;
	text-shadow: 0 0 16px rgba(159, 208, 255, 0.5);
}

/* The global reduced-motion rule already stops the sweep; this makes sure what is left
   still looks deliberate rather than a frozen half-gradient. */
@media (prefers-reduced-motion: reduce) {
	.l200-glow {
		animation: none;
		background-position: 25% center;
	}
}

/* ==========================================================================
   Club admin panel
   ========================================================================== */

.l200-admin__bar {
	align-items: baseline;
	border-bottom: 2px solid var(--wp--preset--color--accent);
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.5rem;
	justify-content: space-between;
	margin-bottom: var(--wp--preset--spacing--30);
	padding-bottom: 0.7rem;
}

.l200-admin__who,
.l200-admin__links {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	margin: 0;
}

.l200-admin__links {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
}

.l200-admin-members {
	display: grid;
	gap: var(--wp--preset--spacing--20);
}

.l200-admin-member {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	border-top: 2px solid rgba(0, 41, 79, 0.18);
	box-sizing: border-box;
	display: grid;
	gap: 0.85rem;
	padding: var(--wp--preset--spacing--20);
}

.l200-admin-member__head {
	align-items: center;
	display: flex;
	gap: 0.75rem;
	min-width: 0;
}

.l200-admin-member__head img,
.l200-admin-member__head .l200-avatar-initial {
	border-radius: 50%;
	flex: 0 0 auto;
}

.l200-admin-member__ident {
	display: grid;
	gap: 0.15rem;
	min-width: 0;
}

.l200-admin-member__name {
	color: var(--wp--preset--color--accent);
	font-size: 1.05rem;
	overflow-wrap: anywhere;
}

.l200-admin-member__meta {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

.l200-admin-label {
	color: var(--wp--preset--color--muted);
	display: block;
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	margin-bottom: 0.4rem;
	text-transform: uppercase;
}

.l200-admin-member__earned {
	border-top: 1px solid var(--wp--preset--color--line);
	padding-top: 0.7rem;
}

.l200-admin-grant {
	border-top: 1px solid var(--wp--preset--color--line);
	display: grid;
	gap: 0.6rem;
	justify-items: start;
	padding-top: 0.7rem;
}

/* Auto-fit rather than a fixed column count: the badge list is meant to grow, and a
   hard-coded grid would need editing every time one is added. */
.l200-admin-badge-grid {
	display: grid;
	gap: 0.4rem;
	grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
	width: 100%;
}

.l200-admin-badge-toggle {
	align-items: center;
	background: var(--wp--preset--color--surface-raised);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	cursor: pointer;
	display: flex;
	font-size: var(--wp--preset--font-size--small);
	gap: 0.5rem;
	padding: 0.5rem 0.7rem;
}

.l200-admin-badge-toggle:hover {
	border-color: var(--wp--preset--color--accent);
}

.l200-admin-badge-toggle input {
	flex: 0 0 auto;
	height: 1.05rem;
	margin: 0;
	width: 1.05rem;
}

.l200-admin-badge-toggle--glow {
	background: linear-gradient(100deg, rgba(0, 41, 79, 0.06), rgba(79, 163, 227, 0.14));
	border-color: rgba(79, 163, 227, 0.5);
	font-weight: 600;
}

/* ==========================================================================
   Admin panel: collapsed controls
   Nine checkboxes per member turned a five-member club into a page of scrolling.
   <details> keeps each member to a few lines until you open them. Native, so it
   needs no JavaScript and works from the keyboard without any help from us.
   ========================================================================== */

.l200-admin-drop {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	width: 100%;
}

.l200-admin-drop__summary {
	align-items: center;
	color: var(--wp--preset--color--accent);
	cursor: pointer;
	display: flex;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	gap: 0.5rem;
	list-style: none;
	padding: 0.6rem 0.8rem;
}

/* Safari draws its own triangle through ::-webkit-details-marker, which list-style
   alone does not remove. */
.l200-admin-drop__summary::-webkit-details-marker {
	display: none;
}

/* Our own marker, so it can rotate on open. */
.l200-admin-drop__summary::before {
	border-bottom: 2px solid currentColor;
	border-right: 2px solid currentColor;
	content: "";
	display: inline-block;
	height: 0.42rem;
	transform: rotate(45deg);
	transition: transform .15s ease;
	width: 0.42rem;
}

.l200-admin-drop[open] > .l200-admin-drop__summary::before {
	transform: rotate(-135deg);
}

.l200-admin-drop__summary:hover {
	background: var(--wp--preset--color--surface-raised);
}

.l200-admin-drop__count {
	background: var(--wp--preset--color--accent);
	border-radius: 999px;
	color: #fff;
	font-size: 0.7rem;
	line-height: 1;
	margin-left: auto;
	padding: 0.25rem 0.5rem;
}

.l200-admin-drop__body {
	border-top: 1px solid var(--wp--preset--color--line);
	display: grid;
	gap: 0.6rem;
	justify-items: start;
	padding: 0.8rem;
}

.l200-admin-drop--mod .l200-admin-drop__summary {
	color: var(--wp--preset--color--muted);
}

/* The grant form is now just a wrapper round the disclosure. */
.l200-admin-grant {
	border-top: 1px solid var(--wp--preset--color--line);
	display: block;
	padding-top: 0.7rem;
}

/* With the controls folded away a card is short enough to tile two-up on a desktop,
   which is the other half of "more compact". */
@media (min-width: 1100px) {
	.l200-admin-members {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* View count under a topic. Quiet by design — it is context, not a headline. */
.l200-views {
	border-top: 1px solid var(--wp--preset--color--line);
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.04em;
	margin: var(--wp--preset--spacing--30) 0 0;
	padding-top: 0.6rem;
}

/* --- The eye ---------------------------------------------------------------
   currentColor and a baseline nudge, so the icon takes the colour of whatever
   text it sits in and lines up with it rather than floating.
   -------------------------------------------------------------------------- */

.l200-views__eye {
	fill: currentColor;
	flex: 0 0 auto;
	vertical-align: -1px;
}

.l200-views__badge {
	align-items: center;
	display: inline-flex;
	gap: 0.35rem;
	white-space: nowrap;
}

.l200-views {
	align-items: center;
	display: flex;
	gap: 0.4rem;
}

/* Board card: the view count sits on the bottom edge, right-aligned, however tall the
   card turns out. margin-top:auto in a flex COLUMN is the intended way to do that — not
   to be confused with the margin-inline:auto trap in section 6 of the handoff, which is
   about constrained-layout children and a different thing entirely. */
.l200-board {
	display: flex;
	flex-direction: column;
}

.l200-board__views {
	align-self: flex-end;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	margin: var(--wp--preset--spacing--20) 0 0;
	padding-top: 0.5rem;
}

/* The shortcode version, used inside the block-template archives where it sits beside the
   author and date in a flex row. */
.l200-views__inline {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

/* Profile topic list: count sits after the title, quietly. */
.l200-profile__topics .l200-views__badge {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	margin-left: 0.6rem;
}

/* ==========================================================================
   Member personalisation: name colour and profile banner
   ========================================================================== */

.l200-colour-row {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

/* A native colour input is a full RGB picker on every platform and needs no library.
   Browsers draw it at wildly different default sizes, hence the explicit box. */
.l200-colour-row input[type="color"] {
	background: none;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	cursor: pointer;
	height: 44px;
	padding: 3px;
	width: 64px;
}

.l200-colour-preview {
	font-size: 1.05rem;
	font-weight: 700;
}

/* Banner beside the poster. margin-left:auto pushes it to the right of the header row;
   the :has() rule then stops the date fighting it for the same space, since both cannot
   claim the free space with auto margins.

   540px must stay in step with L200_BANNER_WIDTH in personalisation.php — that constant is
   what the cropper writes the file at, and this is what it is displayed at. If this number
   is the larger of the two, every banner is an upscale. */
.l200-reply__banner {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 6px;
	display: block;
	height: auto;
	margin-left: auto;
	max-width: min(100%, 540px);
}

.l200-reply__by:has(.l200-reply__banner) .l200-reply__date {
	margin-left: 0.75rem;
}

/* On a phone the banner drops under the name rather than squeezing it to nothing. */
@media (max-width: 600px) {
	.l200-reply__banner {
		margin-left: 0;
		order: 10;
		width: 100%;
	}

	.l200-reply__by:has(.l200-reply__banner) .l200-reply__date {
		margin-left: auto;
	}
}

/* The banner preview on the account page is a plain image, not a reply header. */
.l200-field .l200-reply__banner {
	margin-bottom: 0.5rem;
	margin-left: 0;
}

/* ==========================================================================
   Replies and the reply box sit on grey
   These were `surface`, which is #FFFFFF — the same colour as the page behind
   them — so only a 1px hairline separated a reply from nothing. On a long thread
   that reads as one undifferentiated wall. A light grey ground makes each post a
   distinct object without turning the page into a set of boxes.

   Not `surface-raised` (#F2F6FA): against pure white that is a ~3% step and barely
   registers. This is a deliberate shade further.
   ========================================================================== */

.l200-reply,
.l200-form--reply {
	background: #EDF1F6;
}

/* Inputs have to invert to white now, or a textarea on a grey card is invisible for
   exactly the reason the card was. The field should read as the thing you type into. */
.l200-form--reply .l200-field input[type="text"],
.l200-form--reply .l200-field input[type="email"],
.l200-form--reply .l200-field input[type="number"],
.l200-form--reply .l200-field select,
.l200-form--reply .l200-field textarea {
	background: var(--wp--preset--color--base);
}

/* The accepted answer keeps its darker left rule, which still reads on grey. */
.l200-reply.is-solution {
	background: #E8EEF5;
}

/* ==========================================================================
   Forum index cards on grey
   Same reasoning as the replies: white cards on a white page are held apart by a
   1px hairline and nothing else.

   SCOPED DELIBERATELY. Board cards only ever appear on the forum index, so they can
   be tinted outright. Topic cards (.l200-latest__item) do NOT get the same treatment
   globally — the identical component sits on the front page inside a band that is
   already tinted #EDF3F9, and a grey card on a grey band is the exact problem this
   is meant to fix, in reverse. Hence .l200-forum-topics as the scope.
   ========================================================================== */

.l200-board,
.l200-forum-topics .l200-latest__item {
	background: #EDF1F6;
}

/* The search box keeps a white field so it still reads as something to type into. */
.l200-search input[type="search"],
.l200-search input[type="text"] {
	background: var(--wp--preset--color--base);
}

/* ==========================================================================
   Card outline and hover
   A defined dark edge instead of the near-invisible #DCE4EC hairline, so a card
   reads as an object rather than a faint suggestion of one.

   The line is `contrast` (#0E1B2A), the house ink — not pure #000. Against a navy
   palette true black is the one colour that looks like a mistake, and every other
   dark thing on this site is already this ink.
   ========================================================================== */

.l200-board,
.l200-latest__item,
.l200-reply,
.l200-form--reply {
	border: 1px solid var(--wp--preset--color--contrast);
}

/* These carried a navy top edge from an earlier pass. With a full dark outline it
   read as a mistake rather than a detail. */
.l200-latest__item,
.l200-board {
	border-top: 1px solid var(--wp--preset--color--contrast);
}

/* Hover: lift, shadow, navy edge. Only on the cards that are actually links — a
   reply is not clickable and lifting it would promise something that is not there. */
.l200-board,
.l200-latest__item {
	transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.l200-board:hover,
.l200-latest__item:hover,
.l200-latest__item:focus-visible {
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 8px 20px rgba(0, 41, 79, 0.18);
	transform: translateY(-3px);
}

/* The global reduced-motion block kills the transition, but a transform still jumps.
   Keep the shadow and the edge, drop the movement. */
@media (prefers-reduced-motion: reduce) {
	.l200-board:hover,
	.l200-latest__item:hover,
	.l200-latest__item:focus-visible {
		transform: none;
	}
}

/* ==========================================================================
   Likes, and the topic footer bar
   ========================================================================== */

/* Views, reply count and the like control on one line rather than three stacked
   paragraphs. */
.l200-postbar {
	align-items: center;
	border-top: 1px solid var(--wp--preset--color--line);
	color: var(--wp--preset--color--muted);
	display: flex;
	flex-wrap: wrap;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.5rem 1.1rem;
	margin-top: var(--wp--preset--spacing--30);
	padding-top: 0.6rem;
}

/* The bar owns the rule now, so the standalone version must not draw a second one. */
.l200-postbar .l200-views {
	border-top: 0;
	margin: 0;
	padding-top: 0;
}

.l200-like {
	align-items: center;
	background: none;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 999px;
	color: var(--wp--preset--color--muted);
	cursor: pointer;
	display: inline-flex;
	font: inherit;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.35rem;
	line-height: 1;
	padding: 0.35rem 0.7rem;
	transition: border-color .15s ease, color .15s ease;
}

.l200-like__icon {
	fill: currentColor;
}

.l200-like:hover {
	border-color: var(--wp--preset--color--club-red);
	color: var(--wp--preset--color--club-red);
}

/* Liked. club-red is reserved for errors everywhere else on this site, so the FILL is the
   signal here and the text stays ink — a red heart reads as affection, a red sentence
   reads as a problem. */
.l200-like.is-on {
	border-color: var(--wp--preset--color--club-red);
	color: var(--wp--preset--color--contrast);
}

.l200-like.is-on .l200-like__icon {
	fill: var(--wp--preset--color--club-red);
}

.l200-like.is-static {
	border-color: transparent;
	cursor: default;
	padding-inline: 0;
}

/* ==========================================================================
   The opening post
   Same card as a reply, so a thread reads as one conversation rather than an
   article followed by some comments. The author header reuses .l200-reply__by
   wholesale, which is why the poster's badges, name colour and banner all appear
   here without a line of extra styling.
   ========================================================================== */

.l200-topic-post {
	background: #EDF1F6;
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 12px;
	box-sizing: border-box;
	margin-top: var(--wp--preset--spacing--20);
	padding: var(--wp--preset--spacing--30);
}

.l200-topic-post__title {
	font-size: clamp(1.8rem, 3.4vw, 2.6rem);
	line-height: 1.15;
	margin: 0.75rem 0 0.5rem;
}

/* First and last children lose their outer margins so the card's padding is the only
   spacing that shows — otherwise a leading paragraph pushes the text off-centre. */
.l200-topic-post__body > :first-child {
	margin-top: 0;
}

.l200-topic-post__body > :last-child {
	margin-bottom: 0;
}

/* ==========================================================================
   Forms and panels join the card system
   The last white-on-white holdouts: the gallery upload form, join, login, the
   account form, new topic, and the .l200-panel notices. Same grey and same ink
   outline as boards, replies and archive rows, so every card on the site is one
   thing rather than two.
   ========================================================================== */

.l200-form,
.l200-panel {
	background: #EDF1F6;
	border: 1px solid var(--wp--preset--color--contrast);
}

/* Fields invert to white. A grey input on a grey card is invisible for exactly the reason
   the card was — the field has to read as the thing you type into. This supersedes the
   `background: deep` further up the file, which was only ever a near-white. */
.l200-form .l200-field input[type="text"],
.l200-form .l200-field input[type="email"],
.l200-form .l200-field input[type="password"],
.l200-form .l200-field input[type="number"],
.l200-form .l200-field input[type="search"],
.l200-form .l200-field select,
.l200-form .l200-field textarea {
	background: var(--wp--preset--color--base);
}

/* ==========================================================================
   Gallery cards
   Grey ground and ink outline like every other card, the owner shown with their
   picture, and the delete action tucked into a menu over the photo.
   ========================================================================== */

.l200-truck-wrap {
	position: relative;
}

.l200-truck {
	background: #EDF1F6;
	border: 1px solid var(--wp--preset--color--contrast);
	overflow: hidden;
}

.l200-truck__owner {
	align-items: center;
	color: var(--wp--preset--color--muted);
	display: flex;
	gap: 0.45rem;
}

.l200-truck__owner img,
.l200-truck__owner .l200-avatar-initial {
	border-radius: 50%;
	flex: 0 0 auto;
}

.l200-truck__owner-name {
	overflow-wrap: anywhere;
}

/* --- The corner menu ------------------------------------------------------ */

.l200-truck__menu {
	position: absolute;
	right: 0.55rem;
	top: 0.55rem;
	z-index: 2;
}

.l200-truck__menu > summary {
	align-items: center;
	background: rgba(14, 27, 42, 0.72);
	border-radius: 999px;
	color: #fff;
	cursor: pointer;
	display: flex;
	font-size: 1.1rem;
	height: 32px;
	justify-content: center;
	line-height: 1;
	list-style: none;
	/* The dots sit low in their line box; nudge them back to optical centre. */
	padding-bottom: 0.45rem;
	width: 32px;
}

.l200-truck__menu > summary::-webkit-details-marker {
	display: none;
}

.l200-truck__menu > summary:hover {
	background: var(--wp--preset--color--contrast);
}

.l200-truck__menu[open] > summary {
	background: var(--wp--preset--color--contrast);
}

.l200-truck__menu-body {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 10px;
	box-shadow: 0 8px 20px rgba(0, 41, 79, 0.22);
	padding: 0.45rem;
	position: absolute;
	right: 0;
	top: calc(100% + 0.35rem);
}

/* The old standalone action row is gone; anything left of it should not reserve space. */
.l200-truck__actions {
	display: none;
}

/* ==========================================================================
   Gallery card — the authoritative version
   Supersedes the scattered .l200-truck rules above. If a gallery card needs
   changing, change it HERE.
   ========================================================================== */

.l200-truck-wrap {
	display: block;
	position: relative;
}

.l200-truck {
	background: #EDF1F6;
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 12px;
	display: block;
	overflow: hidden;
	text-decoration: none;
	transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.l200-truck:hover,
.l200-truck:focus-visible {
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 8px 20px rgba(0, 41, 79, 0.18);
	transform: translateY(-3px);
}

@media (prefers-reduced-motion: reduce) {
	.l200-truck:hover,
	.l200-truck:focus-visible {
		transform: none;
	}
}

.l200-truck__body {
	display: grid;
	gap: 0.4rem;
	padding: 0.8rem 0.9rem 0.85rem;
}

.l200-truck__title {
	color: var(--wp--preset--color--accent);
	font-size: 1.02rem;
	font-weight: 700;
	line-height: 1.3;
	/* Two lines maximum, so one member's essay of a title cannot make its card twice the
	   height of every other card in the row. */
	-webkit-box-orient: vertical;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	overflow: hidden;
}

.l200-truck__owner {
	align-items: center;
	color: var(--wp--preset--color--muted);
	display: flex;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.45rem;
	min-width: 0;
}

/* Explicit box. Without it the avatar inherits whatever the thumbnail rule says, which is
   how it ended up 261px wide. flex-shrink 0 keeps it round when the name is long. */
.l200-truck__owner img,
.l200-truck__owner .l200-avatar-initial {
	border-radius: 50%;
	flex: 0 0 auto;
	height: 24px;
	object-fit: cover;
	width: 24px;
}

.l200-truck__owner-name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* --- Corner menu ---------------------------------------------------------- */

.l200-truck__menu {
	position: absolute;
	right: 0.5rem;
	top: 0.5rem;
	z-index: 3;
}

.l200-truck__menu > summary {
	align-items: center;
	backdrop-filter: blur(4px);
	background: rgba(14, 27, 42, 0.66);
	border-radius: 999px;
	/* box-sizing and an explicit zero padding are both needed: an earlier version of this
	   rule set padding-bottom to nudge the dots, and under content-box that made the circle
	   34x41 — an oval. Reset both rather than leaving the old value to leak through. */
	box-sizing: border-box;
	color: #fff;
	cursor: pointer;
	display: flex;
	font-size: 1.25rem;
	font-weight: 700;
	height: 34px;
	justify-content: center;
	letter-spacing: 0.06em;
	line-height: 0;
	list-style: none;
	padding: 0;
	width: 34px;
}

/* The ellipsis glyph sits low in its line box; shift the span, not the button. */
.l200-truck__menu > summary > span {
	display: block;
	transform: translateY(-0.18em);
}

/* Both are needed: list-style handles Firefox, the pseudo-element handles Safari and
   older Chrome. Miss either and a ▶ marker appears beside the dots. */
.l200-truck__menu > summary::marker,
.l200-truck__menu > summary::-webkit-details-marker {
	content: "";
	display: none;
}

.l200-truck__menu > summary:hover,
.l200-truck__menu[open] > summary {
	background: var(--wp--preset--color--contrast);
}

.l200-truck__menu-body {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 10px;
	box-shadow: 0 10px 24px rgba(0, 41, 79, 0.25);
	padding: 0.4rem;
	position: absolute;
	right: 0;
	top: calc(100% + 0.35rem);
	white-space: nowrap;
}

.l200-truck__actions {
	display: none;
}

/* ==========================================================================
   Opening post: header spacing, corner menu, helpful rating
   ========================================================================== */

.l200-topic-post {
	position: relative;
}

/* The header wrapped because the date carries margin-left:auto and the ident block had no
   min-width, so on a narrow measure the date was pushed onto a line of its own and left
   hanging under the badges. Let the ident take the slack and keep the date on the row. */
.l200-topic-post .l200-reply__by {
	align-items: center;
	gap: 0.5rem 0.75rem;
	padding-right: 3rem; /* room for the ⋯ button */
}

.l200-topic-post .l200-reply__ident {
	align-items: center;
	display: flex;
	flex: 1 1 auto;
	flex-wrap: wrap;
	gap: 0.4rem 0.6rem;
	min-width: 0;
}

.l200-topic-post .l200-reply__date {
	flex: 0 0 auto;
	white-space: nowrap;
}

.l200-topic-post__title {
	margin-top: 1rem;
}

/* --- The ⋯ menu on a post ------------------------------------------------- */

.l200-post-menu {
	position: absolute;
	right: 0.75rem;
	top: 0.75rem;
	z-index: 3;
}

.l200-post-menu > summary {
	align-items: center;
	background: rgba(14, 27, 42, 0.08);
	border-radius: 999px;
	box-sizing: border-box;
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	display: flex;
	font-size: 1.25rem;
	font-weight: 700;
	height: 34px;
	justify-content: center;
	line-height: 0;
	list-style: none;
	padding: 0;
	width: 34px;
}

.l200-post-menu > summary > span {
	display: block;
	transform: translateY(-0.18em);
}

/* Firefox honours ::marker, Safari and older Chrome need the webkit pseudo. Miss either
   and a ▶ appears next to the dots. */
.l200-post-menu > summary::marker,
.l200-post-menu > summary::-webkit-details-marker {
	content: "";
	display: none;
}

.l200-post-menu > summary:hover,
.l200-post-menu[open] > summary {
	background: var(--wp--preset--color--contrast);
	color: #fff;
}

.l200-post-menu__body {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 10px;
	box-shadow: 0 10px 24px rgba(0, 41, 79, 0.25);
	display: grid;
	gap: 0.6rem;
	min-width: 15rem;
	padding: 0.75rem;
	position: absolute;
	right: 0;
	top: calc(100% + 0.4rem);
}

.l200-report-form {
	display: grid;
	gap: 0.4rem;
}

.l200-report-form input[type="text"] {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	box-sizing: border-box;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	padding: 0.5rem 0.6rem;
	width: 100%;
}

/* --- Was this helpful? ---------------------------------------------------- */

.l200-rate {
	align-items: center;
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.l200-rate__label {
	color: var(--wp--preset--color--muted);
}

.l200-rate__btn {
	align-items: center;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 999px;
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	display: inline-flex;
	font: inherit;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.35rem;
	line-height: 1;
	padding: 0.35rem 0.7rem;
	transition: border-color .15s ease, background-color .15s ease;
}

.l200-rate__btn:hover {
	border-color: var(--wp--preset--color--accent);
}

/* The chosen side goes navy. Green is reserved for "solved" and red for errors, so neither
   is used here even though a yes/no control invites them. */
.l200-rate__btn.is-on {
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
	color: #fff;
}

.l200-rate__count {
	opacity: 0.75;
}

/* --- Moderator application form ------------------------------------------- */

.l200-fieldset {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 10px;
	margin: 0;
	padding: 0.9rem 1rem;
}

.l200-fieldset legend {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	padding: 0 0.35rem;
}

.l200-check-row {
	align-items: center;
	display: flex;
	font-weight: 400;
	gap: 0.6rem;
	padding: 0.25rem 0;
}

.l200-check-row input[type="checkbox"] {
	flex: 0 0 auto;
	height: 1.15rem;
	width: 1.15rem;
}

/* The stored application, shown in the admin panel. Pre-wrap keeps the question/answer
   layout the handler wrote without needing markup in the record. */
.l200-application {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	font-family: inherit;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.55;
	margin: 0;
	max-height: 26rem;
	overflow: auto;
	padding: 0.8rem;
	white-space: pre-wrap;
	width: 100%;
}

/* ==========================================================================
   Board cards and topic rows, rebuilt
   Three references, three different things worth taking:
     - a card grid with a stat footer, so a board states its size (Shopify)
     - a coloured rail and an icon tile, so boards are told apart at a glance (Coda)
     - a LAST POST column with the poster's face, so the index shows life (phpBB)
   The last one is the one a forum actually lives on and the one this site lacked.
   ========================================================================== */

.l200-boards {
	gap: var(--wp--preset--spacing--20);
	grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
}

/* auto-FILL, not auto-fit. With auto-fit a lone board on a wide screen stretches to the
   full 1600px and reads as a banner rather than a card; auto-fill keeps empty tracks so
   the card stays card-sized however few there are. */

.l200-board {
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	overflow: hidden;
	padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--20) 0;
	position: relative;
}

/* The rail. A pseudo-element rather than a border so it cannot fight the card's own
   outline, and tinted from a custom property set inline per board. */
.l200-board::before {
	background: var(--board-tint, var(--wp--preset--color--accent));
	bottom: 0;
	content: "";
	left: 0;
	position: absolute;
	top: 0;
	width: 5px;
}

.l200-board__head {
	align-items: flex-start;
	display: flex;
	gap: 0.75rem;
	padding-left: 0.35rem;
}

/* The icon tile. Tinted at 12% so it reads as belonging to the rail without shouting;
   flex 0 0 auto so a long board name cannot squeeze it out of square. */
.l200-board__icon {
	align-items: center;
	background: color-mix(in srgb, var(--board-tint, var(--wp--preset--color--accent)) 12%, #FFF);
	border-radius: 10px;
	display: inline-flex;
	flex: 0 0 auto;
	font-size: 1.25rem;
	height: 42px;
	justify-content: center;
	line-height: 1;
	width: 42px;
}

.l200-board__ident {
	min-width: 0;
}

.l200-board__title {
	font-size: var(--wp--preset--font-size--large);
	margin: 0 0 0.2rem;
}

/* The stretched link: the whole card is one tap target. Everything else in the card that
   needs its own destination raises itself above this with z-index. */
.l200-board__title a::after {
	content: "";
	inset: 0;
	position: absolute;
	z-index: 0;
}

.l200-board__desc {
	font-size: var(--wp--preset--font-size--x-small);
	line-height: 1.55;
	margin: 0;
}

.l200-board__stats {
	color: var(--wp--preset--color--muted);
	display: flex;
	flex-wrap: wrap;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.9rem;
	margin: 0;
	padding-left: 0.35rem;
}

.l200-board__stat strong {
	color: var(--wp--preset--color--contrast);
	font-weight: 700;
}

/* Last post. Full-bleed to the card edges and sitting on its own tint so it reads as a
   footer strip rather than another paragraph — this is the row that tells a visitor the
   forum is alive, so it gets to look like its own thing. */
.l200-board__last {
	align-items: center;
	background: color-mix(in srgb, var(--board-tint, var(--wp--preset--color--accent)) 7%, #FFF);
	border-top: 1px solid var(--wp--preset--color--line);
	display: flex;
	gap: 0.6rem;
	/* auto on top pins the strip to the bottom of a flex column, so cards of different
	   heights still line their footers up. The -1rem sides cancel the card's own 1rem
	   padding so the strip runs edge to edge; keep the two numbers equal if either
	   changes. The extra 5px on the left clears the rail. */
	margin: auto -1rem 0;
	padding: 0.7rem 1rem 0.7rem calc(1rem + 5px);
	position: relative;
	text-decoration: none;
	z-index: 1;
}

.l200-board__last img,
.l200-board__last .l200-avatar-initial {
	border-radius: 50%;
	flex: 0 0 auto;
	height: 32px;
	width: 32px;
}

.l200-board__last-text {
	display: grid;
	gap: 0.1rem;
	min-width: 0;
}

/* One line, clipped. A wrapped two-line title here would make every card a different
   height and the grid would comb. */
.l200-board__last-title {
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.l200-board__last-meta {
	color: var(--wp--preset--color--muted);
	font-size: 0.72rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.l200-board__last:hover .l200-board__last-title {
	color: var(--wp--preset--color--accent-bright);
	text-decoration: underline;
}

.l200-board__last--empty {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	font-style: italic;
}

/* --- Latest / Top tabs ----------------------------------------------------- */

.l200-section-head--tabs {
	align-items: flex-end;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	justify-content: space-between;
}

.l200-tabs {
	background: color-mix(in srgb, var(--wp--preset--color--contrast) 6%, #FFF);
	border-radius: 999px;
	display: inline-flex;
	gap: 0.15rem;
	padding: 0.2rem;
}

.l200-tab {
	border-radius: 999px;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 700;
	padding: 0.4rem 1rem;
	text-decoration: none;
	transition: background .15s ease, color .15s ease;
}

.l200-tab:hover {
	color: var(--wp--preset--color--contrast);
}

.l200-tab.is-on {
	background: var(--wp--preset--color--accent);
	color: #FFF;
}

/* --- Topic rows: a face, then the thread ----------------------------------- */

/* `.l200-latest .l200-latest__item`, not the bare class, and the extra class is doing real
   work. app.css declares `.l200-latest__item { display: grid }` and app.css loads AFTER
   this file, so a bare `.l200-latest__item { display: flex }` here loses at equal
   specificity and loses SILENTLY — the avatar quietly stacked above the title instead of
   sitting beside it, on a page that otherwise looked fine. Trap 3 in the session notes,
   walked into again. Two classes (0,2,0) beats one (0,1,0) from any file.

   min-width: 0 because this is a grid item of .l200-latest, and grid items default to
   min-width: auto — without it a long title sets the track's min-content and the row
   refuses to shrink on a narrow phone. */
.l200-latest .l200-latest__item {
	align-items: center;
	display: flex;
	gap: 0.8rem;
	min-width: 0;
}

.l200-latest__item > img,
.l200-latest__item > .l200-avatar-initial {
	border-radius: 50%;
	flex: 0 0 auto;
	height: 36px;
	width: 36px;
}

/* min-width: 0 so a long title shrinks this track instead of pushing the row wider than
   the card — the same guard the member cards need, for the same reason. */
.l200-latest__text {
	display: grid;
	gap: 0.3rem;
	min-width: 0;
}

/* The board chip, with a dot in the board's own rail colour so a row and its card read as
   the same place. */
.l200-latest__board {
	align-items: center;
	display: inline-flex;
	gap: 0.35rem;
}

.l200-latest__board::before {
	background: var(--board-tint, var(--wp--preset--color--accent));
	border-radius: 50%;
	content: "";
	height: 7px;
	width: 7px;
}

/* --- Mobile ---------------------------------------------------------------- */

@media (max-width: 700px) {
	.l200-boards {
		grid-template-columns: 1fr;
	}

	/* The tab row goes full width: thumb-sized targets rather than small pills tucked in a
	   corner. */
	.l200-section-head--tabs {
		align-items: stretch;
		flex-direction: column;
	}

	.l200-tabs {
		width: 100%;
	}

	/* `1 1 auto`, NOT `1 1 0`. Equal thirds would hand "Top" as much room as "Unanswered"
	   and then clip the long one — the widest label is the one that decides whether the row
	   fits. Sizing from content lets each tab take what its word needs and share out only
	   the slack. Padding drops with it, since three labels have to fit where two did. */
	.l200-tab {
		flex: 1 1 auto;
		padding-inline: 0.7rem;
		text-align: center;
		white-space: nowrap;
	}

	.l200-board__icon {
		font-size: 1.1rem;
		height: 36px;
		width: 36px;
	}

	/* Nothing here truncates on a phone. There is one card across, so there is room for
	   the title to wrap, and a clipped title on the narrowest screen is where an ellipsis
	   costs the most. */
	.l200-board__last-title {
		white-space: normal;
	}
}

/* --- Member stats: three figures where there were two ---------------------- */

/* The row was a nowrap flex with a 1.1rem gap, which fitted two numbers and would have
   pushed the third off the edge of a narrow card. Wrapping with a tighter column gap keeps
   all three on one line at normal widths and drops them onto two lines rather than
   overflowing when the card is small. */
.l200-member__stats {
	flex-wrap: wrap;
	gap: 0.3rem 0.9rem;
}

/* --- Profile: their replies, each linking to the reply itself -------------- */

.l200-profile__replies li {
	display: grid;
	gap: 0.15rem;
}

.l200-profile__snippet,
.l200-profile__when {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
}

/* Member-written text again, so the same guard as the post bodies: one pasted URL in a
   reply would otherwise set this list's min-content width and push the page sideways. */
.l200-profile__snippet {
	overflow-wrap: anywhere;
}

/* ==========================================================================
   Photo lightbox
   Opening a photo used to mean leaving the thread. This keeps the reader where
   they were: the picture fills the screen, escape or a tap on the backdrop puts
   it away, and the conversation is still underneath.
   ========================================================================== */

/* The `hidden` attribute is only display:none at user-agent strength, so ANY class rule
   setting display beats it. This one sets `display: flex`, which is exactly the collision
   that left both cropper panels on screen at once — hence the explicit [hidden] guard
   rather than trusting the attribute. */
.l200-lb {
	align-items: center;
	background: rgba(0, 12, 24, 0.94);
	display: flex;
	gap: 0.5rem;
	inset: 0;
	justify-content: center;
	padding: clamp(0.5rem, 3vw, 2rem);
	position: fixed;
	z-index: 9999;
}

.l200-lb[hidden] {
	display: none;
}

.l200-lb__stage {
	align-items: center;
	display: flex;
	justify-content: center;
	max-height: 100%;
	min-width: 0;
}

/* The photo is the point, so it gets the whole viewport minus the controls. object-fit
   contain rather than cover: cropping somebody's truck to fill a box is the one thing a
   photo viewer must never do. */
.l200-lb__img {
	border-radius: 6px;
	display: block;
	max-height: 88vh;
	max-width: 100%;
	object-fit: contain;
}

.l200-lb__btn {
	align-items: center;
	background: rgba(255, 255, 255, 0.12);
	border: 1px solid rgba(255, 255, 255, 0.28);
	border-radius: 50%;
	color: #FFF;
	cursor: pointer;
	display: inline-flex;
	flex: 0 0 auto;
	font-size: 1.6rem;
	height: 46px;
	justify-content: center;
	line-height: 1;
	padding: 0;
	transition: background .15s ease, border-color .15s ease;
	width: 46px;
}

.l200-lb__btn:hover {
	background: rgba(255, 255, 255, 0.24);
	border-color: rgba(255, 255, 255, 0.55);
}

.l200-lb__btn:focus-visible {
	outline: 2px solid #FFF;
	outline-offset: 3px;
}

.l200-lb__btn[hidden] {
	display: none;
}

.l200-lb__close {
	position: absolute;
	right: clamp(0.5rem, 3vw, 2rem);
	top: clamp(0.5rem, 3vw, 2rem);
}

.l200-lb__counter,
.l200-lb__caption {
	bottom: clamp(0.5rem, 3vw, 2rem);
	color: rgba(255, 255, 255, 0.82);
	font-size: var(--wp--preset--font-size--x-small);
	left: 0;
	margin: 0;
	position: absolute;
	right: 0;
	text-align: center;
}

.l200-lb__counter {
	bottom: calc(clamp(0.5rem, 3vw, 2rem) + 1.4rem);
	font-variant-numeric: tabular-nums;
}

.l200-lb__caption {
	font-weight: 600;
}

.l200-lb__counter[hidden],
.l200-lb__caption[hidden] {
	display: none;
}

/* Lock the page behind the overlay. Without this the thread scrolls under the photo on a
   phone, and closing drops the reader somewhere they never chose to be. */
.l200-lb-open,
.l200-lb-open body {
	overflow: hidden;
}

@media (max-width: 700px) {
	/* The arrows leave the sides of the photo and sit at the bottom, where a thumb is. Side
	   arrows on a narrow screen either overlap the picture or squeeze it to nothing, and
	   swiping is the gesture people reach for first anyway — these are the fallback. */
	.l200-lb {
		flex-wrap: wrap;
	}

	.l200-lb__stage {
		flex: 1 0 100%;
		order: 1;
	}

	.l200-lb__img {
		max-height: 72vh;
	}

	.l200-lb__prev {
		order: 2;
	}

	.l200-lb__next {
		order: 3;
	}

	.l200-lb__prev,
	.l200-lb__next {
		margin-bottom: 2.6rem;
	}
}

/* ==========================================================================
   Buy & Sell
   Cards carry a photo, because on a classifieds page the picture IS the advert.
   Everything else — price, category, where it is — is secondary to whether the
   thing looks right.
   ========================================================================== */

/* A single column of wide rows, not a grid of tiles. See the note on the card renderer:
   a tile grid is a gallery, and this is a classifieds page. */
.l200-listings {
	display: grid;
	gap: 0.75rem;
	margin-bottom: var(--wp--preset--spacing--40);
}

.l200-listing {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	display: grid;
	/* The photo column is fixed so every price in the list starts at the same x — the eye
	   runs down one straight edge instead of a ragged one, which is most of why a
	   classifieds page feels orderly. */
	grid-template-columns: 260px 1fr;
	overflow: hidden;
	position: relative;
	transition: border-color .18s ease, box-shadow .18s ease;
}

/* White card on the grey page ground, not grey-on-grey: a listing should read as an object
   you could pick up. Hover raises the edge rather than lifting the card — a 3px jump on a
   dense list of rows is fidgety in a way it is not on a sparse grid of tiles. */
.l200-listing:hover {
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 6px 18px rgba(0, 41, 79, 0.14);
}

/* Fixed 4:3 so a portrait phone photo and a landscape one leave the rows the same height. */
.l200-listing__media {
	aspect-ratio: 4 / 3;
	background: var(--wp--preset--color--surface-raised);
	position: relative;
}

.l200-listing__media > img {
	display: block;
	height: 100%;
	object-fit: cover;
	width: 100%;
}

/* DIRECT CHILD only. As `.l200-listing__media img` this would also catch anything nested
   inside a badge later — the same mistake that once stretched a 26px avatar to 261px. */

.l200-listing__noimage {
	align-items: center;
	display: flex;
	font-size: 2rem;
	height: 100%;
	justify-content: center;
	opacity: 0.45;
}

.l200-listing__sold,
.l200-listing__flag {
	border-radius: 999px;
	font-size: 0.72rem;
	font-weight: 700;
	left: 0.6rem;
	letter-spacing: 0.04em;
	padding: 0.25rem 0.6rem;
	position: absolute;
	text-transform: uppercase;
	top: 0.6rem;
}

/* Sold uses the ink, NOT club-red. Red means error on this site and a sold advert is a
   success — it is the whole point of the page. */
.l200-listing__sold {
	background: var(--wp--preset--color--contrast);
	color: #FFF;
}

.l200-listing__flag {
	background: var(--wp--preset--color--accent);
	color: #FFF;
}

/* A sold card stays legible but stops competing with the live ones. */
.l200-listing.is-sold .l200-listing__media > img {
	filter: grayscale(1);
	opacity: 0.6;
}

.l200-listing__body {
	align-content: start;
	display: grid;
	gap: 0.3rem;
	min-width: 0;
	padding: var(--wp--preset--spacing--20);
}

.l200-listing__title {
	font-size: var(--wp--preset--font-size--large);
	margin: 0;
	overflow-wrap: anywhere;
}

.l200-listing__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

/* Stretched link: the whole row is one target. */
.l200-listing__title a::after {
	content: "";
	inset: 0;
	position: absolute;
}

.l200-listing__title a:hover {
	color: var(--wp--preset--color--accent-bright);
}

/* The biggest thing in the card, and first in the source. On a page people scan by price,
   anything else being louder is a design that fights its own reader. */
.l200-listing__price {
	color: var(--wp--preset--color--accent);
	font-size: 1.65rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1.1;
}

.l200-listing__price.is-poa,
.l200-listing__price.is-free {
	font-size: 1.1rem;
	font-weight: 700;
}

.l200-listing__blurb {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	margin: 0.1rem 0 0;
	overflow-wrap: anywhere;
}

/* --- Spec chips ---
   Deliberately quieter than the interactive chips elsewhere: these are facts, not controls,
   and making them look clickable would be a lie the cursor immediately exposes. */
.l200-listing__specs {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	margin: 0.25rem 0 0;
}

.l200-spec {
	background: var(--wp--preset--color--surface-raised);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 6px;
	color: var(--wp--preset--color--contrast);
	font-size: 0.74rem;
	font-weight: 600;
	padding: 0.22rem 0.55rem;
	white-space: nowrap;
}

.l200-spec--place::before {
	content: "📍 ";
}

.l200-listing__meta {
	color: var(--wp--preset--color--muted);
	display: flex;
	flex-wrap: wrap;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.6rem;
	margin: 0.35rem 0 0;
}

/* --- Search rail --------------------------------------------------------- */

.l200-market-search {
	align-items: end;
	background: #EDF1F6;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	display: grid;
	gap: 0.75rem;
	grid-template-columns: 2fr 1fr 1fr 1.4fr auto;
	margin-bottom: var(--wp--preset--spacing--30);
	padding: var(--wp--preset--spacing--20);
}

.l200-market-search .l200-field {
	margin: 0;
	min-width: 0;
}

.l200-market-search label {
	font-size: 0.72rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.l200-market-search__go {
	margin: 0;
}

.l200-market-search__go .l200-btn {
	white-space: nowrap;
}

/* --- The category filter row --- */

.l200-market-cats {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin-bottom: var(--wp--preset--spacing--30);
}

/* --- Single listing --- */

.l200-listing-facts {
	background: #EDF1F6;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	display: grid;
	gap: 0.85rem;
	grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
	margin: var(--wp--preset--spacing--30) 0;
	padding: var(--wp--preset--spacing--20);
}

.l200-listing-facts dt {
	color: var(--wp--preset--color--muted);
	font-size: 0.72rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.l200-listing-facts dd {
	font-weight: 700;
	margin: 0.15rem 0 0;
	overflow-wrap: anywhere;
}

.l200-listing-detail__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin-bottom: var(--wp--preset--spacing--30);
}

.l200-listing-detail__sold {
	border-left: 4px solid var(--wp--preset--color--contrast);
}

/* --- The safety notice ---------------------------------------------------
   Deliberately not styled as an error. club-red means "something went wrong"
   everywhere else on this site, and a permanent red block trains people to
   ignore it — which on the one notice that actually protects them is the
   worst possible outcome. Ink and a heavy left rule reads as "read this".
   ------------------------------------------------------------------------ */

.l200-market-safety {
	background: #EDF1F6;
	border: 1px solid var(--wp--preset--color--contrast);
	border-left-width: 5px;
	border-radius: 10px;
	color: var(--wp--preset--color--contrast);
	margin-bottom: var(--wp--preset--spacing--30);
}

.l200-market-safety p {
	margin: 0 0 0.5rem;
}

.l200-market-safety__list {
	font-size: var(--wp--preset--font-size--small);
	margin: 0;
	padding-left: 1.15rem;
}

.l200-market-safety__list li {
	margin-bottom: 0.3rem;
}

.l200-market-cta h2 {
	font-size: var(--wp--preset--font-size--x-large);
	margin: 0 0 0.5rem;
}

/* Between a phone and a desktop the fixed 260px photo column starts eating the text, so the
   photo narrows before the card gives up and stacks. */
@media (max-width: 900px) {
	.l200-listing {
		grid-template-columns: 190px 1fr;
	}

	.l200-market-search {
		grid-template-columns: 1fr 1fr;
	}

	.l200-market-search__q {
		grid-column: 1 / -1;
	}

	.l200-market-search__go {
		grid-column: 1 / -1;
	}

	.l200-market-search__go .l200-btn {
		width: 100%;
	}
}

@media (max-width: 560px) {
	/* Photo on top on a phone. A 190px image beside text leaves neither enough room, and the
	   photo is what makes somebody stop scrolling. */
	.l200-listing {
		grid-template-columns: 1fr;
	}

	.l200-listing__media {
		aspect-ratio: 16 / 9;
	}

	.l200-market-search {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   Thread density
   Measured before touching anything: eight short replies made a 4,840px page,
   5.4 screens. The text column was 698px inside a 1,217px card — 43% of every
   reply was empty — and a one-line reply cost 169px, of which 29px was the
   sentence. The chrome was more expensive than the content.
   ========================================================================== */

/* 24px of padding and a 24px gap on a card whose content is one line is most of the
   problem. Both come down; nothing is removed. */
.l200-reply {
	padding: var(--wp--preset--spacing--20);
}

.l200-replies {
	gap: 0.75rem;
}

/* The header was a full row for three short things, and the banner is what forced it —
   540px wide and 135px tall in EVERY reply. It keeps its shape and its place beside the
   poster, capped to the height of the avatar row so it reads as a flourish next to a name
   rather than a billboard above a sentence. See the note in the reply on this: it partly
   walks back the "make the banner bigger" change, deliberately and reversibly. */
.l200-reply__by {
	gap: 0.5rem;
	margin-bottom: 0.6rem;
	padding-bottom: 0.45rem;
}

.l200-reply__by .l200-reply__banner {
	max-height: 56px;
	width: auto;
}

/* The actions row loses its rule and most of its spacing but stays VISIBLE. Hiding it
   until hover was the original plan and it was wrong twice over: it saves no height at all
   because the row still occupies the layout, and it hides the controls from everyone on a
   touch screen, where hover does not exist. Quieter, not hidden. */
.l200-reply__actions {
	border-top: 0;
	gap: 0.3rem;
	margin-top: 0.55rem;
	padding-top: 0;
}

/* --- The photo goes in the dead space ------------------------------------
   Attached photos sat BELOW the text at 392px tall while 43% of the card sat
   empty BESIDE it. Floating the photo right fills the void and removes the
   height in one move — the tallest reply measured 770px and should land near
   half that.

   GRID, not float — and the first attempt used a float, which is why this
   note exists. A right float cannot rise above content that precedes it in
   the source: on a reply with three paragraphs before the photo, it floated
   right but STARTED below them, so the dead space at the top stayed dead and
   the page only came down 22% instead of the expected 46%.

   Explicit grid placement puts the photo in the second column starting at the
   first row whatever its position in the markup, so the source order stays as
   it reads — text, then photo — which is also the order a screen reader wants.
   `span 100` rather than `1 / -1` because the rows here are implicit, and -1
   resolves against explicit lines that do not exist.
   ------------------------------------------------------------------------ */

@media (min-width: 900px) {
	.l200-reply__body:has(.l200-reply__photo) {
		display: grid;
		gap: 0 1.25rem;
		grid-template-columns: minmax(0, 1fr) 340px;
	}

	.l200-reply__body:has(.l200-reply__photo) > * {
		grid-column: 1;
		min-width: 0;
	}

	.l200-reply__body .l200-reply__photo {
		align-self: start;
		grid-column: 2;
		grid-row: 1 / span 100;
		margin: 0;
		max-width: 340px;
	}
}

/* --- The opening post is the question ------------------------------------
   It was styled identically to the replies, so a thread read as nine equal
   boxes with no way to tell the question from the answers. White ground
   against the grey replies, a heavier edge and slightly larger type: the
   thing being asked should look like the thing being asked.
   ------------------------------------------------------------------------ */

.l200-topic-post {
	background: var(--wp--preset--color--base);
	border-width: 2px;
}

.l200-topic-post__body {
	font-size: 1.08rem;
}

/* --- Accepted answer, promoted -------------------------------------------
   On a fault-diagnosis forum somebody arriving from a search wants the fix,
   not eight posts of context. When a topic has an accepted answer a copy is
   rendered directly under the question, with a link down to it in place.
   ------------------------------------------------------------------------ */

.l200-answer-first {
	background: color-mix(in srgb, var(--wp--preset--color--club-green) 7%, #FFF);
	border: 2px solid var(--wp--preset--color--club-green);
	border-radius: 12px;
	margin: var(--wp--preset--spacing--30) 0;
	padding: var(--wp--preset--spacing--20);
}

/* club-green, and here it is not decoration: green MEANS solved on this site, and this is
   the one block on the page that is literally the solution. */
.l200-answer-first__label {
	align-items: center;
	color: var(--wp--preset--color--club-green);
	display: flex;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 800;
	gap: 0.4rem;
	letter-spacing: 0.06em;
	margin: 0 0 0.5rem;
	text-transform: uppercase;
}

.l200-answer-first__body {
	overflow-wrap: anywhere;
}

.l200-answer-first__body > :first-child {
	margin-top: 0;
}

.l200-answer-first__body > :last-child {
	margin-bottom: 0;
}

.l200-answer-first__who {
	color: var(--wp--preset--color--muted);
	display: flex;
	flex-wrap: wrap;
	font-size: var(--wp--preset--font-size--x-small);
	gap: 0.5rem;
	margin: 0.6rem 0 0;
}

.l200-answer-first__who a {
	font-weight: 700;
}

@media (max-width: 560px) {
	/* The banner is decoration and this is a phone. The name, the badges and what they
	   drive are all still there. */
	.l200-reply__by .l200-reply__banner {
		display: none;
	}
}
