/* ============================================================================
   Coach Profile Page — /coach-profile.html
   Public storefront + owner edit surface. Read-only by default; owner gets
   inline edit buttons via [data-cp-owner="true"] on the root.
   ============================================================================ */

body.coach-profile-page .ds-main {
    padding: 2rem 2rem 4rem;
    max-width: 1040px;
    margin: 0 auto;
}

/* Top strip */
.cp-topstrip {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 1.25rem;
    margin-bottom: 2rem;
    border-bottom: 1px solid var(--border-subtle);
}
.cp-share-link {
    font-size: 0.8125rem;
    color: var(--text-tertiary, #9ca3af);
    text-decoration: none;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}
.cp-share-link:hover { color: var(--accent); }
.cp-share-link svg { width: 14px; height: 14px; }

/* ---- Hero: two-column identity + credentials ---- */
.cp-hero {
    display: grid;
    grid-template-columns: 1fr 280px;
    gap: 2.5rem;
    padding: 0 0 2.5rem;
    margin-bottom: 2.5rem;
    border-bottom: 1px solid var(--border-subtle);
    align-items: start;
}
@media (max-width: 820px) {
    .cp-hero { grid-template-columns: 1fr; }
}

.cp-id {
    display: flex;
    gap: 1.25rem;
    align-items: flex-start;
    position: relative;
}
.cp-avatar {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    background: var(--coach-accent, linear-gradient(135deg, #3b82f6, #1e40af));
    color: var(--coach-on-accent, #fff);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    font-weight: 700;
    flex-shrink: 0;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}
.cp-id-text { flex: 1; min-width: 0; }
.cp-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent);
    background: rgba(96, 165, 250, 0.1);
    padding: 0.25rem 0.625rem;
    border-radius: 999px;
    margin-bottom: 0.625rem;
}
.cp-tag svg { width: 11px; height: 11px; }
.cp-name {
    font-size: 1.875rem;
    font-weight: 700;
    color: var(--text-primary);
    margin: 0 0 0.25rem;
    letter-spacing: -0.02em;
    line-height: 1.15;
}
.cp-gym {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin-bottom: 0.875rem;
}
.cp-bio {
    font-size: 0.9375rem;
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0;
}

/* Credentials card (right column) */
.cp-creds {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    background: var(--bg-elevated, #1a1a1a);
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    padding: 1rem 1.125rem;
}
.cp-cred {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
}
.cp-cred + .cp-cred { border-top: 1px solid var(--border-subtle); }
.cp-cred-icon {
    width: 28px;
    height: 28px;
    border-radius: 7px;
    background: rgba(96, 165, 250, 0.1);
    color: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.cp-cred-icon svg { width: 15px; height: 15px; }
.cp-cred-text { font-size: 0.8125rem; line-height: 1.35; }
.cp-cred-text .label {
    color: var(--text-tertiary, #9ca3af);
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.cp-cred-text .value { color: var(--text-primary); font-weight: 500; }

/* Inline edit button — hidden by default, shown for owner */
.cp-edit-btn {
    position: absolute;
    top: 0;
    right: 0;
    background: transparent;
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    padding: 0.375rem 0.75rem;
    border-radius: 8px;
    font-size: 0.75rem;
    font-weight: 500;
    cursor: pointer;
    display: none;
    align-items: center;
    gap: 0.375rem;
    font-family: inherit;
}
.cp-edit-btn:hover { border-color: var(--accent); color: var(--accent); }
.cp-edit-btn svg { width: 12px; height: 12px; }
[data-cp-owner="true"] .cp-edit-btn { display: inline-flex; }

/* ---- Section heads ---- */
.cp-section-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin: 2.5rem 0 1.25rem;
}
.cp-section-head:first-of-type { margin-top: 0; }
.cp-section-head h2 {
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0;
}
.cp-section-head .sub {
    font-size: 0.8125rem;
    color: var(--text-tertiary, #9ca3af);
}

/* ---- Socials row ---- */
.cp-socials {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.cp-social {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    background: var(--bg-elevated, #1a1a1a);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    font-size: 0.8125rem;
    color: var(--text-secondary);
    text-decoration: none;
    transition: border-color 0.15s ease, color 0.15s ease;
}
.cp-social:hover {
    border-color: var(--accent);
    color: var(--text-primary);
}
.cp-social svg { width: 15px; height: 15px; color: var(--accent); }

/* ---- Specialties chips ---- */
.cp-chips {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.cp-chip {
    font-size: 0.75rem;
    padding: 0.375rem 0.75rem;
    background: rgba(96, 165, 250, 0.08);
    color: var(--accent-text);  /* lighter variant — accent-as-bg is too dark for text on the tinted-blue chip bg (#1f252e blended); use the link/text variant instead. WCAG AA. */
    border: 1px solid rgba(96, 165, 250, 0.2);
    border-radius: 999px;
}

/* ---- Grid + cards (shared games + courses) ---- */
.cp-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
}
@media (max-width: 820px) {
    .cp-grid { grid-template-columns: 1fr; }
}

.cp-card {
    background: var(--bg-elevated, #1a1a1a);
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    padding: 1.375rem;
    cursor: pointer;
    transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    text-decoration: none;
    color: inherit;
    min-height: 200px;
}
.cp-card:hover {
    transform: translateY(-3px);
    border-color: var(--accent);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.3);
}
.cp-card-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: rgba(96, 165, 250, 0.1);
    color: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
}
.cp-card-icon svg { width: 20px; height: 20px; }

.cp-card-body { flex: 1; }
.cp-card-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 0.25rem;
    line-height: 1.3;
}
.cp-card-sub {
    font-size: 0.8125rem;
    color: var(--text-tertiary, #9ca3af);
    line-height: 1.45;
}
.cp-card-footer {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding-top: 0.875rem;
    border-top: 1px solid var(--border-subtle);
}
.cp-card-price {
    font-size: 1.1875rem;
    font-weight: 700;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}
.cp-card-meta {
    font-size: 0.75rem;
    color: var(--text-tertiary, #9ca3af);
}
.cp-card-cta {
    font-size: 0.8125rem;
    color: var(--accent);
    font-weight: 500;
}

/* Empty state for "no games yet" */
.cp-empty {
    padding: 2rem;
    text-align: center;
    color: var(--text-tertiary, #9ca3af);
    background: var(--bg-elevated, #1a1a1a);
    border: 1px dashed var(--border-subtle);
    border-radius: 12px;
    font-size: 0.875rem;
    line-height: 1.5;
}

/* ── Public Profile (A2) ────────────────────────────────────────────── */

.cp-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    padding: 4rem 1rem;
    color: var(--text-secondary);
}
.cp-loading-spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--border-subtle, #e4e4e7);
    border-top-color: var(--accent-primary, #3b82f6);
    border-radius: 50%;
    animation: cp-spin 0.7s linear infinite;
}
@keyframes cp-spin { to { transform: rotate(360deg); } }

.cp-error {
    text-align: center;
    padding: 4rem 1rem;
    color: var(--text-secondary);
}

.cp-subscribe-banner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1.5rem;
    background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
    border: 1px solid #bfdbfe;
    padding: 1.25rem 1.5rem;
    border-radius: 12px;
    margin: 1.5rem 0;
    flex-wrap: wrap;
}
.cp-subscribe-banner__info h2 {
    margin: 0 0 0.25rem;
    font-size: 1.125rem;
    color: #1e3a8a;
}
.cp-subscribe-banner__info p {
    margin: 0;
    color: #475569;
    font-size: 0.875rem;
}
.cp-subscribe-banner__cta {
    display: flex;
    align-items: center;
    gap: 1rem;
}
.cp-subscribe-banner__price {
    font-size: 1.5rem;
    font-weight: 700;
    color: #1e3a8a;
}
.cp-subscribe-btn {
    background: #2563eb;
    color: white;
    border: 0;
    padding: 0.625rem 1.5rem;
    border-radius: 6px;
    font-size: 0.9375rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s;
}
.cp-subscribe-btn:hover { background: #1d4ed8; }

.cp-subscribed-banner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: #dcfce7;
    color: #166534;
    padding: 0.75rem 1.25rem;
    border-radius: 8px;
    margin: 1.5rem 0;
    font-weight: 500;
}
.cp-subscribed-banner svg { width: 18px; height: 18px; }

/* Public video cards */
.cp-video-card-public {
    display: flex;
    flex-direction: column;
    background: var(--surface-primary, #fff);
    border: 1px solid var(--border-subtle, #e4e4e7);
    border-radius: 10px;
    overflow: hidden;
    cursor: pointer;
    transition: border-color 0.15s, transform 0.15s;
}
.cp-video-card-public:hover {
    border-color: var(--accent-primary, #3b82f6);
    transform: translateY(-2px);
}
.cp-video-thumb-wrap {
    position: relative;
    aspect-ratio: 16 / 9;
}
.cp-video-thumb-public {
    width: 100%;
    height: 100%;
    background-size: cover;
    background-position: center;
    background-color: #18181b;
}
.cp-video-thumb-public--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
}
.cp-video-lock-badge,
.cp-video-play-badge {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.4);
    transition: background 0.15s;
}
.cp-video-card-public:hover .cp-video-lock-badge,
.cp-video-card-public:hover .cp-video-play-badge {
    background: rgba(0, 0, 0, 0.6);
}
.cp-video-lock-badge svg,
.cp-video-play-badge svg {
    width: 36px;
    height: 36px;
    color: white;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
}
.cp-video-meta-public {
    padding: 0.75rem 0.875rem 0.875rem;
}
.cp-video-title-public {
    margin: 0 0 0.25rem;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--text-primary, #1a1a1a);
    word-break: break-word;
}
.cp-video-duration-public {
    font-size: 0.75rem;
    color: var(--text-tertiary, #71717a);
    font-variant-numeric: tabular-nums;
}

.cp-empty-videos {
    text-align: center;
    padding: 2rem;
    color: var(--text-secondary);
    background: var(--surface-subtle, #f4f4f5);
    border-radius: 8px;
}

/* Player + paywall modal overlays */
.cp-player-overlay,
.cp-paywall-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.cp-player-modal {
    background: #000;
    border-radius: 8px;
    overflow: hidden;
    max-width: 1024px;
    width: 100%;
    position: relative;
}
.cp-player-frame {
    aspect-ratio: 16 / 9;
    background: #000;
}
.cp-player-meta {
    padding: 0.75rem 1rem;
    color: #f4f4f5;
}
.cp-player-meta h3 {
    margin: 0;
    font-size: 1rem;
}
.cp-player-close {
    position: absolute;
    top: 8px;
    right: 8px;
    background: rgba(0, 0, 0, 0.5);
    color: white;
    border: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    z-index: 10;
}

.cp-paywall-modal {
    background: var(--surface-primary, #fff);
    border-radius: 12px;
    padding: 2rem;
    max-width: 420px;
    width: 100%;
    text-align: center;
    position: relative;
}
.cp-paywall-modal h2 {
    margin: 0 0 0.5rem;
    color: var(--text-primary, #1a1a1a);
}
.cp-paywall-modal p {
    margin: 0 0 1.5rem;
    color: var(--text-secondary);
}
.cp-paywall-modal .cp-player-close {
    background: transparent;
    color: var(--text-secondary);
}

/* ============================================================================
   Public coach profile — Package card (one-time purchase)
   Renders above the existing subscription banner. Hero CTA for the buyer
   flow on /c/{slug} pages.
   ============================================================================ */

.cp-package-card {
    background: linear-gradient(135deg, var(--accent, #3b82f6), #6366f1);
    color: white;
    border-radius: 14px;
    padding: 1.4rem 1.5rem;
    margin: 1.25rem 0;
    box-shadow: 0 10px 30px rgba(59, 130, 246, 0.18);
}
.cp-package-pill {
    display: inline-block;
    background: rgba(255, 255, 255, 0.2);
    color: white;
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 4px 10px;
    border-radius: 999px;
    margin-bottom: 0.6rem;
}
.cp-package-title {
    margin: 0 0 0.2rem;
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.2;
}
.cp-package-subtitle {
    margin: 0 0 0.75rem;
    opacity: 0.85;
    font-size: 0.95rem;
    font-weight: 500;
}
.cp-package-desc {
    margin: 0 0 1rem;
    font-size: 0.875rem;
    line-height: 1.5;
    opacity: 0.92;
}
.cp-package-meta {
    display: flex;
    gap: 1.4rem;
    flex-wrap: wrap;
    margin-bottom: 1.1rem;
    font-size: 0.8125rem;
    opacity: 0.92;
}
.cp-package-meta-item strong { font-weight: 700; font-size: 1rem; }
.cp-package-buy {
    display: block;
    width: 100%;
    padding: 0.85rem 1rem;
    background: white;
    color: var(--accent, #3b82f6);
    border: none;
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.9375rem;
    font-weight: 700;
    cursor: pointer;
    transition: transform 0.05s ease, box-shadow 0.15s ease;
}
.cp-package-buy:hover {
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
}
.cp-package-buy:active { transform: translateY(1px); }
.cp-package-fineprint {
    margin: 0.7rem 0 0;
    font-size: 0.6875rem;
    opacity: 0.7;
    text-align: center;
}


/* ============================================================================
   PRODUCT PAGE LAYOUT — V2
   /c/{slug} as a real course landing page (BJJ Fanatics-style).
   Activates on .cp-content--product. Existing .cp-hero / .cp-package-card
   styles above are kept for backwards-compat but are overridden when the
   V2 markup is in use.
   ============================================================================ */

/* Per-coach brand vars — frontend reads coach.brand and writes these to
   :root at fetch time. Defaults are GrappleU blue (matches the rest of
   the app when no coach customization). */
:root {
    --coach-accent: #3b82f6;
    --coach-on-accent: #ffffff;
}

/* Hide the dashboard sidebar/topbar on the public profile page —
   marketing pages shouldn't carry the authenticated app's chrome.
   Scoped to .coach-profile-public-shell so the authenticated editor
   (coach-profile-edit.html), which shares .coach-profile-page, keeps
   its sidebar and topbar. */
body.coach-profile-public-shell .ds-sidebar,
body.coach-profile-public-shell .ds-sidebar-backdrop,
body.coach-profile-public-shell .ds-topbar {
    display: none !important;
}
body.coach-profile-public-shell .ds-content {
    margin-left: 0 !important;
}
body.coach-profile-public-shell .ds-main {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 4rem;
}

.cp-content--product {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

/* Brand strip — coach's gym logo × GrapplingU at the very top.
   Reads as a co-branded course header. */
.cp-brand-strip {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 1.25rem;
    padding: 1.5rem 0 0.75rem;
}
.cp-brand-strip__logo {
    width: 96px;
    height: 96px;
    object-fit: contain;
    border-radius: 50%;
    flex-shrink: 0;
}
.cp-brand-strip__logo--gu {
    /* GrapplingU logo is its own circular badge — no extra framing.
       Bump up slightly so it matches the visual weight of the coach's
       gym logo (which usually has perimeter text/imagery filling more
       of the canvas). */
    width: 112px;
    height: 112px;
}
@media (max-width: 640px) {
    /* Scale logos down on mobile so they don't dominate above-the-fold. */
    .cp-brand-strip__logo { width: 72px; height: 72px; }
    .cp-brand-strip__logo--gu { width: 84px; height: 84px; }
}
.cp-brand-strip__sep {
    color: var(--text-tertiary, #9ca3af);
    font-size: 1.25rem;
    font-weight: 300;
    line-height: 1;
    user-select: none;
}

/* HERO — split layout: left = title + media; right rail = buy card */
.cp-product-hero {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(280px, 360px);
    gap: 2rem;
    align-items: start;
}
@media (max-width: 900px) {
    .cp-product-hero { grid-template-columns: 1fr; gap: 1.5rem; }
}

.cp-product-hero__main { min-width: 0; }

.cp-product-hero__badge {
    display: inline-block;
    background: var(--coach-accent);
    color: var(--coach-on-accent);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 0.3rem 0.6rem;
    border-radius: 4px;
    margin-bottom: 0.875rem;
}

.cp-product-hero__title {
    font-size: clamp(1.625rem, 3.5vw, 2.5rem);
    font-weight: 800;
    line-height: 1.15;
    margin: 0 0 0.6rem;
    color: var(--text-primary);
}

.cp-product-hero__pitch {
    font-size: 1rem;
    color: var(--text-secondary);
    line-height: 1.5;
    margin: 0 0 1.25rem;
    max-width: 56ch;
}

.cp-product-hero__media {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: 12px;
    background: var(--bg-elevated, #14141a);
    border: 1px solid var(--border-subtle);
    overflow: hidden;
}
/* When the media is an iframe (Bunny embed), don't apply hover/cursor
   tricks — the iframe captures the pointer and runs its own play UI.
   The thumbnail-only fallback (no bunny_guid) keeps a plain border. */
.cp-product-hero__media--video {
    cursor: default;
}
.cp-product-hero__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.cp-product-hero__media-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.cp-product-hero__media-play svg {
    width: 64px;
    height: 64px;
    fill: rgba(255, 255, 255, 0.95);
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
}
.cp-product-hero__media-tag {
    position: absolute;
    bottom: 0.625rem;
    left: 0.625rem;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.25rem 0.5rem;
    border-radius: 3px;
}
.cp-product-hero__media--placeholder {
    cursor: default;
    background: linear-gradient(135deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01));
}

/* Lite-embed pattern — show a click-to-play poster instead of auto-loading
   the Bunny iframe. Eliminates the third-party DNS error from Bunny's player
   placeholder fetch and saves ~3s of LCP. The iframe is injected on click. */
.cp-product-hero__media--lite {
    cursor: pointer;
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.18), rgba(0, 0, 0, 0.4)),
                radial-gradient(ellipse at center, rgba(255, 255, 255, 0.08), transparent 60%);
}
.cp-product-hero__play-btn {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    width: 100%;
    height: 100%;
    border: 0;
    background: transparent;
    color: rgba(255, 255, 255, 0.95);
    cursor: pointer;
    transition: background 0.2s ease;
}
.cp-product-hero__play-btn:hover,
.cp-product-hero__play-btn:focus-visible {
    background: rgba(0, 0, 0, 0.18);
    outline: none;
}
.cp-product-hero__play-btn:focus-visible {
    box-shadow: inset 0 0 0 3px var(--accent, #3b82f6);
}
.cp-product-hero__play-btn svg {
    width: 64px;
    height: 64px;
    fill: rgba(255, 255, 255, 0.95);
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
    flex-shrink: 0;
}
.cp-product-hero__play-label {
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* BUY CARD — right rail. Static (not sticky) — coach feedback was that
   following-the-scroll felt distracting on the curriculum read-through.
   Mobile sticky bottom CTA already keeps a buy CTA in view on small
   viewports, so dropping the desktop sticky doesn't lose conversions. */
.cp-product-buy-card {
    background: var(--bg-elevated, #14141a);
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    padding: 1.5rem 1.25rem;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
    /* Reserve space for renderProductBuyCard()'s injected content (CTA, bullets,
       trust strip). Without min-height this aside is 0px until JS paints, then
       jumps to full height — single biggest CLS source on this page. The
       reservation is sized to the FREE-JOIN card (the common storefront — every
       partner-funnel coach + Greg's reverse trial), which leads with the "Join
       Group" CTA (the "Free" price headline is suppressed on these — see
       renderProductBuyCard's priceRowHTML) and measures ~336px of content. A
       directly-paid card (price headline + more rows) has more content than this
       floor and simply grows to fit — a min-height never clips, it only pads when
       content is shorter. So: a floor that's pixel-tight for the high-traffic free
       storefronts and content-driven for the rarer paid ones. (History: was 480px,
       calibrated for a paid card, which overshot the free variant by ~110px of
       visible dead space; then 380px when the free card still showed the "Free"
       headline; now 335px with that headline removed.) */
    min-height: 335px;
    /* Vertically center the buy card next to the (often much taller) hero video.
       A short free-join card (Ellee ~350px) beside a tall 16:9 video was
       top-aligned by the grid's `align-items: start`, so the "Join Group" CTA
       floated near the top with a large empty column beneath it ("the join group
       is so far up"). Centering balances it in the column. Safe for taller cards
       (Greg ~575px): when the card is the tallest grid item it defines the row
       height and align-self is a no-op; on the mobile single-column layout it is
       also a no-op. */
    align-self: center;
}

.cp-buy__price-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}
.cp-buy__price {
    font-size: 2rem;
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1;
}
.cp-buy__price-anchor {
    font-size: 1rem;
    color: var(--text-tertiary);
    text-decoration: line-through;
    font-weight: 600;
}
.cp-buy__price-note {
    font-size: 0.75rem;
    color: var(--text-tertiary);
    margin-bottom: 1rem;
}

/* ──────────────────────────────────────────────────────────────────────
 * "More from this coach" tile grid — renders below the primary buy card.
 *
 * Uses flexbox (not CSS Grid) so the last row auto-centers when its tile
 * count is less than the per-row capacity. For 5 tiles in a 3-col layout:
 *   row 1: 3 tiles
 *   row 2: 2 tiles, centered
 * CSS Grid would left-align the partial row instead.
 * ────────────────────────────────────────────────────────────────────── */
.cp-other-packages {
    margin-top: 2.5rem;
    margin-bottom: 2rem;
}
.cp-other-packages__grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1rem;
}
.cp-other-tile {
    /* fixed-width tiles so flex wrapping is predictable across breakpoints.
       3-col @ ≥960px (3 × ~280 + 2 gaps = 880px fits 1100px max-width),
       2-col @ 640-960px, 1-col below. */
    flex: 0 1 280px;
    min-width: 240px;
    max-width: 320px;
    display: flex;
    flex-direction: column;
    text-align: left;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-radius: 12px;
    padding: 0;  /* image edge-bleeds to the rounded corners; body has its own padding */
    overflow: hidden;
    color: inherit;
    cursor: pointer;
    transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
    font: inherit;
}
.cp-other-tile:hover {
    transform: translateY(-2px);
    border-color: var(--coach-accent);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
}
.cp-other-tile__thumb {
    width: 100%;
    aspect-ratio: 16 / 9;
    background: #0a0a0a;
    overflow: hidden;
}
.cp-other-tile__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.cp-other-tile__body {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    padding: 1rem 1.125rem 1.125rem;
}
.cp-other-tile__title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.3;
    margin: 0 0 0.375rem;
}
.cp-other-tile__pitch {
    font-size: 0.875rem;
    color: var(--text-secondary);
    line-height: 1.45;
    margin: 0 0 1rem;
    flex-grow: 1;
}
.cp-other-tile__footer {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
}
.cp-other-tile__price {
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--text-primary);
}
.cp-other-tile__cta {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--coach-accent);
}

/* ── Pool C drilldown ───────────────────────────────────────────────────
   When the viewer is a signed-in free-tier Greg coach who picked one
   instructional, the "Greg's Game Packages" section swaps from the
   default 5-tile grid to a focused layout: ONE featured tile for their
   owned instructional + a small list of the other 4 as compact upsell
   tiles. Anon viewers + full-access coaches see the unchanged 5-tile
   grid (see coach-profile-public.js renderPoolCDrilldown for the swap
   trigger). */
/* Pool C drilldown — restructured 2026-05-14 to follow NN/g + Material
   Design 3 + consumer-media (Netflix/Spotify/Coursera/Audible) patterns
   for "you own this, here are the others." Two distinct components:
     1. Horizontal "Your Library" banner for the owned item — "resume"
        intent, different component from the upsell grid below.
     2. Uniform 4-up CSS Grid for the remaining 4 instructionals — same
        cp-other-tile component as the default 5-tile grid, so the
        upsell row is a clean comparison grid (homogeneous items in a
        uniform layout, per NN/g).
   Earlier version centered a single featured tile + flex-wrapped 4
   small tiles in a narrow column — produced mixed sizes, inconsistent
   title truncation, and big empty space on wide viewports. */
.cp-pool-c {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.cp-pool-c__section-header {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-top: 0.25rem;
}
/* Horizontal "resume" banner for the owned instructional. Compact (~80px
   tall) so the upsell grid below stays the visual anchor. Left-border
   green stripe + small OWNED pill signal "in your library" without
   inflating the card or failing WCAG contrast (filled green backgrounds
   on dark UIs are unreadable). */
.cp-pool-c__owned-banner {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.875rem 1rem;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-left: 4px solid rgb(34, 197, 94);
    border-radius: 10px;
    text-decoration: none;
    color: inherit;
    transition: transform 0.15s ease, border-color 0.15s ease;
}
.cp-pool-c__owned-banner:hover {
    transform: translateY(-1px);
    border-color: var(--coach-accent, rgba(96, 165, 250, 0.5));
    border-left-color: rgb(34, 197, 94);
}
.cp-pool-c__owned-thumb {
    flex: 0 0 96px;
    height: 56px;
    border-radius: 6px;
    overflow: hidden;
    background: #0a0a0a;
}
.cp-pool-c__owned-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.cp-pool-c__owned-thumb--empty {
    display: block;
}
.cp-pool-c__owned-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}
.cp-pool-c__owned-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cp-pool-c__owned-pitch {
    font-size: 0.8125rem;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cp-pool-c__owned-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.cp-pool-c-owned-badge {
    display: inline-block;
    padding: 0.18rem 0.55rem;
    background: rgba(34, 197, 94, 0.18);
    color: rgb(34, 197, 94);
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
}
.cp-pool-c__owned-cta {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--coach-accent, #60a5fa);
    white-space: nowrap;
}
/* 4-up CSS Grid (not flex-wrap) so columns are equal-width and the
   inconsistent flex-basis truncation in the prior version is gone.
   At <900px collapse to 2 columns; at <600px stack to 1. */
.cp-pool-c__rest-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1rem;
    width: 100%;
}
/* Override the default cp-other-tile's flex-basis/max-width so the grid
   actually controls sizing — without this each tile would fight the
   grid track width via its own `flex: 0 1 280px; max-width: 320px`
   constraints, producing the mixed-widths we just fixed. */
.cp-pool-c__rest-grid .cp-other-tile {
    flex: none;
    min-width: 0;
    max-width: none;
    width: 100%;
}
@media (max-width: 900px) {
    .cp-pool-c__rest-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
@media (max-width: 600px) {
    .cp-pool-c__rest-grid {
        grid-template-columns: 1fr;
    }
    .cp-pool-c__owned-banner {
        flex-wrap: wrap;
    }
    .cp-pool-c__owned-actions {
        width: 100%;
        justify-content: space-between;
        padding-top: 0.5rem;
        border-top: 1px solid var(--border-card);
    }
}

/* Subscription-only member counter — sits between price-note and CTA.
   Hidden by render logic when billing_type !== "subscription" or
   subscriber_count < 50. Pattern mirrored from Skool's "X Members" line. */
.cp-buy__member-count {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin: 0.25rem 0 0.875rem;
    padding: 0.5rem 0.75rem;
    background: var(--bg-card-secondary, rgba(255, 255, 255, 0.04));
    border-radius: 6px;
    text-align: center;
}
.cp-buy__member-count strong {
    color: var(--text-primary);
    font-weight: 700;
}

.cp-buy__cta {
    width: 100%;
    background: var(--coach-accent);
    color: var(--coach-on-accent);
    border: 0;
    border-radius: 8px;
    padding: 0.875rem 1rem;
    font-size: 0.9375rem;
    font-weight: 700;
    cursor: pointer;
    transition: filter 0.15s, transform 0.1s;
    margin-bottom: 1rem;
}
.cp-buy__cta:hover { filter: brightness(1.05); }
.cp-buy__cta:active { transform: translateY(1px); }

/* Flash-proof CTA skeleton — rendered while subStatus is genuinely unknown
   (signed in, no cache, fetch still in flight). Inherits .cp-buy__cta's box
   (width/padding/border-radius/margin) so there is ZERO layout shift when
   the real CTA swaps in; only the fill + interactivity differ. Content is
   a non-breaking space (not empty) so the line-box height matches a real
   button's, and aria-hidden keeps it out of the accessibility tree (it is
   not a control — nothing to announce or focus). */
.cp-buy__cta--pending {
    background: var(--bg-elevated);
    color: transparent;
    cursor: default;
    pointer-events: none;
    animation: cpBuyCtaPendingPulse 1.4s ease-in-out infinite;
}
.cp-buy__cta--pending:hover { filter: none; }
@keyframes cpBuyCtaPendingPulse {
    0%, 100% { opacity: 0.55; }
    50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .cp-buy__cta--pending { animation: none; opacity: 0.75; }
}

.cp-buy__bullets {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.cp-buy__bullets li {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    font-size: 0.8125rem;
    color: var(--text-secondary);
    line-height: 1.4;
}
.cp-buy__bullets li::before {
    content: '✓';
    color: var(--coach-accent);
    font-weight: 700;
    flex-shrink: 0;
    margin-top: 1px;
}

.cp-buy__trust {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.875rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--border-subtle);
    font-size: 0.6875rem;
    color: var(--text-tertiary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.cp-buy__trust span {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}
.cp-buy__trust span::before {
    content: '·';
    color: var(--coach-accent);
    font-weight: 700;
}
.cp-buy__trust span:first-child::before { content: ''; }

/* CURRICULUM ACCORDION */
.cp-curriculum__list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.cp-level-row {
    background: var(--bg-elevated, #14141a);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    overflow: hidden;
    transition: border-color 0.15s;
}
.cp-level-row:hover { border-color: rgba(255, 255, 255, 0.18); }

.cp-level-row__head {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.875rem 1rem;
    cursor: pointer;
    user-select: none;
}
.cp-level-row__num {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--coach-accent);
    color: var(--coach-on-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.875rem;
}
.cp-level-row__title {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    color: var(--text-primary);
    font-size: 0.9375rem;
}
.cp-level-row__meta {
    flex-shrink: 0;
    font-size: 0.75rem;
    color: var(--text-tertiary);
}
.cp-level-row__free-pill {
    background: var(--coach-accent);
    color: var(--coach-on-accent);
    font-size: 0.625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 0.2rem 0.45rem;
    border-radius: 4px;
    flex-shrink: 0;
}
.cp-level-row__chev {
    flex-shrink: 0;
    color: var(--text-tertiary);
    transition: transform 0.15s;
}
.cp-level-row.is-open .cp-level-row__chev { transform: rotate(90deg); }

.cp-level-row__body {
    padding: 0 1rem 1rem;
    border-top: 1px solid var(--border-subtle);
    background: rgba(255, 255, 255, 0.015);
    display: none;
}
.cp-level-row.is-open .cp-level-row__body { display: block; padding-top: 0.875rem; }

.cp-level-row__desc {
    font-size: 0.875rem;
    color: var(--text-secondary);
    line-height: 1.45;
    margin: 0 0 0.875rem;
}

.cp-level-row__stages {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
.cp-level-row__stage {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 0.625rem;
    background: var(--bg-card, #1a1a1a);
    border: 1px solid var(--border-subtle);
    border-radius: 6px;
    font-size: 0.8125rem;
}
.cp-level-row__stage--locked {
    opacity: 0.62;
}
.cp-level-row__stage-num {
    color: var(--coach-accent);
    font-weight: 700;
    font-size: 0.75rem;
    min-width: 56px;
}
.cp-level-row__stage-name {
    color: var(--text-primary);
    flex: 1;
    min-width: 0;
}
.cp-level-row__stage-lock {
    color: var(--text-tertiary);
    font-size: 0.6875rem;
}

/* COACH INTRO CARD (lower on page) */
.cp-coach-intro__card {
    background: var(--bg-elevated, #14141a);
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    padding: 1.5rem;
}
.cp-coach-intro__id {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}
.cp-coach-intro__id-text { min-width: 0; }
.cp-coach-intro__id-text .cp-name { font-size: 1.25rem; font-weight: 700; margin: 0; }
.cp-coach-intro__id-text .cp-gym { color: var(--text-secondary); font-size: 0.875rem; }
.cp-coach-intro__card .cp-bio {
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0 0 1rem;
    white-space: pre-wrap;
}
.cp-coach-intro__creds,
.cp-coach-intro__specialties {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.625rem;
}
.cp-avatar.cp-avatar--small {
    width: 64px;
    height: 64px;
    flex-shrink: 0;
}

/* STICKY MOBILE CTA */
.cp-sticky-cta {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--bg-card, #1a1a1a);
    border-top: 1px solid var(--border-subtle);
    padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
    z-index: 100;
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.35);
}
.cp-sticky-cta__btn {
    width: 100%;
    background: var(--coach-accent);
    color: var(--coach-on-accent);
    border: 0;
    border-radius: 8px;
    padding: 0.875rem;
    font-size: 0.9375rem;
    font-weight: 700;
    cursor: pointer;
}
@media (min-width: 901px) {
    .cp-sticky-cta { display: none !important; }
}

/* FOOTER share strip */
.cp-footer-strip {
    margin-top: 2rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border-subtle);
    display: flex;
    justify-content: center;
}

/* Override the v1 gradient buy card if it ever renders again. The .cp-package-card
   styles above are kept for legacy compat but never visible on the V2 layout. */
.cp-content--product .cp-package-card {
    display: none;
}

/* ─────────────────────────────────────────────────────────────────────────
   UNIT 3 — Public storefront chrome.

   Replaces the dashboard ds-sidebar/ds-topbar that this page used to inherit.
   Slim public top bar + owner banner + marketing footer. Two shells, one
   page — auth state only swaps the topbar's right-side CTA, not the layout.
   ───────────────────────────────────────────────────────────────────────── */

/* Reset the body padding the dashboard shell used to apply via .dashboard-shell */
body.coach-profile-public-shell {
    background: var(--bg-base);
    margin: 0;
    /* Fail-safe: if the page is ever framed inside something that expects the
       dashboard CSS grid, force a clean column flow. */
    display: block;
}

/* ── Top bar ─────────────────────────────────────────────────────────── */

.cp-public-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.875rem 1.25rem;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--bg-base);
    position: sticky;
    top: 0;
    z-index: 50;
    /* Hairline shadow so the bar reads as "above" content on light backgrounds. */
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04);
}

.cp-public-topbar__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    font-weight: 700;
    font-size: 1.0625rem;
    text-decoration: none;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}
.cp-public-topbar__brand img {
    width: 32px;
    height: 32px;
    border-radius: 8px;
}
.cp-public-topbar__brand:hover {
    color: var(--accent);
}

.cp-public-topbar__right {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* Signed-in coach's "← Back to dashboard" link. Inherits flex alignment
   from the parent topbar row. Ghost styling: subtle text color, no
   underline, small padding so it sits comfortably next to the avatar
   dropdown without dominating. Hidden by default — JS reveals it when
   the viewer is authenticated. */
.cp-public-topbar__back {
    display: inline-flex;
    align-items: center;
    padding: 0.375rem 0.75rem;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text-secondary, #b0b0b0);
    text-decoration: none;
    border-radius: 8px;
    transition: color 0.15s ease, background 0.15s ease;
}
.cp-public-topbar__back:hover {
    color: var(--text-primary, #fff);
    background: rgba(255, 255, 255, 0.06);
}
.cp-public-topbar__back:focus-visible {
    outline: 2px solid var(--accent, #3b82f6);
    outline-offset: 2px;
}
/* Hide on very small viewports — too crowded next to the avatar pill. */
@media (max-width: 480px) {
    .cp-public-topbar__back { display: none; }
}

/* "Sign in" — ghost link, secondary visual weight. Mirrors the landing
   page's .btn-secondary in grapple-landing-enhanced.html. */
.cp-public-topbar__signin {
    display: inline-flex;
    align-items: center;
    padding: 0.5rem 1rem;
    border-radius: 999px;
    background: transparent;
    color: var(--text-secondary, #b0b0b0);
    text-decoration: none;
    font-weight: 500;
    font-size: 0.9375rem;
    transition: color 0.15s ease, background 0.15s ease;
}
.cp-public-topbar__signin:hover {
    color: var(--text-primary, #fff);
    background: rgba(255, 255, 255, 0.06);
}
.cp-public-topbar__signin:focus-visible {
    outline: 2px solid var(--accent, #3b82f6);
    outline-offset: 2px;
}

/* "Get Started" + "Dashboard" — primary accent pill. Same shape, swapped
   in/out by JS based on auth state. Matches landing-page .btn-primary. */
.cp-public-topbar__signup,
.cp-public-topbar__dashboard {
    display: inline-flex;
    align-items: center;
    padding: 0.5rem 1rem;
    border-radius: 999px;
    background: var(--accent, #3b82f6);
    color: #fff;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9375rem;
    transition: background 120ms ease, transform 120ms ease;
}
.cp-public-topbar__signup:hover,
.cp-public-topbar__dashboard:hover {
    background: var(--accent-hover, #2563eb);
    transform: translateY(-1px);
}
.cp-public-topbar__signup:focus-visible,
.cp-public-topbar__dashboard:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ── Owner banner ────────────────────────────────────────────────────── */

.cp-owner-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.75rem 1.25rem;
    background: #fef3c7;             /* warm yellow strip */
    color: #78350f;
    border-bottom: 1px solid #fde68a;
    font-size: 0.9375rem;
    font-weight: 500;
}
.cp-owner-banner__action {
    color: #78350f;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.cp-owner-banner__action:hover { color: #451a03; }

/* Hide the buy-card buttons that don't apply when the owner views their
   own page. Done via the data-attr on <main> instead of inline display
   so renderProductBuyCard can keep its DOM shape consistent. */
main.cp-public-main[data-cp-owner="true"] .cp-buy__cta:not(.cp-buy__cta--owner) {
    display: none;
}
main.cp-public-main[data-cp-owner="true"] .cp-buy__secondary-link {
    display: none;
}

/* Owner / owned CTA visual states */
.cp-buy__cta--owner {
    background: #fef3c7;
    color: #78350f;
    border: 1px solid #fde68a;
    text-decoration: none;
    display: block;
    text-align: center;
}
.cp-buy__cta--owner:hover {
    background: #fde68a;
    color: #451a03;
}

.cp-buy__cta--owned {
    background: #dcfce7;
    color: #14532d;
    border: 1px solid #bbf7d0;
    text-decoration: none;
    display: block;
    text-align: center;
}
.cp-buy__cta--owned:hover {
    background: #bbf7d0;
}

/* Community-member CTA ("Open the classroom →") — an <a>, not a <button>,
   so it needs the same anchor-as-button treatment as --owner/--owned
   (display:block + centered text + no underline). Keeps the base
   .cp-buy__cta coach-accent background/color since this is a real primary
   action (unlike the muted owner/owned "you're done" states). */
.cp-buy__cta--member {
    text-decoration: none;
    display: block;
    text-align: center;
}

.cp-buy__secondary {
    margin-top: 0.5rem;
    font-size: 0.8125rem;
    color: var(--text-secondary);
    text-align: center;
}
.cp-buy__secondary--owner { color: #92400e; }
.cp-buy__secondary--owned { color: #166534; }

.cp-buy__secondary-link {
    display: block;
    margin-top: 0.5rem;
    font-size: 0.8125rem;
    color: var(--text-secondary);
    text-align: center;
    text-decoration: none;
}
.cp-buy__secondary-link:hover {
    color: var(--accent);
    text-decoration: underline;
}
/* Free-join front door (ad funnel): the cardless "Join Free" is the primary
   accent CTA (inherits .cp-buy__cta); the paid "Or subscribe — $X" is a
   button rendered as a centered text link below it. */
.cp-buy__secondary-link--btn {
    width: 100%;
    background: transparent;
    border: 0;
    padding: 0;
    cursor: pointer;
    font: inherit;
}
.cp-buy__secondary-link--btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ── Free-community 3-tier ladder (Greg ad-funnel) ──────────────────────
   "Join Free" is the primary accent CTA above; these two paid tier rows
   (Follow Along $37 / Inner Circle $200) sit below it as full-width
   selectable cards. */
.cp-buy__tiers {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.75rem;
    /* Breathing room before the "what's included" bullet list — without it
       the last tier card crowds flush against the first checkmark. */
    margin-bottom: 1.5rem;
}
.cp-buy__tier {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    text-align: left;
    background: var(--bg-card-secondary, rgba(255, 255, 255, 0.04));
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    padding: 0.75rem 0.875rem;
    cursor: pointer;
    font: inherit;
    color: var(--text-primary);
    transition: border-color 0.15s, background 0.15s;
}
.cp-buy__tier:hover {
    border-color: var(--coach-accent);
    background: var(--bg-card-secondary, rgba(255, 255, 255, 0.07));
}
.cp-buy__tier:focus-visible {
    outline: 2px solid var(--coach-accent);
    outline-offset: 2px;
}
/* Inner Circle is the top rung — give it a subtle accent border to read
   as the premium option without competing with the primary Join Free CTA. */
.cp-buy__tier--inner {
    border-color: color-mix(in srgb, var(--coach-accent) 45%, transparent);
}
.cp-buy__tier-info {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}
.cp-buy__tier-name {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--text-primary);
}
.cp-buy__tier-price {
    font-size: 0.75rem;
    color: var(--text-secondary);
}
.cp-buy__tier-cta {
    flex-shrink: 0;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--coach-accent);
}

/* ── Founding-member link (small, de-emphasized, under the Join Group CTA) ── */
.cp-buy__founding {
    margin-top: 0.75rem;
    /* Clear separation from the feature bullets below — the founding-migrate
       link is a sub-action of the CTA, not part of the feature list, so it needs
       a visible gap before the "N courses · N lessons" bullets (was flush). */
    margin-bottom: 1rem;
    text-align: center;
}
.cp-buy__founding-link {
    background: none;
    border: 0;
    padding: 0.25rem 0.5rem;
    font: inherit;
    font-size: 0.8125rem;
    color: var(--text-secondary, #94a3b8);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
    border-radius: 6px;
}
.cp-buy__founding-link:hover {
    color: var(--coach-accent);
}
.cp-buy__founding-link:focus-visible {
    outline: 2px solid var(--coach-accent);
    outline-offset: 2px;
}

/* ── Free-community hero copy (Greg storefront only; hidden elsewhere) ── */
.cp-product-hero__lead {
    margin: 0 0 0.5rem;
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--coach-accent);
}
.cp-product-hero__pain {
    margin: 0.75rem 0 0;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--text-secondary);
}
.cp-product-hero__trust {
    margin: 0.75rem 0 0;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--text-tertiary);
}

/* ── Main content reset (was .ds-main) ───────────────────────────────── */

.cp-public-main {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 4rem;
}

/* ── Public footer ────────────────────────────────────────────────────── */

.cp-public-footer {
    border-top: 1px solid var(--border-subtle);
    padding: 3rem 1.25rem 2rem;
    background: var(--bg-base);
    color: var(--text-secondary);
}
.cp-public-footer__row {
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1.5rem;
}
.cp-public-footer__row--links {
    justify-content: space-between;
    margin-bottom: 1.5rem;
}
.cp-public-footer__row--legal {
    justify-content: center;
    border-top: 1px solid var(--border-subtle);
    padding-top: 1.5rem;
    font-size: 0.8125rem;
    color: var(--text-tertiary);
}
.cp-public-footer__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--text-primary);
    text-decoration: none;
    font-weight: 600;
}
.cp-public-footer__brand img {
    width: 28px;
    height: 28px;
    border-radius: 6px;
}
.cp-public-footer__links {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
}
.cp-public-footer__links a {
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.875rem;
}
.cp-public-footer__links a:hover {
    color: var(--accent);
    text-decoration: underline;
}

/* Profile dropdown — re-used markup from dashboard-shell, but the page no
   longer loads dashboard-shell.css. Inline the bare minimum so the menu
   actually renders + opens. */
.cp-public-topbar .profile-dropdown {
    position: relative;
}
.cp-public-topbar .profile-btn {
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    border-radius: 999px;
    width: 36px;
    height: 36px;
    overflow: hidden;
}
.cp-public-topbar .profile-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.cp-public-topbar .profile-avatar {
    width: 36px;
    height: 36px;
    border-radius: 999px;
    background-size: cover;
    background-position: center;
    background-color: var(--bg-elevated, #1f2937);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.875rem;
}
.cp-public-topbar .profile-menu {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    min-width: 200px;
    background: var(--bg-elevated, #fff);
    border: 1px solid var(--border-subtle);
    border-radius: 0.5rem;
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.12);
    padding: 0.375rem;
    display: none;
    z-index: 60;
}
.cp-public-topbar .profile-menu.show { display: block; }
.cp-public-topbar .profile-menu-item {
    display: block;
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 0;
    background: none;
    border-radius: 0.375rem;
    color: var(--text-primary);
    text-decoration: none;
    text-align: left;
    font-size: 0.9375rem;
    cursor: pointer;
}
.cp-public-topbar .profile-menu-item:hover {
    background: var(--bg-hover, rgba(0,0,0,0.04));
}
.cp-public-topbar .profile-menu-item--signout { color: #b91c1c; }
.cp-public-topbar .profile-menu-divider {
    height: 1px;
    background: var(--border-subtle);
    margin: 0.375rem 0;
}

/* Tighter top bar on small screens. */
@media (max-width: 480px) {
    .cp-public-topbar { padding: 0.625rem 0.875rem; }
    .cp-public-topbar__brand span { display: none; }
    .cp-public-footer__row--links {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* ============================================================================
   CLS reservations (Apr 2026)
   These sections are JS-populated AFTER initial paint:
     - .cp-curriculum   (renderCurriculum)
     - .cp-coach-intro  (renderHero)
     - .cp-grid         (renderVideos)
   Without reservations, each grows from 0px → final height when JS injects
   content, shifting everything below. Was responsible for CLS 0.909 on this
   page. Pattern: web.dev "Optimize CLS" — content-visibility:auto skips
   off-screen render work AND reserves space via contain-intrinsic-size.
   See tests/mobile-audit/PLAN.md for context.
   ============================================================================ */

.cp-curriculum {
    /* Min-height while empty so the section doesn't collapse to 0 between
       initial paint and JS render. content-visibility:auto skips off-screen
       layout entirely on first paint, since this is below the fold. */
    min-height: 200px;
    content-visibility: auto;
    contain-intrinsic-size: auto 600px;
}

.cp-coach-intro {
    content-visibility: auto;
    contain-intrinsic-size: auto 320px;
}

/* The video grid only gets populated when the coach has individual videos
   (separate from packages). Even when empty, browser-allocated space matches
   typical 3-card row height. */
.cp-grid {
    content-visibility: auto;
    contain-intrinsic-size: auto 400px;
}

/* ─── Tier-1 section accordion (Dillon's pack — multi-game sections) ───
   Scoped to body.coach-profile-page so these rules don't bleed onto the
   coach-planner page after a SPA round-trip. The planner has its own
   .cp-section-card styles in coach-planner-library.css and EXPLICITLY
   forbids `overflow: hidden` (it collapses the section body to 0px on
   expand — see the warning at coach-planner-library.css:1281). nav-spa
   never unloads stylesheets, so without this scope the editor's
   `overflow: hidden` cascades onto the planner's section cards and hides
   every game inside an expanded section. */
body.coach-profile-page .cp-section-card {
    background: var(--surface-1, rgba(255, 255, 255, 0.02));
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    margin: 0 0 0.75rem;
    overflow: hidden;
    transition: border-color 0.15s;
}
body.coach-profile-page .cp-section-card:hover { border-color: rgba(255, 255, 255, 0.18); }
body.coach-profile-page .cp-section-card.is-open { border-color: var(--coach-accent, rgba(96, 165, 250, 0.4)); }

body.coach-profile-page .cp-section-card__head {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    width: 100%;
    padding: 1rem 1.125rem;
    background: transparent;
    border: 0;
    color: var(--text-primary, #fff);
    text-align: left;
    cursor: pointer;
    font: inherit;
    /* WCAG 2.5.8 — 44px minimum target on touch */
    min-height: 44px;
}
body.coach-profile-page .cp-section-card__head:focus-visible {
    outline: 2px solid var(--coach-accent, #60a5fa);
    outline-offset: -2px;
}

body.coach-profile-page .cp-section-card__num {
    flex: 0 0 auto;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-tertiary, rgba(255, 255, 255, 0.55));
    font-weight: 600;
    padding: 0.25rem 0.6rem;
    background: rgba(255, 255, 255, 0.06);
    border-radius: 999px;
}

body.coach-profile-page .cp-section-card__title {
    flex: 1 1 auto;
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.2;
}

body.coach-profile-page .cp-section-card__count {
    flex: 0 0 auto;
    font-size: 0.8125rem;
    color: var(--text-secondary, rgba(255, 255, 255, 0.65));
}

body.coach-profile-page .cp-section-card__chev {
    flex: 0 0 auto;
    color: var(--text-tertiary, rgba(255, 255, 255, 0.55));
    transition: transform 0.18s ease;
}
body.coach-profile-page .cp-section-card.is-open .cp-section-card__chev { transform: rotate(90deg); }

/* Rename affordance — sibling of the head button. Drives the single-source
   section-title edit (coach_packages.sections[].name → propagates everywhere). */
body.coach-profile-page .cp-section-card__rename {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.65rem 0.5rem 2.4rem;   /* indent under the head's num chip */
}
body.coach-profile-page .cp-section-rename-btn {
    background: none;
    border: none;
    color: var(--text-tertiary, rgba(255, 255, 255, 0.55));
    font-size: 0.82rem;
    cursor: pointer;
    padding: 0.15rem 0.3rem;
    border-radius: 4px;
}
body.coach-profile-page .cp-section-rename-btn:hover { color: var(--text-secondary, rgba(255, 255, 255, 0.8)); background: var(--bg-hover, rgba(255,255,255,0.04)); }
body.coach-profile-page .cp-section-rename-btn:focus-visible { outline: 2px solid var(--coach-accent, #2563eb); outline-offset: 2px; }
body.coach-profile-page .cp-section-rename-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.35rem 0.5rem;
    font-size: 0.9rem;
    color: var(--text-primary, #fff);
    background: var(--bg-card, #1a1c1f);
    border: 1px solid var(--coach-accent, #2563eb);
    border-radius: 6px;
}
body.coach-profile-page .cp-section-rename-save,
body.coach-profile-page .cp-section-rename-cancel {
    flex: 0 0 auto;
    padding: 0.35rem 0.7rem;
    font-size: 0.82rem;
    border-radius: 6px;
    cursor: pointer;
    border: 1px solid var(--border-subtle, rgba(255,255,255,0.12));
}
body.coach-profile-page .cp-section-rename-save {
    background: var(--coach-accent, #2563eb);
    color: var(--text-on-accent, #fff);
    border-color: transparent;
}
body.coach-profile-page .cp-section-rename-cancel { background: transparent; color: var(--text-secondary, rgba(255,255,255,0.8)); }
body.coach-profile-page .cp-section-rename-save:focus-visible,
body.coach-profile-page .cp-section-rename-cancel:focus-visible { outline: 2px solid var(--coach-accent, #2563eb); outline-offset: 2px; }

body.coach-profile-page .cp-section-card__body {
    padding: 0 0.5rem 0.75rem;
    border-top: 1px solid var(--border-subtle);
    background: rgba(255, 255, 255, 0.01);
}
body.coach-profile-page .cp-section-card__body[hidden] { display: none; }
/* Inner cp-level-rows render with slightly reduced surface so they
   visually nest inside the section card. */
body.coach-profile-page .cp-section-card__body .cp-level-row {
    margin-top: 0.5rem;
    background: rgba(255, 255, 255, 0.015);
}

/* Editor-side variant — same surface, slightly tighter spacing to fit
   the cp-course-detail-pane-left column. */
.cp-section-card-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 0.5rem;
}
.cp-course-detail-pane-left .cp-section-card { margin-bottom: 0.5rem; }
.cp-course-detail-pane-left .cp-section-card__head { padding: 0.75rem 0.875rem; }
.cp-course-detail-pane-left .cp-section-card__title { font-size: 0.9375rem; }

/* When section accordion is in the editor, the inner <ol> needs to
   sit flush; the parent body already has padding. */
.cp-course-detail-levels.cp-course-detail-levels--in-section {
    margin: 0.5rem 0 0;
    padding: 0;
}

/* ─── Program tabs (multi-program packs — Greg's Curriculum) ───────────
   Sits above the section accordion. Two-button row that filters which
   program's sections are shown. Buttons are big touch targets (44px+)
   with primary label + count subline ("22 weeks · 208 games"). */
.cp-program-tabs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    padding: 0.75rem 0.5rem 0.25rem;
}
.cp-program-tab {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    padding: 0.875rem 1rem;
    background: rgba(255, 255, 255, 0.025);
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    color: var(--text-primary, #fff);
    cursor: pointer;
    font: inherit;
    text-align: left;
    transition: border-color 0.15s, background 0.15s, transform 0.05s;
    /* WCAG 2.5.8 — 44px min touch target */
    min-height: 56px;
}
.cp-program-tab:hover {
    border-color: rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.04);
}
.cp-program-tab:active { transform: translateY(1px); }
.cp-program-tab:focus-visible {
    outline: 2px solid var(--coach-accent, #60a5fa);
    outline-offset: 2px;
}
.cp-program-tab.is-active {
    border-color: var(--coach-accent, rgba(96, 165, 250, 0.6));
    background: rgba(96, 165, 250, 0.08);
}
.cp-program-tab__title {
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.2;
}
.cp-program-tab__sub {
    font-size: 0.75rem;
    color: var(--text-secondary, rgba(255, 255, 255, 0.6));
}

.cp-program-tab-panel {
    /* Container holds the section accordion for the active program */
    padding-top: 0.25rem;
}

/* Single-column on narrow viewports (<= 480px) — stack the tabs */
@media (max-width: 480px) {
    .cp-program-tabs {
        grid-template-columns: 1fr;
    }
}

/* Bullet perks list on classroom-style profile pages — matches Skool's
   group-landing layout (e.g. Greg's standardjiujitsu). Renders below
   the package description, above the meta row. */
.cp-package-perks {
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.cp-package-perks li {
    padding-left: 1.25rem;
    position: relative;
    color: var(--text-secondary, rgba(255, 255, 255, 0.85));
    font-size: 0.9375rem;
    line-height: 1.45;
}
.cp-package-perks li::before {
    content: "•";
    position: absolute;
    left: 0;
    color: var(--accent, #2563eb);
    font-weight: 700;
}

/* Classroom-style coaches (Greg-style weekly content) get a single
   "Browse all weeks" CTA in place of the flat per-level accordion that
   instructional-pack coaches show. */
.cp-classroom-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.875rem 1.25rem;
    background: var(--accent, #2563eb);
    color: var(--text-on-accent, #ffffff);
    border-radius: 8px;
    font-size: 0.9375rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s ease;
}
.cp-classroom-link:hover {
    background: var(--accent-hover, #60a5fa);
}
.cp-classroom-link:focus-visible {
    outline: 2px solid var(--accent-text, #60a5fa);
    outline-offset: 2px;
}
