/**
 * Shared styles for the detail-page header used on event, campaign, and
 * article detail pages. Models the about-page hero pattern (.about-hero):
 * a two-column block with the image on the left and the title + key meta
 * on the right.
 *
 * Included once per detail page (event.php, campaign.php, article.php).
 */

.detail-hero {
  padding: 60px 0;
  background: #fff;
}
.detail-hero .detail-hero-image-wrap {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 16px;
  overflow: hidden;
  background: #eee;
}
.detail-hero .detail-hero-image-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.detail-hero h1 {
  font-family: var(--font-stack);
  font-size: 32px;
  font-weight: 700;
  color: #505050;
  margin: 0 0 16px;
  line-height: 1.25;
}
.detail-hero .detail-hero-meta {
  font-family: var(--font-stack);
  font-size: 0.95rem;
  color: #505050;
  line-height: 1.7;
}
.detail-hero .detail-hero-meta p {
  margin: 0 0 8px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
/* When the meta row leads with an icon (img or svg), the trailing span
	   should fill the row so long text wraps cleanly. Plain rows without an
	   icon let their spans size to their natural content (no forced stretch). */
.detail-hero .detail-hero-meta p > img + span,
.detail-hero .detail-hero-meta p > svg + span {
  flex: 1;
  min-width: 0;
}
.detail-hero .detail-hero-meta p:last-child {
  margin-bottom: 0;
}
.detail-hero .detail-hero-meta img {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.detail-hero .detail-hero-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--theme-color-readable);
}
.detail-hero .detail-hero-meta .hightlight-text {
  font-weight: 600;
  color: #505050;
}
.detail-hero .detail-hero-cta {
  display: inline-block;
  margin-top: 20px;
  padding: 12px 22px;
  background: var(--theme-color);
  color: var(--theme-on-primary);
  border-radius: 8px;
  text-decoration: none;
  font-weight: 600;
  font-family: var(--font-stack);
}
.detail-hero .detail-hero-cta:hover {
  background: var(--theme-color-hover);
  color: var(--theme-on-primary);
  text-decoration: none;
}

/* Inline pill badges shown above the title (event type, Free, members only). */
.detail-hero .detail-hero-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.detail-hero .detail-hero-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: #f0f3f8;
  color: #4a4a68;
  font-family: var(--font-stack);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2px;
}
.detail-hero .detail-hero-badge-accent {
  background: var(--theme-color);
  color: var(--theme-on-primary);
}
/* Soft variant — informational pills like "Instant approval" that should
   read as a chip but not compete with a solid accent badge in the same
   row. Uses a slightly darker NEUTRAL (one step from .detail-hero-badge
   default) so it's visually distinct without pulling --theme-light onto
   a --theme-color-text pairing. We can't put the primary color and the
   secondary color on the same pill — across white-label themes there's
   no contrast guarantee between the two, so the chip would become
   unreadable on some orgs. */
.detail-hero .detail-hero-badge-soft {
  background: #e3e9f2;
  color: #3d3f54;
}
.detail-hero .detail-hero-badge-members {
  background: #fff;
  color: var(--theme-color-readable);
  border: 1.5px solid var(--theme-color);
}
.detail-hero .detail-hero-summary {
  font-family: var(--font-stack);
  font-size: 1rem;
  color: #505050;
  line-height: 1.6;
  margin: 0 0 16px;
}

/* Campaign progress bar in the hero — full-width bar with rounded ends. */
.detail-hero .detail-hero-progress {
  background: #eef2f6;
  border-radius: 999px;
  height: 10px;
  overflow: hidden;
  margin: 14px 0 8px;
}
.detail-hero .detail-hero-progress-bar {
  background: var(--theme-color);
  height: 100%;
  border-radius: 999px;
  transition: width 0.4s ease;
}
.detail-hero .detail-hero-progress-label {
  margin: 0;
  font-family: var(--font-stack);
  font-size: 0.95rem;
  color: #555;
  text-align: center;
}

/* Campaign hero "Raised: $X" + "Goal: $Y" line above the progress bar.
   Raised hugs the left, Goal hugs the right — visual anchors for the
   progress bar that sits below them. Uses justify-content: space-between
   on the existing flex row (.detail-hero-meta p is already flex). */
.detail-hero .detail-hero-raised-line {
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.detail-hero .detail-hero-goal {
  text-align: right;
}

/* Hero action buttons (like, comment, etc.) */
.detail-action-buttons {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 18px;
}
.detail-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 18px;
  background: #fff;
  border: 1.5px solid #e3e8f0;
  border-radius: 999px;
  color: #4a4a68;
  font-family: var(--font-stack);
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    color 0.15s ease,
    background 0.15s ease;
}
.detail-action-btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
.detail-action-btn:hover {
  border-color: var(--theme-color);
  color: var(--theme-color-readable);
}
.detail-action-btn.is-active {
  background: var(--theme-color);
  border-color: var(--theme-color);
  color: var(--theme-on-primary);
}

/* Hide the duplicate image and title that originally sat inside the
	   detail page's main column. Scoped via .detail-hero-duplicate so each
	   page only hides what it tags. */
.detail-hero-duplicate {
  display: none !important;
}

/* ── Info blocks under the description (coordinator, directions, FAQ, terms) ── */
.detail-info-card {
  background: #f7f8fb;
  border-radius: 14px;
  padding: 22px 24px;
  margin: 32px 0 0;
  font-family: var(--font-stack);
}
.detail-info-card.detail-info-card-accent {
  background: #fff;
  border: 1px solid var(--theme-color);
}
.detail-info-card.detail-info-card-warn {
  background: #fffbea;
  border: 1px solid #e0c560;
}
.detail-info-card h3 {
  font-family: var(--font-stack);
  font-size: 22px;
  font-weight: 700;
  color: #505050;
  margin: 0 0 14px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.detail-info-card h3 .detail-info-icon {
  width: 20px;
  height: 20px;
  color: var(--theme-color-readable);
  flex-shrink: 0;
}
.detail-info-card p {
  margin: 0 0 8px;
  color: #505050;
  line-height: 1.7;
  font-size: 0.95rem;
}
.detail-info-card p:last-child {
  margin-bottom: 0;
}
.detail-info-card .detail-info-contact {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.detail-info-card .detail-info-contact:last-child {
  border-bottom: 0;
}
.detail-info-card .detail-info-contact-name {
  font-weight: 600;
  color: #505050;
}
.detail-info-card .detail-info-contact-meta {
  color: #666;
  font-size: 0.88rem;
  margin-top: 2px;
}
.detail-info-card .detail-info-contact-icons {
  display: flex;
  gap: 12px;
  margin-left: auto;
}
.detail-info-card .detail-info-contact-icons a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #fff;
  color: var(--theme-color-readable);
  text-decoration: none;
  border: 1px solid #e3e8f0;
}
.detail-info-card .detail-info-contact-icons a:hover {
  background: var(--theme-color);
  color: var(--theme-on-primary);
}
.detail-info-card .detail-info-contact-icons svg {
  width: 16px;
  height: 16px;
}

/* FAQ accordion */
.detail-faq-item {
  border-bottom: 1px solid #e3e8f0;
}
.detail-faq-item:last-child {
  border-bottom: 0;
}
.detail-faq-item details {
  padding: 14px 0;
}
.detail-faq-item summary {
  cursor: pointer;
  font-weight: 600;
  color: #505050;
  font-size: 1rem;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}
.detail-faq-item summary::-webkit-details-marker {
  display: none;
}
.detail-faq-item summary::after {
  content: "+";
  color: var(--theme-color-readable);
  font-size: 1.3rem;
  font-weight: 700;
  transition: transform 0.2s;
  flex-shrink: 0;
}
.detail-faq-item details[open] summary::after {
  content: "−";
}
.detail-faq-item .detail-faq-body {
  padding: 12px 0 0;
  color: #555;
  line-height: 1.7;
  font-size: 0.95rem;
}

/* ── Tighten rich-text description paragraph spacing ──────────────────
	   Rich-text editors (campaigns, events, resources, about) often emit a
	   <p><br></p> between real paragraphs which doubles the visual gap.
	   We hide those empty paragraphs and pull real paragraph margins back to
	   a normal-feeling 0.5em. */
.event-details-area .section-content p,
.event-details-area .event-description p,
.event-details-area .blog_details p,
.about-wrapper .text-muted-custom p {
  margin: 0 0 1.5em;
  line-height: 1.7;
}
.event-details-area .section-content p:empty,
.event-details-area .section-content p:has(> br:only-child),
.event-details-area .event-description p:empty,
.event-details-area .event-description p:has(> br:only-child),
.event-details-area .blog_details p:empty,
.event-details-area .blog_details p:has(> br:only-child),
.about-wrapper .text-muted-custom p:empty,
.about-wrapper .text-muted-custom p:has(> br:only-child) {
  display: none;
}

/* ── Full-width FAQ section below the main detail content ───────────── */
.detail-faq-section {
  padding: 100px 0;
  background: #fff;
}
.detail-faq-section-title {
  font-family: var(--font-stack);
  font-size: 28px;
  font-weight: 700;
  color: #505050;
  margin: 0 0 50px;
  text-align: center;
}
/* 3-column grid that collapses gracefully on smaller screens.
	   Q&A is rendered fully expanded for SEO indexing — no accordion. */
.detail-faq-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  max-width: 1100px;
  margin: 0 auto;
}
@media (max-width: 900px) {
  .detail-faq-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .detail-faq-grid {
    grid-template-columns: 1fr;
  }
}
.detail-faq-card {
  background: #f7f8fb;
  border: 2px solid transparent;
  border-radius: 14px;
  padding: 22px 24px;
  font-family: var(--font-stack);
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.15s ease;
}
.detail-faq-card:hover {
  border-color: var(--theme-color);
  box-shadow: 0 12px 28px rgba(9, 151, 217, 0.14);
  transform: translateY(-3px);
}
.detail-faq-q {
  font-family: var(--font-stack);
  font-size: 1rem;
  font-weight: 700;
  color: #505050;
  margin: 0 0 10px;
  line-height: 1.4;
}
.detail-faq-a {
  color: #505050;
  line-height: 1.7;
  font-size: 0.92rem;
}

/* ── Terms & conditions modal triggered from ticket panel ────────────── */
.detail-terms-link {
  color: var(--theme-color-readable);
  text-decoration: underline;
  font-family: var(--font-stack);
}
.detail-terms-link:hover {
  color: var(--theme-color-hover);
}
dialog.detail-terms-modal {
  border: none;
  border-radius: 16px;
  padding: 0;
  max-width: 560px;
  width: 90%;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.2);
}
dialog.detail-terms-modal::backdrop {
  background: rgba(0, 0, 0, 0.45);
}
.detail-terms-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px;
  border-bottom: 1px solid #e3e8f0;
}
.detail-terms-modal-header h4 {
  margin: 0;
  font-family: var(--font-stack);
  font-size: 18px;
  font-weight: 700;
  color: #505050;
}
.detail-terms-modal-close {
  background: transparent;
  border: none;
  font-size: 28px;
  line-height: 1;
  color: #666;
  cursor: pointer;
  padding: 0 4px;
}
.detail-terms-modal-close:hover {
  color: #000;
}
.detail-terms-modal-body {
  padding: 22px;
  color: #505050;
  line-height: 1.7;
  font-size: 0.95rem;
  font-family: var(--font-stack);
  max-height: 60vh;
  overflow-y: auto;
}

/* ── Registration modal: wraps attendee/payment/success so tickets stay
	      visible behind it and the user can close out mid-flow. ───────────── */
dialog.ev-checkout-modal {
  border: none;
  border-radius: 16px;
  padding: 0;
  max-width: 640px;
  width: 92%;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.25);
  font-family: var(--font-stack);
}
dialog.ev-checkout-modal::backdrop {
  background: rgba(0, 0, 0, 0.55);
}
.ev-checkout-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 24px;
  border-bottom: 1px solid #e3e8f0;
}
.ev-checkout-modal-header h4 {
  margin: 0;
  font-family: var(--font-stack);
  font-size: 18px;
  font-weight: 700;
  color: #505050;
}
.ev-checkout-modal-close {
  background: transparent;
  border: none;
  font-size: 28px;
  line-height: 1;
  color: #666;
  cursor: pointer;
  padding: 0 4px;
}
.ev-checkout-modal-close:hover {
  color: #000;
}
.ev-checkout-modal-body {
  padding: 24px;
  color: #505050;
  font-family: var(--font-stack);
  max-height: 75vh;
  overflow-y: auto;
  /* Stop scroll-chaining: when scrolling reaches the top/bottom of the
     modal body, the page behind it must NOT start scrolling. */
  overscroll-behavior: contain;
}
/* Pin the dialog so the dev's native <dialog> centering doesn't drift
   when the on-screen keyboard appears (iOS / Android) or when the modal
   body scrolls. position: fixed via inset keeps it centered relative to
   the visual viewport, not the layout viewport. */
dialog.ev-checkout-modal[open] {
  position: fixed;
  inset: 50% auto auto 50%;
  transform: translate(-50%, -50%);
  margin: 0;
}
/* Lock body scroll while the registration modal is open so the page
   behind doesn't scroll/shift when the user is interacting with the
   modal — native <dialog> doesn't automatically lock body scroll on
   touch devices, so a long fingertip drag on the backdrop scrolls the
   page underneath. :has() is at ~94% browser support, matching our
   color-mix baseline. */
body:has(dialog.ev-checkout-modal[open]) {
  overflow: hidden;
}
/* The step divs inside the modal already render with display:none unless
	   the dev's JS has flipped them. Don't override that — but ensure the
	   first visible step has no extra top margin colliding with the modal
	   header. */
.ev-checkout-modal-body > div:first-child > h4:first-child {
  margin-top: 0;
}
.ev-checkout-modal-body h4 {
  font-family: var(--font-stack);
  font-size: 22px;
  font-weight: 700;
  color: #505050;
}

/* Step action rows inside the modal: one primary CTA on the right, Back
	   on the left as a subtle text link. Avoids the prior two-primary look. */
.ev-modal-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 20px;
}
/* Modal Back / Cancel — text-link style. Used as the SECONDARY in any
   step navigation row (event registration, plan join, campaign donate).
   .ev-modal-back kept as an alias for the event modal's existing markup. */
.modal-back-link,
.ev-modal-back {
  background: transparent;
  border: none;
  color: var(--theme-color-readable);
  font-family: var(--font-stack);
  font-size: 0.95rem;
  font-weight: 600;
  padding: 8px 4px;
  cursor: pointer;
  text-decoration: none;
}
.modal-back-link:hover,
.ev-modal-back:hover {
  color: var(--theme-color-hover);
  text-decoration: underline;
}
.ev-modal-primary {
  min-width: 180px;
}

/* ── Attendee step copy: email-delivery context + tooltip + comms opt-in
	      + implicit terms-of-use legal line. ─────────────────────────────── */
.ev-attendee-context {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-family: var(--font-stack);
  font-size: 0.92rem;
  color: var(--theme-on-secondary);
  line-height: 1.5;
  margin: 0 0 18px;
  padding: 12px 14px;
  background: var(--theme-light);
  border-radius: 10px;
}
.ev-attendee-context-icon {
  width: 18px;
  height: 18px;
  color: var(--theme-on-secondary);
  flex: 0 0 auto;
  margin-top: 2px;
}
/* Inline tooltip on the right of the context line. The "?" badge stays
	   small and round; hover reveals the helper sentence in a dark bubble
	   anchored to the badge. */
.ev-attendee-tooltip {
  position: relative;
  display: inline-flex;
  align-items: center;
  background: transparent;
  border: none;
  padding: 0;
  margin-left: 4px;
  cursor: help;
  color: var(--theme-color-readable);
}
.ev-attendee-tooltip-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--theme-color);
  color: var(--theme-color-readable);
  font-family: var(--font-stack);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
}
.ev-attendee-tooltip-text {
  position: absolute;
  /* Anchor to the RIGHT edge of the badge so the tooltip extends LEFT.
     Centering on the badge (translateX(-50%)) overflowed the screen
     because the badge sits at the end of a long context line — the
     tooltip's natural width pushed it off-screen on the right. With
     right:0 the tooltip can't extend beyond the badge's right edge. */
  right: 0;
  left: auto;
  top: calc(100% + 10px);
  /* Width capped to the viewport (minus a 16px safety inset on each
     side) so even an out-of-position tooltip never clips the screen. */
  min-width: min(240px, calc(100vw - 32px));
  max-width: min(280px, calc(100vw - 32px));
  padding: 10px 12px;
  background: #1f2433;
  color: #fff;
  font-family: var(--font-stack);
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.45;
  border-radius: 8px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 10;
  white-space: normal;
  text-align: left;
}
/* Arrow now points up at the badge from the right edge of the tooltip,
   not the center — so it lines up with the help-icon above. */
.ev-attendee-tooltip-text::after {
  content: "";
  position: absolute;
  bottom: 100%;
  right: 4px;
  left: auto;
  border: 6px solid transparent;
  border-bottom-color: #1f2433;
}
.ev-attendee-tooltip:hover .ev-attendee-tooltip-text,
.ev-attendee-tooltip:focus-visible .ev-attendee-tooltip-text {
  opacity: 1;
}

/* Comms opt-in. Optional, friendly framing, blue-tinted background to
	   distinguish from required form fields. */
.ev-attendee-optin {
  margin: 18px 0 12px;
  padding: 14px 16px;
  background: #f7f8fb;
  border: 1px solid #e3e8f0;
  border-radius: 10px;
}
.ev-attendee-optin-label {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-family: var(--font-stack);
  font-size: 0.92rem;
  color: #505050;
  line-height: 1.5;
  margin: 0;
  cursor: pointer;
}
.ev-attendee-optin-checkbox {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex: 0 0 auto;
  accent-color: var(--theme-color);
  cursor: pointer;
}

/* Implicit terms-of-use copy directly under the action row. Quiet, fine
	   print — purchasing is the agreement, no separate gating checkbox. */
.ev-attendee-legal {
  font-family: var(--font-stack);
  font-size: 0.78rem;
  color: #666;
  line-height: 1.5;
  margin: 0 0 8px;
}
.ev-attendee-legal a {
  color: var(--theme-color-readable);
  text-decoration: underline;
}
.ev-attendee-legal a:hover {
  color: var(--theme-color-hover);
}

/* Terms reminder shown above the Pay Now button so users see the same
	   agreement language they checked off on the attendee step. */
.ev-modal-terms-reminder {
  font-family: var(--font-stack);
  font-size: 0.82rem;
  color: #666;
  line-height: 1.5;
  margin: 12px 0 0;
}
.ev-modal-terms-reminder a {
  color: var(--theme-color-readable);
  text-decoration: underline;
}
.ev-modal-terms-reminder a:hover {
  color: var(--theme-color-hover);
}

/* ── Tickets purchase: full-width section matching coordinator/FAQ bg ──── */
.event-tickets-section {
  background: #f7f8fb;
  padding: 100px 0;
  width: 100%;
}
/* Constrain to the same 1100px max-width as the description/coordinator
	   row above, with matching horizontal padding so everything aligns. */
.event-tickets-main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 15px;
}
/* Override the renderer's .event-bx wrapper so we don't get a card-in-card */
.event-tickets-main .event-bx {
  background: transparent;
  box-shadow: none;
  padding: 0;
  border: 0;
}

/* The panel uses a flex-wrap row that centers ticket cards while
	   non-card siblings (heading, checkout row, etc.) take their own
	   full-width rows via flex-basis 100% below. */
.event-tickets-main #ev-step-tickets {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: 14px;
}
.event-tickets-main #ev-step-tickets > h4 {
  font-family: var(--font-stack);
  font-weight: 700;
  font-size: 22px;
  color: #505050;
  margin: 0 auto;
  text-align: center;
  max-width: 50%;
}
/* The "X tickets remaining" intro line — center it under the heading,
	   at the same half-panel width. */
.event-tickets-main #ev-step-tickets > p {
  margin: 0 auto;
  text-align: center;
  max-width: 50%;
  justify-content: center;
}
@media (max-width: 600px) {
  .event-tickets-main #ev-step-tickets > h4,
  .event-tickets-main #ev-step-tickets > p {
    max-width: 100%;
  }
}
/* Heading, error alert, checkout row, terms link, etc. take a full row. */
.event-tickets-main #ev-step-tickets > h4,
.event-tickets-main #ev-step-tickets > p,
.event-tickets-main #ev-step-tickets > .alert,
.event-tickets-main #ev-step-tickets > button,
.event-tickets-main #ev-step-tickets > .ev-checkout-row-wrap {
  flex: 0 0 100%;
  max-width: 100%;
}
/* Wrapper claims the full row; the inner pill (.ev-checkout-row) shrinks
	   to fit its content and centers via justify-content. */
.event-tickets-main .ev-checkout-row-wrap {
  display: flex;
  justify-content: center;
  margin-top: 44px;
}
/* Ticket cards have a fixed-ish width: never bigger than 340px, never
	   smaller than 280px when there's room. 1 card centers; 2 sit centered
	   side-by-side; 3 fill the row evenly; 4+ wraps to a new row.
	   At small viewports they collapse to 100% via the media query below. */
.event-tickets-main #ev-step-tickets > .ev-ticket-row {
  flex: 0 1 320px;
  max-width: 340px;
}
@media (max-width: 600px) {
  .event-tickets-main #ev-step-tickets > .ev-ticket-row {
    flex: 0 1 100%;
    max-width: 100%;
  }
}

/* Individual ticket card — tear-off stub design: top section holds name +
	   description, a perforated dashed line with circular notches separates
	   the top from a bottom stub that shows price + remaining progress bar. */
.event-tickets-main .ev-ticket-card {
  margin: 0 !important;
  background: #fff;
  /* 2px solid transparent border so the card stays the SAME size when
		   the selected state swaps it to a 2px theme-color border. Without
		   this, the card would shift 1px on each side on click. */
  border: 2px solid #e5e2d8;
  border-radius: 14px;
  padding: 0 !important;
  display: flex;
  flex-direction: column;
  text-align: left;
  font-family: var(--font-stack);
  box-shadow: 0 1px 2px rgba(28, 27, 23, 0.05);
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.15s ease;
  overflow: visible;
}
.event-tickets-main .ev-ticket-card:hover:not(.opacity-50) {
  border-color: var(--theme-color);
  box-shadow: 0 12px 28px rgba(9, 151, 217, 0.14);
  transform: translateY(-3px);
}
/* Selected state — JS toggles .ev-ticket-selected on the clicked card.
	   Only color changes; border-width stays 2px so the card doesn't resize. */
.event-tickets-main .ev-ticket-card.ev-ticket-selected {
  border-color: var(--theme-color) !important;
  box-shadow: 0 12px 28px rgba(9, 151, 217, 0.18);
}
.event-tickets-main .ev-ticket-card.ev-ticket-selected .ev-ticket-name {
  color: var(--theme-color-readable);
}

/* Top section: name + description with comfortable padding. */
.event-tickets-main .ev-ticket-top {
  padding: 22px 22px 16px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  flex: 1;
}
.event-tickets-main .ev-ticket-name {
  font-size: 1.05rem;
  font-weight: 700;
  color: #505050;
  line-height: 1.3;
}
.event-tickets-main .ev-ticket-description {
  font-size: 0.85rem;
  color: #6e6a5f;
  line-height: 1.55;
}

/* Perforation line + die-cut circular notches that sit half-outside the
	   card edge on left and right. Notches match the panel background so they
	   read as cutouts in the card. */
.event-tickets-main .ev-ticket-perf {
  position: relative;
  border-top: 2px dashed #ddd9ce;
  height: 0;
  margin: 0 -1px; /* compensate for card border so dashes flow edge-to-edge */
}
.event-tickets-main .ev-ticket-perf-notch {
  position: absolute;
  top: -9px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: transparent;
}
.event-tickets-main .ev-ticket-perf-notch-left {
  left: -9px;
}
.event-tickets-main .ev-ticket-perf-notch-right {
  right: -9px;
}

/* Bottom stub: price on the left, remaining meter + progress bar on the right. */
.event-tickets-main .ev-ticket-stub {
  padding: 15px 22px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.event-tickets-main .ev-ticket-price {
  font-size: 1.4rem;
  font-weight: 750;
  color: #505050;
  line-height: 1;
  letter-spacing: -0.3px;
}
.event-tickets-main .ev-ticket-stub-meter {
  display: flex;
  flex-direction: column;
  gap: 5px;
  align-items: flex-end;
  flex: 1;
  max-width: 140px;
}
.event-tickets-main .ev-ticket-stub-label {
  font-size: 0.72rem;
  color: var(--theme-color-readable);
  font-weight: 600;
  white-space: nowrap;
}
.event-tickets-main .ev-ticket-stub-label-sold {
  color: #b91c1c;
  font-weight: 600;
}

/* ── Inline checkout row (below the ticket grid) ─────────────────────── */
.event-tickets-main .ev-checkout-row {
  background: var(--theme-light);
  border: 1px solid color-mix(in srgb, var(--theme-color) 22%, transparent);
  border-radius: 14px;
  padding: 10px 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 60px;
  font-family: var(--font-stack);
  /* inline-flex makes the pill hug its content (stepper + summary + Continue). */
}

/* Left: quantity stepper */
.event-tickets-main .ev-checkout-quantity {
  display: flex;
  align-items: center;
  gap: 14px;
}
.event-tickets-main .ev-checkout-quantity-label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--theme-on-secondary);
}
.event-tickets-main .ev-checkout-stepper {
  display: flex;
  align-items: center;
  gap: 10px;
}
.event-tickets-main .ev-checkout-stepper-btn {
  width: 36px;
  height: 36px;
  border: 1px solid #d9d6cc;
  border-radius: 9px;
  background: #fff;
  font-size: 16px;
  color: #505050;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  padding: 0;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}
.event-tickets-main .ev-checkout-stepper-btn:hover {
  background: #efede6;
}
.event-tickets-main .ev-checkout-stepper-value {
  min-width: 24px;
  text-align: center;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--theme-on-secondary);
}

/* Right: subtotal column + Continue button */
.event-tickets-main .ev-checkout-actions {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}

/* The summary div IS #ev-order-summary — the dev's JS injects multi-line
	   flex markup into it. We arrange it as a tight right-aligned column
	   where the line items stack visually like "label / value". */
/* Stacked summary: ticket name on top, price/Free underneath. Free and
	   paid tickets use the SAME slots so switching never shifts the pill. */
.event-tickets-main .ev-checkout-summary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-family: var(--font-stack);
  min-height: 44px;
  justify-content: center;
  min-width: 0;
}
.event-tickets-main .ev-checkout-summary .ev-checkout-summary-name {
  font-size: 0.78rem;
  color: var(--theme-on-secondary);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}
.event-tickets-main .ev-checkout-summary .ev-checkout-summary-value {
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--theme-on-secondary);
  line-height: 1.1;
  white-space: nowrap;
}

/* Continue button — design-spec primary pill */
.event-tickets-main .ev-checkout-continue {
  padding: 13px 36px;
  border: none;
  border-radius: 10px;
  background: var(--theme-color);
  color: var(--theme-on-primary);
  font-family: var(--font-stack);
  font-size: 0.92rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease;
}
.event-tickets-main .ev-checkout-continue:hover {
  background: var(--theme-color-hover);
}

/* Terms link below the row, centered */
.event-tickets-main .ev-checkout-terms {
  text-align: center;
  margin: 18px 0 24px;
  font-size: 0.78rem;
  color: #8a8578;
}

/* ── Coordinator card in sidebar: stack contact info vertically ─────── */
.detail-info-card-sidebar {
  padding: 22px 20px;
  margin-top: 0;
}
.detail-info-card-sidebar + .detail-info-card-sidebar {
  margin-top: 18px;
}

/* Event location map sidebar card */
.detail-info-card-map {
  padding: 0;
  overflow: hidden;
}
.detail-info-card-map .detail-map-frame {
  width: 100%;
  height: 220px;
  background: #eef2f6;
}
.detail-info-card-map iframe {
  display: block;
}
/* "Get directions" is a navigation action (off to Google Maps), not an
   org-commit — and not a button either. Rendered as a quiet centered link
   on the map card: theme-color text + svg, underline on hover. Full-width
   flush slab with centered content so it doesn't sit awkwardly to one
   side of the card. */
.detail-info-card-map .detail-map-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 18px;
  background: transparent;
  color: var(--theme-color-readable);
  border: none;
  border-top: 1px solid #e3e8f0;
  font-family: var(--font-stack);
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  transition: color 0.15s ease;
}
.detail-info-card-map .detail-map-btn:hover {
  color: var(--theme-color-hover);
  background: transparent;
  text-decoration: underline;
}
.detail-info-card-map .detail-map-btn svg {
  width: 16px;
  height: 16px;
}
.detail-info-card-sidebar .detail-info-contact-stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
.detail-info-card-sidebar .detail-info-contact-icons {
  margin-left: 0;
}

/* Inline phone/email rows on the coordinator card. The phone icon sits
   directly next to the phone number; same for email. Whole row is a
   tel:/mailto: anchor so click target is generous and stays understandable
   when the icon and text travel together (vs the old layout that pushed
   the call/email icons off to the right of the card). */
.detail-info-card .detail-info-contact-line {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--theme-color-readable);
  text-decoration: none;
  font-family: var(--font-stack);
  font-size: 0.92rem;
  font-weight: 500;
  transition: color 0.15s ease;
  word-break: break-word;
  max-width: 100%;
}
.detail-info-card .detail-info-contact-line:hover {
  color: var(--theme-color-hover);
  text-decoration: underline;
}
.detail-info-card .detail-info-contact-line svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* ── Campaign donation sidebar (single CTA card with preset picker) ──── */
.campaign-cta-card {
  background: #f7f8fb;
  border-radius: 14px;
  padding: 24px 22px;
  font-family: var(--font-stack);
  margin-bottom: 18px;
  text-align: center;
}
.campaign-cta-heading {
  font-family: var(--font-stack);
  font-size: 1.05rem;
  font-weight: 700;
  color: #505050;
  line-height: 1.35;
  margin: 0 0 8px;
}
.campaign-cta-sub {
  font-family: var(--font-stack);
  font-size: 0.85rem;
  color: #4a4a68;
  line-height: 1.55;
  margin: 0 0 18px;
}
.campaign-cta-btn,
.campaign-cta-btn:hover,
.campaign-cta-btn:focus,
.campaign-cta-btn:visited {
  width: 100%;
  justify-content: center;
  color: #fff;
}

/* Preset amount buttons */
.campaign-amount-presets {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin: 0 0 16px;
}
.campaign-amount-preset {
  padding: 12px 8px;
  background: #fff;
  border: 1.5px solid #d9dfeb;
  border-radius: 10px;
  font-family: var(--font-stack);
  font-size: 0.95rem;
  font-weight: 600;
  color: #505050;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background 0.15s ease,
    color 0.15s ease;
}
.campaign-amount-preset:hover {
  border-color: var(--theme-color);
  color: var(--theme-color-readable);
}
.campaign-amount-preset.is-selected {
  background: var(--theme-color);
  border-color: var(--theme-color);
  color: var(--theme-on-primary);
}
/* Custom button spans full width on the second row */
.campaign-amount-custom-btn {
  grid-column: 1 / -1;
}

/* Custom amount input — only revealed when Custom is selected */
.campaign-amount-custom-wrap {
  margin: 0 0 14px;
}
.campaign-amount-custom-input {
  position: relative;
  display: flex;
  align-items: center;
}
.campaign-amount-prefix {
  position: absolute;
  left: 14px;
  font-family: var(--font-stack);
  font-size: 1rem;
  font-weight: 600;
  color: #4a4a68;
  pointer-events: none;
}
.campaign-amount-custom-input input {
  width: 100%;
  padding: 11px 16px 11px 30px;
  border: 1.5px solid #d9dfeb;
  border-radius: 10px;
  font-family: var(--font-stack);
  font-size: 1rem;
  color: #505050;
  outline: none;
  transition: border-color 0.15s ease;
}
.campaign-amount-custom-input input:focus {
  border-color: var(--theme-color);
}
.campaign-amount-error {
  font-size: 0.82rem;
  color: #b91c1c;
  margin: 0 0 10px;
}
.campaign-amount-summary {
  font-family: var(--font-stack);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--theme-color-readable);
}

/* Article hero byline + tightened meta separator */
.article-hero-byline {
  font-family: var(--font-stack);
  font-size: 1rem;
  color: #505050;
  margin: 0 0 10px;
  font-weight: 500;
}
.article-hero-byline strong {
  color: #505050;
  font-weight: 700;
}
.detail-hero .article-hero-meta p {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin: 0;
}
.detail-hero .article-hero-meta p > span {
  flex: 0 0 auto;
}
.detail-hero .article-hero-meta .article-hero-meta-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.detail-hero .article-hero-meta .article-hero-meta-icon {
  width: 16px;
  height: 16px;
  color: var(--theme-color-readable);
  flex: 0 0 auto;
}

/* Attached-document chip in the hero (replaces the sidebar doc card).
   Neutral fill, not --theme-light, because the chip carries primary
   text + primary border and we can't guarantee --theme-light reads
   against --theme-color across white-label themes. */
.article-hero-doc {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
  margin-top: 14px;
  padding: 10px 14px;
  background: #f0f3f8;
  border: 1px solid var(--theme-color);
  border-radius: 10px;
  color: var(--theme-color);
  font-family: var(--font-stack);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}
.article-hero-doc:hover {
  background: var(--theme-color);
  color: var(--theme-on-primary);
}
.article-hero-doc svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}
.article-hero-doc-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 280px;
}

/* ── Resource (article) detail sidebar ─────────────────────────────── */
/* assets/css/style.css sets `html, body { overflow-x: hidden }`. That
	   creates a scroll container on the body which traps position:sticky on
	   any descendant. Override with overflow-x: clip — same visual effect
	   (no horizontal scroll) without creating a scroll container, so sticky
	   resolves against the viewport correctly. Scoped to detail pages only
	   (this partial is included on article/event/campaign). */
html,
body {
  overflow-x: clip !important;
}
/* col-md-4 must STRETCH to the row's full height so the sticky child
	   has somewhere to scroll. Bootstrap's equal-height flex row provides
	   this by default — do not add `align-self: flex-start`, which shrinks
	   the column to the sidebar's own height and leaves zero scroll room. */

/* Add breathing room between the description column and the sidebar
	   beyond Bootstrap's default gutter — feels too tight at .g-4. */
@media (min-width: 768px) {
  .event-details-area .row > .col-md-4 {
    padding-left: 36px;
  }
}
.article-sidebar {
  position: -webkit-sticky;
  position: sticky;
  top: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-family: var(--font-stack);
}
.article-sidebar-card {
  background: #f7f8fb;
  border: 2px solid transparent;
  border-radius: 14px;
  padding: 22px 22px 24px;
}
.article-sidebar-card:hover {
  border-color: transparent;
  box-shadow: none;
}
.article-sidebar-heading {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #8a8578;
  margin: 0 0 14px;
}

/* Author block */
.article-author {
  display: flex;
  align-items: center;
  gap: 12px;
}
.article-author-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.article-author-initials {
  background: var(--theme-color);
  color: var(--theme-on-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
}
.article-author-meta {
  flex: 1;
  min-width: 0;
}
.article-author-name {
  font-size: 0.95rem;
  font-weight: 700;
  color: #505050;
  line-height: 1.2;
}
.article-author-role {
  font-size: 0.8rem;
  color: #6e6a5f;
  margin-top: 2px;
}
.article-author-mail {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #fff;
  color: var(--theme-color-readable);
  border: 1px solid #e3e8f0;
  text-decoration: none;
}
.article-author-mail svg {
  width: 14px;
  height: 14px;
}
.article-author-mail:hover {
  background: var(--theme-color);
  color: var(--theme-on-primary);
}

/* Quick actions: Like, Comment, Share */
.article-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.article-action-btn {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 10px;
  background: #fff;
  border: 1.5px solid #e3e8f0;
  border-radius: 10px;
  color: #4a4a68;
  font-family: var(--font-stack);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    color 0.15s ease;
}
.article-action-btn svg {
  width: 14px;
  height: 14px;
}
.article-action-btn:hover {
  border-color: var(--theme-color);
  color: var(--theme-color-readable);
}
.article-action-btn.is-active {
  border-color: var(--theme-color);
  color: var(--theme-color);
  background: #f0f3f8;
}
.article-action-btn.is-active svg {
  fill: var(--theme-color);
  stroke: var(--theme-color);
}
.article-action-count {
  font-size: 0.72rem;
  color: #8a8578;
  font-weight: 600;
}
/* Toast feedback for like / copy actions. Sits ABOVE the Stay connected
	   card, absolutely positioned so it doesn't shift layout when it fades. */
.article-sidebar-card {
  position: relative;
}
.article-action-toast {
  position: absolute;
  left: 50%;
  top: -38px;
  transform: translate(-50%, 4px);
  padding: 7px 12px;
  background: var(--theme-color);
  color: var(--theme-on-primary);
  border-radius: 8px;
  font-family: var(--font-stack);
  font-size: 0.78rem;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  z-index: 5;
  transition:
    opacity 0.18s ease,
    transform 0.18s ease;
}
.article-action-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* Inline subscribe CTA inside Quick actions card.
	   The button uses the canonical .theme-btn class for visual styling
	   (color/radius/height/padding/hover) and .article-subscribe-btn only
	   for layout (width: fit-content so it centers inside the column). */
.article-subscribe-inline {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px dashed #e3e8f0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.article-subscribe-btn {
  width: fit-content;
  min-width: 140px;
}
.article-subscribe-inline-text {
  margin: 0;
  font-family: var(--font-stack);
  font-size: 0.88rem;
  font-weight: 600;
  color: #505050;
  text-align: center;
}

/* Inline "More from {org}" list inside Quick actions card. */
.article-recent-inline {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px dashed #e3e8f0;
}
.article-recent-inline-heading {
  margin: 0 0 14px;
  font-family: var(--font-stack);
  font-size: 0.82rem;
  font-weight: 700;
  color: #505050;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Share menu — horizontal icon row that opens below the Share button.
	   Our `.article-share-menu { display: flex }` is later in source order
	   than the global `.hide { display: none }` in style.css, so without a
	   scoped override the menu would be permanently visible. Explicitly
	   hide it when the .hide class is also present. */
.article-share-menu {
  display: flex;
  flex-direction: row;
  gap: 10px;
  margin-top: 10px;
  padding: 8px;
  background: #fff;
  border: 1px solid #e3e8f0;
  border-radius: 10px;
  justify-content: center;
}
.article-share-menu.hide {
  display: none;
}
.article-share-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: #4a4a68;
  cursor: pointer;
  text-decoration: none;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}
.article-share-icon svg {
  width: 16px;
  height: 16px;
}
.article-share-icon:hover {
  background: #f0f3f8;
  border-color: var(--theme-color);
  color: var(--theme-color);
  text-decoration: none;
}
/* Custom hover tooltip — replaces the native title= attribute (which is
	   slow to appear and styled by the OS). Anchored to the icon, positioned
	   above so the arrow points down at it. The sidebar card has no overflow:
	   hidden so an upward bubble won't get clipped. */
.article-share-icon[data-tip] {
  position: relative;
}
.article-share-icon[data-tip]::after,
.article-share-icon[data-tip]::before {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  position: absolute;
  left: 50%;
}
.article-share-icon[data-tip]::after {
  content: attr(data-tip);
  bottom: calc(100% + 10px);
  transform: translateX(-50%);
  min-width: 140px;
  max-width: 220px;
  padding: 7px 10px;
  background: #1f2433;
  color: #fff;
  font-family: var(--font-stack);
  font-size: 0.74rem;
  font-weight: 400;
  line-height: 1.4;
  border-radius: 6px;
  text-align: center;
  white-space: normal;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.22);
  z-index: 20;
}
.article-share-icon[data-tip]::before {
  content: "";
  bottom: calc(100% + 4px);
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #1f2433;
  z-index: 20;
}
.article-share-icon[data-tip]:hover::after,
.article-share-icon[data-tip]:hover::before,
.article-share-icon[data-tip]:focus-visible::after,
.article-share-icon[data-tip]:focus-visible::before {
  opacity: 1;
}

/* Attached document card */
.article-doc-card .article-doc-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid #e3e8f0;
  border-radius: 10px;
  text-decoration: none;
  color: #505050;
}
.article-doc-card .article-doc-link:hover {
  border-color: var(--theme-color);
  color: var(--theme-color-readable);
  text-decoration: none;
}
.article-doc-icon,
.article-doc-download {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--theme-color-readable);
}
.article-doc-icon svg {
  width: 20px;
  height: 20px;
}
.article-doc-download svg {
  width: 16px;
  height: 16px;
}
.article-doc-name {
  flex: 1;
  min-width: 0;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* (Legacy .article-subscribe-card / standalone .article-subscribe-btn
	   styles removed — the subscribe CTA now lives inside Quick actions
	   and the button uses .theme-btn for canonical styling.) */

/* Recent resources list */
.article-recent-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.article-recent-item + .article-recent-item {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid #e3e8f0;
}
.article-recent-link {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  text-decoration: none;
  color: inherit;
}
.article-recent-link:hover {
  text-decoration: none;
}
.article-recent-link:hover .article-recent-title {
  color: var(--theme-color-readable);
}
.article-recent-thumb {
  width: 58px;
  height: 58px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
  background: #eef2f6;
}
.article-recent-meta {
  flex: 1;
  min-width: 0;
}
.article-recent-title {
  font-size: 0.88rem;
  font-weight: 600;
  color: #505050;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 0.15s ease;
}
.article-recent-date {
  font-size: 0.72rem;
  color: #8a8578;
  margin-top: 4px;
}

/* ── Plan / Membership / Group / Program detail page ─────────────────────
   Styles for the hero pricing block + the join wizard modal. The hero
   itself reuses .detail-hero / .detail-hero-badges / .detail-hero-summary
   from above; these add only what's plan-specific. */

.plan-hero-category {
  font-family: var(--font-stack);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--theme-color-readable);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 14px;
}

.plan-hero-price {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 20px;
}
.plan-hero-price-amount {
  font-family: var(--font-stack);
  font-size: 2.4rem;
  font-weight: 700;
  color: #505050;
  line-height: 1;
}
.plan-hero-price-duration {
  font-family: var(--font-stack);
  font-size: 0.95rem;
  font-weight: 500;
  color: #707070;
}

.plan-hero-cta {
  min-width: 160px;
}

/* Plan description sits in the col-md-8 main column and inherits the
   .detail-info-card body type-scale from above so it matches the size /
   line-height used on article / event / campaign description bodies. */
.plan-detail-description {
  font-family: var(--font-stack);
  font-size: 0.95rem;
  color: #505050;
  line-height: 1.7;
}
.plan-detail-description p {
  margin: 0 0 16px;
}
.plan-detail-description p:last-child {
  margin-bottom: 0;
}

/* "Member benefits" full-width block under the description. Two-column
   responsive grid so even a long list (10 x 200-char items) stays
   readable instead of crammed into a narrow sidebar. */
.plan-detail-benefits-block {
  margin: 40px 0 8px;
}
.plan-detail-benefits-heading {
  font-family: var(--font-stack);
  font-size: 22px;
  font-weight: 700;
  color: #505050;
  margin: 0 0 18px;
}
.plan-detail-benefits-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px 24px;
}
.plan-detail-benefits-list li {
  font-family: var(--font-stack);
  font-size: 0.95rem;
  color: #505050;
  line-height: 1.55;
  padding-left: 30px;
  position: relative;
}
.plan-detail-benefits-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--theme-color);
  color: var(--theme-on-primary);
  font-weight: 700;
  font-size: 0.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Sticky sidebar CTA card — uses the article-sidebar / article-sidebar-card
   chrome already shipped for the resource detail page. These tiny rules
   just style the CTA sub-line + button placement inside the card. */
.plan-sidebar-cta-sub {
  font-family: var(--font-stack);
  font-size: 0.88rem;
  color: #505050;
  line-height: 1.5;
  margin: 0 0 14px;
}
.plan-sidebar-cta-actions {
  display: flex;
  justify-content: center;
}
.plan-sidebar-cta-btn {
  width: 100%;
  justify-content: center;
}

/* "Other memberships" recent-list uses card_image() which wraps EITHER
   an <img class="card-image"> (real banner) OR a <div class="card-image-
   fallback"> (colored-name placeholder). Both need to render at the
   58x58 thumb size that the article-recent-list expects. */
.article-recent-thumb.article-recent-thumb-wrap {
  display: block;
  padding: 0;
  overflow: hidden;
}
.article-recent-thumb.article-recent-thumb-wrap .card-image,
.article-recent-thumb.article-recent-thumb-wrap .card-image-fallback {
  width: 100%;
  height: 100%;
  min-height: 0;
  aspect-ratio: auto;
  border-radius: 8px;
  font-size: 0.78rem;
  padding: 6px;
  line-height: 1.15;
}

/* The dev's .membership-area carries margin: 100px 0 (style.css) which
   pushes the body content way below where article/event description bodies
   start. The new layout uses .event-details-area for its own spacing —
   neutralize the outer-wrapper margin so we match the other detail pages. */
.membership-area.join-area {
  margin: 0;
}
.membership-area.join-area > .container {
  padding: 0;
  max-width: none;
}

/* ── Join wizard modal — shares the SAME styles as the event registration
      modal (ev-checkout-modal) above so the two popups are visually
      identical. We just alias .plan-join-modal-* selectors onto the same
      rules as .ev-checkout-modal-* using grouped selectors. */
/* .plan-join-modal-* + .campaign-donate-modal-* rules below are grouped
   with their .ev-checkout-modal-* counterparts so all three modals share
   identical dimensions / chrome and cannot drift visually. */
dialog.plan-join-modal,
dialog.campaign-donate-modal {
  border: none;
  border-radius: 16px;
  padding: 0;
  max-width: 640px;
  width: 92%;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.25);
  font-family: var(--font-stack);
}
dialog.plan-join-modal::backdrop,
dialog.campaign-donate-modal::backdrop {
  background: rgba(0, 0, 0, 0.55);
}
.plan-join-modal-header,
.campaign-donate-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 24px;
  border-bottom: 1px solid #e3e8f0;
}
.plan-join-modal-header h4,
.campaign-donate-modal-header h4 {
  margin: 0;
  font-family: var(--font-stack);
  font-size: 18px;
  font-weight: 700;
  color: #505050;
}
.plan-join-modal-close,
.campaign-donate-modal-close {
  background: transparent;
  border: none;
  font-size: 28px;
  line-height: 1;
  color: #666;
  cursor: pointer;
  padding: 0 4px;
}
.plan-join-modal-close:hover,
.campaign-donate-modal-close:hover {
  color: #000;
}
.plan-join-modal-body,
.campaign-donate-modal-body {
  padding: 24px;
  color: #505050;
  font-family: var(--font-stack);
  max-height: 75vh;
  overflow-y: auto;
}
.plan-join-modal-body > div:first-child > h4:first-child,
.campaign-donate-modal-body > div:first-child > h4:first-child {
  margin-top: 0;
}
.plan-join-modal-body h4,
.campaign-donate-modal-body h4 {
  font-family: var(--font-stack);
  font-size: 22px;
  font-weight: 700;
  color: #505050;
}

/* ── Join wizard step indicator (Basic Details → Additional Details).
   Modern numbered-circle pattern. Overrides the dev's earlier clip-path
   chevron shape in style.css — we keep the .form-timeline class +
   ul/li IDs (the dev's JS toggles .active on these) and just visually
   redesign with a more-specific .form-timeline-steps selector. */
.form-timeline.form-timeline-steps {
  margin: 4px 0 22px;
}
.form-timeline.form-timeline-steps ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
}
.form-timeline.form-timeline-steps ul li {
  /* Reset the dev's clip-path chevron + background + padding. */
  background: transparent;
  color: #8a8a8a;
  padding: 0;
  clip-path: none;
  width: auto;
  text-align: center;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-stack);
  font-size: 0.92rem;
  font-weight: 600;
  white-space: nowrap;
}
.form-timeline.form-timeline-steps ul li.active {
  background: transparent;
  color: var(--theme-color-readable);
}
.form-timeline.form-timeline-steps .form-timeline-num {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid #d9dfeb;
  background: #fff;
  color: #8a8a8a;
  font-family: var(--font-stack);
  font-size: 0.85rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.15s ease,
    border-color 0.15s ease,
    color 0.15s ease;
  flex-shrink: 0;
}
.form-timeline.form-timeline-steps ul li.active .form-timeline-num {
  background: var(--theme-color);
  border-color: var(--theme-color);
  color: var(--theme-on-primary);
}
.form-timeline.form-timeline-steps .form-timeline-label {
  font-family: var(--font-stack);
  font-weight: 600;
}
/* Connector line between the two steps. Sits between the <li>s as a
   pseudo-element on every <li> after the first. */
.form-timeline.form-timeline-steps ul li + li::before {
  content: "";
  display: inline-block;
  width: 64px;
  height: 2px;
  background: #d9dfeb;
  margin: 0 14px 0 0;
  flex-shrink: 0;
}
/* When step 2 is the active one, the connector becomes themed too. */
.form-timeline.form-timeline-steps ul li.active + li::before,
.form-timeline.form-timeline-steps ul li:has(+ li.active)::before {
  background: var(--theme-color);
}
/* Narrow viewports: keep the circles + numbers, hide the wordy labels. */
@media (max-width: 480px) {
  .form-timeline.form-timeline-steps .form-timeline-label {
    display: none;
  }
  .form-timeline.form-timeline-steps ul li + li::before {
    width: 32px;
    margin-right: 6px;
  }
}

/* Drop the dev's .membership-form-box card chrome when it's rendered
   INSIDE the join modal — the modal is already the card, so the inner
   box-shadow + padding creates a card-in-a-card look. Scoped to the
   modal so plan listings / other contexts where membership-form-box
   appears stand-alone keep their original framed look. */
.plan-join-modal .membership-form-box {
  box-shadow: none;
  border-radius: 0;
  padding: 0;
}

/* Shrink the Other-memberships list inside the plan-detail sidebar so the
   titles + prices don't read as oversized. Scoped to .plan-sidebar-cta
   territory (the parent .article-sidebar-card here lives only on the
   plan detail page) — the article page's "More from this community"
   list stays at its original size. */
.plan-sidebar-cta-actions
  ~ .article-recent-inline
  .article-recent-inline-heading,
.article-sidebar-card:has(.plan-sidebar-cta-actions)
  .article-recent-inline-heading {
  font-size: 0.72rem;
  margin-bottom: 10px;
}
.plan-sidebar-cta-actions ~ .article-recent-inline .article-recent-title,
.article-sidebar-card:has(.plan-sidebar-cta-actions) .article-recent-title {
  font-size: 0.78rem;
  line-height: 1.25;
}
.plan-sidebar-cta-actions ~ .article-recent-inline .article-recent-date,
.article-sidebar-card:has(.plan-sidebar-cta-actions) .article-recent-date {
  font-size: 0.7rem;
}

/* Tighten the form field labels + helper text inside the join modal —
   the dev's defaults felt loose, especially the form-check-label helper
   text below the email field. Scoped to .plan-join-modal so other pages
   that use .membership-form keep their original spacing. */
.plan-join-modal .membership-form label {
  font-size: 0.85rem;
  margin-bottom: 4px;
  line-height: 1.35;
}
.plan-join-modal .membership-form .form-check-label,
.plan-join-modal .membership-form .text-muted {
  font-size: 0.78rem !important;
  line-height: 1.4 !important;
}
.plan-join-modal .membership-form .form-control {
  font-size: 0.92rem;
  padding-top: 8px;
  padding-bottom: 8px;
}
.plan-join-modal .membership-form .mt-2 {
  margin-top: 0.4rem;
}

/* Custom org-defined fields with short-text or textarea content span
   full width inside the modal — they get a data-customfield attribute
   from the foreach loop in web/join.php so we can target them without
   wrapping (a wrapper div would break the Bootstrap row gutters). */
.plan-join-modal [data-customfield].col-md-6:has(input[type="text"]),
.plan-join-modal [data-customfield].col-md-12:has(textarea) {
  flex: 0 0 100%;
  max-width: 100%;
}

/* Step action buttons (.form-btn) — keep Back left, push Submit/Next
   right. The dev's step-1 row already has justify-content-end (only
   one button), step-2 has a typo "   ustify-content-between" missing
   the j — works by Bootstrap default but doesn't guarantee separation.
   Force the correct layout for both steps. */
.plan-join-modal .form-btn {
  justify-content: space-between !important;
}
.plan-join-modal .form-btn > .theme-btn:only-child,
.plan-join-modal .form-btn > .theme-btn:last-child:first-child {
  margin-left: auto;
}

/* Shrink the text inside colored-name fallback thumbs in the
   Other-memberships list further — at 58x58 even 0.78rem reads as
   "too much" for plan names. Drop to 0.65rem so they stay legible
   without dominating the disc. */
.article-recent-thumb.article-recent-thumb-wrap .card-image-fallback {
  font-size: 0.65rem;
  padding: 4px;
  line-height: 1.1;
}

/* ── Event detail page — mobile-only fixes ─────────────────────────────
   Desktop layout is untouched: the right column (.event-sidebar-col) sits
   beside the description as col-md-4 + col-md-8. On mobile Bootstrap
   collapses both to full-width and stacks them vertically. */
@media (max-width: 767px) {
  /* Hero meta: pack the first two rows (date + time) onto the same line
     so a long address row below them still flows on its own line. The
     first two <p> rows take ~50% each; rows 3+ keep the default 100%
     width via the row reverting to full block flow. */
  .detail-hero .detail-hero-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
  }
  .detail-hero .detail-hero-meta p {
    flex: 1 1 100%;
    margin-bottom: 0;
  }
  .detail-hero .detail-hero-meta p:nth-child(1),
  .detail-hero .detail-hero-meta p:nth-child(2) {
    flex: 1 1 calc(50% - 6px);
    min-width: 0;
  }
  /* Campaign hero "Raised: $X" + "Goal: $Y" line — escape the 50%
     date+time pairing above. It needs the FULL row so its
     justify-content: space-between (from the desktop rule) can anchor
     Raised to the left edge and Goal to the right edge. */
  .detail-hero .detail-hero-meta p.detail-hero-raised-line {
    flex: 1 1 100%;
  }

  /* Reorder the event-detail sidebar so coordinators come BEFORE the map
     card on mobile. Desktop renders map first because the map is the
     bigger visual anchor in the sidebar; on mobile we follow the user's
     reading flow: description → who → where → directions. The flex order
     trick keeps desktop markup order intact. */
  .event-details-area .event-sidebar-col {
    display: flex;
    flex-direction: column;
    gap: 24px;
  }
  /* The desktop sibling-margin rule (.detail-info-card-sidebar +
     .detail-info-card-sidebar { margin-top: 18px }) is DOM-sibling based,
     so when we re-order with flex `order` it no longer applies between
     the visually-adjacent cards. The flex-container gap above handles
     that — zero out the sibling margin so we don't get a doubled
     space on the card that would have inherited it. */
  .event-details-area .event-sidebar-col .detail-info-card-sidebar + .detail-info-card-sidebar {
    margin-top: 0;
  }
  .event-details-area .event-sidebar-col .detail-info-card-map {
    order: 2;
  }
  .event-details-area .event-sidebar-col .detail-info-card:not(.detail-info-card-map) {
    order: 1;
  }

  /* Tickets section padding — the desktop's 100px top/bottom band is too
     much on mobile; tighten so the ticket flow doesn't feel like a giant
     empty band. */
  .event-tickets-section {
    padding: 40px 0;
  }

  /* Inline checkout pill — desktop is one tall horizontal row (Stepper |
     Summary | Continue) with a 60px gap that crushes everything together
     under ~500px. On mobile we let it grow taller and stack vertically so
     the full ticket name (which previously got ellipsis-truncated at
     220px) can show in full. The summary block becomes a 2-line wrap
     allowance instead of nowrap, and the row uses flex-direction: column
     so each section gets its own row of real estate. */
  .event-tickets-main .ev-checkout-row {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 16px 20px;
    width: 100%;
    max-width: 100%;
  }
  .event-tickets-main .ev-checkout-quantity,
  .event-tickets-main .ev-checkout-actions {
    width: 100%;
    justify-content: center;
  }
  .event-tickets-main .ev-checkout-summary {
    min-height: 0;
    text-align: center;
  }
  /* Ticket name wraps to as many lines as it needs; the 220px clamp +
     nowrap from desktop is dropped. */
  .event-tickets-main .ev-checkout-summary .ev-checkout-summary-name {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    max-width: 100%;
    line-height: 1.35;
    word-break: break-word;
  }
  .event-tickets-main .ev-checkout-continue {
    width: 100%;
  }
}
