/*
 * URBN Dental Job Listing — front end.
 *
 * Every colour and size here is a fallback. The widgets write CSS custom properties on their
 * own wrapper from Elementor's global kit, so day one this looks like URBN's site with nobody
 * having styled anything. No palette ships in this file beyond neutral defaults.
 */

.urbn-jobs__list {
	display: grid;
	grid-template-columns: repeat(var(--urbn-columns, 1), minmax(0, 1fr));
	gap: var(--urbn-card-gap, 1rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * The listing card.
 *
 * Structure follows the pattern candidates already know from job boards: when it was listed, the
 * role, the facts as pills, where, when it closes, and one way in. What it does not follow is the
 * decorative colour those designs usually carry — a card tinted at random says nothing, so the tint
 * here comes from the employment type and a candidate scanning a grid can see which roles are
 * full-time without reading. Every tint is a variable, so a theme can change or neutralise the set.
 */

.urbn-job-card {
	--urbn-tint: var(--urbn-card-bg, rgba(0, 0, 0, 0.025));

	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	padding: var(--urbn-card-padding, 1.35rem);
	background: var(--urbn-tint);
	border: 1px solid var(--urbn-card-border, rgba(0, 0, 0, 0.1));
	border-radius: var(--urbn-card-radius, 14px);
}

/* Tint by employment type. Light enough that body text keeps its contrast on any of them. */
.urbn-job-card--full-time {
	--urbn-tint: var(--urbn-tint-full-time, #eef4fb);
}

.urbn-job-card--part-time {
	--urbn-tint: var(--urbn-tint-part-time, #fdf3ea);
}

.urbn-job-card--contract {
	--urbn-tint: var(--urbn-tint-contract, #f1f0fb);
}

.urbn-job-card--prn {
	--urbn-tint: var(--urbn-tint-prn, #eaf6f1);
}

.urbn-job-card--temporary {
	--urbn-tint: var(--urbn-tint-temporary, #fbf0f3);
}

.urbn-job-card__listed {
	margin: 0;
	font-size: 0.8em;
	opacity: 0.7;
}

.urbn-job-card__title {
	margin: 0;
	line-height: 1.2;
	color: var(--urbn-title-colour, inherit);
}

.urbn-job-card__title a {
	color: inherit;
	text-decoration: none;
}

.urbn-job-card__title a:hover,
.urbn-job-card__title a:focus-visible {
	text-decoration: underline;
}

.urbn-job-card__pills {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	margin: 0;
}

.urbn-job-card__pill {
	padding: 0.15rem 0.6rem;
	border: 1px solid rgba(0, 0, 0, 0.12);
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.65);
	font-size: 0.8em;
	line-height: 1.6;
	white-space: nowrap;
}

.urbn-job-card__practices {
	margin: 0;
	color: var(--urbn-meta-colour, inherit);
	font-size: 0.9em;
	line-height: 1.45;
}

/* Sits directly under the practice name, so it reads as that practice's address rather than as a
   second fact about the role. Lighter than the name for the same reason. */
.urbn-job-card__address {
	/* The card is a flex column with a 0.6rem gap, which is right between separate facts and too
	   much between a practice and its own address — at that distance it reads as a fourth fact
	   about the role rather than as part of the line above it. */
	margin: -0.35rem 0 0;
	color: var(--urbn-meta-colour, inherit);
	font-size: 0.85em;
	line-height: 1.45;
	opacity: 0.75;
}

.urbn-job-card__closing {
	margin: 0;
	font-size: 0.85em;
	opacity: 0.75;
}

/* Pushed to the bottom so every card in a row ends the same way. */
.urbn-job-card__cta {
	margin: 0.25rem 0 0;
	margin-top: auto;
}

.urbn-job-card__button {
	display: inline-block;
	padding: 0.5rem 1.1rem;
	border-radius: var(--urbn-button-radius, 999px);
	background: var(--urbn-button-bg, #1d2327);
	color: var(--urbn-button-text, #fff);
	font-size: 0.9em;
	text-decoration: none;
	/* 44px target on touch. */
	min-height: 44px;
	line-height: 1.9;
}

.urbn-job-card__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 1rem;
	margin: 0;
	color: var(--urbn-meta-colour, inherit);
}

.urbn-job-card__pay {
	color: var(--urbn-pay-colour, inherit);
}

.urbn-jobs--empty {
	opacity: 0.85;
}

/* Single posting ---------------------------------------------------------- */

.urbn-job-meta {
	display: grid;
	gap: var(--urbn-meta-gap, 0.35rem);
	margin: 0 0 1.5rem;
	padding: 0;
	list-style: none;
	color: var(--urbn-meta-colour, inherit);
}

.urbn-job-meta__label {
	font-weight: 600;
	margin-inline-end: 0.4em;
}

.urbn-job-meta__pay {
	color: var(--urbn-pay-colour, inherit);
}

.urbn-job-meta__pay-note {
	opacity: 0.9;
}

.urbn-job-offers {
	margin: 0 0 1.5rem;
	padding-inline-start: 1.2rem;
}

.urbn-job__apply-link,
.urbn-apply__button,
.urbn-sticky-apply__button {
	display: inline-block;
	padding: var(--urbn-button-padding, 0.75rem 1.5rem);
	background: var(--urbn-button-bg, #1d2327);
	color: var(--urbn-button-text, #fff);
	border: 0;
	border-radius: var(--urbn-button-radius, 4px);
	text-decoration: none;
	cursor: pointer;
	font: inherit;
}

.urbn-apply__button[disabled] {
	opacity: 0.7;
	cursor: progress;
}

/* Sticky apply ------------------------------------------------------------ */

.urbn-sticky-apply {
	position: fixed;
	inset-inline: 0;
	bottom: 0;
	z-index: 90;
	display: none;
	padding: 0.75rem 1rem;
	/* Or it sits under the iPhone home indicator. */
	padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
	background: var(--urbn-sticky-bg, rgba(255, 255, 255, 0.96));
	box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.12);
	text-align: center;
}

.urbn-sticky-apply__button {
	width: 100%;
	max-width: 30rem;
}

@media (max-width: 767px) {
	.urbn-sticky-apply:not([hidden]) {
		display: block;
	}
}

/* Apply form ------------------------------------------------------------- */

.urbn-apply {
	margin-top: 2.5rem;
}

.urbn-apply__field {
	display: block;
	margin: 0 0 var(--urbn-field-gap, 1.25rem);
	border: 0;
	padding: 0;
}

.urbn-apply__label {
	display: block;
	margin-bottom: 0.25rem;
	padding: 0;
	font-weight: 600;
	color: var(--urbn-label-colour, inherit);
}

.urbn-apply__example,
.urbn-apply__formats,
.urbn-apply__attach {
	margin: 0 0 0.4rem;
	color: var(--urbn-help-colour, inherit);
}

/* Two hint lines, visually distinct, never merged: one is what to send, the other how. */
.urbn-apply__attach {
	font-size: 1em;
}

.urbn-apply__formats {
	font-size: 0.875em;
	opacity: 0.8;
}

.urbn-apply__field input[type="text"],
.urbn-apply__field input[type="email"],
.urbn-apply__field input[type="tel"] {
	width: 100%;
	padding: var(--urbn-input-padding, 0.7rem 0.8rem);
	border: 1px solid var(--urbn-input-border, currentColor);
	border-radius: var(--urbn-input-radius, 4px);
	font: inherit;
	/* 16px minimum, or iOS zooms the page on focus. */
	font-size: max(1rem, 16px);
}

/* Error colour is a third signal, never the only one. A field in trouble carries the message in
   words, aria-invalid for anything not reading colour, and a heavier border as well as the tint —
   so the form still works for somebody who cannot distinguish it. The value is a variable, because
   a theme with a red brand needs to be able to move it without losing the meaning. */
.urbn-apply {
	--urbn-apply-error: #b3261e;
	--urbn-apply-error-bg: rgba( 179, 38, 30, 0.06 );
}

.urbn-apply__field--error input,
.urbn-apply__field--error textarea,
.urbn-apply__field--error .urbn-apply__dropzone {
	border-width: 2px;
	border-color: var( --urbn-apply-error );
	background-color: var( --urbn-apply-error-bg );
}

/* The practices fieldset has no input of its own to recolour, so it takes the mark itself —
   otherwise the two controls a candidate is most likely to skip are the two that look fine. */
.urbn-apply__practices.urbn-apply__field--error {
	border-left: 4px solid var( --urbn-apply-error );
	padding-left: 0.9rem;
	background-color: var( --urbn-apply-error-bg );
	border-radius: 4px;
}

.urbn-apply__error {
	margin: 0 0 0.4rem;
	font-weight: 600;
	color: var( --urbn-apply-error );
}

/* The summary is the first thing a returning eye lands on, so it carries the same colour as the
   fields it points at rather than a second one. */
.urbn-apply__summary {
	border-left: 4px solid var( --urbn-apply-error );
	background-color: var( --urbn-apply-error-bg );
	padding: 0.9rem 1rem;
	border-radius: 4px;
}

/* Five red underlined lines read as five alarms rather than as a way to get to the fields. The
   panel already carries the alarm — its border, its tint and its lead sentence — so the links take
   the reading colour and earn the accent on hover and focus instead. They keep their underline:
   these are the one thing on the page somebody is meant to click. */
.urbn-apply__summary a {
	color: inherit;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.15em;
}

.urbn-apply__summary a:hover,
.urbn-apply__summary a:focus-visible {
	color: var( --urbn-apply-error );
}

.urbn-apply__summary ul {
	margin: 0;
	padding-left: 1.2rem;
}

.urbn-apply__summary li + li {
	margin-top: 0.3rem;
}

/* "Required" is a word rather than an asterisk. An asterisk means nothing to somebody who has not
   been told what it means, and is read aloud as "star" by some screen readers. */
.urbn-apply__required {
	margin-left: 0.35rem;
	font-size: 0.8em;
	font-weight: 400;
	opacity: 0.7;
}

.urbn-apply__summary {
	margin: 0 0 1.5rem;
	padding: 1rem 1.25rem;
	border: 2px solid currentColor;
	border-radius: 4px;
}

.urbn-apply__summary-lead {
	margin: 0 0 0.5rem;
	font-weight: 600;
}

.urbn-apply__summary ul {
	margin: 0;
	padding-inline-start: 1.2rem;
}

/* The honeypot: off-screen rather than display:none. */
.urbn-apply__decoy {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/*
 * The practice chooser.
 *
 * Fourteen options is the most consequential question on this form, and a bare checkbox list made a
 * candidate weigh "Uptown" against "Montrose" against "Heights" with nothing to go on. Each option
 * is now a card carrying the name and the street address, because two practices are in Katy and the
 * neighbourhood names mean nothing to somebody who does not already know Houston.
 *
 * No palette is introduced: the selected state borrows the accent the Elementor global kit already
 * supplies to the submit button, and the tint is a translucent black so it sits correctly on a light
 * or dark theme. The checkbox still carries the state, so selection is never colour alone.
 */

.urbn-apply__practice-list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: 0.6rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.urbn-apply__practice label {
	display: flex;
	align-items: flex-start;
	gap: 0.7rem;
	height: 100%;
	/* Comfortably past a 44px target, and the whole card is the target. */
	padding: 0.85rem 0.95rem;
	border: 1px solid var(--urbn-card-border, rgba(0, 0, 0, 0.14));
	border-radius: var(--urbn-card-radius, 10px);
	background: rgba(0, 0, 0, 0.02);
	cursor: pointer;
	transition: border-color 120ms ease, background-color 120ms ease;
}

.urbn-apply__practice label:hover {
	background: rgba(0, 0, 0, 0.04);
}

/* Selected. The checkbox says so too — this only makes it legible at a glance. */
.urbn-apply__practice label:has(input:checked) {
	border-color: var(--urbn-button-bg, currentColor);
	background: rgba(0, 0, 0, 0.05);
	box-shadow: inset 0 0 0 1px var(--urbn-button-bg, transparent);
}

.urbn-apply__practice label:focus-within {
	outline: 2px solid var(--urbn-button-bg, currentColor);
	outline-offset: 2px;
}

.urbn-apply__practice input {
	flex: 0 0 auto;
	width: 1.15rem;
	height: 1.15rem;
	margin-top: 0.1rem;
}

.urbn-apply__practice-body {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	min-width: 0;
}

.urbn-apply__practice-name {
	font-weight: 600;
	line-height: 1.3;
}

.urbn-apply__practice-address {
	font-size: 0.85em;
	line-height: 1.4;
	opacity: 0.75;
}

.urbn-apply__practice-opening {
	font-size: 0.8em;
	font-weight: 600;
	opacity: 0.9;
}

/* "I'm open to any location" is the common answer, so it leads and spans the row. */
.urbn-apply__practice--any {
	grid-column: 1 / -1;
}

.urbn-apply__practice--any label {
	align-items: center;
}

.urbn-apply__practice--any .urbn-apply__practice-name {
	font-size: 1.05em;
}

/* One column on a phone: all fourteen stay visible, which is the deliberate choice. */
@media (max-width: 600px) {
	.urbn-apply__practice-list {
		grid-template-columns: minmax(0, 1fr);
	}
}

.urbn-job-meta__address {
	display: block;
	font-size: 0.9em;
	opacity: 0.75;
}

.urbn-apply__dropzone {
	position: relative;
	padding: 1rem;
	border: 1px solid var(--urbn-input-border, currentColor);
	border-radius: 4px;
}

.urbn-apply__dropzone--over {
	border-style: solid;
	border-width: 2px;
}

.urbn-apply__dropzone-pointer,
.urbn-apply__dropzone-touch {
	display: block;
	margin-top: 0.5rem;
	font-size: 0.9em;
	opacity: 0.8;
}

/* Two treatments, one markup. A dashed drop zone is meaningless on a phone. */
.urbn-apply__dropzone-touch {
	display: none;
}

@media (hover: hover) and (pointer: fine) {
	.urbn-apply__dropzone {
		border-style: dashed;
		border-width: 2px;
		text-align: center;
		padding: 1.75rem 1rem;
	}
}

@media (hover: none), (pointer: coarse) {
	.urbn-apply__dropzone-pointer {
		display: none;
	}

	.urbn-apply__dropzone-touch {
		display: block;
	}

	.urbn-apply__dropzone input[type="file"] {
		width: 100%;
		min-height: 44px;
	}
}

.urbn-apply__file-list {
	margin: 0.75rem 0 0;
	padding: 0;
	list-style: none;
}

/* Restored rows render identically to fresh ones: if a restored file looks provisional,
   candidates re-upload it, which is what tokens exist to prevent. */
.urbn-apply__file {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.5rem 0;
	border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.urbn-apply__file-name {
	flex: 1 1 auto;
	overflow-wrap: anywhere;
}

.urbn-apply__file-size {
	opacity: 0.75;
	font-size: 0.9em;
	white-space: nowrap;
}

.urbn-apply__file-remove {
	background: none;
	border: 0;
	padding: 0.4rem;
	min-height: 44px;
	font: inherit;
	text-decoration: underline;
	cursor: pointer;
	color: inherit;
}

.urbn-apply__file-bar {
	flex: 0 0 5rem;
	height: 4px;
	background: rgba(0, 0, 0, 0.12);
	border-radius: 2px;
	overflow: hidden;
}

.urbn-apply__file-bar span {
	display: block;
	height: 100%;
	width: 0;
	background: currentColor;
	transition: width 150ms linear;
}

.urbn-apply__file--error {
	font-weight: 600;
}

.urbn-apply__progress {
	margin-top: 1rem;
}

.urbn-apply__progress-track {
	height: 6px;
	background: rgba(0, 0, 0, 0.12);
	border-radius: 3px;
	overflow: hidden;
}

.urbn-apply__progress-bar {
	height: 100%;
	width: 0;
	background: var(--urbn-button-bg, #1d2327);
	transition: width 150ms linear;
}

.urbn-apply__progress-text {
	margin: 0.4rem 0 0;
	font-size: 0.9em;
}

.urbn-apply--done,
.urbn-apply--unavailable {
	padding: 1.25rem;
	border: 1px solid currentColor;
	border-radius: 4px;
}

@media (max-width: 767px) {
	.urbn-apply__field,
	.urbn-apply__dropzone {
		max-width: 100%;
	}
}

/* One media query, applied globally: nothing animates. */
@media (prefers-reduced-motion: reduce) {
	.urbn-apply__file-bar span,
	.urbn-apply__progress-bar,
	.urbn-apply__practice label {
		transition: none;
	}
}

/* ---------------------------------------------------------------------
 * Candidate filters
 *
 * A plain GET form: it works with JavaScript off, and a narrowed view is a link somebody can send to
 * a friend who also wants Katy. Colours come from the Elementor global kit like everything else here.
 * ------------------------------------------------------------------ */

.urbn-jobs__filters {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 0.6rem 0.75rem;
	margin: 0 0 1.25rem;
	padding: 0.9rem 1rem;
	background: var(--urbn-card-bg, rgba(0, 0, 0, 0.025));
	border: 1px solid var(--urbn-card-border, rgba(0, 0, 0, 0.1));
	border-radius: var(--urbn-card-radius, 14px);
}

.urbn-jobs__filter {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
	min-width: 0;
	flex: 1 1 11rem;
}

.urbn-jobs__filter-label {
	font-size: 0.8em;
	font-weight: 600;
	opacity: 0.8;
}

.urbn-jobs__filters select {
	width: 100%;
	min-height: 44px;
	padding: 0.45rem 0.6rem;
	border: 1px solid var(--urbn-input-border, rgba(0, 0, 0, 0.2));
	border-radius: var(--urbn-input-radius, 6px);
	background: #fff;
	font: inherit;
	/* 16px minimum, or iOS zooms the page on focus. */
	font-size: max(0.95rem, 16px);
}

.urbn-jobs__filter-button {
	min-height: 44px;
	padding: 0.5rem 1.2rem;
	border: 0;
	border-radius: var(--urbn-button-radius, 999px);
	background: var(--urbn-button-bg, #1d2327);
	color: var(--urbn-button-text, #fff);
	font: inherit;
	font-weight: 600;
	cursor: pointer;
}

.urbn-jobs__filter-clear {
	align-self: center;
	min-height: 44px;
	padding: 0.5rem 0;
	font-size: 0.9em;
	line-height: 1.9;
}

.urbn-jobs__count {
	margin: 0 0 0.9rem;
	font-size: 0.9em;
	opacity: 0.8;
}

@media (max-width: 600px) {
	.urbn-jobs__filter {
		flex: 1 1 100%;
	}

	.urbn-jobs__filter-button {
		width: 100%;
	}

	.urbn-jobs__filter-clear {
		width: 100%;
		text-align: center;
	}
}

/* Only ever seen by somebody who can fix it. */
.urbn-jobs__error {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 0.8em;
	overflow-wrap: anywhere;
	opacity: 0.85;
}

/* Only ever seen by somebody who can publish the page it appears on. */
.urbn-draft-notice {
	margin: 0 0 1.5rem;
	padding: 1rem 1.25rem;
	border: 1px solid rgba(0, 0, 0, 0.15);
	border-left: 4px solid #b4530a;
	border-radius: 10px;
	background: #fdf3e8;
	color: #16202a;
}

.urbn-draft-notice p {
	margin: 0 0 0.5rem;
}

.urbn-draft-notice p:last-child {
	margin-bottom: 0;
	font-size: 0.9em;
	opacity: 0.85;
}

/* The chosen practice's full address, under the filter bar. */
.urbn-jobs__chosen {
	margin: -0.5rem 0 1.25rem;
	font-size: 0.9em;
	opacity: 0.8;
}

.urbn-jobs__chosen-name {
	font-weight: 600;
	opacity: 1;
}
