/*
 * site-polish.css — Shared interaction layer across every public page.
 *
 * Provides:
 *  - .anim-border     : animated conic cyan ring on hover (FAQs-style pill-bar effect)
 *  - .pulse-cta       : pulsing cyan halo on primary CTAs driving urgency
 *  - .section-divider : elegant cyan gradient line with pulsing center dot between sections
 *  - Mobile section rhythm + tap feedback
 */

/* ============ animated cyan ring on hover ============ */
.anim-border {
    position: relative;
    isolation: isolate;
}
@property --ab-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}
.anim-border::before {
    content: '';
    position: absolute;
    inset: -1.5px;
    border-radius: inherit;
    padding: 1.5px;
    background: conic-gradient(
        from var(--ab-angle, 0deg),
        rgba(0,245,255,0) 0deg,
        rgba(0,245,255,0) 60deg,
        rgba(0,245,255,0.85) 95deg,
        rgba(125,244,255,1) 120deg,
        rgba(0,245,255,0.85) 145deg,
        rgba(0,245,255,0) 180deg,
        rgba(0,245,255,0) 360deg
    );
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: ab-spin 6s linear infinite;
    opacity: 0;
    transition: opacity 0.4s ease;
    pointer-events: none;
    z-index: 2;
}
.anim-border:hover::before,
.anim-border:focus-within::before {
    opacity: 1;
}
@keyframes ab-spin { to { --ab-angle: 360deg; } }

/* Always-on variant for priority cards (featured tier, key CTAs) */
.anim-border-on::before {
    opacity: 0.85;
}

@supports not (background: conic-gradient(from 0deg, red, blue)) {
    .anim-border::before { display: none; }
}

/* ============ Always-on animated border ============
 * Full-time cyan comet + breathing halo. Use on key feature cards
 * site-wide (What-You-Get cards on home, Standards flip cards on
 * how-we-work, etc.). */
@property --abl-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}
.anim-border-live {
    position: relative;
    isolation: isolate;
}
.anim-border-live::before {
    content: '';
    position: absolute;
    inset: -1.5px;
    border-radius: inherit;
    padding: 1.5px;
    background: conic-gradient(
        from var(--abl-angle, 0deg),
        rgba(0,245,255,0) 0deg,
        rgba(0,245,255,0) 55deg,
        rgba(0,245,255,0.8) 85deg,
        rgba(125,244,255,1) 110deg,
        rgba(0,245,255,0.8) 135deg,
        rgba(0,245,255,0) 165deg,
        rgba(0,245,255,0) 360deg
    );
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: abl-spin 6s linear infinite;
    pointer-events: none;
    z-index: 2;
}
.anim-border-live::after {
    content: '';
    position: absolute;
    inset: -8px;
    border-radius: inherit;
    background: radial-gradient(ellipse at 50% 50%, rgba(0,245,255,0.14), transparent 70%);
    filter: blur(14px);
    opacity: 0.35;
    pointer-events: none;
    z-index: -1;
    animation: abl-halo 3.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes abl-spin { to { --abl-angle: 360deg; } }
@keyframes abl-halo {
    0%, 100% { opacity: 0.25; }
    50%      { opacity: 0.55; }
}
@supports not (background: conic-gradient(from 0deg, red, blue)) {
    .anim-border-live::before,
    .anim-border-live::after { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .anim-border-live::before,
    .anim-border-live::after { animation: none; }
}

/* ============ Header "Begin My Workup" CTA: animated border (matches .anim-border-live) ============
 * Same cyan-comet spin + breathing halo as the .anim-border-live
 * treatment on the home "What You Get" cards. Uses ::after for the
 * spinning ring because .nav-cta::before is already the horizontal
 * hover shine; the breathing halo rides on the element's own
 * box-shadow via a keyframe so we do not need a third pseudo. */
@property --nav-cta-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}
.nav-cta {
    position: relative;
    isolation: isolate;
    /* Subtle static cyan border sits underneath the animated ring so
     * the pill always reads as bordered, even in the gaps of the
     * spinning gradient. */
    border-color: rgba(0, 245, 255, 0.28) !important;
}
.nav-cta::after {
    content: '';
    position: absolute;
    /* Inside the button's edge because each page's .nav-cta sets
     * overflow: hidden (needed for the hover shine). Padding creates
     * the ring width via the content-box/border-box mask composite. */
    inset: 0;
    border-radius: inherit;
    padding: 1.5px;
    /* Exact gradient stops from .anim-border-live::before so the comet
     * shape matches the What-You-Get cards on the home page. */
    background: conic-gradient(
        from var(--nav-cta-angle, 0deg),
        rgba(0,245,255,0) 0deg,
        rgba(0,245,255,0) 55deg,
        rgba(0,245,255,0.8) 85deg,
        rgba(125,244,255,1) 110deg,
        rgba(0,245,255,0.8) 135deg,
        rgba(0,245,255,0) 165deg,
        rgba(0,245,255,0) 360deg
    );
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    /* 6 s linear spin — same cadence as .anim-border-live */
    animation: nav-cta-spin 6s linear infinite;
    pointer-events: none;
    z-index: 3;
    transition: opacity 0.3s ease;
}
@keyframes nav-cta-spin { to { --nav-cta-angle: 360deg; } }
/* On hover the CTA fills solid cyan — hide the ring so the fill
 * state stays clean. */
.nav-cta:hover::after { opacity: 0; }
/* Fallback for browsers without @property / conic-gradient support:
 * fall back to a visible static cyan border. */
@supports not (background: conic-gradient(from 0deg, red, blue)) {
    .nav-cta::after { display: none; }
    .nav-cta { border-color: rgba(0, 245, 255, 0.55) !important; }
}
@media (prefers-reduced-motion: reduce) {
    .nav-cta::after { animation: none; opacity: 0.7; }
}

/* ============ pulsing CTA halo ============ */
.pulse-cta {
    position: relative;
    animation: pulse-cta-halo 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse-cta-halo {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(0,245,255,0.55),
                    0 0 22px rgba(0,245,255,0.3);
    }
    50% {
        box-shadow: 0 0 0 10px rgba(0,245,255,0),
                    0 0 40px rgba(0,245,255,0.55);
    }
}
.pulse-cta:hover { animation-play-state: paused; }

/* Section dividers removed — the repeated cyan gradient lines plus
 * pulsing dots added too much visual noise when scrolling. The
 * <div class="section-divider"> elements still exist in markup but
 * render as nothing. Section rhythm is now carried by padding and
 * the headline treatment alone. */
.section-divider { display: none; }

/* ============ Footer brand lockup ============
 * Inline chevron mark sitting on the wordmark cap-height baseline,
 * sized to the cap-height itself so it reads as part of the
 * lettering, not a stamp on top of it. */
.brand-mark {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
}
.brand-mark > .brand-chevron,
.brand-mark > .brand-mark-img {
    display: inline-block;
    width: 0.85em;
    height: 0.85em;
    flex-shrink: 0;
    transform: translateY(0.05em);
}
.brand-mark > .brand-chevron img,
.brand-mark > .brand-chevron .brand-mark-img,
.brand-chevron > img {
    width: 100%;
    height: 100%;
    display: block;
}

/* Generic brand-mark image: any wrapper around it sizes the box,
 * the image fills its parent. Used for in-text cues, swipe hints,
 * and the footer lockup. */
.brand-mark-img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
}

/* ============ accessibility: focus indicators ============ */
/* WCAG 2.2 AA requires a visible focus indicator on every interactive
 * element. Most Tailwind-styled buttons and links in this codebase
 * set `outline: none` via `focus:outline-none` — which strips the
 * browser default without replacing it. This block restores a
 * visible, themed ring on keyboard focus only (so it doesn't fire
 * on mouse clicks and clash with the visual design). */
:where(a, button, input, textarea, select, summary, [tabindex]:not([tabindex="-1"]))
    :focus-visible,
:where(a, button, input, textarea, select, summary, [tabindex]:not([tabindex="-1"]))
    .focus-visible,
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 2px solid #00f5ff;
    outline-offset: 3px;
    border-radius: 6px;
    box-shadow: 0 0 0 4px rgba(0, 245, 255, 0.18);
    transition: none;
}

/* ============ scroll reveal variants (site-wide) ============
 * Existing pages use `.reveal` (fade + translateY) driven by an
 * IntersectionObserver that adds `.visible` when the element is
 * in view. These variants extend that system — any element with
 * `.reveal` AND one of the modifier classes below gets a richer
 * entry animation. Observer code is unchanged.
 */
.reveal.reveal-left  { transform: translateX(-40px) translateY(10px); }
.reveal.reveal-right { transform: translateX(40px)  translateY(10px); }
.reveal.reveal-scale { transform: scale(0.94) translateY(12px); transform-origin: center bottom; }
.reveal.reveal-blur  { filter: blur(10px); }
.reveal.reveal-lift  { transform: translateY(60px); }

.reveal.visible.reveal-left,
.reveal.visible.reveal-right { transform: translateX(0) translateY(0); }
.reveal.visible.reveal-scale { transform: scale(1) translateY(0); }
.reveal.visible.reveal-blur  { filter: blur(0); }
.reveal.visible.reveal-lift  { transform: translateY(0); }

/* All variants use a slightly springier curve than the default
 * .reveal so the movement reads distinctly. */
.reveal.reveal-left,
.reveal.reveal-right,
.reveal.reveal-scale,
.reveal.reveal-blur,
.reveal.reveal-lift {
    transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1),
                transform 1s cubic-bezier(0.22, 1, 0.36, 1),
                filter 0.9s ease;
}

/* Section-header coordinated entrance: eyebrow slides in, H2 lifts,
 * subhead fades. Apply by putting `.reveal reveal-section` on the
 * wrapping div of any seg-head + H2 + p group. */
.reveal-section > .seg-head,
.reveal-section > .text-\[10px\]:first-child {
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 0.7s ease 0.05s, transform 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.05s;
}
.reveal-section > h2,
.reveal-section > h3 {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.9s ease 0.2s, transform 0.95s cubic-bezier(0.22, 1, 0.36, 1) 0.2s;
}
.reveal-section > p {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.8s ease 0.4s, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.4s;
}
.reveal-section.visible > .seg-head,
.reveal-section.visible > .text-\[10px\]:first-child,
.reveal-section.visible > h2,
.reveal-section.visible > h3,
.reveal-section.visible > p {
    opacity: 1;
    transform: translateY(0);
}

/* =========================================================
 * Mobile polish — applies on coarse-pointer (touch) devices.
 * Keeps everything clean, signalling interactions without
 * saying "tap here," and tightens spacing so the page feels
 * intentional on phones.
 * ========================================================= */
html {
    scroll-behavior: smooth;
}
@supports (scroll-behavior: smooth) {
    html { scroll-padding-top: 90px; }
}

/* Pull-to-bounce: site-polish.js translates body / mobile menu on pull-down.
 * Disable native overscroll so the JS bounce is the only motion the user
 * sees, on both iOS and Android, on every page. */
html, body {
    overscroll-behavior-y: none;
    -webkit-overflow-scrolling: touch;
}
.mobile-menu {
    overscroll-behavior-y: none;
    -webkit-overflow-scrolling: touch;
}

/* Mobile/tablet nav: keep the logo and hamburger off the screen edges. */
@media (max-width: 1024px) {
    #mainNav > div {
        padding-left: 1.25rem;
        padding-right: 1.25rem;
    }
}
@media (hover: none) and (pointer: coarse) {

    /* ---- Flip cards: Propelled chevron tap cue ----
     * Real <span class="flip-tap-cue"> injected by site-polish.js into
     * each .flip-front so the cue isn't a pseudo-element on a
     * backface-hidden 3D-transformed parent (Samsung Internet and
     * other browsers can drop those silently). Inline SVG keeps the
     * icon dependency-free.
     *
     * The span has a pulsing cyan halo behind an inline SVG of the
     * Propelled chevron. Both fade out when the card is flipped. */
    .flip-tap-cue {
        position: absolute;
        top: 14px;
        right: 14px;
        width: 44px;
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
        pointer-events: none;
        z-index: 10;
        opacity: 1;
        transition: opacity 0.35s ease;
        /* Solid disc background so the chevron has a substrate to
         * render against even if the surrounding card paints over. */
        background:
            radial-gradient(circle at center,
                rgba(0, 245, 255, 0.18) 0%,
                rgba(0, 245, 255, 0.08) 60%,
                rgba(0, 245, 255, 0) 80%);
        border-radius: 50%;
        /* Force own compositor layer so the span renders even when
         * the .flip-front parent sits inside a transform-style:
         * preserve-3d ancestor (Samsung Internet quirk). */
        transform: translateZ(1px);
        -webkit-backface-visibility: visible;
        backface-visibility: visible;
    }
    /* The pulsing halo lives behind the chevron */
    .flip-tap-cue::before {
        content: '';
        position: absolute;
        inset: -4px;
        border-radius: 50%;
        background:
            radial-gradient(circle at center,
                rgba(0, 245, 255, 0.45) 0%,
                rgba(0, 245, 255, 0.18) 50%,
                rgba(0, 245, 255, 0) 75%);
        animation: flip-tap-ring 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
    }
    .flip-tap-cue svg {
        position: relative;
        z-index: 1;
        width: 30px;
        height: 30px;
        filter: drop-shadow(0 0 8px rgba(0, 245, 255, 1))
                drop-shadow(0 0 18px rgba(0, 245, 255, 0.5));
        animation: flip-tap-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
    }
    .flip-card.flipped .flip-tap-cue {
        opacity: 0;
    }
    .flip-card.flipped .flip-tap-cue::before,
    .flip-card.flipped .flip-tap-cue svg {
        animation: none;
    }

    /* ---- Swipeable comparison matrix: animated hint arrow ----
     * Render-free bounce on the right edge of the matrix while
     * the user hasn't scrolled it horizontally yet. Fades out
     * once they start scrolling. */
    .matrix {
        position: relative;
    }
    .matrix::after {
        content: '';
        position: absolute;
        top: 50%;
        right: 10px;
        transform: translateY(-50%);
        width: 36px;
        height: 36px;
        border-radius: 50%;
        background: rgba(0, 245, 255, 0.18);
        box-shadow: 0 0 20px rgba(0, 245, 255, 0.35);
        background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300f5ff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M9 18l6-6-6-6'/></svg>");
        background-repeat: no-repeat;
        background-position: center;
        background-size: 20px;
        animation: matrix-swipe-bounce 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;
        pointer-events: none;
        z-index: 10;
        transition: opacity 0.4s ease;
    }
    .matrix.scrolled::after {
        opacity: 0;
    }
    /* The scroll wrapper — fade a subtle cyan strip from the
     * right so users see there's more content hidden. */
    .matrix {
        background-image: linear-gradient(to left, rgba(0, 245, 255, 0.06), transparent 8%);
    }
    .matrix.scrolled {
        background-image: none;
    }

    /* ---- Mobile rhythm: tighter section + card padding ---- */
    main > section {
        padding-top: 4rem !important;
        padding-bottom: 4rem !important;
    }
    /* Kill double gaps between sections + their dividers. */
    .section-divider + section,
    section + section {
        margin-top: 0 !important;
    }
    /* Headlines get a little breathing room below */
    h1, h2 {
        letter-spacing: -0.02em;
    }
    /* Every card pulls in slightly so it doesn't touch the
     * screen edge on phones. */
    .wi-card, .fit-card, .stage-card, .covenant,
    .flip-card, .tier, .shift-card, .rank-col,
    .btn-stat, .journal-card, .article-card, .faqs-item {
        margin-left: 0;
        margin-right: 0;
    }
    /* Touch targets: enforce 44×44 minimum on links + buttons */
    a.nav-link, .faq-filter button, .btn-solid, .btn-ghost,
    .btn-primary, .btn-secondary, .tier-btn, .nav-cta {
        min-height: 44px;
    }
}
@keyframes flip-tap-ring {
    0%, 100% { transform: scale(0.9);  opacity: 0.6; }
    50%      { transform: scale(1.25); opacity: 1; }
}
@keyframes flip-tap-pulse {
    0%, 100% {
        transform: scale(0.96);
        filter: drop-shadow(0 0 4px rgba(0, 245, 255, 0.6))
                drop-shadow(0 0 10px rgba(0, 245, 255, 0.25));
    }
    50% {
        transform: scale(1.08);
        filter: drop-shadow(0 0 10px rgba(0, 245, 255, 1))
                drop-shadow(0 0 22px rgba(0, 245, 255, 0.6));
    }
}
@keyframes matrix-swipe-bounce {
    0%, 100% { transform: translateY(-50%) translateX(0); }
    50%      { transform: translateY(-50%) translateX(8px); }
}
@media (prefers-reduced-motion: reduce) {
    .flip-tap-cue::before,
    .flip-tap-cue svg,
    .matrix::after { animation: none !important; }
}

/* ============ rounded corners, site-wide ============
 * Single source of truth for card corner rounding. All surface-
 * level cards get 12 px; only .persona is larger (16 px) where it
 * was already !important. Runs late so inline page CSS cannot
 * accidentally square them. */
.tier,
.matrix,
.on-numbers-block,
.instrument,
.journal-card,
.faq-item,
.faqs-item,
.shift-card,
.ai-card,
.rank-col,
.stage-card,
.outcome-card,
.article-card,
.wi-card,
.fit-card,
.covenant,
.flip-card,
.flip-face {
    border-radius: 12px;
}
.persona { border-radius: 16px; }

/* ============ reduced motion ============ */
@media (prefers-reduced-motion: reduce) {
    /* Shared polish animations */
    .anim-border::before,
    .pulse-cta { animation: none !important; }

    /* Blanket safety net: disable all page-level animations and
     * scroll-triggered reveals site-wide. Users who opt into
     * reduced motion should not see any kinetic movement. */
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }

    /* Reveals normally animate from translateY(30px). Keep them
     * in their final position without the transform. */
    .reveal,
    .fade-up,
    .fade-up-1,
    .fade-up-2,
    .fade-up-3 {
        opacity: 1 !important;
        transform: none !important;
    }

    /* Auto-playing background video loops (hero, wwa-portrait).
     * Freeze them on the first frame so motion-sensitive users
     * aren't forced to watch. */
    video[autoplay] {
        animation-play-state: paused !important;
    }
}

/* =========================================================
 * Footer bottom strip: left-align on mobile, hold copyright + tagline
 * each on a single line, and shrink type so it fits even on 320px.
 *
 * Multiple selector forms are used so this wins regardless of cascade
 * order against Tailwind's items-center / flex-wrap utilities. */
@media (max-width: 768px) {
    /* The strip has its own 1.5rem horizontal padding on top of the
     * <footer>'s px-6, so its inner content sits 1.5rem further right
     * than the LinkedIn / X icons above. Pull the dark band out by
     * 1.5rem on each side so the band still goes edge-to-edge while
     * its inner content lines up with the footer's top column. */
    .footer-dark-strip {
        margin-left: -1.5rem !important;
        margin-right: -1.5rem !important;
    }

    /* Outer wrapper: align children to the LEFT and stack to the top.
     * Targeting both the structural selector and Tailwind's actual
     * flex-col class so cascade can't undo this. */
    .footer-dark-strip > div:first-child,
    .footer-dark-strip .flex.flex-col {
        align-items: flex-start !important;
        justify-content: flex-start !important;
        text-align: left !important;
    }
    /* Pin each child explicitly so neither row nor tagline drift back
     * to center if items-center wins via cascade order. */
    .footer-dark-strip > div:first-child > div,
    .footer-dark-strip > div:first-child > p {
        align-self: flex-start !important;
        margin-left: 0 !important;
        margin-right: auto !important;
        max-width: 100%;
    }
    /* Copyright row: NO wrap, smaller font, less tracking, so the full
     * "(c) 2026 Propelled MD . Privacy . Terms . Login" line stays on
     * a single row even on a 320px-wide phone. */
    .footer-dark-strip > div:first-child > div {
        flex-wrap: nowrap !important;
        justify-content: flex-start !important;
        font-size: clamp(7px, 2.3vw, 9px) !important;
        letter-spacing: 0.08em !important;
        text-align: left !important;
        white-space: nowrap !important;
        gap: 0.6rem !important;
    }
    .footer-dark-strip > div:first-child > div > * {
        white-space: nowrap !important;
    }
    /* Tagline: force a single line on the longest tagline copy. */
    .footer-dark-strip > div:first-child > p {
        font-size: clamp(7px, 2.3vw, 9px) !important;
        letter-spacing: 0.05em !important;
        white-space: nowrap !important;
        text-align: left !important;
        line-height: 1.4;
    }
    /* Disclaimer paragraph below the strip: pull type in to match. */
    .footer-dark-strip > div:last-child {
        font-size: 10px !important;
        line-height: 1.55 !important;
        text-align: left !important;
    }
}

/* =========================================================
 * Scroll-driven card/row enlarge on mobile is handled entirely by
 * site-polish.js, which sets inline transform every frame so the
 * scale tracks scroll position smoothly on any browser, not just
 * those that ship animation-timeline: view(). The CSS-only versions
 * that lived here only fired during entry, so up/down scroll past a
 * fully-visible card showed nothing. */

