/* ==========================================================================
   CONTENT GRID + CARDS
   Applies to views with the CSS class "fluid-grid" and to nodes rendered in
   the grid_card / grid_card_public view modes.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. THE GRID
   -------------------------------------------------------------------------- */
.fluid-grid .view-content {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 24px;
  align-items: stretch;
}

.fluid-grid .view-content > .views-row {
  display: flex;
  min-width: 0;
  margin: 0;
  padding: 0;
}

/* Phones (up to 600px wide, any phone held upright): one card per row, at
   normal text size, so titles, author names and buttons have room. */
@media (max-width: 600px) {
  .fluid-grid .view-content {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

/* --------------------------------------------------------------------------
   2. THE CARD
   .node__content is flattened with display:contents so its children (media,
   tags, buttons) and the <header> (title, author) can be ordered together:
     media → title/author → tags/other fields → buttons (pinned to bottom)
   -------------------------------------------------------------------------- */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) {
  --card-pad: 12px;

  position: relative;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 0 var(--card-pad);
  overflow: hidden;
  color: var(--cu-text-main);
  border: 1px solid var(--cu-border);
  border-radius: var(--cu-radius);
  background: var(--cu-bg-surface);
  box-shadow: var(--cu-shadow);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--cu-accent) 35%, var(--cu-border));
  box-shadow: var(--cu-shadow-hover);
}

@media (prefers-reduced-motion: reduce) {
  article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public),
  article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):hover {
    transform: none;
    transition: none;
  }
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content {
  display: contents;
}

/* Default: every non-media piece gets side padding and sits after the media */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > * {
  order: 3;
  margin: 8px var(--card-pad) 0;
  padding: 0;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .field {
  margin-block: 0;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .field__label {
  display: none;
}

/* --------------------------------------------------------------------------
   3. MEDIA — thumbnail at the top, hover loop layered exactly on top of it
   -------------------------------------------------------------------------- */

/* 3a. The still image (base layer) */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > :is(
  .field--name-field-sfw-thumbnail,
  .field--name-field-nsfw-thumbnail,
  .field--name-field-promo-image,
  .field--type-image,
  .cu-hover-poster
) {
  position: relative;
  order: 1;
  width: 100%;
  margin: 0;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--cu-media-bg);
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > :is(
  .field--name-field-sfw-thumbnail,
  .field--name-field-nsfw-thumbnail,
  .field--name-field-promo-image,
  .field--type-image,
  .cu-hover-poster
) img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  object-fit: cover;
  border-radius: 0;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content .slick-slider {
  width: 100%;
  aspect-ratio: 16 / 9;
}

/* 3b. The hover loop (bunny_tus "Hover Loop" formatter, or the theme's
   fallback overlay). Pinned to the top of the card, same 16:9 box as the
   thumbnail, so the loop replaces the image in place. The card is
   position:relative and the media is always its first item. */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > :is(
  .field--name-field-sfw-loop-id,
  .field--name-field-nsfw-loop-id,
  .cu-hover-overlay
) {
  position: absolute;
  z-index: 3; /* above the image and the card-wide title link */
  top: 0;
  right: 0;
  left: 0;
  width: auto;
  margin: 0;
  padding: 0;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: transparent;
}

/* No still image at all? Let the loop box take the image's place in the flow */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):not(:has(
  .field--name-field-sfw-thumbnail img,
  .field--name-field-nsfw-thumbnail img,
  .field--name-field-promo-image img,
  .cu-hover-poster img
)) .node__content > :is(
  .field--name-field-sfw-loop-id,
  .field--name-field-nsfw-loop-id,
  .cu-hover-overlay
) {
  position: relative;
  order: 1;
  background: var(--cu-media-bg);
}

/* The formatter's own wrapper fills the box */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .bunny-hover-wrapper {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
}

/* The Bunny iframe: fill the box, and fade in after a beat so the player's
   black loading frame never flashes over the thumbnail */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .bunny-hover-wrapper iframe {
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border: 0;
  opacity: 0;
  animation: cu-loop-in 0.25s ease 0.45s forwards;
}

@keyframes cu-loop-in {
  to { opacity: 1; }
}

/* Small play badge on cards that have a loop; hides while the loop plays */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > :is(
  .field--name-field-sfw-loop-id,
  .field--name-field-nsfw-loop-id,
  .cu-hover-overlay
)::after {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 30px;
  height: 30px;
  content: "";
  pointer-events: none;
  transition: opacity 0.2s ease;
  border-radius: 50%;
  background: rgb(0 0 0 / 55%) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='white' d='M8 5v14l11-7z'/%3E%3C/svg%3E") center / 16px no-repeat;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > :is(
  .field--name-field-sfw-loop-id,
  .field--name-field-nsfw-loop-id,
  .cu-hover-overlay
):has(iframe)::after {
  opacity: 0;
}

/* Hide the SFW loop if an NSFW loop exists */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):has(.field--name-field-nsfw-loop-id .bunny-hover-wrapper) .field--name-field-sfw-loop-id {
  display: none !important;
}

/* Hide the SFW thumb if the NSFW thumb actually has an image */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):has(.field--name-field-nsfw-thumbnail img) .field--name-field-sfw-thumbnail {
  display: none !important;
}

/* --------------------------------------------------------------------------
   4. TITLE + AUTHOR
   -------------------------------------------------------------------------- */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) > header {
  display: flex;
  flex-direction: column;
  gap: 6px;
  order: 2;
  margin: 10px var(--card-pad) 0;
  padding: 0;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__title {
  display: -webkit-box;
  margin: 0;
  padding: 0;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  font-family: var(--cu-font);
  font-size: 0.95rem;
  font-weight: 650;
  line-height: 1.3;
  letter-spacing: 0;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__title a {
  color: var(--cu-text-main);
  text-decoration: none;
}

/* Make the whole card clickable via the title link */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__title a::after {
  position: absolute;
  z-index: 1;
  inset: 0;
  content: "";
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):hover .node__title a {
  color: var(--cu-link);
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
}

/* Hide "By" and ", date" — keep only the author name */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__meta > span:not(.cu-card-badges) {
  font-size: 0;
  line-height: 1;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__author,
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__author a {
  position: relative;
  z-index: 2; /* above the card-wide link */
  color: var(--cu-text-muted);
  font-size: 0.85rem;
  line-height: 1.2;
  text-decoration: none;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__author a:hover {
  color: var(--cu-text-main);
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__author-image {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__author-image img {
  display: block;
  width: 28px;
  height: 28px;
  object-fit: cover;
  border: 2px solid var(--cu-border);
  border-radius: 50%;
}

/* Hide the admin "Masquerade" link next to the avatar */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__author-image a:not(:has(img)) {
  display: none;
}

/* --------------------------------------------------------------------------
   AUTHOR BADGES — exactly one set per card
   Kept: .cu-card-badges (built in theme2.theme, same compact set as the
   Views title badges on /find-professionals).
   Hidden: everything cu_user_flags prints elsewhere in a card —
     • the verbose block attached to the author's avatar (hook_user_view)
     • .cu-author-flags in the card body (hook_node_view)
     • badges appended to a Views title field around the card
   -------------------------------------------------------------------------- */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__author-image .profile > :not(.field--name-user-picture),
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .cu-author-flags,
.fluid-grid .views-row :is(.cu-admin-badge, .cu-flag-pill):not(.cu-card-badges *) {
  display: none !important;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .cu-card-badges {
  position: relative;
  z-index: 2; /* above the card-wide link so the tooltips work */
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-inline-start: auto;
  font-size: 0.8rem;
  line-height: 1;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .cu-card-badges .cu-admin-badge {
  margin-right: 0 !important;
  font-size: 1.1em !important;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .cu-card-badges .cu-flag-pill {
  min-width: 18px;
  height: 18px;
  margin-right: 0;
  padding: 0 5px;
  border-radius: 9px;
  font-size: 11px;
}

/* --------------------------------------------------------------------------
   5. TAGGING FIELDS
   -------------------------------------------------------------------------- */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) [class*="field--name-field-tagging-"] {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 6px;
  margin-top: 6px;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) [class*="field--name-field-tagging-"] .field__label {
  display: inline-block;
  margin: 0;
  color: var(--cu-accent-warm);
  font-size: 0.8rem;
  font-weight: 600;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) [class*="field--name-field-tagging-"] .field__label::after {
  content: ":";
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) [class*="field--name-field-tagging-"] .field__items {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) [class*="field--name-field-tagging-"] .field__item a {
  color: var(--cu-link);
  font-size: 0.8rem;
  text-decoration: none;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) [class*="field--name-field-tagging-"] .field__item a:hover {
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   6. BUTTONS (Buy / Bookmark) — pinned to the bottom so rows line up
   -------------------------------------------------------------------------- */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > :is(.flag, .flag-buy-now, .flag-bookmark, .cu-paywall-wrapper),
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__links {
  position: relative;
  z-index: 2; /* above the card-wide link */
  order: 10;
  pointer-events: auto;
}

/* Buy button first (pushed to the bottom), bookmark underneath */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > .flag-buy-now {
  margin-top: auto;
  padding-top: 12px;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > .flag-bookmark {
  order: 11;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):not(:has(.flag-buy-now)) .node__content > .flag-bookmark {
  margin-top: auto;
  padding-top: 12px;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .flag-buy-now a {
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: none;
  min-height: 42px;
  margin: 0;
  padding: 8px 10px;
  font-size: 0.9rem;
  line-height: 1.2;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .flag-bookmark a {
  color: var(--cu-text-muted);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .flag-bookmark a:hover {
  color: var(--cu-text-main);
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .flag-buy-now a.cu-external-only-badge,
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .flag-buy-now a.cu-processing-badge {
  font-size: 0.85rem;
}

/* --------------------------------------------------------------------------
   7. EXCLUSIVE STREAM BUTTON
   -------------------------------------------------------------------------- */
article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .field--name-field-exclusive {
  display: none;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):has(.field--name-field-exclusive) .flag-buy-now a.use-ajax {
  color: transparent !important;
  border-color: #c9302c;
  background-color: #d9534f;
  font-size: 0;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):has(.field--name-field-exclusive) .flag-buy-now a.use-ajax::before {
  content: "EXCLUSIVE! Add to Cart";
  color: #ffffff;
  font-size: 0.9rem;
  font-weight: 700;
}

article.node:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):has(.field--name-field-exclusive) .flag-buy-now a.use-ajax:hover {
  border-color: #ac2925;
  background-color: #c9302c;
}

/* --------------------------------------------------------------------------
   8. UNLOCKED CARD — the viewer has bought this Stream or has it through a
   subscription. Whole card goes bright green (same green as the site's
   .cu-pill-bright-green), in both light and dark mode.
   .cu-unlocked is added in cu_display_rules_preprocess_node() from the flag set by
   cu_access_entity_view().

   The text tokens are redefined on the card itself, so every child (title,
   author, tags, bookmark) switches to dark, readable colours without
   needing its own override.
   -------------------------------------------------------------------------- */
article.node.cu-unlocked:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) {
  --cu-bg-surface: #00e676;
  --cu-text-main: #08210f;
  --cu-text-muted: #0f4220;
  --cu-link: #053d1a;
  --cu-link-hover: #000000;
  --cu-accent-warm: #053d1a;
  --cu-border: #00c853;

  color: var(--cu-text-main);
  border: 2px solid #00c853;
  background: #00e676;
  box-shadow: 0 0 0 3px rgb(0 230 118 / 30%), var(--cu-shadow);
}

article.node.cu-unlocked:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public):hover {
  border-color: #00a844;
  box-shadow: 0 0 0 4px rgb(0 230 118 / 45%), var(--cu-shadow-hover);
}

/* Already unlocked: hide Buy / Add to Cart (nobody pays twice) and
   Bookmark this / Remove Bookmark (it is already in My Library). */
article.node.cu-unlocked:is(.node--view-mode-grid-card, .node--view-mode-grid-card-public) .node__content > :is(.flag-buy-now, .flag-bookmark) {
  display: none;
}

/* ==========================================================================
   Portrait / tall videos in cards
   Cards stay landscape so the grid stays tidy. For tall videos (class
   cu-media--tall, set by bunny_tus from the video's real shape) the whole
   picture is shown, centred, over a blurred, darkened copy of itself
   (.cu-media-backdrop, added by js/portrait-cards.js). The hover loop is
   centred in the same frame by bunny_hover.js, so there is no jump.
   ========================================================================== */
article.node.cu-media--tall .node__content > :is(
  .field--name-field-sfw-thumbnail,
  .field--name-field-nsfw-thumbnail,
  .field--name-field-promo-image,
  .field--type-image,
  .cu-hover-poster
) img {
  z-index: 1;
  object-fit: contain;
}

article.node.cu-media--tall .cu-media-backdrop {
  position: absolute;
  inset: -8%;
  z-index: 0;
  background-position: center;
  background-size: cover;
  filter: blur(18px) brightness(0.55) saturate(1.1);
  transform: scale(1.08);
  pointer-events: none;
}

/* The loop plays over the backdrop: keep its box see-through. */
article.node.cu-media--tall :is(.bunny-hover-wrapper, .cu-hover-overlay) {
  background: transparent;
}
