/**
 * VolunteerPress front-end baseline styles.
 *
 * Intentionally minimal and theme-agnostic: layout only, colours and spacing
 * pull from CSS custom properties (with neutral fallbacks) so the active theme
 * can restyle everything by setting --vpress-* variables or overriding the
 * prefixed classes. No fonts, colours, or borders are forced beyond subtle
 * neutrals.
 */

.vpress-opportunities__grid {
	display: grid;
	grid-template-columns: repeat( var( --vpress-columns, 3 ), minmax( 0, 1fr ) );
	gap: var( --vpress-gap, 1.5rem );
}

@media ( max-width: 782px ) {
	.vpress-opportunities__grid {
		grid-template-columns: 1fr;
	}
}

.vpress-opportunity-card {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-1, 0.25rem );
}

.vpress-opportunity-card__link {
	text-decoration: none;
	color: inherit;
}

.vpress-opportunity-card__image img {
	width: 100%;
	height: auto;
	display: block;
	border-radius: var( --vpress-radius, 0.625rem );
}

.vpress-opportunity-card__title {
	margin: var( --vpress-space-2, 0.5rem ) 0 0;
}

.vpress-opportunity-card__location,
.vpress-opportunity-card__categories,
.vpress-opportunity-card__next {
	margin: 0;
	font-size: 0.9em;
	opacity: 0.85;
}

.vpress-opportunity-card__next--none {
	opacity: 0.6;
}

/* The sheet is an interactive surface (the signup entry point), so it takes
   the owned compact base like every other vpress surface (#31) — quieter than
   the host theme's reading prose, per the token layer's type rationale. */
.vpress-shift-sheet {
	font-size: var( --vpress-font-size, 0.875rem );
	line-height: var( --vpress-line, 1.45 );
}

/* The sheet's section heading sits at the calendar caption's type level (#31)
   — the same rank as the month caption, so the two surfaces read as one. */
.vpress-shift-sheet__heading {
	margin: 0 0 var( --vpress-space-3, 0.75rem );
	font-size: var( --vpress-text-xl, 1.0625rem );
	font-weight: 600;
	line-height: var( --vpress-line-tight, 1.25 );
}

/* Quiet meta lines, at the manage page's list-meta level (#31). */
.vpress-shift-sheet__notice,
.vpress-shift-sheet__empty {
	margin: 0;
	font-size: var( --vpress-text-md, 0.8125rem );
	opacity: 0.75;
}

.vpress-shift-sheet__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-3, 0.75rem );
}

.vpress-shift-sheet__item {
	padding: var( --vpress-space-4, 1rem );
	border: 1px solid var( --vpress-border, rgba( 128, 128, 128, 0.28 ) );
	border-radius: var( --vpress-radius, 0.625rem );
}

/* The card's title anchor per the M16.4 hierarchy (issue #31): one type-scale
   step above the body base, the card's only weight-700 text — the same
   relationship the calendar shift row and the manage page carry, so the
   intended read order (title → when → availability) holds here too instead of
   the theme's prose h3 outweighing everything below it. */
.vpress-shift__title {
	margin: 0;
	font-size: var( --vpress-text-lg, 0.9375rem );
	font-weight: 700;
	line-height: var( --vpress-line-tight, 1.25 );
}

/* The sheet's pager (issue #14): plain links either side of a "Page X of Y"
   label, on the shared token layer like the rest of the sheet. */
.vpress-shift-sheet__pagination {
	display: flex;
	align-items: center;
	gap: var( --vpress-space-4, 1rem );
	margin-top: var( --vpress-gap, 1.5rem );
}

.vpress-shift-sheet__page-label {
	font-size: var( --vpress-text-md, 0.8125rem );
	opacity: 0.75;
}

/* The card's details as stacked icon-plus-text rows (#46) — the signup
   modal's M16.5 treatment (same icons, same row shape, same 0.875rem body
   base) so both surfaces read as one system. The explicit size keeps the
   bold when-row below the card's h3 title on the type scale — without it the
   rows inherit the theme's full body size and the when-row outweighs the
   title (H1.1 hierarchy fix). Structure and spacing are owned here; color
   inherits from the theme (chameleon), with icons in quieted currentColor
   strokes so the values stay the loudest thing in each row. */
.vpress-shift__details {
	list-style: none;
	margin: var( --vpress-space-2, 0.5rem ) 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-2, 0.5rem );
	font-size: var( --vpress-font-size, 0.875rem );
}

.vpress-shift__detail {
	display: flex;
	align-items: flex-start;
	gap: var( --vpress-space-2, 0.5rem );
	margin: 0;
}

.vpress-shift__detail-icon {
	flex: 0 0 auto;
	width: 1.125rem;
	height: 1.125rem;
	margin-top: 0.1em;
	opacity: 0.65;
}

.vpress-shift__when {
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.vpress-shift__role,
.vpress-shift__location {
	opacity: 0.75;
}

/* The availability value keeps the row's body base rather than shrinking
   below it — the modal's M16.5 legibility floor, mirrored here. */
.vpress-shift__availability {
	font-size: var( --vpress-font-size, 0.875rem );
}

.vpress-shift__availability--full {
	opacity: 0.8;
}

.vpress-shift__signup {
	margin-top: var( --vpress-space-2, 0.5rem );
}

/* The sheet's signup toggle is the shift's one entry point, styled as a
   secondary button on the shared token layer (M9.7b): accent-derived border
   and label over a transparent background, filling with an accent tint on
   hover and focus-visible. The accent roles arrive pre-blended toward the
   local text colour (tokens.css) so the button stays legible on dark themes.
   It stays a <summary> — the disclosure behavior is untouched — but reads as
   a clear affordance instead of a bare text line. */
.vpress-shift__signup-toggle {
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 2.75rem; /* 44px touch target at the ~16px root. */
	padding: var( --vpress-space-2, 0.5rem ) var( --vpress-space-4, 1rem );
	border: 1px solid var( --vpress-accent-border, #2271b1 );
	border-radius: var( --vpress-radius-sm, 0.375rem );
	background: transparent;
	color: var( --vpress-accent-text, #2271b1 );
	font-family: inherit;
	font-size: var( --vpress-text-md, 0.8125rem );
	font-weight: 600;
	line-height: var( --vpress-line-tight, 1.25 );
	list-style: none; /* A button affordance, not a disclosure triangle. */
	transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* Safari exposes the disclosure marker as a pseudo-element instead. */
.vpress-shift__signup-toggle::-webkit-details-marker {
	display: none;
}

.vpress-shift__signup-toggle:hover {
	background: var( --vpress-accent-tint, rgba( 128, 128, 128, 0.06 ) );
	border-color: var( --vpress-accent-border-strong, #2271b1 );
}

.vpress-shift__signup-toggle:focus-visible {
	outline: 2px solid var( --vpress-focus, currentColor );
	outline-offset: 2px;
	background: var( --vpress-accent-tint, rgba( 128, 128, 128, 0.06 ) );
	border-color: var( --vpress-accent-border-strong, #2271b1 );
}

/* While the form is open the toggle keeps its tinted (active) state and gains
   token spacing so the revealed form doesn't butt against the button. */
.vpress-shift__signup[open] > .vpress-shift__signup-toggle {
	margin-bottom: var( --vpress-space-3, 0.75rem );
	background: var( --vpress-accent-tint, rgba( 128, 128, 128, 0.06 ) );
}

/* After this shift's form confirms or waitlists the visitor, the toggle reads
   as a done state: label and border shift to the success token. Shape, size,
   and the M9.7b secondary-button treatment are otherwise unchanged. */
.vpress-shift__signup-toggle.is-signed-up {
	color: var( --vpress-success, #1a7f37 );
	border-color: var( --vpress-success, #1a7f37 );
}

/* -------------------------------------------------------------------------- */
/* Signup form — composed on the shared token layer (tokens.css).             */
/* The plugin owns structure, spacing, and interaction/validation states;     */
/* colour derives from the host theme: the accent token for focus and the     */
/* primary action, currentColor tints for borders and field surfaces.         */
/* -------------------------------------------------------------------------- */

.vpress-signup {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-4, 1rem );
	font-size: var( --vpress-font-size, 0.875rem );
	line-height: var( --vpress-line, 1.45 );
}

/*
 * Honour the `hidden` attribute (the same law the calendar pins): the script
 * swaps the form body for the confirmation panel — and shows field errors —
 * by toggling `hidden`, and any authored `display` on those elements would
 * otherwise win over the UA rule and defeat the hide.
 */
.vpress-signup [hidden] {
	display: none !important;
}

/* The interactive body (fields + honeypot + submit) hides as one unit when
   the confirmation panel replaces it; it keeps the form's own rhythm. */
.vpress-signup__body {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-4, 1rem );
}

.vpress-signup__heading {
	margin: 0;
	font-size: var( --vpress-text-lg, 0.9375rem );
	font-weight: 600;
	line-height: var( --vpress-line-tight, 1.25 );
}

.vpress-signup__availability {
	margin: calc( -1 * var( --vpress-space-3, 0.75rem ) ) 0 0;
	font-size: var( --vpress-text-sm, 0.75rem );
	opacity: 0.75;
}

.vpress-signup__field {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-1, 0.25rem );
	margin: 0;
}

/* Labels are always visible above the input — never a placeholder-as-label. */
.vpress-signup__label {
	font-size: var( --vpress-text-md, 0.8125rem );
	font-weight: 600;
	line-height: var( --vpress-line-tight, 1.25 );
}

/* Required marker: a glyph, not colour alone; the input's `required` attribute
   carries the semantics, so the glyph is aria-hidden. */
.vpress-signup__required {
	margin-inline-start: 0.125rem;
	color: var( --vpress-accent-text, currentColor );
}

.vpress-signup__input {
	box-sizing: border-box;
	width: 100%;
	min-height: 2.75rem; /* 44px touch target at the ~16px root. */
	padding: var( --vpress-space-2, 0.5rem ) var( --vpress-space-3, 0.75rem );
	border: 1px solid var( --vpress-border-strong, rgba( 128, 128, 128, 0.46 ) );
	border-radius: var( --vpress-radius-sm, 0.375rem );
	background: var( --vpress-surface, rgba( 128, 128, 128, 0.06 ) );
	color: inherit;
	font-family: inherit;
	/* Floor at a hard 16px, with the rem term still growing the control with
	   the user's root-size preference — iOS Safari zooms the page when
	   focusing a control rendered below 16px, and a bare 1rem floor resolves
	   under 16px on themes that downscale the root font-size (the 62.5% root
	   trick), silently re-enabling the zoom (M16.6). Applies to every signup
	   control: inputs, selects, and textareas all carry this class. */
	font-size: max( 16px, 1rem );
	line-height: var( --vpress-line, 1.45 );
}

/* Focus is part of the identity: a clear ring derived from the accent token. */
.vpress-signup__input:focus-visible {
	outline: 2px solid var( --vpress-focus, currentColor );
	outline-offset: 2px;
}

/* Validation state: the message element does the explaining; the border makes
   the field findable at a glance. */
.vpress-signup__input[aria-invalid="true"] {
	border-color: var( --vpress-error, #b32d2e );
}

.vpress-signup__error {
	font-size: var( --vpress-text-sm, 0.75rem );
	color: var( --vpress-error, #b32d2e );
}

/* Admin-authored help text: quieter than the label, above the error slot,
   announced via the control's aria-describedby. */
.vpress-signup__help {
	font-size: var( --vpress-text-sm, 0.75rem );
	opacity: 0.75;
}

/* -------------------------------------------------------------------------- */
/* Custom-field control variants (M11) — the same box, type scale, and        */
/* 2.75rem targets as the core inputs; only what each control type demands    */
/* differs. Selects inherit the input box unchanged.                          */
/* -------------------------------------------------------------------------- */

.vpress-signup__input--textarea {
	resize: vertical;
	min-height: 5.5rem; /* two rows of the 2.75rem rhythm — room for a real answer. */
}

/* Checkbox: the native box is the control; the whole label row carries the
   2.75rem touch target. */
.vpress-signup__checkbox {
	display: flex;
	align-items: center;
	gap: var( --vpress-space-2, 0.5rem );
	min-height: 2.75rem; /* 44px touch target at the ~16px root. */
	cursor: pointer;
}

.vpress-signup__input--checkbox {
	flex: none;
	width: 1.25rem;
	height: 1.25rem;
	min-height: 0;
	margin: 0;
	padding: 0;
	accent-color: var( --vpress-accent, currentColor );
}

.vpress-signup__actions {
	margin: 0;
}

/* The submit is the form's one primary action: accent-filled, owned shape. */
.vpress-signup__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 2.75rem; /* 44px touch target at the ~16px root. */
	padding: var( --vpress-space-2, 0.5rem ) var( --vpress-space-5, 1.5rem );
	border: 1px solid transparent;
	border-radius: var( --vpress-radius-sm, 0.375rem );
	background: var( --vpress-accent, #2271b1 );
	/* A block theme's base surface colour sits opposite its accent, so it is
	   the theme-derived text-on-accent; white is the safe fallback. */
	color: var( --wp--preset--color--base, #fff );
	font-family: inherit;
	font-size: var( --vpress-text-lg, 0.9375rem );
	font-weight: 600;
	line-height: var( --vpress-line-tight, 1.25 );
	cursor: pointer;
}

.vpress-signup__submit:hover {
	filter: brightness( 0.94 );
}

.vpress-signup__submit:active {
	filter: brightness( 0.88 );
}

.vpress-signup__submit:focus-visible {
	outline: 2px solid var( --vpress-focus, currentColor );
	outline-offset: 2px;
}

.vpress-signup__submit[disabled] {
	cursor: default;
	filter: none;
	opacity: 0.6;
}

/* Success confirmation — replaces the form body inside the same container.
   Structure and spacing from the shared scale; the surface and border come
   from the derived tint tokens; only the check icon carries the success hue. */
.vpress-signup__confirmation {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-2, 0.5rem );
	padding: var( --vpress-space-4, 1rem );
	border: 1px solid var( --vpress-border, rgba( 128, 128, 128, 0.28 ) );
	border-radius: var( --vpress-radius, 0.625rem );
	background: var( --vpress-surface, rgba( 128, 128, 128, 0.06 ) );
}

.vpress-signup__confirmation-heading {
	display: flex;
	align-items: center;
	gap: var( --vpress-space-2, 0.5rem );
	margin: 0;
	font-size: var( --vpress-text-lg, 0.9375rem );
	font-weight: 600;
	line-height: var( --vpress-line-tight, 1.25 );
}

.vpress-signup__confirmation-icon {
	flex: none;
	width: 1.5rem;
	height: 1.5rem;
	color: var( --vpress-success, #1a7f37 );
}

.vpress-signup__confirmation-message {
	margin: 0;
	font-size: var( --vpress-text-md, 0.8125rem );
}

/* Form-level feedback sits at the shared status level (text-md) — the same
   size the manage page's notice region and the calendar's loading/error lines
   use (#31); field-level annotations (help, errors) stay a step below. */
.vpress-signup__status {
	margin: 0;
	font-size: var( --vpress-text-md, 0.8125rem );
}

/* An empty status paragraph must not claim a slot in the form's rhythm. */
.vpress-signup__status:empty {
	display: none;
}

.vpress-signup__status.is-success {
	color: var( --vpress-success, #1a7f37 );
}

.vpress-signup__status.is-error {
	color: var( --vpress-error, #b32d2e );
}

.vpress-opportunities__pagination {
	display: flex;
	align-items: center;
	gap: var( --vpress-space-4, 1rem );
	margin-top: var( --vpress-gap, 1.5rem );
}

/* -------------------------------------------------------------------------- */
/* Manage-my-signups page — composed on the shared token layer (tokens.css).  */
/* The plugin owns the layout, the row structure, and every interaction       */
/* state; colour derives from the host theme via the token layer.             */
/* -------------------------------------------------------------------------- */

.vpress-manage {
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-4, 1rem );
	max-width: 40rem;
	margin: var( --vpress-space-6, 2rem ) auto;
	padding: 0 var( --vpress-space-4, 1rem );
	font-size: var( --vpress-font-size, 0.875rem );
	line-height: var( --vpress-line, 1.45 );
}

/* Honour the `hidden` attribute (the same law the signup form pins): the
   store swaps a row's form for its cancelled marker by toggling `hidden`. */
.vpress-manage [hidden] {
	display: none !important;
}

.vpress-manage__app {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-4, 1rem );
}

/* The one live region for cancel outcomes; state colour is paired with the
   message text itself, never colour alone. */
.vpress-manage__notice {
	margin: 0;
	padding: var( --vpress-space-3, 0.75rem ) var( --vpress-space-4, 1rem );
	border: 1px solid var( --vpress-border, rgba( 128, 128, 128, 0.28 ) );
	border-radius: var( --vpress-radius-sm, 0.375rem );
	background: var( --vpress-surface, rgba( 128, 128, 128, 0.06 ) );
	color: var( --vpress-success, #1a7f37 );
	font-size: var( --vpress-text-md, 0.8125rem );
	font-weight: 600;
}

/* An empty region must not claim a slot in the page rhythm. */
.vpress-manage__notice:empty {
	display: none;
}

.vpress-manage__notice.is-error {
	color: var( --vpress-error, #b32d2e );
}

.vpress-manage__list {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-3, 0.75rem );
	margin: 0;
	padding: 0;
	list-style: none;
}

.vpress-manage__item {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var( --vpress-space-3, 0.75rem );
	padding: var( --vpress-space-4, 1rem );
	border: 1px solid var( --vpress-border, rgba( 128, 128, 128, 0.28 ) );
	border-radius: var( --vpress-radius, 0.625rem );
	background: var( --vpress-surface, rgba( 128, 128, 128, 0.06 ) );
}

/* A cancelled row stays in place, muted; its state is carried by the visible
   "Cancelled" marker that replaces the button, not by the fade alone. */
.vpress-manage__item.is-cancelled {
	opacity: 0.7;
}

.vpress-manage__details {
	display: flex;
	flex-direction: column;
	gap: var( --vpress-space-1, 0.25rem );
	min-width: 0;
}

/* The card's type hierarchy mirrors the calendar shift card (M16.4):
   title anchors, datetime subordinate, status by weight — never a fill. */
.vpress-manage__title {
	font-size: var( --vpress-text-lg, 0.9375rem );
	font-weight: 700;
	line-height: var( --vpress-line-tight, 1.25 );
}

.vpress-manage__opportunity,
.vpress-manage__location {
	font-size: var( --vpress-text-sm, 0.75rem );
	opacity: 0.75;
}

.vpress-manage__when {
	font-size: var( --vpress-font-size, 0.875rem );
	opacity: 0.75;
}

.vpress-manage__status {
	font-size: var( --vpress-text-sm, 0.75rem );
	font-weight: 600;
}

.vpress-manage__form {
	margin: 0;
}

/* The cancel is destructive and secondary: bordered on the shared shape
   language, the error hue on the label (paired with the explicit label text),
   never an accent fill. */
.vpress-manage__cancel {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 2.75rem; /* 44px touch target at the ~16px root. */
	padding: var( --vpress-space-2, 0.5rem ) var( --vpress-space-4, 1rem );
	border: 1px solid var( --vpress-border-strong, rgba( 128, 128, 128, 0.46 ) );
	border-radius: var( --vpress-radius-sm, 0.375rem );
	background: transparent;
	color: var( --vpress-error, #b32d2e );
	font-family: inherit;
	font-size: var( --vpress-text-md, 0.8125rem );
	font-weight: 600;
	line-height: var( --vpress-line-tight, 1.25 );
	cursor: pointer;
}

.vpress-manage__cancel:hover {
	background: var( --vpress-surface-raised, rgba( 128, 128, 128, 0.1 ) );
}

.vpress-manage__cancel:focus-visible {
	outline: 2px solid var( --vpress-focus, currentColor );
	outline-offset: 2px;
}

.vpress-manage__cancel[disabled] {
	cursor: default;
	opacity: 0.6;
}

/* The enhanced path's in-place confirmation; a focus target (tabindex="-1"),
   so it keeps a visible focus outline. */
.vpress-manage__cancelled {
	margin: 0;
	font-size: var( --vpress-text-md, 0.8125rem );
	font-weight: 600;
	opacity: 0.75;
}

.vpress-manage__empty,
.vpress-manage__more {
	margin: 0;
	font-size: var( --vpress-text-md, 0.8125rem );
	opacity: 0.75;
}

.vpress-manage__error {
	margin: 0;
	font-size: var( --vpress-font-size, 0.875rem );
}
