/* Planet Chambers (Move F1) — per-planet chat view inside houseOfPlanets.html.
   Loads after hop-main.css. Per-planet accent arrives via CSS custom properties
   set by planet-chat.js (single palette source, lifted from hopicon-faces.js):
   --pc-accent (hex), --pc-accent-soft / --pc-accent-atmo (rgba tints). */

#planet-chat-view {
    position: fixed;
    inset: 0;
    display: none;
    z-index: 15;
    overflow: hidden;
    background:
        radial-gradient(ellipse at 50% -8%, var(--pc-accent-atmo, rgba(138, 155, 196, 0.12)) 0%, transparent 52%),
        radial-gradient(ellipse at 50% 88%, rgba(20, 32, 54, 0.5) 0%, transparent 55%),
        linear-gradient(180deg, #030508 0%, #020406 45%, #020304 100%);
}
#planet-chat-view.visible {
    display: block;
}

.planet-chat-shell {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    max-width: 760px;
    margin: 0 auto;
    padding: 18px 20px calc(16px + env(safe-area-inset-bottom, 0px));
    box-sizing: border-box;
}

/* --- Planet rail (F2): nine doors at the top of the chamber ---
   Per-disc accent arrives via --pc-rail-accent / --pc-rail-accent-soft set by
   planet-chat.js. Visited = lit ring; current = aria-pressed (design system:
   aria-pressed is the sole active-state signal). */
.planet-chat-rail {
    flex: none;
    display: flex;
    justify-content: center;
    gap: 10px;
    padding: 4px 0 0;
}
.planet-chat-rail-disc {
    position: relative;
    width: 34px;
    height: 34px;
    padding: 3px;
    border: none;
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
    opacity: 0.55;
    transition: opacity 0.2s ease, box-shadow 0.2s ease;
    /* fallback letter when faces lib is absent */
    color: rgba(203, 213, 225, 0.7);
    font-size: 13px;
    line-height: 1;
}
.planet-chat-rail-disc svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible; /* Saturn's ring spills past the disc box — let it */
}
.planet-chat-rail-disc:hover,
.planet-chat-rail-disc:focus-visible {
    opacity: 0.9;
}
.planet-chat-rail-disc--visited {
    opacity: 0.75;
    box-shadow: 0 0 0 1px var(--pc-rail-accent-soft, rgba(148, 163, 184, 0.4));
}
.planet-chat-rail-disc[aria-pressed="true"] {
    opacity: 1;
    box-shadow:
        0 0 0 1.5px var(--pc-rail-accent, #8A9BC4),
        0 0 14px var(--pc-rail-accent-soft, rgba(148, 163, 184, 0.4));
}

/* --- Face header: the planet's presence --- */
.planet-chat-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 14px 0 18px;
    flex: none;
}

/* Identity = face + name. On mobile it is the door to the switcher sheet
   (the rail is hidden there); on desktop the rail does that job, so inert. */
.planet-chat-identity {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
@media (min-width: 641px) {
    .planet-chat-identity { pointer-events: none; }
}

.planet-chat-face {
    width: 118px;
    height: 118px;
    filter: drop-shadow(0 0 26px var(--pc-accent-soft, rgba(138, 155, 196, 0.22)));
}
/* Saturn's ring spills past the disc box at the chamber's discFill — let it. */
.planet-chat-face svg {
    overflow: visible;
    display: block;
}

.planet-chat-name {
    font-family: var(--font-display, 'Marcellus SC', serif);
    font-size: 22px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--pc-accent, #8A9BC4);
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.5);
}

.planet-chat-status {
    min-height: 16px;
    font-size: 11px;
    letter-spacing: 0.08em;
    color: rgba(148, 163, 184, 0.75);
    text-align: center;
}
.planet-chat-status--error {
    color: rgba(248, 113, 113, 0.9);
}

/* Free-message runway under the chamber status — same quiet meta voice as the
   Living Dialogue header (base .pricing-status-line in chart-app-theme.css).
   Collapses entirely when hop-payments has nothing to say. */
.planet-chat-header .pricing-status-line--chamber {
    margin: 0;
    font-size: 11px;
    letter-spacing: 0.08em;
    color: rgba(148, 163, 184, 0.6);
}
.planet-chat-header .pricing-status-line--chamber:empty {
    display: none;
}

/* --- Transcript --- */
.planet-chat-transcript {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 22px;
    padding: 8px 2px 18px;
    scrollbar-width: thin;
    scrollbar-color: rgba(148, 163, 184, 0.25) transparent;
}

/* Planet speaks full-width — voice on the night air, no bubble, no card. */
.planet-chat-message--planet {
    align-self: stretch;
    max-width: 62ch;
    color: rgba(230, 233, 242, 0.94);
    font-size: 15px;
    line-height: 1.75;
}
.planet-chat-message--planet .planet-chat-message-meta {
    font-family: var(--font-display, 'Marcellus SC', serif);
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--pc-accent, #8A9BC4);
    opacity: 0.85;
    margin-bottom: 6px;
}
.planet-chat-message--planet .chart-chat-markdown p {
    margin: 0 0 10px;
}
.planet-chat-message--planet .chart-chat-markdown p:last-child {
    margin-bottom: 0;
}

/* --- Boundary chip (F3): the truer planet, named under the reply ---
   Per-chip accent (the TARGET planet's, not the chamber's) arrives via
   --pc-chip-accent / --pc-chip-accent-soft set by planet-chat.js. Talkable =
   button, tap switches chamber. Locked = span, named but inert. */
.planet-chat-boundary-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    padding: 5px 12px 5px 6px;
    border: 1px solid var(--pc-chip-accent-soft, rgba(148, 163, 184, 0.35));
    border-radius: 999px;
    background: rgba(8, 13, 22, 0.55);
    cursor: pointer;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    /* fallback letter when faces lib is absent */
    color: rgba(203, 213, 225, 0.7);
    font-size: 12px;
    line-height: 1;
}
.planet-chat-boundary-chip:hover:not(.planet-chat-boundary-chip--locked),
.planet-chat-boundary-chip:focus-visible {
    border-color: var(--pc-chip-accent, #8A9BC4);
    box-shadow: 0 0 12px var(--pc-chip-accent-soft, rgba(148, 163, 184, 0.35));
}
.planet-chat-boundary-chip-disc {
    flex: none;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.planet-chat-boundary-chip-disc svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible; /* Saturn's ring spills — let it */
}
.planet-chat-boundary-chip-label {
    font-family: var(--font-display, 'Marcellus SC', serif);
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--pc-chip-accent, #8A9BC4);
}
.planet-chat-boundary-chip--locked {
    cursor: default;
    opacity: 0.55;
}

/* User answers from the edge — right-aligned, muted. */
.planet-chat-message--user {
    align-self: flex-end;
    max-width: 78%;
    text-align: right;
    color: rgba(203, 213, 225, 0.55);
    font-size: 13.5px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
}

.planet-chat-thinking {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--pc-accent-soft, rgba(138, 155, 196, 0.6));
    font-size: 12px;
    letter-spacing: 0.06em;
}
.planet-chat-thinking-dots span {
    display: inline-block;
    width: 4px;
    height: 4px;
    margin-right: 3px;
    border-radius: 50%;
    background: var(--pc-accent, #8A9BC4);
    opacity: 0.5;
    animation: planet-chat-dot 1.2s infinite ease-in-out;
}
.planet-chat-thinking-dots span:nth-child(2) { animation-delay: 0.15s; }
.planet-chat-thinking-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes planet-chat-dot {
    0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
    30% { opacity: 0.9; transform: translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) {
    .planet-chat-thinking-dots span { animation: none; }
}

/* --- Composer --- */
.planet-chat-composer-bar {
    flex: none;
    padding-top: 10px;
}
/* Chamber gate (dialogue-subscription): planet-chat.js borrows the ONE invitation
   node (#chat-subscription-paywall) into this bar and the send form yields — same
   morph as Living Dialogue. Button styles live in chart-chat.css.

   Why a class and not an ancestor `:has()` match on the borrowed node, the way the
   Living Dialogue bar does it: the chamber's borrow lands as the view leaves
   display:none, and a
   node moved into a subtree that had no computed style does not reliably re-run the
   ancestor's :has() match in that first recalc. Measured on Check: the node was in
   this bar BEFORE paint, yet the form still rendered — and only vanished when an
   unrelated recalc (updateComposer flipping input.disabled after the thread fetch)
   forced the match. That was the split-second flash. A class on the bar itself is
   matched by the element's own selector, so it applies in the same paint. The class
   is the only mechanism here — showInvitation/returnInvitation own it both ways. */
.planet-chat-composer-bar--gated > form {
    display: none;
}
/* Entitlement not yet known — attribute absent (pre-boot) or hop-payments still
   'checking'. Disabling the input in JS is NOT enough: a greyed composer is still
   a visible promise, and replacing it with a price a beat later is exactly the
   flash this phase exists to kill. CSS reacts in the same paint as the attribute,
   so no JS ordering can race it. visibility, not display: the bar keeps its
   footprint so the transcript doesn't jump twice on the common path. */
html:not([data-payment-state]) .planet-chat-composer-bar > form,
html[data-payment-state="checking"] .planet-chat-composer-bar > form {
    visibility: hidden;
}
/* Seized: the invitation wears the chamber's accent (--pc-accent* set on
   #planet-chat-view by setPlanet). Solid fill — the accents are mid-tone;
   the glow carries the life. */
#planet-chat-view .chat-sub-paywall-btn {
    --sub-fill: var(--pc-accent, #8A9BC4);
    --sub-glow: var(--pc-accent-soft, rgba(148, 163, 184, 0.4));
    color: rgba(8, 12, 20, 0.94);
}
/* Terms / Refunds too — the graha seizes the whole invitation, not just its
   button. Amber left standing in a Mars chamber reads as a foreign surface. */
#planet-chat-view .chat-sub-paywall-fine a {
    color: var(--pc-accent, #8A9BC4);
}
.planet-chat-composer-shell {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 18px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(8, 13, 22, 0.62);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    transition: border-color 0.25s ease;
}
.planet-chat-composer-shell:focus-within {
    border-color: var(--pc-accent-soft, rgba(138, 155, 196, 0.45));
}
/* Scoped to the shell, not #planet-chat-input, so any composer that reuses
   .planet-chat-composer-shell inherits the whole look — the planet modal does. */
.planet-chat-composer-shell textarea {
    flex: 1;
    resize: none;
    border: none;
    outline: none;
    background: transparent;
    color: rgba(248, 250, 252, 0.92);
    font-size: 14px;
    line-height: 1.6;
    max-height: 132px;
    /* The shell bottom-aligns its children so the send button holds its place
       as the textarea grows. One line (14px x 1.6 = 22.4px) against the 34px
       button therefore sat ~12px low — that was the placeholder hanging below
       centre. Matching the button's height and splitting the remainder into
       padding centres the first line without breaking multi-line growth. */
    box-sizing: border-box;
    min-height: 34px;
    padding: 6px 0;
}
.planet-chat-composer-shell textarea::placeholder {
    color: rgba(148, 163, 184, 0.5);
}
.planet-chat-composer-shell button[type="submit"] {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--pc-accent-soft, rgba(138, 155, 196, 0.45));
    background: transparent;
    color: var(--pc-accent, #8A9BC4);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s ease, opacity 0.2s ease;
}
.planet-chat-composer-shell button[type="submit"]::before {
    content: '↑';
    font-size: 16px;
    line-height: 1;
}
.planet-chat-composer-shell button[type="submit"]:hover:not(:disabled) {
    background: var(--pc-accent-atmo, rgba(138, 155, 196, 0.12));
}
.planet-chat-composer-shell button[type="submit"]:disabled,
.planet-chat-composer-shell textarea:disabled {
    opacity: 0.45;
    cursor: default;
}

/* --- Planet picker: nine doors, 3×3. Bottom sheet on mobile (replaces the
   rail under 640px — nine 44px targets cannot fit one phone row), centered
   panel on desktop (opened from the Planet Dialogue menu item).
   Per-door accent via --pc-door-accent* set by planet-chat.js. --- */
#planet-chat-switcher {
    position: fixed;
    inset: 0;
    z-index: 60; /* above the floating hamburger (40) / account (41) */
    display: none;
}
#planet-chat-switcher.visible {
    display: block;
}
.planet-chat-switcher-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(2, 4, 8, 0.6);
}
.planet-chat-switcher-sheet {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 16px 14px calc(16px + env(safe-area-inset-bottom, 0px));
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-bottom: none;
    border-radius: 20px 20px 0 0;
    background: rgba(8, 13, 22, 0.92);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    animation: planet-chat-sheet-up 0.25s ease;
}
@keyframes planet-chat-sheet-up {
    from { transform: translateY(24px); opacity: 0; }
    to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .planet-chat-switcher-sheet { animation: none; }
}
/* Desktop: centered panel, not a phone sheet. The entrance keyframe carries
   the centering transform so the animation cannot unseat the position. */
@media (min-width: 641px) {
    .planet-chat-switcher-sheet {
        left: 50%;
        right: auto;
        top: 50%;
        bottom: auto;
        width: min(440px, calc(100vw - 48px));
        transform: translate(-50%, -50%);
        padding: 22px 20px;
        border-bottom: 1px solid rgba(255, 255, 255, 0.12);
        border-radius: 20px;
        animation: planet-chat-picker-in 0.25s ease;
    }
}
@keyframes planet-chat-picker-in {
    from { transform: translate(-50%, -50%) scale(0.97); opacity: 0; }
    to { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
@media (min-width: 641px) and (prefers-reduced-motion: reduce) {
    .planet-chat-switcher-sheet { animation: none; }
}
.planet-chat-switcher-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    max-width: 420px;
    margin: 0 auto;
}
.planet-chat-switcher-door {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    padding: 12px 4px 10px;
    border: none;
    border-radius: 14px;
    background: transparent;
    cursor: pointer;
    opacity: 0.6;
    -webkit-tap-highlight-color: transparent;
    /* fallback letter when faces lib is absent */
    color: rgba(203, 213, 225, 0.7);
    font-size: 14px;
    line-height: 1;
}
.planet-chat-switcher-door--visited {
    opacity: 0.85;
}
.planet-chat-switcher-door[aria-pressed="true"] {
    opacity: 1;
    background: var(--pc-door-accent-atmo, rgba(148, 163, 184, 0.1));
    box-shadow: inset 0 0 0 1px var(--pc-door-accent-soft, rgba(148, 163, 184, 0.4));
}
.planet-chat-switcher-door-disc {
    flex: none;
    width: 44px;
    height: 44px;
}
.planet-chat-switcher-door-disc svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible; /* Saturn's ring spills — let it */
}
.planet-chat-switcher-door-label {
    font-family: var(--font-display, 'Marcellus SC', serif);
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--pc-door-accent, #8A9BC4);
}

@media (max-width: 640px) {
    .planet-chat-shell {
        padding-left: 14px;
        padding-right: 14px;
    }
    /* Rail dies on mobile: 9 × 44px targets + gaps = 460px — wider than the
       phone. The identity button + switcher sheet replace it. */
    .planet-chat-rail {
        display: none;
    }
    .planet-chat-face {
        width: 96px;
        height: 96px;
        transition: width 0.3s ease, height 0.3s ease, filter 0.3s ease;
    }
    .planet-chat-name {
        font-size: 18px;
    }
    /* ≥16px or iOS Safari zooms the whole page on focus. The taller line box
       (16 x 1.6 = 25.6px) needs less padding to stay centred in the same 34px. */
    .planet-chat-composer-shell textarea {
        font-size: 16px;
        padding: 4px 0;
    }

    /* Compact header (.pc-compact, set by planet-chat.js): once conversation
       is live, the transcript owns the screen — face shrinks to a row that
       sits in the same chrome band as the hamburger/account buttons, so it
       must center on the same var(--chart-actions-top) + 44px row those use
       (see chart-app-theme.css --mobile-header-row-height). Shell's default
       18px top padding is arrival-only spacing and ignores safe-area-inset-top,
       so it's overridden here to keep the two in sync on notched phones. */
    #planet-chat-view.pc-compact .planet-chat-shell {
        padding-top: var(--chart-actions-top);
    }
    #planet-chat-view.pc-compact .planet-chat-header {
        padding: 5px 0 10px;
        gap: 4px;
    }
    #planet-chat-view.pc-compact .planet-chat-identity {
        flex-direction: row;
        gap: 8px;
    }
    #planet-chat-view.pc-compact .planet-chat-face {
        width: 34px;
        height: 34px;
        filter: drop-shadow(0 0 10px var(--pc-accent-soft, rgba(138, 155, 196, 0.22)));
    }
    #planet-chat-view.pc-compact .planet-chat-name {
        font-size: 13px;
        letter-spacing: 0.18em;
    }
    /* Switcher affordance, compact only — arrival stays pure presence. */
    #planet-chat-view.pc-compact .planet-chat-identity::after {
        content: '▾';
        font-size: 10px;
        line-height: 1;
        color: var(--pc-accent, #8A9BC4);
        opacity: 0.55;
    }
    #planet-chat-view.pc-compact .planet-chat-status {
        min-height: 0;
    }
    #planet-chat-view.pc-compact .planet-chat-status:empty {
        display: none;
    }
}
@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
    .planet-chat-face { transition: none; }
}
