/**
 * Pulseheaven — core styles
 * ================================================================
 * Always-loaded foundation. Tokens + components used by every other
 * Pulseheaven stylesheet. Edit here when:
 *   - changing brand colors, button colors, radii, or shadows site-wide
 *   - tweaking modal shell behavior (overlay, animation, sizing)
 *   - updating form field appearance globally
 *
 * To restyle a button color across the whole app: change the
 * --ph-btn-* tokens in :root. Don't touch individual button classes.
 *
 * Loaded on: every page where Pulseheaven UI appears.
 *
 * SCOPING NOTE — `.ph-btn`:
 *   `.ph-btn` is a generic class name and was previously bleeding
 *   into theme/third-party buttons that happened to share it (e.g.
 *   Astra's "Shop Women" link). Every `.ph-btn` rule below is now
 *   scoped to a Pulseheaven container — `.ph-modal`,
 *   `.dokan-offers-content[data-ph-offers-tab]`, `.ph-offers-area`,
 *   or `.ph-evt-card` (chat offer-event cards inside PeepSo
 *   conversation bubbles) — so theme buttons keep their own styling
 *   and only Pulseheaven's offer-flow buttons get this treatment.
 *
 *   If you add a new Pulseheaven surface that uses `.ph-btn`, either
 *   nest it inside one of those containers OR add a new ancestor
 *   selector to the `.ph-btn` rule chain below.
 *
 * Pulseheaven mobile breakpoints (mirrors the rest of the system):
 *   61.24em  (~979px) — tablet/desktop boundary
 *   46.24em  (~740px) — phone boundary
 *
 * TABLE OF CONTENTS
 *   1. Design tokens (:root variables)
 *   2. Animations (@keyframes)
 *   3. Body lock for modals
 *   4. Modal shell (.ph-modal, .ph-modal__*)
 *   5. Form fields (.ph-field)
 *   6. Buttons (.ph-btn, variants, .is-armed) — scoped
 *   7. Toast notifications (.ph-toast)
 *   8. Loader (.ph-loader)
 *   9. Countdown timer (.ph-countdown)
 *  10. Reputation badge (.ph-rep-badge)
 *  11. Offers menu bubble (notification dot in nav)
 *  12. Mobile responsiveness
 */


/* ==================================================================
 * 1. Design tokens
 *
 * Single source of truth for colors, radii, and shadows. Change a
 * token here and it propagates everywhere.
 * ================================================================== */
:root {
    /* Surface colors */
    --ph-bg:         #ffffff;
    --ph-bg-soft:    #fafafa;
    --ph-bg-softer:  #f5f5f5;
    --ph-bg-deep:    #f3f3f3;

    /* Text colors */
    --ph-text:       #1a1a1a;
    --ph-text-muted: #6b7280;
    --ph-text-light: #999999;

    /* Borders */
    --ph-border:       #e5e7eb;
    --ph-border-light: #ececec;
    --ph-border-soft:  #f0f0f0;

    /* Status — used for badges, pills, button variants */
    --ph-success:    #027a48;
    --ph-success-bg: #ecfdf3;
    --ph-danger:     #b42318;
    --ph-danger-bg:  #fef2f2;
    --ph-warning:    #92400e;
    --ph-warning-bg: #fef3c7;
    --ph-info:       #1d4ed8;
    --ph-info-bg:    #eff6ff;

    /* Buttons — change these to retheme buttons across the whole app */
    --ph-btn-primary-bg:        #e4e4e4;
    --ph-btn-primary-bg-hover:  #d8d8d8;
    --ph-btn-primary-text:      #000000;
    --ph-btn-primary-border:    #e4e4e4;

    --ph-btn-ghost-bg:          #ffffff;
    --ph-btn-ghost-bg-hover:    #f6f6f6;
    --ph-btn-ghost-text:        #111111;
    --ph-btn-ghost-border:      #d8d8d8;

    --ph-btn-danger-bg:         #ffffff;
    --ph-btn-danger-bg-hover:   #fdf3f1;
    --ph-btn-danger-text:       #b3261e;
    --ph-btn-danger-border:     #f0c4c0;

    /* "You sure?" armed-button state */
    --ph-btn-armed-bg:          #fef3f2;
    --ph-btn-armed-border:      #b3261e;
    --ph-btn-armed-text:        #b3261e;

    /* Radii */
    --ph-radius:      12px;
    --ph-radius-sm:   8px;
    --ph-radius-pill: 999px;

    /* Shadows */
    --ph-shadow-sm:    0 1px 2px rgba(0,0,0,.04), 0 1px 3px rgba(0,0,0,.06);
    --ph-shadow-md:    0 4px 6px -1px rgba(0,0,0,.08), 0 2px 4px -1px rgba(0,0,0,.04);
    --ph-shadow-lg:    0 10px 25px -5px rgba(0,0,0,.1), 0 8px 10px -6px rgba(0,0,0,.04);
    --ph-shadow-modal: 0 12px 60px rgba(0,0,0,.22);
}


/* ==================================================================
 * 2. Animations
 * ================================================================== */
@keyframes ph-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes ph-pop-in {
    from { opacity: 0; transform: translateY(8px) scale(.97); }
    to   { opacity: 1; transform: translateY(0)   scale(1); }
}

@keyframes ph-slide-up {
    from { transform: translateY(20px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}

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

/* "You sure?" armed button — soft outward radial pulse */
@keyframes ph-armed-pulse {
    0%, 100% { box-shadow: 0 0 0 0   rgba(179, 38, 30, .35); }
    50%      { box-shadow: 0 0 0 6px rgba(179, 38, 30, 0); }
}


/* ==================================================================
 * 3. Body lock for modals
 * ================================================================== */
body.ph-modal-lock { overflow: hidden; }


/* ==================================================================
 * 4. Modal shell
 *
 * Used by every offer-related modal: send-offer, review-offer,
 * offer-to-likers. Edit here to change behavior across all of them.
 *
 * Note: the PDP "Ask a question" popup uses .ph-msg-popup (in
 * ph-messaging.css), not .ph-modal — different markup, different
 * animation. Don't conflate them.
 *
 * Markup contract:
 *   <div class="ph-modal" hidden>
 *     <div class="ph-modal__dialog">
 *       <header class="ph-modal__header">
 *         <h2 class="ph-modal__title">…</h2>
 *         <button class="ph-modal__close">×</button>
 *       </header>
 *       <div class="ph-modal__body">…</div>
 *       <footer class="ph-modal__footer">…</footer>
 *     </div>
 *   </div>
 * ================================================================== */
.ph-modal {
    position: fixed; inset: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0, 0, 0, .55);
    z-index: 99999;
    padding: 16px;
    opacity: 0;
    transition: opacity .15s ease;
}
.ph-modal.is-open { opacity: 1; }
.ph-modal[hidden] { display: none; }

.ph-modal__dialog {
    background: var(--ph-bg);
    border-radius: 14px;
    width: 100%;
    max-width: 480px;
    max-height: calc(100vh - 32px);
    display: flex; flex-direction: column;
    box-shadow: var(--ph-shadow-modal);
    transform: translateY(8px);
    transition: transform .15s ease;
}
.ph-modal.is-open .ph-modal__dialog { transform: translateY(0); }

.ph-modal__header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 20px 24px 12px;
    border-bottom: 1px solid var(--ph-border-soft);
}
.ph-modal__title {
    font-size: 17px; font-weight: 600; margin: 0; line-height: 1.3;
    color: #111;
}
.ph-modal__close {
    background: none; border: 0; cursor: pointer;
    font-size: 26px; line-height: 1; color: #666;
    padding: 4px 8px; border-radius: 6px;
    transition: background .15s ease, color .15s ease;
}
.ph-modal__close:hover { background: var(--ph-bg-deep); color: #000; }
.ph-modal__close:focus-visible { outline: 2px solid #000; outline-offset: 2px; }

.ph-modal__body {
    padding: 16px 24px;
    overflow-y: auto;
    flex: 1 1 auto;
}

.ph-modal__footer {
    display: flex; align-items: center; justify-content: flex-end;
    gap: 8px;
    padding: 12px 24px 20px;
    border-top: 1px solid var(--ph-border-soft);
}

/* Product preview row — used at the top of offer modals to show
 * which product the action relates to. */
.ph-modal__product {
    background: var(--ph-bg-soft);
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 16px;
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    font-size: 14px; color: #333;
}
.ph-modal__product-price {
    color: #777; font-size: 13px; white-space: nowrap;
}


/* ==================================================================
 * 5. Form fields
 *
 * Generic field container with label + input/textarea + optional
 * help/warning text. Used in send-offer, review-offer, counter form,
 * and the "Ask a question" popup body.
 * ================================================================== */
.ph-field { margin: 14px 0; }
.ph-field label {
    display: block; font-size: 13px; font-weight: 600;
    margin-bottom: 6px; color: #222;
}
.ph-field input[type="number"],
.ph-field input[type="text"],
.ph-field textarea {
    width: 100%;
    border: 1px solid #d8d8d8;
    border-radius: var(--ph-radius-sm);
    padding: 10px 12px;
    font-size: 15px;
    font-family: inherit;
    background: var(--ph-bg);
    color: #111;
    transition: border-color .15s ease, box-shadow .15s ease;
    box-sizing: border-box;
}
.ph-field input:focus,
.ph-field textarea:focus {
    border-color: #000;
    outline: none;
    box-shadow: 0 0 0 3px rgba(0,0,0,.08);
}
.ph-field textarea { resize: vertical; min-height: 64px; }

.ph-min-label {
    display: block; font-size: 12px; color: #666; margin-top: 6px;
}
.ph-min-warning {
    display: block; font-size: 12px; color: var(--ph-danger);
    margin-top: 6px; font-weight: 600;
}


/* ==================================================================
 * 6. Buttons (scoped to Pulseheaven offer surfaces)
 *
 * Variants:
 *   .ph-btn--primary   solid grey, black text   (Send, Submit, Accept)
 *   .ph-btn--ghost     white, dark text         (Cancel, Counter)
 *   .ph-btn--danger    white, red text          (Decline, Withdraw)
 *   .ph-btn--link      transparent, muted       (subtle text actions)
 *
 * Modifiers:
 *   .ph-btn--small     smaller padding/text
 *   .ph-btn--block     full-width
 *   .is-armed          confirmation state — text → "You sure?", red pulse
 *
 * Scope: each rule requires an offer-context ancestor —
 *   .ph-modal                                       (modals)
 *   .dokan-offers-content[data-ph-offers-tab]       (offers dashboard tab)
 *   .ph-offers-area                                 (any other Pulseheaven surface)
 *   .ph-evt-card                                    (chat offer-event cards in PeepSo bubbles)
 *
 * Buttons matching `.ph-btn` outside these contexts (e.g. Astra
 * theme buttons that happen to share the class) get their default
 * theme styling instead of being hijacked by Pulseheaven's tokens.
 *
 * To recolor: edit --ph-btn-* tokens in :root above. Don't override
 * individual variants here.
 * ================================================================== */

/* Base */
.ph-modal .ph-btn,
.dokan-offers-content[data-ph-offers-tab] .ph-btn,
.ph-offers-area .ph-btn,
.ph-evt-card .ph-btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: 6px;
    border: 1px solid transparent;
    border-radius: var(--ph-radius-sm);
    padding: 10px 16px;
    font-size: 14px; font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease, box-shadow .15s ease;
    text-decoration: none;
    line-height: 1;
    font-family: inherit;
}
.ph-modal .ph-btn:focus-visible,
.dokan-offers-content[data-ph-offers-tab] .ph-btn:focus-visible,
.ph-offers-area .ph-btn:focus-visible,
.ph-evt-card .ph-btn:focus-visible {
    outline: 2px solid #000; outline-offset: 2px;
}
.ph-modal .ph-btn[disabled],
.ph-modal .ph-btn.is-loading,
.dokan-offers-content[data-ph-offers-tab] .ph-btn[disabled],
.dokan-offers-content[data-ph-offers-tab] .ph-btn.is-loading,
.ph-offers-area .ph-btn[disabled],
.ph-offers-area .ph-btn.is-loading,
.ph-evt-card .ph-btn[disabled],
.ph-evt-card .ph-btn.is-loading {
    opacity: .55; cursor: not-allowed;
}

/* Primary */
.ph-modal .ph-btn--primary,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--primary,
.ph-offers-area .ph-btn--primary,
.ph-evt-card .ph-btn--primary {
    background: var(--ph-btn-primary-bg);
    color: var(--ph-btn-primary-text);
    border-color: var(--ph-btn-primary-border);
}
.ph-modal .ph-btn--primary:hover,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--primary:hover,
.ph-offers-area .ph-btn--primary:hover,
.ph-evt-card .ph-btn--primary:hover {
    background: var(--ph-btn-primary-bg-hover);
    border-color: var(--ph-btn-primary-bg-hover);
    color: var(--ph-btn-primary-text);
}

/* Ghost */
.ph-modal .ph-btn--ghost,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--ghost,
.ph-offers-area .ph-btn--ghost,
.ph-evt-card .ph-btn--ghost {
    background: var(--ph-btn-ghost-bg);
    color: var(--ph-btn-ghost-text);
    border-color: var(--ph-btn-ghost-border);
}
.ph-modal .ph-btn--ghost:hover,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--ghost:hover,
.ph-offers-area .ph-btn--ghost:hover,
.ph-evt-card .ph-btn--ghost:hover {
    background: var(--ph-btn-ghost-bg-hover);
}

/* Danger */
.ph-modal .ph-btn--danger,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--danger,
.ph-offers-area .ph-btn--danger,
.ph-evt-card .ph-btn--danger {
    background: var(--ph-btn-danger-bg);
    color: var(--ph-btn-danger-text);
    border-color: var(--ph-btn-danger-border);
}
.ph-modal .ph-btn--danger:hover,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--danger:hover,
.ph-offers-area .ph-btn--danger:hover,
.ph-evt-card .ph-btn--danger:hover {
    background: var(--ph-btn-danger-bg-hover);
}

/* Link */
.ph-modal .ph-btn--link,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--link,
.ph-offers-area .ph-btn--link,
.ph-evt-card .ph-btn--link {
    background: transparent;
    color: #555;
    border-color: transparent;
    padding: 10px 8px;
}
.ph-modal .ph-btn--link:hover,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--link:hover,
.ph-offers-area .ph-btn--link:hover,
.ph-evt-card .ph-btn--link:hover {
    color: #000;
}

/* Modifiers */
.ph-modal .ph-btn--small,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--small,
.ph-offers-area .ph-btn--small,
.ph-evt-card .ph-btn--small {
    padding: 6px 10px;
    font-size: 12px;
    border-radius: 6px;
}
.ph-modal .ph-btn--block,
.dokan-offers-content[data-ph-offers-tab] .ph-btn--block,
.ph-offers-area .ph-btn--block,
.ph-evt-card .ph-btn--block {
    width: 100%;
}

/* Armed state — second-click-to-confirm pattern.
 * JS swaps the button text to "You sure?" and adds .is-armed for
 * visual cue. After 4s without a confirmation click, the JS reverts. */
.ph-modal .ph-btn.is-armed,
.dokan-offers-content[data-ph-offers-tab] .ph-btn.is-armed,
.ph-offers-area .ph-btn.is-armed,
.ph-evt-card .ph-btn.is-armed {
    background: var(--ph-btn-armed-bg);
    color: var(--ph-btn-armed-text);
    border-color: var(--ph-btn-armed-border);
    animation: ph-armed-pulse 1.2s ease-in-out infinite;
}


/* ==================================================================
 * 7. Toast notifications
 *
 * Floating pill at the bottom of the screen for transient success/
 * error/warning messages.
 * ================================================================== */
.ph-toast-host {
    position: fixed;
    bottom: 16px; left: 50%; transform: translateX(-50%);
    z-index: 100000;
    display: flex; flex-direction: column; gap: 8px;
    pointer-events: none;
}
.ph-toast {
    background: #111; color: #fff;
    padding: 10px 14px;
    border-radius: var(--ph-radius-pill);
    font-size: 13px; font-weight: 500;
    box-shadow: 0 8px 24px rgba(0,0,0,.18);
    opacity: 0; transform: translateY(8px);
    transition: opacity .2s ease, transform .2s ease;
    max-width: 90vw;
    pointer-events: auto;
}
.ph-toast.is-visible { opacity: 1; transform: translateY(0); }
.ph-toast--success { background: #14532d; }
.ph-toast--error   { background: #7f1d1d; }
.ph-toast--warning { background: #92400e; }


/* ==================================================================
 * 8. Loader (inline block-level placeholder with spinner)
 * ================================================================== */
.ph-loader {
    display: flex; align-items: center; justify-content: center;
    padding: 32px 0;
    color: #888; font-size: 13px;
}
.ph-loader::before {
    content: ''; display: inline-block;
    width: 14px; height: 14px;
    border: 2px solid #ddd; border-top-color: #111;
    border-radius: 50%;
    animation: ph-spin .7s linear infinite;
    margin-right: 8px;
}


/* ==================================================================
 * 9. Countdown timer
 * ================================================================== */
.ph-countdown {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: #444;
}
.ph-countdown.is-expired { color: var(--ph-danger); }


/* ==================================================================
 * 10. Reputation badge
 *
 * Inline pill rendered next to a buyer name in the seller's review
 * modal: "good buyer", "1st-time", "low completion rate", etc.
 * ================================================================== */
.ph-rep-badge {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 8px;
    border-radius: var(--ph-radius-pill);
    font-size: 11px; font-weight: 600;
    line-height: 1;
    vertical-align: middle;
}
.ph-rep-badge--positive { background: #d1fae5; color: #047857; }
.ph-rep-badge--neutral  { background: #f0f0f0; color: #444; }
.ph-rep-badge--warning  { background: #fff5d6; color: #8a5a00; }
.ph-rep-badge--danger   { background: #fee2e2; color: #b91c1c; }
.ph-rep-badge__detail {
    display: block; font-size: 11px; color: #666;
    font-weight: 400; margin-top: 4px;
}


/* ==================================================================
 * 11. Offers menu bubble
 *
 * Small bubble badge on the "Offers" main-nav item showing pending
 * count. Uses PeepSo CSS variables (--PADD--*, --bubble-*) so it
 * inherits PeepSo's theming for nav-bar bubbles.
 * ================================================================== */
.offers-menu-item,
.offers-menu-link {
    position: relative;       /* anchor for the absolutely positioned bubble */
    display: inline-block;
}

.peepso-offers-bubble {
    position: absolute;
    top: calc(-1 * var(--PADD--SM));
    right: 10%;
    transform: translateX(var(--PADD--MD));

    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 2px;
    min-width: 17px;
    height: 16px;

    font-size: var(--bubble-font-size);
    line-height: 1;
    color: var(--bubble-color);
    background-color: var(--bubble-bg);
    border-radius: 4px;
    box-shadow: 0 2px 2px rgba(0, 0, 0, .1);
}
.peepso-offers-bubble:empty {
    display: none;
    padding: 0;
}


/* ==================================================================
 * 12. Mobile responsiveness
 *
 * On phones (≤46.24em / ~740px), modals slide up from the bottom
 * and span full width.
 * ================================================================== */
@media (max-width: 46.24em) {
    .ph-modal { padding: 0; align-items: flex-end; }
    .ph-modal__dialog {
        max-width: none;
        border-radius: 14px 14px 0 0;
        max-height: 92vh;
    }
    .ph-modal__header { padding: 16px 18px 10px; }
    .ph-modal__body   { padding: 14px 18px; }
    .ph-modal__footer { padding: 10px 18px 18px; }
}