/**
 * Branwell PsyCards — plugin styles
 *
 * Scope: ALL rules nested under .branwell-psycard so nothing escapes
 * into the rest of the theme. No font-family declarations at all —
 * typography inherits from the body / theme.
 *
 * Containers do NOT set their own left/right padding or max-width.
 * The theme's content wrapper controls width; the plugin just fills
 * whatever container it lands in.
 *
 * Colour policy:
 *   - Status colours (ribbon backgrounds, button backgrounds) are
 *     defined as CSS variables on each card via [data-status]. Three
 *     palettes: available (soft green), speaking (soft red), offline
 *     (soft grey). No inline styles, no PHP-side hex constants.
 *   - The primary call/profile-button colours fall back to a brand
 *     blue if the theme doesn't expose --color-primary / --color-accent-soft.
 *   - The agenthead.webp background pattern sits behind the avatar
 *     via a ::before pseudo-element at 0.5 opacity, exactly like the
 *     legacy design.
 */

.branwell-psycard,
.branwell-psycard *,
.branwell-psycard *::before,
.branwell-psycard *::after {
    box-sizing: border-box;
}

/* ============================================================
   CSS variables — per-status palette
   ============================================================ */
.branwell-psycard__card[data-status="available"] {
    --bps-ribbon-from:  #d4ead8;
    --bps-ribbon-to:    #c4e0c8;
    --bps-ring:         #2d9d6f;
    --bps-pill-bg:      #2d9d6f;
    --bps-pill-fg:      #ffffff;
    --bps-pill-soft:    #d4ead8;
    --bps-status-fg:    #1e6b3e;
    --bps-photo-filter: none;
    --bps-photo-opacity: 1;
}
.branwell-psycard__card[data-status="speaking"] {
    --bps-ribbon-from:  #f9dcdc;
    --bps-ribbon-to:    #f4cccc;
    --bps-ring:         #c44545;
    --bps-pill-bg:      #f9dcdc;
    --bps-pill-fg:      #c44545;
    --bps-pill-soft:    #f9dcdc;
    --bps-status-fg:    #8b2a2a;
    --bps-photo-filter: none;
    --bps-photo-opacity: 1;
}
.branwell-psycard__card[data-status="offline"] {
    --bps-ribbon-from:  #ececec;
    --bps-ribbon-to:    #e0e0e0;
    --bps-ring:         #a0a0a0;
    --bps-pill-bg:      #f4f4f4;
    --bps-pill-fg:      #6b6b6b;
    --bps-pill-soft:    #ececec;
    --bps-status-fg:    #6b6b6b;
    --bps-photo-filter: grayscale(100%);
    --bps-photo-opacity: 0.55;
}

/* Profile button + brand-primary fallbacks. Use theme tokens when
   available, otherwise the legacy brand blue. */
.branwell-psycard {
    --bps-primary:        var(--color-primary, #185fa5);
    --bps-primary-soft:   var(--color-accent-soft, #ebf0f8);
    --bps-text:           var(--color-text, #1a1a1a);
    --bps-text-muted:     #888888;
    --bps-border:         #e5e5e5;
    --bps-star-on:        #f5a623;
    --bps-star-off:       #e0e0e0;
}

/* ============================================================
   Layout root — no outer padding/margin so theme controls width
   ============================================================ */
.branwell-psycard {
    display: block;
    width: 100%;
    color: var(--bps-text);
}

/* Header markup is rendered by the theme partial
   template-parts/section-header.php and styled by §6e SHARED
   SECTION HEADER in css/soulpath-website.css. The plugin owns
   no header CSS. */

/* ============================================================
   Live count line
   ============================================================ */
.branwell-psycard__live {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 20px;
    margin: 0 0 1rem;
    min-height: 24px;     /* Reserve space so layout doesn't shift on update */
}
.branwell-psycard__live-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 400;
}
.branwell-psycard__live-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px currentColor;
    /* The outer ring uses currentColor at 25% opacity via the parent
       text colour. Set on each item to get the right tint. */
}
.branwell-psycard__live-item--available { color: #2d7a3e; }
.branwell-psycard__live-item--available .branwell-psycard__live-dot {
    background: #2d7a3e;
    box-shadow: 0 0 0 2px rgba(45, 122, 62, 0.25);
}
.branwell-psycard__live-item--speaking  { color: #a83232; }
.branwell-psycard__live-item--speaking .branwell-psycard__live-dot {
    background: #a83232;
    box-shadow: 0 0 0 2px rgba(168, 50, 50, 0.2);
}
.branwell-psycard__live-item--offline   { color: #6b6b6b; }
.branwell-psycard__live-item--offline .branwell-psycard__live-dot {
    background: #6b6b6b;
    box-shadow: 0 0 0 2px rgba(107, 107, 107, 0.2);
}

/* ============================================================
   Search bar — real-time client-side filter
   ============================================================ */
.branwell-psycard__search {
    position: relative;
    display: flex;
    align-items: center;
    margin: 0 0 1.25rem;
    width: 100%;
}
.branwell-psycard__search-icon {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--bps-text-muted);
    pointer-events: none;
    display: flex;
    align-items: center;
    justify-content: center;
}
.branwell-psycard__search-input {
    width: 100%;
    padding: 11px 40px 11px 40px;
    font-size: 0.95rem;
    line-height: 1.4;
    background: #ffffff;
    border: 1px solid var(--bps-border);
    border-radius: 8px;
    color: var(--bps-text);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    appearance: none;
    -webkit-appearance: none;
}
.branwell-psycard__search-input:focus {
    outline: none;
    border-color: var(--bps-primary);
    box-shadow: 0 0 0 3px var(--bps-primary-soft);
}
.branwell-psycard__search-input::placeholder {
    color: var(--bps-text-muted);
}
/* Hide native browser X / search cancel buttons so our custom one is
   the only clear control */
.branwell-psycard__search-input::-webkit-search-cancel-button,
.branwell-psycard__search-input::-webkit-search-decoration {
    -webkit-appearance: none;
    appearance: none;
}
.branwell-psycard__search-clear {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 24px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 50%;
    color: var(--bps-text-muted);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease, color 0.15s ease;
}
.branwell-psycard__search-clear:hover,
.branwell-psycard__search-clear:focus-visible {
    background: var(--bps-primary-soft);
    color: var(--bps-primary);
    outline: none;
}

/* No-results message shown when search filters out all cards */
.branwell-psycard__empty-search {
    margin: 1.5rem 0;
    padding: 1rem;
    text-align: center;
    color: var(--bps-text-muted);
    font-size: 0.95rem;
    background: var(--bps-primary-soft);
    border-radius: 8px;
}

/* Cards filtered out by search are hidden entirely — grid reflows tighter */
.branwell-psycard__card[hidden] {
    display: none;
}

/* ============================================================
   Grid
   ============================================================ */
.branwell-psycard__grid {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    margin: 0 0 2rem;
}
/* Centred when the total card count isn't a multiple of 5 (the desktop
   row size) — keeps the incomplete last row visually balanced rather
   than left-aligned. Full rows above look identical either way. */
.branwell-psycard__grid--center-last-row {
    justify-content: center;
}

/* ============================================================
   Card
   No overflow: hidden — the avatar must be able to overflow the
   ribbon and sit half on / half off, anchored by the body's top
   padding. The ribbon and body each clip their own contents.
   ============================================================ */
.branwell-psycard__card {
    flex: 0 1 calc(20% - 16px);     /* 5 per row with the 20px gap accounted for */
    max-width: 240px;
    min-width: 180px;
    background: #ffffff;
    border-radius: 16px;
    box-shadow: 0 0 0 1px var(--bps-border);
    display: flex;
    flex-direction: column;
    position: relative;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.branwell-psycard__card:hover {
    box-shadow: 0 0 0 1px var(--bps-ring), 0 8px 20px rgba(0, 0, 0, 0.08);
    transform: translateY(-2px);
}

/* ============================================================
   Ribbon (top section behind avatar)
   Stack order (bottom → top):
     1. solid status colour gradient
     2. agenthead.webp pattern at 0.5 opacity
     3. FEATURED + NEW chips (z-index 5)
     4. photo (z-index 10) — overflows the ribbon downward into the body
   ============================================================ */
.branwell-psycard__ribbon {
    position: relative;
    height: 110px;
    /* No overflow: hidden — the photo must escape the ribbon
       downward into the body area. The agenthead pattern is
       clipped by its own ::before bounds, not by the ribbon. */
    background: linear-gradient(180deg, var(--bps-ribbon-from) 0%, var(--bps-ribbon-to) 100%);
    border-radius: 16px 16px 0 0;
    display: flex;
    justify-content: center;
    align-items: flex-end;
}
/* Decorative pattern — sits on top of the gradient, below the chips/photo.
   Hotlinked from the live media library at the same URL the original
/* Background pattern for the ribbon. The URL is injected by PHP via
   wp_add_inline_style() as a CSS custom property --bw-ribbon-bg so this
   stylesheet stays portable across production/staging/local. PHP resolves
   the URL via content_url('/uploads/headers/agenthead.webp') which uses
   the same media library that the rest of the plugin uses, so no media
   library changes are required. */
.branwell-psycard__ribbon::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: var(--bw-ribbon-bg);
    background-repeat: repeat-x;
    background-position: center;
    opacity: 0.5;
    border-radius: 16px 16px 0 0;   /* respect the card's corner radius */
    pointer-events: none;
    z-index: 1;
}

/* Avatar wrapper — owns positioning, ribbon overlap, and the coloured
   state ring. z-index: 10 puts it above the agenthead pattern AND above
   the chips in the visual stack within the ribbon. The status dot sits
   inside this wrapper but OUTSIDE the clipped photo-link so it isn't
   clipped by the circle. */
.branwell-psycard__avatar {
    position: relative;
    z-index: 10;
    width: 96px;
    height: 96px;
    margin-bottom: -48px;             /* half the height overlaps below ribbon */
    border-radius: 50%;
    background: #ffffff;
    box-shadow:
        0 0 0 4px #ffffff,            /* white outer ring */
        0 0 0 6px var(--bps-ring);    /* coloured state ring */
}

/* Inner photo link — just the clipped circle holding the img.
   No positioning, no overlap, no ring. Border-radius + clip-path
   guarantee a circle regardless of theme overrides. */
.branwell-psycard__photo-link {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50% !important;
    clip-path: circle(50% at 50% 50%);
    line-height: 0;
}
.branwell-psycard__photo {
    width: 100% !important;
    height: 100% !important;
    border-radius: 50% !important;
    clip-path: circle(50% at 50% 50%);
    object-fit: cover;
    object-position: top center;
    border: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    display: block;
    filter: var(--bps-photo-filter);
    opacity: var(--bps-photo-opacity);
    max-width: none !important;
}

/* ============================================================
   Status indicator dot
   Small coloured circle on the bottom-right of the avatar.
   Universal UX convention (Messenger, Slack, Teams, Discord).
   - Available  : solid green, static
   - Speaking   : solid red, pulsing rings (animation)
   - Offline    : solid grey, static
   Colour is driven by the parent card's data-status attribute
   so the front-end status poll can swap it in place by changing
   the data-status — no extra DOM mutation needed.
   ============================================================ */
.branwell-psycard__status-dot {
    position: absolute;
    /* Sit just inside the bottom-right of the 96px avatar wrapper.
       Slightly tucked in (not flush with the edge) so it reads as
       attached to the avatar, not floating beside it. */
    bottom: 4px;
    right: 4px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    /* The dot needs to render ABOVE the avatar's 6px coloured ring,
       so it's placed at z-index 11 (avatar wrapper is 10). */
    z-index: 11;
    /* White outer hairline so the dot reads as a separate token,
       not blended into the photo. */
    box-shadow: 0 0 0 2px #ffffff;
    background: #a0a0a0;   /* default = offline grey (overridden per state below) */
    transition: background 0.2s ease;
}

/* Available — solid green */
.branwell-psycard__card[data-status="available"] .branwell-psycard__status-dot {
    background: #2d9d6f;
}

/* Speaking — solid red + pulsing rings (rings drawn via ::before pseudo) */
.branwell-psycard__card[data-status="speaking"] .branwell-psycard__status-dot {
    background: #c44545;
}
.branwell-psycard__card[data-status="speaking"] .branwell-psycard__status-dot::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: #c44545;
    animation: branwell-psycard-pulse 1.6s ease-out infinite;
    z-index: -1;
}

/* Offline — solid grey (matches default, here explicitly for clarity) */
.branwell-psycard__card[data-status="offline"] .branwell-psycard__status-dot {
    background: #a0a0a0;
}

@keyframes branwell-psycard-pulse {
    0% {
        transform: scale(1);
        opacity: 0.7;
    }
    100% {
        transform: scale(2.4);
        opacity: 0;
    }
}

/* Respect reduced-motion preferences — disable the pulse for users
   who've opted out of animations. The static red dot is still shown. */
@media (prefers-reduced-motion: reduce) {
    .branwell-psycard__card[data-status="speaking"] .branwell-psycard__status-dot::before {
        animation: none;
    }
}

/* Featured chip — top-LEFT of ribbon.
   z-index: 5 sits above the agenthead pattern (z-index 1) but
   below the photo (z-index 10). */
.branwell-psycard__featured {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 5;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 9px;
    color: var(--bps-status-fg);
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    padding: 3px 9px;
    border-radius: 999px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1;
}
.branwell-psycard__featured::before {
    content: '★';
    font-size: 10px;
}

/* NEW READER chip — top-LEFT of ribbon, same z-index as Featured.
   Sits below the Featured chip when both are present (handled by
   the :has() rule below). */
.branwell-psycard__new-ribbon {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 5;
    display: inline-flex;
    align-items: center;
    background: var(--bps-ring);
    color: #ffffff;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 3px 9px;
    border-radius: 999px;
    line-height: 1;
    pointer-events: none;
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
/* If FEATURED is present, push NEW down below it.
   Uses :has() — supported in all evergreen browsers as of 2024. */
.branwell-psycard__ribbon:has(.branwell-psycard__featured) .branwell-psycard__new-ribbon {
    top: 36px;
}

/* ============================================================
   Card body
   Clips its own bottom corners since the card no longer has
   overflow: hidden. Top padding clears the overlapping avatar
   (48px overlap + 8px breathing room).
   ============================================================ */
.branwell-psycard__body {
    padding: 56px 14px 14px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    border-radius: 0 0 16px 16px;
    background: #ffffff;
}
.branwell-psycard__name {
    font-size: 1rem !important;
    font-weight: 700 !important;
    margin: 0 !important;
    line-height: 1.2 !important;
    color: var(--bps-text);
}
.branwell-psycard__code {
    font-size: 0.78rem;
    color: var(--bps-text-muted);
    margin: 0;
    line-height: 1.3;
}
.branwell-psycard__code span {
    color: var(--bps-primary);
    font-weight: 600;
}

/* Stars */
.branwell-psycard__stars {
    display: flex;
    justify-content: center;
    gap: 2px;
    margin: 4px 0 8px;
}
.branwell-psycard__star {
    width: 11px;
    height: 11px;
    display: inline-block;
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.branwell-psycard__star--on   { background: var(--bps-star-on); }
.branwell-psycard__star--half { background: linear-gradient(to right, var(--bps-star-on) 50%, var(--bps-star-off) 50%); }
.branwell-psycard__star--off  { background: var(--bps-star-off); }

/* ============================================================
   Action area — status pill + view profile button (same slot)
   ============================================================ */
.branwell-psycard__actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
}

/* Shared pill base — same shape across all three states so the cards
   land at identical heights regardless of which pill renders.
   text-decoration: none with !important so the theme's <a> underline
   styles can't sneak through and underline the phone number. */
.branwell-psycard__pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    padding: 10px 10px;
    border-radius: 8px;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none !important;
    border: none;
    cursor: default;
    transition: filter 0.15s ease, background 0.15s ease;
    box-sizing: border-box;
}
.branwell-psycard__pill-icon {
    flex-shrink: 0;
}

/* Available — filled green, clickable call CTA.
   Force colors with !important so theme `a:link / a:visited / a:hover`
   color rules can't override (which is why the icon and number were
   rendering in theme blue instead of white). */
.branwell-psycard__pill--available,
.branwell-psycard__pill--available:link,
.branwell-psycard__pill--available:visited,
.branwell-psycard__pill--available:hover,
.branwell-psycard__pill--available:focus,
.branwell-psycard__pill--available:active {
    background: var(--bps-pill-bg) !important;
    color: var(--bps-pill-fg) !important;
    cursor: pointer;
}
.branwell-psycard__pill--available:hover,
.branwell-psycard__pill--available:focus-visible {
    filter: brightness(0.92);
    outline: none;
}
/* The icon inherits currentColor — also force it so the SVG fill
   tracks the white pill foreground. */
.branwell-psycard__pill--available .branwell-psycard__pill-icon {
    color: var(--bps-pill-fg) !important;
    fill: currentColor !important;
}

/* Speaking — soft red filled info pill (not clickable) */
.branwell-psycard__pill--speaking {
    background: var(--bps-pill-bg) !important;
    color: var(--bps-pill-fg) !important;
}

/* Offline — neutral grey info pill */
.branwell-psycard__pill--offline {
    background: var(--bps-pill-bg) !important;
    color: var(--bps-pill-fg) !important;
}

/* View Profile button — always present, outlined, palette-primary */
.branwell-psycard__profile-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 9px 10px;
    background: transparent;
    color: var(--bps-primary);
    border: 1px solid var(--bps-border);
    border-radius: 8px;
    font-size: 0.8rem;
    font-weight: 500;
    text-decoration: none !important;
    line-height: 1;
    transition: background 0.15s ease, border-color 0.15s ease;
    box-sizing: border-box;
}
.branwell-psycard__profile-btn:hover,
.branwell-psycard__profile-btn:focus-visible {
    background: var(--bps-primary-soft);
    border-color: var(--bps-primary);
    outline: none;
}
.branwell-psycard__profile-btn:visited {
    color: var(--bps-primary);
}

/* Offline card adjustments — fade the name slightly to reinforce state */
.branwell-psycard__card[data-status="offline"] .branwell-psycard__name {
    color: #6b6b6b;
}

/* ============================================================
   Footer CTA + refresh message
   ============================================================ */
.branwell-psycard__footer-cta {
    display: flex;
    justify-content: center;
    margin-top: 1rem;
    width: 100%;
}
.branwell-psycard__view-all {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 14px 36px;
    background: var(--bps-primary-soft);
    color: var(--bps-primary);
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none !important;
    transition: filter 0.15s ease;
}
.branwell-psycard__view-all:hover,
.branwell-psycard__view-all:focus-visible {
    filter: brightness(0.95);
    outline: none;
}
.branwell-psycard__view-all:visited {
    color: var(--bps-primary);
}

.branwell-psycard__refresh-msg {
    text-align: center;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.5px;
    color: var(--bps-text-muted);
    /* !important and padding-top together — !important beats any theme
       `p { margin: 0 }` reset, and padding-top can't be collapsed away
       by neighboring margins like margin-top can. */
    margin-top: 2rem !important;
    margin-bottom: 0;
    padding-top: 12px;
    text-transform: uppercase;
    opacity: 0.6;
}

.branwell-psycard__empty {
    text-align: center;
    padding: 2rem 0;
    color: var(--bps-text-muted);
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 1024px) {
    /* 4 per row */
    .branwell-psycard__card {
        flex: 0 1 calc(25% - 15px);
    }
}
@media (max-width: 768px) {
    .branwell-psycard__grid { gap: 12px; }
    /* 2 per row */
    .branwell-psycard__card {
        flex: 0 1 calc(50% - 6px);
        max-width: none;
    }
    .branwell-psycard__body { padding: 60px 10px 12px; gap: 4px; }
    .branwell-psycard__name { font-size: 0.95rem; }
    .branwell-psycard__code { font-size: 0.72rem; }
    .branwell-psycard__pill,
    .branwell-psycard__profile-btn {
        font-size: 0.78rem;
        padding: 9px 8px;
    }
}
@media (max-width: 420px) {
    .branwell-psycard__card {
        flex: 0 1 100%;
    }
}
