/* =========================================================
   HERTSPARTNERS COMPONENT LIBRARY
   Canonical, reusable UI components for the wider platform.
   Documented in docs/COMPONENT_LIBRARY.md — read that alongside
   this file. Every value here is a design token (docs/DESIGN_SYSTEM.md,
   assets/css/tokens.css) — no hardcoded colour, spacing, radius, or
   shadow values below.

   Namespace: `.hp-c-*` ("c" = component), deliberately distinct from
   Directorist's own `.directorist-*` classes (styled separately in
   legacy-directorist.css) and from the Partner Hub plugin's existing,
   independently-shipped `.hp-*` classes (assets/css/public.css in that
   repository) — so this stylesheet can load site-wide without ever
   colliding with either. See docs/COMPONENT_LIBRARY.md for why the
   Partner Hub was not migrated onto these exact class names this pass.
   ========================================================= */

/* =========================================================
   GLOBAL CANVAS (design-system consolidation, 2026-08-06)
   Large pure-white expanses on public discovery pages read as
   unfinished. A barely-noticed off-white/purple-tinted base, felt
   rather than consciously seen -- real working surfaces (cards, panels,
   forms) still sit on --hp-color-white for genuine contrast against it.
   Utility/dashboard/form pages (.hp-utility-page) intentionally keep
   the plain white canvas -- calmer, not "unfinished" there by design.
   ========================================================= */
body {
	background-color: var( --hp-color-canvas );
	background-image: var( --hp-color-canvas-wash );
	background-attachment: fixed;
}

body.hp-utility-page {
	background-color: var( --hp-color-white );
	background-image: none;
}

/* =========================================================
   BUTTONS
   ========================================================= */

.hp-c-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--hp-space-2);
	min-height: 44px; /* mobile touch target, D004 */
	padding: var(--hp-space-3) var(--hp-space-6);
	border-radius: var(--hp-radius-md);
	border: 2px solid transparent;
	font-family: var(--hp-font-body);
	font-weight: 600;
	font-size: var(--hp-text-sm);
	line-height: 1.2;
	/* hello-elementor's own `.page-content a { text-decoration: underline }`
	   (theme.css) has higher specificity (0,1,1) than a single class here
	   (0,1,0) and always wins regardless of load order -- invisible until a
	   .hp-c-btn action link is rendered inside a page wrapped in Elementor's
	   .page-content (Wave 1, 2026-08-08: HertsJobs/Volunteering/HertsOffers'
	   new masthead action links, unlike What's On's own non-Elementor
	   template). A site component must never inherit a raw-content link
	   style regardless of which page wrapper it lands in. */
	text-decoration: none !important;
	cursor: pointer;
	transition: var(--hp-transition-base);
	transition-property: background-color, border-color, color, transform, box-shadow;
}

/* L01.1 (2026-09-12): the same specificity trap as the text-decoration note
   above, found by rendering real pages rather than reading CSS. A later
   reset -- `[type="button"], [type="submit"], button { background-color:
   transparent; color: #c36 }` at (0,1,1) -- beat every single-class variant
   below at (0,1,0), so a `<button class="hp-c-btn hp-c-btn--primary">`
   rendered as #c36 text on no background at all, while the identical
   `<a class="hp-c-btn hp-c-btn--primary">` rendered correctly. That hit the
   real Contact send action and the directory filter search button, in both
   themes. Each variant is therefore also qualified by `button` so it matches
   the reset's specificity and wins on order. The class-only selector is kept
   so links, spans and inputs are unaffected. */
.hp-c-btn--primary,
button.hp-c-btn--primary {
	background: var(--hp-color-primary-500);
	color: var(--hp-color-white);
}

.hp-c-btn--primary:hover,
button.hp-c-btn--primary:hover {
	background: var(--hp-color-primary-700);
	transform: translateY(-1px);
}

.hp-c-btn--secondary,
button.hp-c-btn--secondary {
	background: transparent;
	color: var(--hp-color-primary-500);
	border-color: var(--hp-color-primary-200);
}

.hp-c-btn--secondary:hover,
button.hp-c-btn--secondary:hover {
	background: var(--hp-color-primary-100);
}

.hp-c-btn--ghost,
button.hp-c-btn--ghost {
	background: transparent;
	color: var(--hp-color-ink);
	border-color: transparent;
}

.hp-c-btn--ghost:hover {
	background: var(--hp-color-border);
}

/* Pressed (active) — a visibly different, deliberately non-hover state,
   since touch devices never see :hover (D004: no hover-only interaction) */
.hp-c-btn:active {
	transform: translateY(0);
	filter: brightness(0.95);
}

.hp-c-btn:disabled,
.hp-c-btn[aria-disabled="true"] {
	background: var(--hp-color-border);
	color: var(--hp-color-body);
	border-color: var(--hp-color-border);
	cursor: not-allowed;
	transform: none;
}

.hp-c-btn:focus-visible {
	outline: 3px solid var(--hp-color-primary-400);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.hp-c-btn {
		transition: none;
	}

	.hp-c-btn:hover,
	.hp-c-btn:active {
		transform: none;
	}
}

/* =========================================================
   CARDS AND SURFACES
   ========================================================= */

.hp-c-surface {
	background: var(--hp-color-white);
	border: 1px solid var(--hp-color-border);
	border-radius: var(--hp-radius-lg);
}

.hp-c-card {
	background: var(--hp-color-white);
	border: 1px solid var(--hp-color-border);
	border-radius: var(--hp-radius-xl);
	box-shadow: var(--hp-shadow-card);
	padding: var(--hp-space-6);
	transition: var(--hp-transition-card);
	transition-property: box-shadow, transform;
}

/* CV-24: an honest "not live yet" card — no call-to-action button at all,
   since there is nowhere real to send someone; a dashed border and muted
   text distinguish it from a genuine, clickable card at a glance. */
.hp-c-card--muted {
	background: var(--hp-color-white);
	border: 1px dashed var(--hp-color-border);
	border-radius: var(--hp-radius-xl);
	padding: var(--hp-space-6);
}

.hp-c-card--muted h3,
.hp-c-card--muted p {
	color: var(--hp-color-body);
}

/* Elevation on hover is decorative only — never the sole means of
   conveying a card is interactive; interactive cards must also carry a
   real focusable link/button inside (D004: no hover-only interaction). */
.hp-c-card--interactive:hover {
	box-shadow: var(--hp-shadow-card-hover);
	transform: translateY(-3px);
}

@media (prefers-reduced-motion: reduce) {
	.hp-c-card {
		transition: none;
	}

	.hp-c-card--interactive:hover {
		transform: none;
	}
}

/* =========================================================
   FORM FIELDS AND VALIDATION STATES
   ========================================================= */

.hp-c-field {
	margin-bottom: var(--hp-space-6);
}

.hp-c-field__label {
	display: block;
	font-weight: 600;
	font-size: var(--hp-text-sm);
	color: var(--hp-color-ink);
	margin-bottom: var(--hp-space-2);
}

.hp-c-field__required {
	color: var(--hp-color-danger-text);
}

.hp-c-input,
.hp-c-textarea,
.hp-c-select {
	width: 100%;
	box-sizing: border-box;
	min-height: 44px; /* mobile touch target, D004 */
	padding: var(--hp-space-3) var(--hp-space-4);
	border: 1px solid var(--hp-color-border-strong);
	border-radius: var(--hp-radius-md);
	font-family: var(--hp-font-body);
	font-size: var(--hp-text-base);
	color: var(--hp-color-ink);
	background: var(--hp-color-white);
	transition: var(--hp-transition-base);
	transition-property: border-color, box-shadow;
}

.hp-c-textarea {
	min-height: 8em;
}

.hp-c-input:focus-visible,
.hp-c-textarea:focus-visible,
.hp-c-select:focus-visible {
	outline: none;
	border-color: var(--hp-color-primary-500);
	box-shadow: 0 0 0 4px rgba(124, 58, 237, 0.12);
}

.hp-c-input:disabled,
.hp-c-textarea:disabled,
.hp-c-select:disabled {
	background: var(--hp-color-border);
	color: var(--hp-color-body);
	cursor: not-allowed;
}

.hp-c-field__help {
	font-size: var(--hp-text-xs);
	color: var(--hp-color-body);
	margin-top: var(--hp-space-2);
}

/* Validation states */

.hp-c-field--error .hp-c-input,
.hp-c-field--error .hp-c-textarea,
.hp-c-field--error .hp-c-select {
	border-color: var(--hp-color-danger-text);
}

.hp-c-field--error .hp-c-input:focus-visible,
.hp-c-field--error .hp-c-textarea:focus-visible,
.hp-c-field--error .hp-c-select:focus-visible {
	box-shadow: 0 0 0 4px rgba(153, 27, 27, 0.12);
}

.hp-c-field__error {
	display: flex;
	align-items: center;
	gap: var(--hp-space-2);
	font-size: var(--hp-text-xs);
	font-weight: 600;
	color: var(--hp-color-danger-text);
	margin-top: var(--hp-space-2);
}

.hp-c-field--success .hp-c-input,
.hp-c-field--success .hp-c-textarea,
.hp-c-field--success .hp-c-select {
	border-color: var(--hp-color-success-text);
}

@media (prefers-reduced-motion: reduce) {
	.hp-c-input,
	.hp-c-textarea,
	.hp-c-select {
		transition: none;
	}
}

/* =========================================================
   BADGES AND STATUS LABELS
   ========================================================= */

.hp-c-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--hp-space-1);
	padding: 0.25em 0.85em;
	border-radius: var(--hp-radius-pill);
	font-size: var(--hp-text-xs);
	font-weight: 600;
	line-height: 1.6;
	white-space: nowrap;
}

.hp-c-badge--neutral {
	background: var(--hp-color-border);
	color: var(--hp-color-body);
}

.hp-c-badge--primary {
	background: var(--hp-color-primary-100);
	color: var(--hp-color-primary-500);
}

.hp-c-badge--info {
	background: var(--hp-color-info-bg);
	color: var(--hp-color-info-text);
}

.hp-c-badge--warning {
	background: var(--hp-color-warning-bg);
	color: var(--hp-color-warning-text);
}

.hp-c-badge--success {
	background: var(--hp-color-success-bg);
	color: var(--hp-color-success-text);
}

.hp-c-badge--danger {
	background: var(--hp-color-danger-bg);
	color: var(--hp-color-danger-text);
}

/* =========================================================
   ALERTS AND NOTICES

   Foundational batch, item 2 (2026-08-06): `.hp-c-alert` used to live here
   as a second, fully unused notice component (zero references anywhere in
   either repo -- confirmed by search) alongside the real, actually-used
   `.hp-notice` system, previously defined only in the Partner Hub plugin's
   own public.css (30+ templates). That stylesheet is conditionally
   enqueued -- only on pages whose content contains a Partner Hub
   shortcode -- so theme-owned pages (Directory, Local Updates, Contact,
   Help Centre...) had no notice component available to them at all. Moved
   here instead, since components.css loads unconditionally on every
   front-end page in both repos, making `.hp-notice` genuinely site-wide
   and giving both repos exactly one canonical definition. Info/error
   colours are unchanged from the pre-existing, already-approved Partner
   Hub appearance (just re-expressed with tokens guaranteed to exist
   wherever this file loads, rather than that file's own local aliases).
   Warning/success are newly added -- `.hp-notice--warning` was already
   used in several templates with no matching CSS rule at all (rendered
   with zero background/colour, a real live bug); `.hp-notice--success` did
   not exist before. Both reuse the same warning/success tokens `.hp-c-alert`
   was already using, so this isn't a new colour decision. See
   `docs/COMPONENT_LIBRARY.md` for the updated reference.
   ========================================================= */

.hp-notice {
	border-radius: var( --hp-radius-md );
	padding: 0.9rem 1.1rem;
	margin-bottom: 1.5rem;
	font-size: 0.9rem;
}

.hp-notice--info {
	background: #ede9fe;
	color: var( --hp-color-primary-700 );
}

.hp-notice--error {
	background: #fef2f2;
	color: #991b1b;
}

.hp-notice--warning {
	background: var( --hp-color-warning-bg );
	color: var( --hp-color-warning-text );
}

.hp-notice--success {
	background: var( --hp-color-success-bg );
	color: var( --hp-color-success-text );
}

/*
 * Owner-caught bug (2026-08-21): the Partner Payment and Community Article
 * Payment pre-checkout landing pages (Partner Hub's Checkout/PaymentController.php,
 * CommunityArticles/ArticlePaymentController.php) render a plain
 * `<section class="hp-payment">` with no matching CSS anywhere in either
 * repo -- a bare, unstyled browser-default heading/paragraph/button on a
 * real paying customer's checkout path. This does not replace Stripe's own
 * hosted Checkout page (out of this project's styling control by design,
 * confirmed via source); it only styles the on-site pre-redirect landing
 * page shown before the customer ever reaches Stripe.
 */
.hp-payment {
	max-width: 32rem;
	margin: 0 auto;
	padding: var( --hp-space-8, 3rem ) var( --hp-space-5, 1.5rem );
	text-align: center;
}

.hp-payment h1 {
	margin-bottom: var( --hp-space-3, 0.75rem );
	font-size: clamp( 1.5rem, 4vw, 2rem );
}

.hp-payment p {
	margin-bottom: var( --hp-space-5, 1.5rem );
	/* --hp-color-text-muted is referenced elsewhere in this codebase (e.g.
	 * heartbeat.css) but never actually defined in tokens.css -- a real,
	 * separate, pre-existing gap not introduced or fixed here; using an
	 * explicit fallback rather than silently inheriting default ink. */
	color: var( --hp-color-text-muted, #6b7280 );
}

/* =========================================================
   TABLES AND RESPONSIVE TABLE HANDLING
   ========================================================= */

/* Wrap any .hp-c-table in .hp-c-table-wrap for horizontal-scroll
   overflow handling — never let a wide table force page-level
   horizontal overflow (D004's zero-overflow rule is non-negotiable). */
.hp-c-table-wrap {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	border: 1px solid var(--hp-color-border);
	border-radius: var(--hp-radius-md);
}

.hp-c-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--hp-text-sm);
}

.hp-c-table th,
.hp-c-table td {
	text-align: left;
	padding: var(--hp-space-3) var(--hp-space-4);
	border-bottom: 1px solid var(--hp-color-border);
	white-space: nowrap;
}

.hp-c-table thead th {
	font-weight: 700;
	color: var(--hp-color-ink);
	background: var(--hp-color-primary-100);
}

.hp-c-table tbody tr:last-child td {
	border-bottom: none;
}

/* Below 600px, prefer stacking each row into a labelled card rather
   than relying on horizontal scroll alone — opt in per-table with
   .hp-c-table--stack-mobile, since not every table's data suits it. */
@media (max-width: 600px) {
	.hp-c-table--stack-mobile thead {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip: rect(0 0 0 0);
	}

	.hp-c-table--stack-mobile,
	.hp-c-table--stack-mobile tbody,
	.hp-c-table--stack-mobile tr,
	.hp-c-table--stack-mobile td {
		display: block;
		width: 100%;
	}

	.hp-c-table--stack-mobile tr {
		border-bottom: 1px solid var(--hp-color-border);
		padding: var(--hp-space-3) 0;
	}

	.hp-c-table--stack-mobile td {
		border-bottom: none;
		padding: var(--hp-space-1) 0;
	}

	/* Requires each <td data-label="Column name"> in markup */
	.hp-c-table--stack-mobile td::before {
		content: attr(data-label);
		display: block;
		font-weight: 700;
		font-size: var(--hp-text-xs);
		color: var(--hp-color-body);
	}
}

/* =========================================================
   TABS AND NAVIGATION CONTROLS
   ========================================================= */

.hp-c-tabs__list {
	display: flex;
	gap: var(--hp-space-2);
	list-style: none;
	margin: 0 0 var(--hp-space-6);
	padding: 0;
	overflow-x: auto; /* never let tabs force page overflow */
	border-bottom: 1px solid var(--hp-color-border);
}

.hp-c-tabs__tab {
	display: inline-flex;
	align-items: center;
	min-height: 44px; /* mobile touch target, D004 */
	padding: var(--hp-space-2) var(--hp-space-4);
	white-space: nowrap;
	font-weight: 600;
	font-size: var(--hp-text-sm);
	color: var(--hp-color-body);
	background: none;
	border: none;
	border-bottom: 3px solid transparent;
	cursor: pointer;
	transition: var(--hp-transition-base);
	transition-property: color, border-color;
}

.hp-c-tabs__tab:hover {
	color: var(--hp-color-ink);
}

.hp-c-tabs__tab[aria-selected="true"] {
	color: var(--hp-color-primary-500);
	border-bottom-color: var(--hp-color-primary-500);
}

.hp-c-tabs__tab:focus-visible {
	outline: 3px solid var(--hp-color-primary-400);
	outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
	.hp-c-tabs__tab {
		transition: none;
	}
}

/* =========================================================
   LOADING, SKELETON AND EMPTY STATES
   ========================================================= */

.hp-c-spinner {
	display: inline-block;
	width: 1.25em;
	height: 1.25em;
	border: 3px solid var(--hp-color-border);
	border-top-color: var(--hp-color-primary-500);
	border-radius: 50%;
	animation: hp-c-spin 0.7s linear infinite;
}

@keyframes hp-c-spin {
	to {
		transform: rotate(360deg);
	}
}

/* Branded alternative to .hp-c-spinner for higher-visibility loading moments
   (a full page-section load, not every small async fetch — reserve the plain
   spinner for those, per the design system's own "not baked into every
   button" restraint on brand moments, DESIGN_SYSTEM.md). Wrap the approved
   web heart image (assets/brand/web/hertspartners-heart.png) in this class. A
   slow, gentle heartbeat pulse — deliberately not the opening animation's
   one-time assembly effect, which would feel gimmicky repeated in a loop. */
.hp-c-loading-mark {
	display: inline-block;
	width: 2.5em;
	animation: hp-c-heartbeat 1.8s ease-in-out infinite;
}

@keyframes hp-c-heartbeat {
	0%, 100% { transform: scale(1); opacity: 1; }
	50% { transform: scale(1.08); opacity: 0.85; }
}

.hp-c-skeleton {
	display: block;
	border-radius: var(--hp-radius-sm);
	background: linear-gradient(
		90deg,
		var(--hp-color-border) 25%,
		var(--hp-color-border-strong) 37%,
		var(--hp-color-border) 63%
	);
	background-size: 400% 100%;
	animation: hp-c-skeleton-shimmer 1.4s ease infinite;
}

@keyframes hp-c-skeleton-shimmer {
	0% {
		background-position: 100% 50%;
	}
	100% {
		background-position: 0 50%;
	}
}

/* Motion-sensitive users get a static, still-legible placeholder
   instead of the spin/shimmer animation, not a blank one. */
@media (prefers-reduced-motion: reduce) {
	.hp-c-spinner {
		animation: none;
		border-top-color: var(--hp-color-border);
	}

	.hp-c-skeleton {
		animation: none;
		background: var(--hp-color-border);
	}

	.hp-c-loading-mark {
		animation: none;
	}
}

.hp-c-empty-state {
	text-align: center;
	padding: var(--hp-space-12) var(--hp-space-6);
	color: var(--hp-color-body);
}

.hp-c-empty-state__icon {
	font-size: var(--hp-text-3xl);
	margin-bottom: var(--hp-space-4);
	line-height: 1;
}

.hp-c-empty-state__title {
	font-weight: 700;
	color: var(--hp-color-ink);
	margin: 0 0 var(--hp-space-2);
}

.hp-c-empty-state__body {
	margin: 0 0 var(--hp-space-6);
	max-width: 40ch;
	margin-inline: auto;
}

/* =========================================================
   FREE TOOLS PAGE (M43)
   Page-specific layout only -- the card, badge and button parts
   themselves are the reusable .hp-c-card/.hp-c-badge/.hp-c-btn
   components above, not reinvented here.
   ========================================================= */

.hp-free-tools__card {
	max-width: 640px;
	margin: var(--hp-space-6) 0;
}

.hp-free-tools__eyebrow {
	margin: 0 0 var(--hp-space-1);
	font-weight: 700;
	font-size: var(--hp-text-xs);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--hp-color-primary-500);
}

.hp-free-tools__badges {
	display: flex;
	flex-wrap: wrap;
	gap: var(--hp-space-2);
	margin: var(--hp-space-3) 0 var(--hp-space-4);
}
/* Shared public-content link treatment. Navigation, buttons, branded media
 * cards and semantic danger actions retain their component colours; ordinary
 * resident-facing text links use one accessible purple token everywhere. */
body:not(.wp-admin) .site-main a:not(.hp-c-btn):not(.hp-btn):not(.directorist-btn):not(.button):not(.hp-link-btn--danger):not([class*="button-link-delete"]) {
	color: var(--hp-color-link, #6d28d9);
	text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
	text-underline-offset: .16em;
}

body:not(.wp-admin) .site-main a:not(.hp-c-btn):not(.hp-btn):not(.directorist-btn):not(.button):not(.hp-link-btn--danger):not([class*="button-link-delete"]):hover,
body:not(.wp-admin) .site-main a:not(.hp-c-btn):not(.hp-btn):not(.directorist-btn):not(.button):not(.hp-link-btn--danger):not([class*="button-link-delete"]):focus-visible {
	color: var(--hp-color-link-hover, #2e1065);
	text-decoration-color: currentColor;
}
