/*
	Self-hosted so no page makes a request to a third-party font host. Two faces ship,
	Heebo and Frank Ruhl Libre. Two Heebo files: the Hebrew subset carries no digits and
	no Latin, which the dates and the phone numbers need. Frank Ruhl Libre sets the
	wordmark and the page headings; it ships Hebrew only and falls back to Heebo outside
	that range.
*/

@font-face {
	font-family: 'Heebo';
	src: url("../fonts/heebo-hebrew.de80852899c5.woff2") format('woff2');
	font-weight: 400 700;
	font-display: swap;
	unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

@font-face {
	font-family: 'Heebo';
	src: url("../fonts/heebo-latin.480b1d24f2aa.woff2") format('woff2');
	font-weight: 400 700;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Frank Ruhl Libre';
	src: url("../fonts/frank-ruhl-libre-hebrew.57720a889009.woff2") format('woff2');
	font-weight: 400 900;
	font-display: swap;
	unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

/* Custom properties. Every colour in the project is defined here and nowhere else. */

:root {
	--color-page-background: #ffffff;
	--color-surface: #ffffff;
	--color-surface-raised: #fdf8ee;
	--color-text: #2a2018;
	--color-text-muted: #6f6152;
	--color-border: #e8dfcd;
	--color-accent: #e2971f;
	--color-accent-hover: #c67f10;
	--color-accent-text: #2a1c08;
	--color-accent-soft: #fbeacb;
	--color-link: #97590a;
	--color-link-hover: #7a4708;
	--color-error: #a8261c;
	--color-error-background: #fbe9e6;
	/*
		The two listing states that are not a fault. Draft is deliberately hotter than the
		marigold accent and cooler than the error brick: a home nobody can see yet is neither
		an ordinary control nor something that went wrong. Hidden by an administrator has no
		pair of its own and reuses the error one.
	*/
	--color-draft: #e0670f;
	--color-draft-soft: #fde3cd;
	--color-live: #4a7a2b;
	--color-live-soft: #edf4e3;
	/*
		The one red that is not a fault: it marks the offer most owners choose. Deeper than
		the error brick so the two are never read as the same thing.
	*/
	--color-popular: #b3271d;
	--color-shadow: rgba(42, 32, 24, 0.13);
	--color-card-shadow: rgba(42, 32, 24, 0.22);
	--color-scrim: rgba(253, 248, 238, 0.55);
	--color-overlay: rgba(20, 15, 10, 0.97);
	--color-overlay-text: #f7f2e8;
	--color-overlay-control: rgba(20, 15, 10, 0.6);

	--space-tiny: 0.25rem;
	--space-small: 0.5rem;
	--space-medium: 1rem;
	--space-large: 1.5rem;
	--space-huge: 2.5rem;

	--font-family-base: 'Heebo', sans-serif;
	--font-family-display: 'Frank Ruhl Libre', 'Heebo', serif;
	--font-weight-strong: 700;
	--font-size-tiny: 0.75rem;
	--font-size-small: 0.875rem;
	--font-size-base: 1rem;
	--font-size-large: 1.125rem;
	--font-size-section-title: 1.375rem;
	--font-size-page-title: 1.75rem;
	--font-size-hero: 2.25rem;

	--radius-small: 4px;
	--radius-medium: 10px;
	--page-width: 1240px;
	--filter-sidebar-width: 16rem;
	--listing-card-min-width: 15rem;
	--detail-panel-width: 18rem;
	--listing-field-width: 20rem;
	--listing-field-narrow-width: 8rem;
	--detail-photo-width: 30rem;
	--photo-thumbnail-width: 6rem;
}

/* Reset and base typography */

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

body {
	margin: 0;
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
	font-family: var(--font-family-base);
	font-size: var(--font-size-base);
	line-height: 1.6;
	color: var(--color-text);
	background-color: var(--color-page-background);
}

h1,
h2,
h3 {
	margin: 0 0 var(--space-medium);
	line-height: 1.3;
	font-weight: var(--font-weight-strong);
}

h1 {
	font-size: var(--font-size-page-title);
}

h2 {
	font-size: var(--font-size-section-title);
}

h3 {
	font-size: var(--font-size-large);
}

p {
	margin: 0 0 var(--space-medium);
}

a {
	color: var(--color-link);
	text-decoration: none;
}

a:hover {
	color: var(--color-link-hover);
	text-decoration: underline;
}

img {
	max-width: 100%;
	height: auto;
}

ul {
	margin: 0 0 var(--space-medium);
	padding-inline-start: var(--space-large);
}

:focus-visible {
	outline: 2px solid var(--color-link);
	outline-offset: 2px;
}

/* Page container, header, footer */

.page-container {
	width: 100%;
	max-width: var(--page-width);
	margin-inline: auto;
	padding-inline: var(--space-large);
}

.page-main {
	flex: 1;
	padding-block: var(--space-huge);
}

.page-header {
	background-color: var(--color-surface-raised);
	border-block-end: 1px solid var(--color-border);
}

.page-header-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-medium);
	padding-block: var(--space-medium);
}

/*
	The whole lockup is one link, and the mark is a sibling of the two lines rather than of
	the name alone. That is what squares the block: the mark stands against both lines
	instead of against the name only, and the name and the slogan start from one edge with
	no indent to keep in step with the mark's size.
*/
.site-name {
	display: flex;
	align-items: center;
	gap: var(--space-small);
	font-family: var(--font-family-display);
	font-size: var(--font-size-section-title);
	font-weight: var(--font-weight-strong);
	color: var(--color-text);
}

.site-name:hover {
	color: var(--color-link);
	text-decoration: none;
}

/*
	The mark is a line rather than a filled block, so it carries the wordmark's ink through
	currentColor and paints only the sun in the accent - which is also why there is no
	colour declaration here: the mark follows the name into the link colour on hover, which
	the filled amber version could not.

	The size is set rather than stretched to the text: a stretched mark would feed its own
	width back into the line the slogan has to fit on, and the slogan would wrap and make
	it taller again. 3.125rem is the two lines together (1.375rem at 1.15, then 0.8125rem
	at 1.2) divided by the share of the box the drawing actually covers - it spans 53 of
	the 64 units, evenly inset - which lands the roof at the top of the name and the floor
	under the slogan.
*/
.site-mark {
	display: block;
	inline-size: 3.125rem;
	block-size: 3.125rem;
}

.site-wordmark {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

/* Tight enough that the slogan reads as the name's second line and not as a line of its own. */
.site-title {
	line-height: 1.15;
}

/*
	The slogan is a subtitle, not a second signature: the body face at small size, opened up
	with letter-spacing so it sits under the name at about the name's own width, in muted
	ink rather than a second amber.
*/
.site-tagline {
	font-family: var(--font-family-base);
	font-size: 0.8125rem;
	font-weight: 400;
	letter-spacing: 0.22em;
	line-height: 1.2;
	color: var(--color-text-muted);
}

.header-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-medium);
}

.header-link {
	font-size: var(--font-size-small);
	font-weight: 500;
	color: var(--color-text);
}

.header-link:hover {
	color: var(--color-link);
	text-decoration: none;
}

.header-logout-form {
	margin: 0;
	display: flex;
}

.header-logout-button {
	padding: 0;
	border: 0;
	background: none;
	font-family: inherit;
	cursor: pointer;
}

.page-footer {
	background-color: var(--color-surface-raised);
	border-block-start: 1px solid var(--color-border);
	padding-block: var(--space-large);
}

.footer-links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-large);
}

.footer-link {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.footer-link:hover {
	color: var(--color-link);
	text-decoration: none;
}

/* Forms, labels, validation errors, buttons */

form section {
	margin-block-end: var(--space-huge);
}

label {
	display: block;
	margin-block-end: var(--space-tiny);
	font-size: var(--font-size-small);
	font-weight: 500;
	color: var(--color-text);
}

input[type='text'],
input[type='email'],
input[type='tel'],
input[type='number'],
input[type='date'],
input[type='file'],
select,
textarea {
	display: block;
	width: 100%;
	max-width: 32rem;
	margin-block-end: var(--space-medium);
	padding: var(--space-small);
	font-family: inherit;
	font-size: var(--font-size-base);
	color: var(--color-text);
	background-color: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-small);
}

textarea {
	min-height: 8rem;
	resize: vertical;
}

input[type='checkbox'] {
	margin-inline-end: var(--space-tiny);
	accent-color: var(--color-accent);
}

input.honeypot {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	overflow: hidden;
	opacity: 0;
	pointer-events: none;
}

.errorlist,
.error-message {
	max-width: 32rem;
	margin: calc(-1 * var(--space-small)) 0 var(--space-medium);
	padding: var(--space-small) var(--space-medium);
	list-style: none;
	font-size: var(--font-size-small);
	color: var(--color-error);
	background-color: var(--color-error-background);
	border-radius: var(--radius-small);
}

.errorlist:empty {
	display: none;
}

.notice {
	padding: var(--space-medium);
	color: var(--color-text-muted);
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

button,
.button {
	display: inline-block;
	padding: var(--space-small) var(--space-large);
	font-family: inherit;
	font-size: var(--font-size-base);
	font-weight: 500;
	color: var(--color-accent-text);
	background-color: var(--color-accent);
	border: 1px solid var(--color-accent);
	border-radius: var(--radius-small);
	cursor: pointer;
	transition: background-color 0.15s;
}

button:hover,
.button:hover {
	color: var(--color-accent-text);
	background-color: var(--color-accent-hover);
	text-decoration: none;
}

.header-link.header-logout-button,
.header-link.header-logout-button:hover {
	color: var(--color-text);
	background: none;
	border: 0;
	font-size: var(--font-size-small);
}

.header-link.header-logout-button:hover {
	color: var(--color-accent);
}

/* Declining, withdrawing and hiding are not what the page is asking you to do. */
.button-quiet,
button.button-quiet {
	color: var(--color-text);
	background-color: transparent;
	border-color: var(--color-border);
}

.button-quiet:hover,
button.button-quiet:hover {
	color: var(--color-text);
	background-color: var(--color-surface-raised);
	border-color: var(--color-text-muted);
}

/*
	The listing form's first section. Every field there answers in a word or a number,
	so the 32rem the shared form rules give them reads as an empty stretch. The
	description below them is a textarea and keeps the full width, which is why these
	rules name the controls rather than the section.
*/
.listing-form-details select,
.listing-form-details .ts-wrapper {
	max-width: var(--listing-field-width);
}

.listing-form-counts input,
.listing-form-counts select {
	max-width: var(--listing-field-narrow-width);
}

.feature-list,
.availability-list {
	list-style: none;
	padding-inline-start: 0;
}

.feature-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-small) var(--space-large);
}

.feature-list label {
	font-weight: 400;
}

.listing-open-availability {
	display: flex;
	flex-direction: column;
	gap: var(--space-small);
	margin-block-end: var(--space-large);
}

.listing-open-availability label {
	font-weight: 400;
}

/*
	The mark on the standing offer most owners choose. It is a star and two words side by
	side in the text flow, so it wraps with the label instead of sticking out of it, and
	nothing is drawn around the words for them to overflow.
*/
.listing-open-availability-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--space-tiny);
	margin-inline-start: var(--space-small);
	font-size: var(--font-size-tiny);
	font-weight: var(--font-weight-strong);
	white-space: nowrap;
	color: var(--color-popular);
	animation: popular-pop 0.4s cubic-bezier(0.34, 1.4, 0.64, 1) both;
}

.listing-open-availability-star {
	inline-size: 0.8rem;
	block-size: 0.8rem;
	fill: var(--color-popular);
}

@keyframes popular-pop {
	from {
		opacity: 0;
		transform: scale(0.6);
	}
}

.availability-list li {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-medium);
	margin-block-end: var(--space-small);
}

/* Photo box: the drop area, and the tiles the formset renders */

.photo-box {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-tiny);
	padding: var(--space-huge) var(--space-large);
	margin-block-end: var(--space-medium);
	text-align: center;
	cursor: pointer;
	background-color: var(--color-surface-raised);
	border: 2px dashed var(--color-border);
	border-radius: var(--radius-medium);
}

.photo-box:hover,
.photo-box.is-receiving {
	border-color: var(--color-accent);
	border-style: solid;
}

.photo-box:focus-within {
	outline: 2px solid var(--color-link);
	outline-offset: 2px;
}

.photo-box-prompt {
	font-weight: var(--font-weight-strong);
}

.photo-box-hint,
.photo-box-reorder-hint {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

/*
	The file input stays in the page and stays reachable by keyboard - the box is its
	label - so it is folded away rather than hidden with display or visibility. Only once
	the script has run: without it, the input is the only way to choose a photo.
*/
.is-enhanced .photo-box input[type='file'] {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.photo-box-message:empty {
	display: none;
}

.photo-box-message {
	margin-block-end: var(--space-medium);
	padding: var(--space-small) var(--space-medium);
	border-radius: var(--radius-small);
	color: var(--color-error);
	background-color: var(--color-error-background);
}

/*
	The tiles are a column rather than a grid. SortableJS assumes DOM order runs left to
	right, so in a Hebrew row a tile could be dragged one way and never the other; its
	vertical logic compares tops and bottoms, which right-to-left does not touch.
*/
.photo-tile-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-small);
	max-inline-size: 32rem;
	list-style: none;
	margin: 0 0 var(--space-medium);
	padding-inline-start: 0;
}

.photo-tile {
	display: flex;
	align-items: center;
	gap: var(--space-medium);
	padding: var(--space-small);
	background-color: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

.is-enhanced .photo-tile {
	cursor: grab;
	/* The tile owns every touch gesture on it, or a drag to reorder scrolls the page instead. */
	touch-action: none;
}

.photo-tile.sortable-chosen {
	cursor: grabbing;
	box-shadow: 0 4px 12px var(--color-shadow);
}

.photo-tile.sortable-ghost {
	opacity: 0.4;
}

.photo-tile-image {
	flex: none;
	inline-size: var(--photo-thumbnail-width);
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background-color: var(--color-surface-raised);
	border-radius: var(--radius-small);
	user-select: none;
}

/* The cover is simply the first tile, so the badge needs no script to follow the drag. */
.photo-tile-badge {
	display: none;
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.photo-tile:first-child .photo-tile-badge {
	display: block;
}

/*
	The X is the formset's own delete checkbox. Marking a photo therefore needs no script
	at all, and un-marking it is another click. Until the script has run it stays a plain
	labelled checkbox, which is what a page without JavaScript needs.
*/
.is-enhanced .photo-tile-remove {
	flex: none;
	margin-inline: auto 0;
	inline-size: 1.75rem;
	block-size: 1.75rem;
	padding: 0;
	font-size: var(--font-size-large);
	line-height: 1.75rem;
	text-align: center;
	color: var(--color-overlay-text);
	background-color: var(--color-overlay-control);
	border: none;
	border-radius: 50%;
	cursor: pointer;
}

.is-enhanced .photo-tile-remove:hover {
	background-color: var(--color-error);
}

.is-enhanced .photo-tile-remove::after {
	content: '\00d7';
}

.is-enhanced .photo-tile-remove input,
.is-enhanced .photo-tile-remove-text,
.is-enhanced .photo-tile-order {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.is-enhanced .photo-tile-remove:focus-within {
	outline: 2px solid var(--color-link);
	outline-offset: 2px;
}

/* A marked photo is not gone yet: it is greyed, and the X reads as undo. */
.is-enhanced .photo-tile:has(input[type='checkbox']:checked) .photo-tile-image {
	opacity: 0.35;
	filter: grayscale(1);
}

.is-enhanced .photo-tile:has(input[type='checkbox']:checked) .photo-tile-remove {
	background-color: var(--color-accent);
	color: var(--color-accent-text);
}

.is-enhanced .photo-tile:has(input[type='checkbox']:checked) .photo-tile-remove::after {
	content: '\21ba';
}

.is-enhanced .photo-tile:has(input[type='checkbox']:checked) .photo-tile-badge {
	display: none;
}

/* Date range field, and the overrides the vendored calendar needs to read as Hebrew */

.date-range-trigger {
	cursor: pointer;
}

.availability-list .date-range-native,
.availability-list .date-range-combined {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-small) var(--space-medium);
}

/* An author display rule outranks the browser's own [hidden], so say it again here. */
.date-range-native[hidden],
.date-range-combined[hidden] {
	display: none;
}

.availability-list .date-range-trigger {
	width: auto;
	min-width: 14rem;
	margin-block-end: 0;
}

/* The calendar hardcodes direction: ltr, so the day grid has to be flipped back. */
.flatpickr-calendar {
	direction: rtl;
	font-family: inherit;
}

/*
	Flipping the grid does not move the arrows, which are pinned to the bar's edges.
	Previous belongs on the right in Hebrew, and both chevrons have to point the other
	way. The doubled class matches the library's own, which is how it wins.
*/
.flatpickr-calendar .flatpickr-months .flatpickr-prev-month.flatpickr-prev-month {
	left: auto;
	right: 0;
}

.flatpickr-calendar .flatpickr-months .flatpickr-next-month.flatpickr-next-month {
	right: auto;
	left: 0;
}

.flatpickr-calendar .flatpickr-months .flatpickr-prev-month svg,
.flatpickr-calendar .flatpickr-months .flatpickr-next-month svg {
	transform: scaleX(-1);
}

.flatpickr-calendar .flatpickr-months .flatpickr-prev-month:hover svg,
.flatpickr-calendar .flatpickr-months .flatpickr-next-month:hover svg {
	fill: var(--color-link);
}

.flatpickr-current-month,
.flatpickr-weekday {
	color: var(--color-text);
}

/*
	Two months side by side ran together: the library separates the day grids with a
	1px shadow in its own grey, on the physical side, and separates nothing at all
	in the header or the weekday row. One rule down the full height of the seam is
	what actually reads as two months.
*/
.flatpickr-calendar .dayContainer + .dayContainer {
	box-shadow: none;
	border-inline-start: 1px solid var(--color-border);
}

.flatpickr-calendar .flatpickr-months .flatpickr-month + .flatpickr-month,
.flatpickr-calendar .flatpickr-weekdays .flatpickr-weekdaycontainer + .flatpickr-weekdaycontainer {
	border-inline-start: 1px solid var(--color-border);
}

/*
	The month dropdown and year box are a select and a number input, so the project's
	own form-field styling lands on them and stretches them across the header.
*/
.flatpickr-calendar .flatpickr-current-month .numInput,
.flatpickr-calendar .flatpickr-monthDropdown-months {
	display: inline-block;
	width: auto;
	max-width: none;
	margin-block-end: 0;
	padding: 0;
	background-color: transparent;
	border: 0;
	border-radius: 0;
}

/*
	Every day rule below is prefixed with .flatpickr-calendar on purpose. The library
	styles its own days in the focused and hovered states too, and those selectors
	outrank a bare .flatpickr-day.selected - without the prefix a clicked day keeps
	the library's blue for as long as it holds focus.
*/

/* The two ends of the range, solid. */
.flatpickr-calendar .flatpickr-day.selected,
.flatpickr-calendar .flatpickr-day.startRange,
.flatpickr-calendar .flatpickr-day.endRange,
.flatpickr-calendar .flatpickr-day.selected:focus,
.flatpickr-calendar .flatpickr-day.startRange:focus,
.flatpickr-calendar .flatpickr-day.endRange:focus,
.flatpickr-calendar .flatpickr-day.selected:hover,
.flatpickr-calendar .flatpickr-day.startRange:hover,
.flatpickr-calendar .flatpickr-day.endRange:hover {
	color: var(--color-accent-text);
	background-color: var(--color-accent);
	border-color: var(--color-accent);
}

/* Everything between them, and the same band while the second end is being chosen. */
.flatpickr-calendar .flatpickr-day.inRange,
.flatpickr-calendar .flatpickr-day.inRange:focus,
.flatpickr-calendar .flatpickr-day.inRange:hover,
.flatpickr-calendar .flatpickr-day:focus,
.flatpickr-calendar .flatpickr-day:hover {
	color: var(--color-text);
	background-color: var(--color-accent-soft);
	border-color: var(--color-accent-soft);
}

/* The library draws the band's continuity with a side shadow, not with a width. */
.flatpickr-calendar .flatpickr-day.inRange {
	box-shadow: -5px 0 0 var(--color-accent-soft), 5px 0 0 var(--color-accent-soft);
}

/*
	The library rounds the two ends with physical left/right radii, written for an
	LTR calendar. This one is forced to RTL, so the start day sits on the right and
	every cap comes out rounded on the inside and square on the outside - the band
	reads as two open ends instead of one closed tube. Swapping the pairs puts the
	round side back on the outside.
*/
.flatpickr-calendar .flatpickr-day.selected.startRange,
.flatpickr-calendar .flatpickr-day.startRange.startRange,
.flatpickr-calendar .flatpickr-day.endRange.startRange {
	border-radius: 0 50px 50px 0;
}

.flatpickr-calendar .flatpickr-day.selected.endRange,
.flatpickr-calendar .flatpickr-day.startRange.endRange,
.flatpickr-calendar .flatpickr-day.endRange.endRange {
	border-radius: 50px 0 0 50px;
}

/* A one-day range is both ends at once and stays a full pill. */
.flatpickr-calendar .flatpickr-day.selected.startRange.endRange,
.flatpickr-calendar .flatpickr-day.startRange.startRange.endRange,
.flatpickr-calendar .flatpickr-day.endRange.startRange.endRange {
	border-radius: 50px;
}

/*
	The one-cell gap the library paints between two touching ends. Under RTL the
	next sibling renders to the left of its predecessor, so the gap to fill is on
	the other side of the cell.
*/
.flatpickr-calendar .flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)) {
	box-shadow: 10px 0 0 var(--color-accent);
}

/*
	At the seam between two months the library bridges the band across the gap in
	its own grey, and that rule is specific enough to outrank the inRange colour
	above. The two months are divided by a rule now, so the band should stop at
	each grid's edge rather than reach over it. Selector copied from the library so
	it matches on specificity and wins on order.
*/
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1) {
	box-shadow: none;
}

.flatpickr-calendar .flatpickr-day.today {
	border-color: var(--color-accent);
}

.flatpickr-calendar .flatpickr-day.flatpickr-disabled,
.flatpickr-calendar .flatpickr-day.flatpickr-disabled:hover {
	color: var(--color-text-muted);
	background-color: transparent;
	border-color: transparent;
	opacity: 0.4;
}

/*
	The city combobox. Tom Select builds its own wrapper beside the select and hides
	the select itself, so nothing here fights the form-field rules above - the shape
	they give every other field is restated on .ts-control instead. The library's
	core stylesheet carries no colours of its own beyond a grey border and a blue
	tint, so this is a repaint rather than the specificity exercise the calendar was.
	The one physical property is the library's own: the dropdown is positioned
	left: 0 at the full width of the field, which right-to-left does not touch.
*/
.ts-wrapper {
	max-width: 32rem;
	margin-block-end: var(--space-medium);
}

.ts-control {
	padding: var(--space-small);
	/* Room for the caret below, so a long name never runs under it. */
	padding-inline-end: var(--space-large);
	font-size: var(--font-size-base);
	color: var(--color-text);
	background-color: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-small);
}

.ts-wrapper.focus .ts-control {
	border-color: var(--color-accent);
}

/*
	The core stylesheet ships no caret - that lives in a theme this project does not
	load. Without one the field reads as a text box beside the selects under it, so
	the triangle is drawn here. It sits on the end edge, which is where the browser
	draws the arrow of every native select on this form.
*/
.ts-wrapper.single .ts-control::after {
	content: '';
	position: absolute;
	inset-block-start: 50%;
	inset-inline-end: var(--space-small);
	border: 5px solid transparent;
	border-block-start-color: var(--color-text-muted);
	transform: translateY(-25%);
}

.ts-wrapper.single.dropdown-active .ts-control::after {
	border-block-start-color: transparent;
	border-block-end-color: var(--color-text-muted);
	transform: translateY(-75%);
}

.ts-control > input,
.ts-control > .item {
	font-family: inherit;
	font-size: var(--font-size-base);
	color: var(--color-text);
}

/*
	The core stylesheet floors the search input at 7rem so it stays usable while typing,
	but that floor plus a long selected city name overruns this field's narrower width and
	wraps onto a second, blank-looking line the moment the control is focused. A zero
	min-width alone does not stop it - the browser still uses the input's own content-based
	width to decide whether the line wraps, before flex-grow or flex-shrink ever run. Basing
	it at zero instead means it starts the line at no width and only grows into whatever
	space flex-grow leaves it, so it never causes the wrap itself.
*/
.ts-control > input {
	flex-basis: 0;
	min-width: 0;
}

.ts-dropdown {
	color: var(--color-text);
	background-color: var(--color-surface);
	border: 1px solid var(--color-border);
	border-block-start: 0 none;
	border-end-start-radius: var(--radius-small);
	border-end-end-radius: var(--radius-small);
	box-shadow: 0 2px 6px var(--color-shadow);
}

.ts-dropdown .option,
.ts-dropdown .no-results {
	padding: var(--space-small);
}

.ts-dropdown .active {
	color: var(--color-text);
	background-color: var(--color-surface-raised);
}

/* The matched letters inside a row, which has to stay legible on the active row too. */
.ts-dropdown [data-selectable] .highlight {
	background-color: var(--color-accent-soft);
	border-radius: var(--radius-small);
}

.ts-dropdown .no-results {
	color: var(--color-text-muted);
}

/*
	The login pages. allauth writes the markup, so everything here hangs off the shape of
	its own forms: a paragraph per field, a submit button, a rule before each alternative
	way in. One card stands on a wall of Israeli posters, and the wall is a single tiled
	SVG rather than photographs, so the page loads from this site alone.
*/

/* The card wants the full width, so the page container stops constraining it. */
.page-main:has(.auth-page) {
	max-width: none;
	padding: 0;
}

.auth-page {
	display: flex;
	align-items: center;
	justify-content: center;
	min-block-size: min(46rem, 78vh);
	padding: var(--space-huge) var(--space-large);
	background-color: var(--color-surface-raised);
	background-image: linear-gradient(var(--color-scrim), var(--color-scrim)), url("../img/login-pic.5d2b7fda4988.jpg");
	background-size: auto, cover;
	background-position: center;
	background-repeat: no-repeat;
}

.auth-card {
	inline-size: 100%;
	max-inline-size: 27rem;
	padding: var(--space-large) var(--space-huge) var(--space-huge);
	background-color: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
	box-shadow: 0 18px 48px var(--color-card-shadow);
}

.auth-card h1 {
	margin-block: 0 var(--space-large);
	padding-block-end: var(--space-medium);
	font-size: var(--font-size-section-title);
	text-align: center;
	border-block-end: 1px solid var(--color-border);
}

/* The one word above the providers is the divider itself, so it takes the rule with it. */
.auth-card h2 {
	display: flex;
	align-items: center;
	gap: var(--space-medium);
	margin-block: var(--space-large);
	font-size: var(--font-size-small);
	font-weight: 500;
	color: var(--color-text-muted);
}

.auth-card h2::before,
.auth-card h2::after {
	content: '';
	flex: 1;
	block-size: 1px;
	background-color: var(--color-border);
}

.auth-card hr:has(+ h2) {
	display: none;
}

.auth-card > p,
.auth-card form > p:has(a) {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.auth-card form > p {
	margin-block-end: var(--space-medium);
}

.auth-card input[type='text'],
.auth-card input[type='email'],
.auth-card input[type='tel'] {
	max-inline-size: none;
	margin-block-end: 0;
	padding: var(--space-medium);
	border-radius: var(--radius-medium);
}

.auth-card input::placeholder {
	color: var(--color-text-muted);
}

/* The terms row reads as one sentence beside its tick rather than a label above a field. */
.auth-card form > p:has(input[type='checkbox']) {
	display: flex;
	align-items: flex-start;
	gap: var(--space-small);
	margin-block: var(--space-large);
}

/* The tick belongs before its sentence, which in a right-to-left row means asking for it. */
.auth-card form > p > input[type='checkbox'] {
	order: -1;
}

.auth-card form > p:has(input[type='checkbox']) label {
	margin: 0;
	font-weight: 400;
	color: var(--color-text-muted);
}

.auth-card form > p > input[type='checkbox'] {
	margin: 0.3rem 0 0;
	flex: none;
}

.auth-card button[type='submit'] {
	inline-size: 100%;
	padding-block: var(--space-medium);
	font-size: var(--font-size-large);
	font-weight: var(--font-weight-strong);
	border-radius: var(--radius-medium);
}

/* Where a screen offers a way out beside its action, the way out is the quiet one. */
.auth-card form button + button {
	margin-block-start: var(--space-small);
	color: var(--color-text);
	background-color: transparent;
	border-color: var(--color-border);
}

.auth-card form button + button:hover {
	color: var(--color-text);
	background-color: var(--color-surface-raised);
	border-color: var(--color-text-muted);
}

/* Each rule allauth prints separates one way in from the next. */
.auth-card hr {
	margin-block: var(--space-large);
	border: 0;
	border-block-start: 1px solid var(--color-border);
}

/* The provider list reads as a row of buttons. */
.auth-card ul a {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-small);
	padding: var(--space-medium);
	font-size: var(--font-size-base);
	font-weight: 500;
	color: var(--color-text);
	background-color: var(--color-surface);
	border: 1px solid var(--color-text-muted);
	border-radius: var(--radius-medium);
}

.auth-card ul a:hover {
	background-color: var(--color-surface-raised);
	text-decoration: none;
}

.auth-card ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.auth-card ul li + li {
	margin-block-start: var(--space-small);
}

.auth-card ul a::before {
	content: '';
	inline-size: 1.25rem;
	block-size: 1.25rem;
	background-image: url("../img/google-mark.73db58418d2f.svg");
	background-size: contain;
	background-repeat: no-repeat;
}

.auth-card .errorlist {
	margin-block: 0 var(--space-small);
}

/* Prose. The static pages are the only place this project sets running body copy. */

.prose {
	max-inline-size: 62ch;
}

.prose h2 {
	margin-block-start: var(--space-huge);
}

.prose h3 {
	margin-block-start: var(--space-large);
	font-size: var(--font-size-large);
}

.prose p,
.prose li {
	font-size: var(--font-size-large);
	line-height: 1.85;
}

.prose ul,
.prose ol {
	margin-block-end: var(--space-large);
	padding-inline-start: var(--space-large);
}

.prose li {
	margin-block-end: var(--space-small);
}

.prose li::marker {
	color: var(--color-accent);
}

.prose a {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.prose-lead {
	font-size: var(--font-size-section-title);
	line-height: 1.5;
	color: var(--color-text-muted);
}

/* The date a legal page was last changed. Quiet, but it has to be on the page. */

.prose-meta {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.prose-note {
	padding: var(--space-medium) var(--space-large);
	background-color: var(--color-surface-raised);
	border-inline-start: 4px solid var(--color-accent);
	border-radius: var(--radius-small);
}

.prose-note p:last-child {
	margin-block-end: 0;
}

/* Search and browse page */

.search-heading {
	margin-block-end: var(--space-huge);
	font-size: var(--font-size-hero);
	font-weight: var(--font-weight-strong);
	line-height: 1.25;
}

.search-layout {
	display: grid;
	grid-template-columns: var(--filter-sidebar-width) 1fr;
	gap: var(--space-huge);
	align-items: start;
}

.search-filters {
	position: sticky;
	top: var(--space-large);
	padding: var(--space-large);
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

.search-filters-title {
	font-size: var(--font-size-small);
	font-weight: 700;
	color: var(--color-text-muted);
}

.search-filter-group {
	margin: 0 0 var(--space-large);
	padding: 0;
	border: 0;
}

.search-filter-group legend {
	padding: 0;
	font-size: var(--font-size-small);
	font-weight: 500;
}

.search-filter-group label {
	margin-block-start: var(--space-small);
}

.search-filter-choice {
	display: flex;
	align-items: center;
	gap: var(--space-tiny);
	margin-block-start: var(--space-tiny);
}

.search-filter-choice[hidden] {
	display: none;
}

.search-filter-choice label {
	margin: 0;
	font-weight: 400;
}

.search-more-filters {
	margin-block-end: var(--space-large);
}

.search-more-filters summary {
	font-size: var(--font-size-small);
	font-weight: 500;
	cursor: pointer;
}

.search-more-filters .search-filter-group {
	margin-block-start: var(--space-medium);
}

.search-filter-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-medium);
}

.search-filters input[type='date'],
.search-filters input[type='number'],
.search-filters select {
	margin-block-end: 0;
}

.search-count {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.search-pagination {
	display: flex;
	gap: var(--space-large);
	margin-block-start: var(--space-huge);
}

.search-empty {
	padding: var(--space-huge) var(--space-large);
	text-align: center;
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

.search-empty p {
	color: var(--color-text-muted);
}

.search-empty-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-large);
}

/* Listing card */

/*
	`--listing-grid-columns` is the one control point of the whole feed. `1` lays the
	results out as a single-column editorial list; `auto-fill` restores the multi-column
	grid, and that one word is the entire revert. Every rule below derives from the card
	width the column count produces, never from the count itself, so nothing here has to
	be undone alongside it. Rows are given more air than columns: the extra space reads as
	rhythm in the list and separates the rows of the grid.
*/

.listing-grid {
	--listing-grid-columns: 1;
	display: grid;
	grid-template-columns: repeat(var(--listing-grid-columns), minmax(var(--listing-card-min-width), 1fr));
	column-gap: var(--space-large);
	row-gap: var(--space-huge);
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
}

.listing-card {
	container-type: inline-size;
	container-name: listing-card;
	background-color: transparent;
	border: 0;
}

.listing-card:hover .listing-card-photo {
	box-shadow: 0 8px 20px var(--color-shadow);
}

.listing-card:hover .listing-card-city {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.listing-card:has(.listing-card-link:focus-visible) .listing-card-photo {
	outline: 2px solid var(--color-link);
	outline-offset: 3px;
}

.listing-card-link {
	display: block;
	color: var(--color-text);
}

.listing-card-link:hover {
	text-decoration: none;
}

.listing-card-photo {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
	transition: box-shadow 0.15s;
}

.listing-card-body {
	padding: var(--space-small) var(--space-tiny) 0;
}

.listing-card-city {
	margin: 0 0 var(--space-tiny);
	font-size: var(--font-size-large);
	font-weight: 700;
}

.listing-card-summary {
	margin: 0 0 var(--space-tiny);
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.listing-card-dates {
	margin: 0;
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.listing-card-features {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-tiny);
	list-style: none;
	margin: var(--space-small) 0 0;
	padding-inline-start: 0;
}

.listing-card-feature {
	padding: 0 var(--space-small);
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-small);
}

/*
	The feed card, in two steps. Both are keyed on the width the card actually has rather
	than on the column count, which is what makes the revert a single word: a card in the
	multi-column grid never reaches either threshold and keeps the compact stack above, and
	nor does a card on a phone, where that stack is the right answer anyway.

	The first step is the editorial voice - the city raised to a headline, the dates given
	weight, the feature chips resolved into a caption. Every one of them is set in the body
	face, which is the whole page's voice; the card is sized and weighted differently from
	the rest of the search page, never lettered differently. It starts as soon as a card is
	wide enough to carry it, whether the photograph sits above the caption or beside it.
*/

@container listing-card (min-width: 28rem) {
	.listing-card-body {
		padding: var(--space-medium) 0 0;
	}

	.listing-card-city {
		margin-block-end: var(--space-tiny);
		font-size: var(--font-size-page-title);
		line-height: 1.2;
	}

	.listing-card-summary {
		font-size: var(--font-size-base);
	}

	/* The dates are what a visitor scans for, so they carry the row's only note of colour. */
	.listing-card-dates {
		margin-block-start: var(--space-large);
		padding-inline-start: var(--space-small);
		font-size: var(--font-size-large);
		font-weight: var(--font-weight-strong);
		color: var(--color-text);
		border-inline-start: 3px solid var(--color-accent);
	}

	/* At this size the outlined chips read as leftover controls; a divided run reads as a caption. */
	.listing-card-features {
		gap: var(--space-small);
		margin-block-start: var(--space-large);
	}

	.listing-card-feature {
		padding: 0;
		border: 0;
		border-radius: 0;
	}

	.listing-card-feature + .listing-card-feature {
		padding-inline-start: var(--space-small);
		border-inline-start: 1px solid var(--color-border);
	}
}

/*
	The second step turns the row: a wide plate with the caption set beside it. The threshold
	is the width at which a photograph and a readable measure both fit on one line. The
	caption is centred against the plate rather than anchored to its edges, because a home
	carries between zero and three features and anchoring leaves the rows that carry none
	with nothing on the bottom edge to line up with.
*/

@container listing-card (min-width: 36rem) {
	.listing-card-link {
		display: grid;
		grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
		gap: var(--space-huge);
		align-items: center;
	}

	.listing-card-photo {
		aspect-ratio: 3 / 2;
	}

	.listing-card-body {
		padding: 0;
	}
}

/* Listing detail page */

/*
	The unpublished banner: the one loud surface in the product, because it is the one place
	the site has to interrupt. The home is saved, the owner believes the job is done, and
	nobody can see it. Wrapping rather than a media query: the notice takes the slack, and
	the button drops to its own line once the two no longer fit side by side.
*/
.listing-draft-banner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-medium) var(--space-large);
	margin-block-end: var(--space-large);
	padding: var(--space-large) var(--space-huge);
	background-color: var(--color-draft);
	border-radius: var(--radius-medium);
}

.listing-draft-banner-notice {
	flex: 1 1 20rem;
	margin: 0;
	color: var(--color-accent-text);
	font-family: var(--font-family-display);
	font-size: var(--font-size-page-title);
	font-weight: var(--font-weight-strong);
	line-height: 1.3;
}

.listing-draft-banner form {
	margin: 0;
}

/* Dark ink: an amber button on the draft colour is a smudge rather than a button. */
.listing-draft-banner-button {
	padding: var(--space-medium) var(--space-huge);
	color: var(--color-overlay-text);
	background-color: var(--color-accent-text);
	border-color: var(--color-accent-text);
	font-size: var(--font-size-large);
	font-weight: var(--font-weight-strong);
}

.listing-draft-banner-button:hover {
	color: var(--color-draft);
	background-color: var(--color-overlay-text);
	border-color: var(--color-overlay-text);
}

/* The page's brown focus ring all but disappears against the draft colour. */
.listing-draft-banner :focus-visible {
	outline-color: var(--color-overlay-text);
}

.listing-detail-photos {
	display: flex;
	gap: var(--space-small);
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scroll-snap-type: x mandatory;
	list-style: none;
	margin: 0 0 var(--space-large);
	padding-inline-start: 0;
	padding-block-end: var(--space-small);
	scrollbar-color: var(--color-border) transparent;
}

.listing-detail-photo-slide {
	flex: 0 0 var(--detail-photo-width);
	scroll-snap-align: start;
}

.listing-detail-photo-link {
	display: block;
	cursor: zoom-in;
}

.listing-detail-photo {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

/* Full-screen photo viewer: a dialog, so the backdrop, the focus trap and Esc are the browser's */

.viewer {
	inline-size: 100vw;
	max-inline-size: 100vw;
	block-size: 100dvh;
	max-block-size: 100dvh;
	padding: 0;
	border: none;
	background-color: var(--color-overlay);
}

.viewer::backdrop {
	background-color: var(--color-overlay);
}

.viewer-slides {
	display: flex;
	block-size: 100%;
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
}

.viewer-slides::-webkit-scrollbar {
	display: none;
}

.viewer-slide {
	flex: 0 0 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-huge) var(--space-large);
	scroll-snap-align: center;
}

.viewer-image {
	max-inline-size: 100%;
	max-block-size: 100%;
	object-fit: contain;
	border-radius: var(--radius-small);
}

.viewer-close,
.viewer-previous,
.viewer-next {
	position: fixed;
	inline-size: 2.75rem;
	block-size: 2.75rem;
	padding: 0;
	font-size: var(--font-size-page-title);
	line-height: 1;
	color: var(--color-overlay-text);
	background-color: var(--color-overlay-control);
	border: none;
	border-radius: 50%;
	cursor: pointer;
}

.viewer-close:hover,
.viewer-previous:hover,
.viewer-next:hover {
	color: var(--color-accent-text);
	background-color: var(--color-accent);
}

.viewer-close {
	inset-block-start: var(--space-medium);
	inset-inline-end: var(--space-medium);
}

.viewer-close::after {
	content: '\00d7';
}

/* The next photo sits where the eye moves next, which in Hebrew is towards the start edge. */
.viewer-previous,
.viewer-next {
	inset-block-start: 50%;
	transform: translateY(-50%);
}

.viewer-previous {
	inset-inline-end: var(--space-medium);
}

.viewer-previous::after {
	content: '\203a';
}

.viewer-next {
	inset-inline-start: var(--space-medium);
}

.viewer-next::after {
	content: '\2039';
}

.viewer-counter {
	position: fixed;
	inset-block-end: var(--space-medium);
	inset-inline: 0;
	margin: 0;
	text-align: center;
	font-size: var(--font-size-small);
	color: var(--color-overlay-text);
}

.listing-detail-header {
	margin-block-end: var(--space-large);
}

.listing-detail-title {
	margin-block-end: var(--space-tiny);
}

.listing-detail-region {
	margin: 0;
	color: var(--color-text-muted);
}

.listing-detail-layout {
	display: grid;
	grid-template-columns: 1fr var(--detail-panel-width);
	gap: var(--space-huge);
	align-items: start;
}

.listing-detail-main section {
	margin-block-end: var(--space-huge);
}

.listing-detail-main section:last-child {
	margin-block-end: 0;
}

.listing-detail-attributes {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: var(--space-tiny) var(--space-large);
	margin: 0;
}

.listing-detail-attributes dt {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.listing-detail-attributes dd {
	margin: 0;
	font-weight: 500;
}

.listing-detail-features {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-small);
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
}

.listing-detail-feature {
	padding: 0 var(--space-medium);
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-small);
}

.listing-detail-dates {
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
}

.listing-detail-date {
	padding-block: var(--space-small);
	border-block-end: 1px solid var(--color-border);
}

.listing-detail-date:last-child {
	border-block-end: 0;
}

.listing-detail-no-dates {
	margin: 0;
	color: var(--color-text-muted);
}

.listing-detail-panel {
	position: sticky;
	top: var(--space-large);
	padding: var(--space-large);
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

.listing-detail-panel-title {
	font-size: var(--font-size-large);
}

.listing-detail-panel form {
	margin: var(--space-small) 0 0;
}

.listing-detail-panel .button,
.listing-detail-panel button {
	display: block;
	width: 100%;
	text-align: center;
}

.listing-detail-panel .notice {
	margin-block-end: var(--space-medium);
	font-size: var(--font-size-small);
}

/* Requests page. One list, one row per request or match, told apart by its icon colour and its edge. */

.request-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--space-medium);
}

.request-row {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: start;
	gap: var(--space-medium);
	padding: var(--space-medium) var(--space-large);
	background-color: var(--color-surface);
	border: 1px solid var(--color-border);
	border-inline-start: 4px solid var(--color-border);
	border-radius: var(--radius-medium);
}

.request-row-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 2.25rem;
	block-size: 2.25rem;
	border-radius: 50%;
	background-color: var(--color-surface-raised);
	color: var(--color-text-muted);
}

.request-row-glyph {
	inline-size: 1.25rem;
	block-size: 1.25rem;
}

.request-row-body {
	min-inline-size: 0;
}

.request-row-heading {
	margin: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--space-small);
}

.request-row-kind {
	font-weight: 700;
}

.request-row-status {
	padding: 0 var(--space-small);
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
	background-color: var(--color-surface-raised);
	border-radius: var(--radius-small);
}

.request-row-link {
	display: inline-block;
	margin-block-start: var(--space-tiny);
	font-weight: 500;
}

.request-row-gone,
.request-row-hint,
.request-row-date {
	margin: var(--space-tiny) 0 0;
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.request-row-contact {
	margin: var(--space-small) 0 0;
	padding: var(--space-small) var(--space-medium);
	display: grid;
	grid-template-columns: auto 1fr;
	gap: var(--space-tiny) var(--space-medium);
	background-color: var(--color-accent-soft);
	border-radius: var(--radius-small);
}

.request-row-contact dt {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.request-row-contact dd {
	margin: 0;
	font-weight: 700;
}

.request-row-actions {
	margin: 0;
}

.request-row-actions button {
	white-space: nowrap;
}

/* The five states, drawn only from the existing palette. */

.request-row-received {
	border-inline-start-color: var(--color-accent);
}

.request-row-received .request-row-icon {
	color: var(--color-accent-text);
	background-color: var(--color-accent);
}

.request-row-matched {
	border-inline-start-color: var(--color-accent);
	background-color: var(--color-surface);
}

.request-row-matched .request-row-icon {
	color: var(--color-accent);
	background-color: var(--color-accent-soft);
}

.request-row-sent .request-row-icon {
	color: var(--color-text);
}

.request-row-declined {
	border-inline-start-color: var(--color-error);
}

.request-row-declined .request-row-icon {
	color: var(--color-error);
	background-color: var(--color-error-background);
}

.request-row-declined .request-row-status {
	color: var(--color-error);
	background-color: var(--color-error-background);
}

.request-row-withdrawn,
.request-row-declined {
	color: var(--color-text-muted);
}

.request-row-withdrawn .request-row-kind,
.request-row-declined .request-row-kind {
	font-weight: 500;
}

.request-empty {
	padding: var(--space-huge) var(--space-large);
	text-align: center;
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

.request-empty p {
	margin-block-end: var(--space-large);
	color: var(--color-text-muted);
}

.account-section {
	max-width: 32rem;
	margin-block-end: var(--space-large);
	padding: var(--space-large);
	background-color: var(--color-surface-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-medium);
}

.account-details {
	margin: 0 0 var(--space-medium);
	display: grid;
	grid-template-columns: auto 1fr;
	gap: var(--space-tiny) var(--space-medium);
}

.account-details dt {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.account-details dd {
	margin: 0;
}

.account-note {
	color: var(--color-text-muted);
}

/* The listing card is drawn in its listing's state, so who can see the home is answered by the colour before it is read. The modifier is the stored status value. */
.account-listing-active {
	background-color: var(--color-live-soft);
	border-color: var(--color-live);
}

.account-listing-hidden_by_owner {
	background-color: var(--color-draft-soft);
	border-color: var(--color-draft);
}

.account-listing-hidden_by_admin {
	background-color: var(--color-error-background);
	border-color: var(--color-error);
}

/* Deleting the account is not what the page is asking you to do either. */
.account-danger {
	background-color: var(--color-error-background);
	border-color: var(--color-error);
}

/* Statistics page. Quiet type and one accent: a figure is read, not looked at. */

.stats-title {
	margin-block-end: var(--space-huge);
}

.stats-figures {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
	gap: var(--space-large) var(--space-medium);
	margin-block-end: var(--space-huge);
}

.stats-figure {
	display: flex;
	flex-direction: column;
	gap: var(--space-tiny);
}

.stats-figure-value {
	font-size: var(--font-size-hero);
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
}

.stats-figure-label {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.stats-section {
	margin-block-end: var(--space-huge);
}

.stats-section-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-medium);
}

.stats-section-title {
	font-size: var(--font-size-large);
	font-weight: 400;
	color: var(--color-text-muted);
}

.stats-range {
	display: flex;
	gap: var(--space-medium);
	margin-block-end: var(--space-medium);
	font-size: var(--font-size-small);
}

.stats-range-option-current {
	color: var(--color-text);
	font-weight: var(--font-weight-strong);
	text-decoration: none;
}

/* The chart's own colours, so the script names a property and never a colour. */

.stats-chart {
	--stats-grid-color: var(--color-border);
	--stats-tick-color: var(--color-text-muted);
}

.stats-chart-frame {
	position: relative;
	block-size: 20rem;
}

.stats-chart-legend {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-medium);
	margin: var(--space-medium) 0 0;
	padding: 0;
	list-style: none;
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.stats-chart-legend-item {
	display: flex;
	align-items: center;
	gap: var(--space-tiny);
}

.stats-chart-legend-item::before {
	content: '';
	inline-size: 0.75rem;
	block-size: 2px;
	background-color: var(--stats-series-color);
}

/* Five lines, five of the palette's existing colours. Nothing new is defined here. */

.stats-chart-legend-item:nth-child(1) {
	--stats-series-color: var(--color-live);
}

.stats-chart-legend-item:nth-child(2) {
	--stats-series-color: var(--color-accent);
}

.stats-chart-legend-item:nth-child(3) {
	--stats-series-color: var(--color-draft);
}

.stats-chart-legend-item:nth-child(4) {
	--stats-series-color: var(--color-link);
}

.stats-chart-legend-item:nth-child(5) {
	--stats-series-color: var(--color-text-muted);
}

.stats-bars {
	display: grid;
	gap: var(--space-small);
	margin: 0;
	padding: 0;
	list-style: none;
}

.stats-bar {
	display: grid;
	grid-template-columns: minmax(6rem, 12rem) 1fr auto;
	align-items: center;
	gap: var(--space-medium);
}

.stats-bar-label {
	font-size: var(--font-size-small);
	color: var(--color-text-muted);
}

.stats-bar-track {
	block-size: 0.6rem;
	border-radius: var(--radius-small);
	background-color: var(--color-surface-raised);
}

.stats-bar-fill {
	display: block;
	block-size: 100%;
	border-radius: var(--radius-small);
	background-color: var(--color-accent);
}

.stats-bar-value {
	font-variant-numeric: tabular-nums;
}

.stats-breakdowns {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-huge);
}

/* Responsive. Desktop first, so a phone visit is not broken. */

@media (max-width: 720px) {
	.page-container {
		padding-inline: var(--space-medium);
	}

	.page-main {
		padding-block: var(--space-large);
	}

	.page-header-inner {
		align-items: flex-start;
		gap: var(--space-small);
	}

	.header-links {
		gap: var(--space-small) var(--space-medium);
	}

	.footer-links {
		gap: var(--space-small) var(--space-medium);
	}

	.listing-grid {
		--listing-grid-columns: 1;
	}

	.search-heading {
		margin-block-end: var(--space-large);
		font-size: var(--font-size-page-title);
	}

	.search-layout {
		grid-template-columns: 1fr;
		gap: var(--space-large);
	}

	.search-filters {
		position: static;
	}

	.listing-detail-layout {
		grid-template-columns: 1fr;
		gap: var(--space-large);
	}

	.listing-detail-panel {
		position: static;
	}

	.listing-detail-photo-slide {
		flex-basis: 85%;
	}

	.request-row {
		grid-template-columns: auto 1fr;
		padding: var(--space-medium);
	}

	.request-row-actions {
		grid-column: 1 / -1;
	}

	.request-row-actions button {
		inline-size: 100%;
	}

	.stats-breakdowns {
		grid-template-columns: 1fr;
		gap: var(--space-large);
	}

	.stats-bar {
		grid-template-columns: minmax(5rem, 9rem) 1fr auto;
		gap: var(--space-small);
	}
}

/* Motion is opt-in. Anyone who asked for stillness gets it. */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0.01ms;
		animation-duration: 0.01ms;
	}

	.listing-card:hover {
		transform: none;
	}
}
