/* ====================================================================
   Tempfolio · Constellation — ported from Claude Design handoff
   (Tempfolio Constellation.html). Everything scoped under .tf-constellation
   so it cannot leak into the rest of the app.
   ==================================================================== */

.tf-constellation {
    /* Structural tokens — alias global tokens defined in styling.css so the
       constellation participates in the project-wide [data-theme="dark"]
       toggle (set by useDarkMode on <html>). The ink/cream naming is kept
       so existing rules like `background: var(--bg-secondary)` don't need rewrites. */
    --ink-0:   var(--bg-page);          /* page background */
    --ink-1:   var(--bg-primary);       /* raised card */
    --ink-2:   var(--bg-secondary);     /* satellite/card surface */
    --ink-3:   var(--bg-muted);         /* satellite hover / deeper inset */
    --cream:   var(--text-primary);     /* main text */
    --cream-2: var(--text-secondary);   /* secondary text */
    --muted:   var(--text-muted);       /* tertiary text */
    --line:    var(--border);
    --line-2:  var(--border-subtle);

    /* Alpha-overlay tokens. Light defaults: dark-on-cream tints. The
       [data-theme="dark"] override below flips these to cream-on-dark. */
    --surface-soft:   rgba(44, 44, 42, 0.04);   /* most subtle tint (empty thumbs, bands) */
    --surface-mid:    rgba(44, 44, 42, 0.08);   /* button bg, sat-kind chip */
    --surface-strong: rgba(44, 44, 42, 0.18);   /* divider, scrollbar thumb */
    --muted-2:        rgba(44, 44, 42, 0.34);
    --neu-bg:         rgba(44, 44, 42, 0.07);
    --grid-tint:      rgba(44, 44, 42, 0.025);  /* .center::before grid lines */

    /* Card surfaces (alpha bgs used with backdrop-filter blur) */
    --card-bg:         rgba(255, 255, 255, 0.85);   /* satellite face */
    --card-bg-strong:  rgba(255, 255, 255, 0.94);   /* expanded-card face */
    --surface-overlay: rgba(245, 240, 235, 0.78);   /* top-bar, side-nav veil */
    --backdrop:        rgba(245, 240, 235, 0.55);   /* expand backdrop */
    --orb-veil:        rgba(255, 255, 255, 0.55);   /* orb inner highlight */
    --card-kiss:       4%;                          /* lens-hue gradient strength */

    /* Text-color RGB triplet — used wherever the code needs an alpha-text
       like color: rgba(var(--text-rgb), 0.85). Flips per theme so muted
       text reads correctly on both backgrounds. */
    --text-rgb: 44, 44, 42;
    /* Page-bg RGB triplet — used for veils over the page (top-bar, side
       nav, guard backdrop) where alpha varies per spot. */
    --page-rgb: 245, 240, 235;
    /* Card-bg RGB triplet — used for satellite/card surface backgrounds
       and their hover variants where alpha varies. */
    --card-rgb: 255, 255, 255;

    /* Lens accent system — oklch + hue-driven. Stays theme-agnostic;
       only the lightness lifts in dark mode (override below). */
    --accent-h:    75;
    --accent:      oklch(0.65 0.13 var(--accent-h));
    --accent-soft: oklch(0.65 0.13 var(--accent-h) / 0.14);
    --accent-line: oklch(0.65 0.13 var(--accent-h) / 0.35);
    --pos:         oklch(0.60 0.13 150);
    --pos-bg:      oklch(0.60 0.13 150 / 0.12);
    --warn:        oklch(0.62 0.13 50);
    --warn-bg:     oklch(0.62 0.13 50 / 0.12);

    --font-ui:      'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    /* Display = card titles + data values. Space Grotesk: fun, modern, with
       legible numerals (replaced Instrument Serif, which was a display serif
       being misused for compact data — hard to read at small sizes). */
    --font-display: 'Space Grotesk', 'Inter', sans-serif;
    /* Serif accent — reserved for the orb monogram + brand score ONLY. */
    --font-serif:   'Instrument Serif', 'Times New Roman', serif;
    --font-mono:    'JetBrains Mono', ui-monospace, monospace;

    /* Sits inside the BrandFootprintPage body wrapper, BELOW the app navbar.
       Full width — the background extends edge-to-edge of the viewport.
       The CONTENT (sidebar + center) is constrained to the same 1400px band
       the navbar uses, via max-width on .scaler below. */
    position: relative;
    width: 100%;
    /* Fill exactly the viewport below the navbar (+ notification bar if shown) —
       no taller. Using the real layout vars (navbar 66px) instead of a stale
       hardcoded 96px removes the dead gap under the lens dock and lets the
       orbit use the full height. The old 1000px floor that pushed the lens
       below the fold is gone. */
    height: calc(100vh - var(--navbar-height) - var(--notification-height));
    min-height: calc(100vh - var(--navbar-height) - var(--notification-height));
    /* Dynamic viewport height — tracks the *visible* area as the mobile URL bar
       shows/hides. Using 100vh here measured the LARGE viewport (URL bar hidden),
       so on a phone the shell ran taller than the screen: the bottom tab bar fell
       below the fold and the body gained a second scrollbar. dvh sizes the shell
       to what's actually on screen, so the pill bar pins to the real bottom on any
       phone and the inner .tfm-scroll is the only scroll region. (vh kept above as
       a fallback for browsers without dvh support.) */
    height: calc(100dvh - var(--navbar-height) - var(--notification-height));
    min-height: calc(100dvh - var(--navbar-height) - var(--notification-height));
    background: var(--ink-0);
    color: var(--text-primary);
    font-family: var(--font-ui);
    font-size: 12.5px;
    -webkit-font-smoothing: antialiased;
    user-select: none;
}

/* Dark-mode overrides. Structural ink/cream tokens already swap via the
   global cascade (--bg-page etc.). Only flip the alpha overlays (now
   cream-on-dark instead of dark-on-cream) and lift the accent lightness. */
[data-theme="dark"] .tf-constellation {
    --surface-soft:   rgba(240, 235, 228, 0.04);
    --surface-mid:    rgba(240, 235, 228, 0.08);
    --surface-strong: rgba(240, 235, 228, 0.18);
    --muted-2:        rgba(240, 235, 228, 0.34);
    --neu-bg:         rgba(240, 235, 228, 0.07);
    --grid-tint:      rgba(240, 235, 228, 0.025);

    --card-bg:         rgba(44, 42, 39, 0.82);
    --card-bg-strong:  rgba(44, 42, 39, 0.94);
    --surface-overlay: rgba(28, 26, 24, 0.78);
    --backdrop:        rgba(8, 10, 18, 0.55);
    --orb-veil:        rgba(255, 255, 255, 0.15);
    --card-kiss:       5%;

    --text-rgb: 240, 235, 228;
    --page-rgb: 28, 26, 24;
    --card-rgb: 44, 42, 39;

    --accent:      oklch(0.82 0.13 var(--accent-h));
    --accent-soft: oklch(0.82 0.13 var(--accent-h) / 0.18);
    --accent-line: oklch(0.82 0.13 var(--accent-h) / 0.35);
    --pos:         oklch(0.80 0.13 150);
    --pos-bg:      oklch(0.80 0.13 150 / 0.14);
    --warn:        oklch(0.78 0.13 50);
    --warn-bg:     oklch(0.78 0.13 50 / 0.14);
}
.tf-constellation * { box-sizing: border-box; }

/* ────────────── viewport + scaler ──────────────
   Originally a 1440×1000 design canvas with transform: scale() to fit. We
   dropped the fixed-canvas approach so the constellation spans full viewport
   width (navbar logo edge → profile-pic edge). The grid inside .stage is
   already responsive (sidebar 240px + 1fr + watch rail 256px), so center
   expands naturally on wider screens. Orb + rings stay centered relative to
   the center column; satellite SLOT_VECTORS are absolute pixel offsets from
   that center, so wider columns just leave more breathing room. */
.tf-constellation .viewport {
    position: absolute; inset: 0;
    background: var(--ink-0);
}
.tf-constellation .scaler {
    width: 100%; height: 100%;
    max-width: 1400px;
    margin: 0 auto;
    position: relative;
}

/* ────────────── Stage ────────────── */
.tf-constellation .stage {
    position: absolute; inset: 0;
    background:
        radial-gradient(900px 700px at 50% 50%, oklch(0.82 0.13 var(--accent-h) / 0.10), transparent 70%),
        radial-gradient(1400px 1100px at 50% 50%, var(--bg-secondary), var(--ink-0) 75%);
    overflow: hidden;
    transition: background 1200ms cubic-bezier(.2,.7,.2,1);
    display: grid;
    grid-template-columns: 288px 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas:
        "side top"
        "side center";
}
.tf-constellation .stage-top {
    grid-area: top;
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px;
    padding: 14px 28px;
    border-bottom: 1px solid var(--line);
    background: rgba(var(--page-rgb), 0.45);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    z-index: 15;
    min-width: 0;
}
.tf-constellation .stage-top__title { flex: 1 1 0; min-width: 0; }
.tf-constellation .stage-top__title .ct-title { margin-bottom: 4px; }
.tf-constellation .stage-top__actions {
    display: flex; align-items: center; justify-content: flex-end; gap: 6px;
    flex: 1 1 0; min-width: 0;
}

/* Centered feedback trigger — looks like an input, opens the feedback modal.
   Lives in the flex flow as the middle item; title/actions each take flex:1 so
   it stays centered while there's room and shrinks (with text ellipsis) instead
   of overlapping the title pills when the viewport narrows. */
.tf-constellation .stage-top { position: relative; }
.tf-constellation .stage-feedback {
    flex: 0 1 284px;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    border-radius: 10px;
    border: 1px solid var(--line);
    background: rgba(var(--page-rgb), 0.5);
    color: rgba(var(--text-rgb), 0.5);
    font-size: 15px;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
    white-space: nowrap;
}
.tf-constellation .stage-feedback:hover {
    border-color: rgba(var(--text-rgb), 0.4);
    color: rgba(var(--text-rgb), 0.95);
    background: rgba(var(--page-rgb), 0.8);
}
.tf-constellation .stage-feedback__icon { font-size: 14px; flex-shrink: 0; }
.tf-constellation .stage-feedback__text { overflow: hidden; text-overflow: ellipsis; }

/* ────────────── Sticky notes ──────────────
   Persistent per-user, per-brand notes overlaid on the center stage. The layer
   is click-through so it never steals orb/satellite clicks — only the cards and
   the toolbar opt back in to pointer events. */
.tf-constellation .notes-layer {
    position: absolute; inset: 0;
    pointer-events: none;
    z-index: 14;
}
.tf-constellation .notes-toolbar {
    position: absolute; top: 14px; left: 16px;
    z-index: 15;
}
.tf-constellation .notes-add {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 12px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: rgba(var(--card-rgb), 0.75);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    color: var(--muted-2);
    font: 600 11px/1 var(--font-mono);
    letter-spacing: 0.12em; text-transform: uppercase;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.tf-constellation .notes-add:hover {
    border-color: oklch(0.7 0.13 var(--accent-h));
    color: oklch(0.55 0.16 var(--accent-h));
    background: rgba(var(--card-rgb), 0.92);
}
.tf-constellation .notes-add__ic { font-size: 13px; }

/* Notepad paper — a fixed warm palette (NOT the theme card vars) so notes read
   as beige/yellow paper, distinct from the dark glass satellite cards. */
.tf-constellation .note-card {
    --paper:       #f6edcf;   /* warm beige-yellow sheet */
    --paper-edge:  #e6d8a8;   /* slightly deeper edge */
    --paper-ink:   #34301f;   /* dark warm ink */
    --paper-faint: #8d8259;   /* muted label / placeholder */
    --paper-rule:  rgba(120, 96, 40, 0.16);  /* ruled lines */

    position: absolute;
    width: 200px; min-height: 150px;
    display: flex; flex-direction: column;
    pointer-events: auto;
    border: 1px solid var(--paper-edge);
    border-radius: 4px;
    background: var(--paper);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.28);
    overflow: hidden;
}
.tf-constellation .note-card__head {
    display: flex; align-items: center; gap: 7px;
    padding: 7px 9px;
    /* Tear-off strip across the top of the pad. */
    background: linear-gradient(var(--paper-edge), color-mix(in srgb, var(--paper-edge) 55%, var(--paper)));
    border-bottom: 1px solid var(--paper-edge);
    cursor: grab;
    user-select: none;
    touch-action: none;
}
.tf-constellation .note-card__head:active { cursor: grabbing; }
.tf-constellation .note-card__dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: oklch(0.62 0.17 var(--accent-h));
    flex-shrink: 0;
}
.tf-constellation .note-card__label {
    flex: 1 1 auto;
    font: 600 10px/1 var(--font-mono);
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--paper-faint);
}
.tf-constellation .note-card__close {
    flex-shrink: 0;
    width: 18px; height: 18px;
    display: inline-flex; align-items: center; justify-content: center;
    border: none; background: transparent;
    color: var(--paper-faint);
    font-size: 16px; line-height: 1;
    cursor: pointer; border-radius: 4px;
    transition: color 0.15s, background 0.15s;
}
.tf-constellation .note-card__close:hover {
    color: #b3402a;
    background: rgba(120, 96, 40, 0.12);
}
.tf-constellation .note-card__text {
    flex: 1 1 auto;
    width: 100%;
    border: none; outline: none; resize: vertical;
    padding: 6px 10px;
    background: transparent;
    /* Ruled lines aligned to the 24px line-height, like a legal pad. */
    background-image: repeating-linear-gradient(
        var(--paper) 0px, var(--paper) 23px,
        var(--paper-rule) 23px, var(--paper-rule) 24px);
    background-position: 0 6px;
    color: var(--paper-ink);
    font-family: var(--font-sans, inherit);
    font-size: 13px; line-height: 24px;
    min-height: 110px;
}
.tf-constellation .note-card__text::placeholder { color: var(--paper-faint); }

.tf-constellation .stage::before {
    content: "";
    position: absolute; inset: 0;
    background-image:
        radial-gradient(1px 1px at 12% 22%, rgba(var(--text-rgb), 0.35) 50%, transparent 100%),
        radial-gradient(1px 1px at 78% 14%, rgba(var(--text-rgb), 0.22) 50%, transparent 100%),
        radial-gradient(1px 1px at 32% 76%, rgba(var(--text-rgb), 0.28) 50%, transparent 100%),
        radial-gradient(1px 1px at 88% 62%, rgba(var(--text-rgb), 0.22) 50%, transparent 100%),
        radial-gradient(1px 1px at 56% 86%, rgba(var(--text-rgb), 0.18) 50%, transparent 100%),
        radial-gradient(1px 1px at 22% 48%, rgba(var(--text-rgb), 0.16) 50%, transparent 100%),
        radial-gradient(1px 1px at 65% 38%, rgba(var(--text-rgb), 0.22) 50%, transparent 100%),
        radial-gradient(1px 1px at 5% 88%, rgba(var(--text-rgb), 0.16) 50%, transparent 100%),
        radial-gradient(1px 1px at 92% 92%, rgba(var(--text-rgb), 0.20) 50%, transparent 100%),
        radial-gradient(1px 1px at 44% 8%, rgba(var(--text-rgb), 0.18) 50%, transparent 100%);
    pointer-events: none;
    animation: tfc-tw 7s ease-in-out infinite alternate;
    z-index: 0;
}
@keyframes tfc-tw { 0% { opacity: .4 } 100% { opacity: .85 } }

/* ────────────── Sidebar (dark Refined chrome) ────────────── */
.tf-constellation .side {
    grid-area: side;
    background: rgba(var(--page-rgb), 0.78);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-right: 1px solid var(--line);
    padding: 18px 14px;
    display: flex; flex-direction: column; gap: 18px;
    z-index: 30;
    overflow: hidden;
}
.tf-constellation .side-brand { display: flex; align-items: center; gap: 8px; padding: 4px 6px 8px; cursor: pointer; }
.tf-constellation .logo-mark {
    width: 26px; height: 26px; border-radius: 7px;
    background: var(--accent); color: var(--ink-0);
    display: grid; place-items: center; font: 600 13px/1 var(--font-display);
}
.tf-constellation .logo-word { font: 600 15px/1 var(--font-ui); letter-spacing: -0.02em; color: var(--text-primary); }
.tf-constellation .new-btn {
    display: flex; align-items: center; justify-content: center;
    background: var(--text-primary); color: var(--ink-0);
    border: 0; border-radius: 10px; padding: 9px 12px;
    font: 500 13px/1 var(--font-ui);
    cursor: pointer; gap: 6px;
}
.tf-constellation .new-btn:hover { opacity: 0.92; }
.tf-constellation .new-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.tf-constellation .nav { display: flex; flex-direction: column; gap: 1px; }
.tf-constellation .nav-h {
    font: 500 10.5px/1 var(--font-mono);
    text-transform: uppercase; letter-spacing: 0.10em;
    color: var(--muted-2); padding: 8px 8px 4px;
}
.tf-constellation .nav-i {
    padding: 7px 8px; border-radius: 6px;
    color: var(--text-primary); font-size: 12.5px; cursor: pointer;
    display: flex; justify-content: space-between; align-items: center;
    text-decoration: none;
}
.tf-constellation .nav-i:hover { background: var(--surface-mid); }
.tf-constellation .nav-i.is-on { background: var(--accent-soft); color: var(--text-primary); font-weight: 500; }
.tf-constellation .nav-i.is-disabled { color: var(--muted-2); cursor: not-allowed; }
.tf-constellation .nav-i.is-disabled:hover { background: transparent; }
.tf-constellation .nav-i .count { color: var(--muted-2); font: 500 11px/1 var(--font-mono); }

/* Tracked-brand list inside the sidebar — beneath the "Tracked" nav item.
   Each row shows logo (or fallback initials) + name. Click swaps the orb. */
.tf-constellation .side-tracked-list {
    display: flex; flex-direction: column;
    margin: 2px 0 6px 16px;
    padding-left: 8px;
    border-left: 1px solid var(--line);
    /* Cap at ~7 rows (≈32px each) so a long tracked list scrolls here instead
       of shoving the lens pills down the sidebar. */
    max-height: 224px;
    overflow-y: auto;
}
.tf-constellation .side-tracked-list::-webkit-scrollbar { width: 4px; }
.tf-constellation .side-tracked-list::-webkit-scrollbar-thumb {
    background: var(--surface-mid);
    border-radius: 2px;
}
.tf-constellation .side-tracked-item {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px;
    border: 0;
    background: transparent;
    border-radius: 6px;
    color: var(--cream-2);
    cursor: pointer;
    text-align: left;
    font: 400 12px/1.2 var(--font-ui);
    transition: background 120ms, color 120ms;
    width: 100%;
    min-width: 0;
}
.tf-constellation .side-tracked-item:hover {
    background: var(--surface-mid);
    color: var(--text-primary);
}
.tf-constellation .side-tracked-item.is-active {
    background: var(--accent-soft);
    color: var(--text-primary);
    font-weight: 500;
}
.tf-constellation .side-tracked-logo,
.tf-constellation .side-tracked-fallback {
    width: 20px; height: 20px;
    border-radius: 5px;
    background: var(--ink-3);
    color: var(--text-primary);
    flex-shrink: 0;
    object-fit: cover;
    border: 1px solid var(--line-2);
    display: grid; place-items: center;
    font: 600 9px/1 var(--font-display);
    letter-spacing: 0.02em;
}
.tf-constellation .side-tracked-item.is-active .side-tracked-fallback {
    background: var(--accent);
    color: var(--ink-0);
    border-color: var(--accent);
}
.tf-constellation .side-tracked-name {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tf-constellation .side-tracked-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent-soft);
    flex-shrink: 0;
}

.tf-constellation .side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 12px; }
.tf-constellation .credits {
    border: 1px solid var(--line); border-radius: 10px;
    padding: 10px 12px; background: var(--surface-soft);
}
.tf-constellation .credits-row { display: flex; justify-content: space-between; font-size: 11.5px; }
.tf-constellation .credits-label { color: var(--muted); }
.tf-constellation .credits-val { color: var(--text-primary); font-weight: 500; font-variant-numeric: tabular-nums; }
.tf-constellation .credits-bar {
    height: 4px; background: var(--surface-mid); border-radius: 2px;
    margin: 8px 0 10px; overflow: hidden;
}
.tf-constellation .credits-bar > span { display: block; height: 100%; background: var(--accent); }
.tf-constellation .upgrade {
    width: 100%; padding: 6px 10px;
    border: 1px solid var(--line-2); background: transparent;
    border-radius: 6px; font: 500 11.5px/1 var(--font-ui);
    cursor: pointer; color: var(--text-primary);
}
.tf-constellation .upgrade:hover { background: var(--surface-mid); }
.tf-constellation .user {
    display: grid; grid-template-columns: 24px 1fr; gap: 8px; align-items: center; padding: 0 6px;
}
.tf-constellation .avi {
    width: 24px; height: 24px; border-radius: 6px;
    background: var(--ink-3); color: var(--text-primary);
    font: 600 10px/1 var(--font-display);
    display: inline-grid; place-items: center;
    border: 1px solid var(--line-2);
}
.tf-constellation .user-meta { font-size: 11.5px; line-height: 1.3; }
.tf-constellation .user-meta > div:first-child { font-weight: 500; color: var(--text-primary); }
.tf-constellation .user-sub { color: var(--muted-2); font-size: 10.5px; }

/* ────────────── Center ────────────── */
.tf-constellation .center {
    grid-area: center;
    position: relative;
    /* Was overflow:hidden which silently clipped any satellite whose anchor
       offset pushed it past .center's edges. Now visible so cards always
       render fully; the constellation root grows to whatever's needed. */
    overflow: visible;
    min-width: 0;
}
.tf-constellation .center::before {
    content: ""; position: absolute; inset: 0;
    background-image:
        linear-gradient(var(--grid-tint) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-tint) 1px, transparent 1px);
    background-size: 64px 64px;
    mask-image: radial-gradient(700px 600px at 50% 50%, black 0%, transparent 80%);
    pointer-events: none;
}
/* .center-top is no longer used — title + admin controls moved to the
   .stage-top header row so they never overlap the satellite cards. */
.tf-constellation .ct-title {
    font: 600 11px/1 var(--font-mono);
    letter-spacing: 0.14em; text-transform: uppercase;
    color: var(--muted-2);
}
.tf-constellation .ct-classify {
    font-family: var(--font-mono); font-size: 11px;
    color: var(--accent); letter-spacing: 0.04em;
    background: rgba(var(--card-rgb), 0.6);
    padding: 5px 11px; border-radius: 999px;
    border: 1px solid var(--accent-line);
    animation: tfc-stripIn 320ms ease-out;
    display: inline-block;
    margin-top: 6px;
}
@keyframes tfc-stripIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.tf-constellation .ct-actions { display: flex; gap: 6px; }
.tf-constellation .pill-btn {
    background: var(--surface-soft);
    border: 1px solid var(--line);
    color: var(--text-primary);
    padding: 6px 11px; border-radius: 999px;
    font: 500 11px/1 var(--font-mono); letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 150ms, border-color 150ms;
}
.tf-constellation .pill-btn:hover { background: var(--surface-mid); border-color: var(--line-2); }
.tf-constellation .pill-btn.is-primary { background: var(--accent); color: var(--ink-0); border-color: var(--accent); }
.tf-constellation .pill-btn.is-primary:hover { opacity: 0.92; background: var(--accent); }
.tf-constellation .pill-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* Track button — idle is outlined gold, tracked state is filled gold so it
   reads as "this brand is in your list". Hover on tracked subtly previews
   the untrack action without committing. */
.tf-constellation .pill-btn--track {
    background: transparent;
    border-color: var(--accent-line);
    color: var(--accent);
}
.tf-constellation .pill-btn--track:hover:not(:disabled) {
    background: var(--accent-soft);
    border-color: var(--accent);
}
.tf-constellation .pill-btn--track.is-on {
    background: var(--accent);
    color: var(--ink-0);
    border-color: var(--accent);
}
.tf-constellation .pill-btn--track.is-on:hover:not(:disabled) {
    background: transparent;
    color: var(--accent);
    border-color: var(--accent-line);
}

/* concentric rings */
.tf-constellation .ring {
    position: absolute; left: 50%; top: 50%;
    border: 1px solid var(--line);
    border-radius: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    z-index: 1;
}
.tf-constellation .ring.r1 { width: 380px; height: 380px; border-style: dashed; opacity: .55; animation: tfc-rspin 80s linear infinite; }
.tf-constellation .ring.r2 { width: 620px; height: 620px; opacity: .30; }
.tf-constellation .ring.r3 { width: 880px; height: 880px; border-style: dashed; opacity: .18; animation: tfc-rspin 160s linear infinite reverse; }
@keyframes tfc-rspin { to { transform: translate(-50%, -50%) rotate(360deg); } }
.tf-constellation .ring.r2::before, .tf-constellation .ring.r2::after {
    content: ""; position: absolute; width: 2px; height: 8px;
    background: var(--accent); left: 50%; transform: translateX(-50%);
    top: -4px; opacity: .8;
}
.tf-constellation .ring.r2::after { top: auto; bottom: -4px; }

/* orb */
.tf-constellation .orb-wrap {
    position: absolute; left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    z-index: 5;
    pointer-events: none;
}
.tf-constellation .orb {
    position: relative;
    width: 200px; height: 200px; border-radius: 50%;
    background:
        radial-gradient(circle at 35% 30%, oklch(0.95 0.05 var(--accent-h) / 0.55), oklch(0.50 0.10 var(--accent-h) / 0.18) 60%, oklch(0.20 0.05 var(--accent-h) / 0.05) 100%),
        radial-gradient(circle at 70% 80%, oklch(0.70 0.16 var(--accent-h) / 0.55), transparent 60%);
    box-shadow:
        0 0 0 1px var(--accent-line),
        0 0 80px 10px var(--accent-soft),
        inset 0 0 50px rgba(255,255,255,0.06);
    display: flex; align-items: center; justify-content: center;
    flex-direction: column;
    color: var(--text-primary);
    pointer-events: auto;
    transition: transform 320ms cubic-bezier(.2,.7,.2,1), box-shadow 400ms;
    animation: tfc-orbBreath 5s ease-in-out infinite alternate;
}
@keyframes tfc-orbBreath {
    0% { box-shadow: 0 0 0 1px var(--accent-line), 0 0 60px 4px var(--accent-soft), inset 0 0 40px rgba(255,255,255,0.04); }
    100% { box-shadow: 0 0 0 1px var(--accent-line), 0 0 100px 16px var(--accent-soft), inset 0 0 60px rgba(255,255,255,0.10); }
}
.tf-constellation .orb.is-over {
    transform: scale(1.05);
    box-shadow:
        0 0 0 1.5px var(--accent),
        0 0 120px 24px var(--accent-soft),
        inset 0 0 60px rgba(255,255,255,0.12);
}
.tf-constellation .orb .orb-logo {
    width: 96px; height: 96px;
    object-fit: contain;
    border-radius: 18px;
    filter: drop-shadow(0 4px 14px rgba(0,0,0,0.35));
    user-select: none;
    -webkit-user-drag: none;
}
.tf-constellation .orb .initials {
    font-family: var(--font-serif);
    font-size: 64px; line-height: 1;
    letter-spacing: 0.02em;
    color: var(--text-primary);
    text-shadow: 0 0 24px var(--accent-soft);
}
.tf-constellation .orb .domain {
    font-family: var(--font-mono);
    font-size: 10.5px; letter-spacing: 0.06em;
    margin-top: 6px;
    color: rgba(var(--text-rgb), 0.85);
}
.tf-constellation .orb .score {
    position: absolute; bottom: -36px; left: 50%; transform: translateX(-50%);
    background: rgba(var(--card-rgb), 0.78);
    border: 1px solid var(--accent-line);
    border-radius: 999px;
    padding: 5px 14px;
    font: 500 11px/1 var(--font-mono);
    color: var(--text-primary);
    white-space: nowrap;
}
.tf-constellation .orb .score b { color: var(--accent); font-family: var(--font-serif); font-size: 14px; font-weight: 400; margin-right: 4px; }

/* In-orb loader — replaces the orb + satellites while we re-analyze a
   tracked brand from the sidebar. Sidebar, lens dock, and watch rail stay
   live so the user doesn't lose context. */
.tf-constellation .orb-loader {
    width: 420px;
    padding: 28px 32px;
    border-radius: 24px;
    background: rgba(var(--card-rgb), 0.85);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid var(--accent-line);
    box-shadow: 0 0 0 1px var(--accent-soft), 0 24px 64px -16px rgba(0,0,0,0.7);
    display: flex; flex-direction: column; gap: 14px;
    animation: tfc-orb-loader-in 320ms cubic-bezier(.2,.7,.2,1);
    pointer-events: auto;
}
@keyframes tfc-orb-loader-in {
    from { opacity: 0; transform: scale(0.92); }
    to   { opacity: 1; transform: scale(1); }
}
.tf-constellation .orb-loader-inits {
    font: 400 36px/1 var(--font-serif);
    color: var(--text-primary);
    letter-spacing: 0.02em;
    text-shadow: 0 0 24px var(--accent-soft);
}
.tf-constellation .orb-loader-domain {
    font: 400 11px/1 var(--font-mono);
    color: var(--accent);
    letter-spacing: 0.08em;
    margin-bottom: 4px;
}
.tf-constellation .orb-loader-steps {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column; gap: 7px;
}
.tf-constellation .orb-loader-steps > li {
    display: grid; grid-template-columns: 22px 1fr;
    align-items: center; gap: 10px;
    font: 500 12px/1.4 var(--font-ui);
    color: var(--muted);
    transition: color 220ms;
}
.tf-constellation .orb-loader-steps > li.is-done { color: var(--cream-2); }
.tf-constellation .orb-loader-steps > li.is-active { color: var(--text-primary); }
.tf-constellation .orb-loader-step-ic {
    width: 22px; height: 22px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--surface-mid);
    border: 1px solid var(--line);
    font: 500 11px/1 var(--font-mono);
}
.tf-constellation .orb-loader-steps > li.is-active .orb-loader-step-ic {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--accent);
    animation: tfc-pulse 1.4s ease-in-out infinite;
}
.tf-constellation .orb-loader-steps > li.is-done .orb-loader-step-ic {
    background: var(--accent);
    color: var(--ink-0);
    border-color: var(--accent);
}

/* ripple from lens drop */
.tf-constellation .ripple {
    position: absolute; left: 50%; top: 50%;
    width: 200px; height: 200px;
    border-radius: 50%;
    border: 2px solid var(--accent);
    transform: translate(-50%, -50%) scale(1);
    pointer-events: none;
    z-index: 4;
    animation: tfc-ripple 900ms ease-out forwards;
}
@keyframes tfc-ripple {
    to { transform: translate(-50%, -50%) scale(4.2); opacity: 0; border-width: 1px; }
}

/* ────────────── Satellite cards ────────────── */
.tf-constellation .satellite {
    position: absolute; left: 50%; top: 50%;
    width: 240px;
    max-height: 230px;
    /* Warm card surface + faint top-down lens-hue kiss so each lens leaves
       a subtle accent fingerprint on its cards. Stop is short (60%) so the
       hue reads only at the top edge. */
    background:
        linear-gradient(
            180deg,
            oklch(from var(--accent) l c h / var(--card-kiss)) 0%,
            transparent 60%
        ),
        var(--card-bg);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 11px 13px;
    color: var(--text-primary);
    pointer-events: auto;
    display: flex; flex-direction: column;
    overflow: hidden;
    transition:
        transform 600ms cubic-bezier(.2,.7,.2,1),
        opacity 400ms,
        border-color 200ms,
        background 200ms,
        box-shadow 200ms;
    will-change: transform;
    z-index: 10;
    animation: tfc-satIn 500ms cubic-bezier(.2,.7,.2,1);
}
@keyframes tfc-satIn {
    from { opacity: 0; transform: translate(calc(-50% + var(--tx, 0px)), calc(-50% + var(--ty, 0px))) scale(0.85); }
    to   { opacity: 1; }
}
.tf-constellation .satellite:hover {
    border-color: var(--line-2);
    background: rgba(var(--card-rgb), 0.92);
    box-shadow: 0 12px 28px -8px rgba(0,0,0,0.45);
}
.tf-constellation .sat-head {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
    margin-bottom: 6px;
}
.tf-constellation .sat-title {
    font: 600 13px/1.2 var(--font-display);
    letter-spacing: -0.01em;
    margin: 0;
}
.tf-constellation .sat-sub {
    font: 400 10.5px/1.3 var(--font-mono);
    color: var(--muted-2);
    letter-spacing: 0.02em;
    margin-top: 2px;
}
.tf-constellation .sat-kind {
    font: 500 9px/1 var(--font-mono);
    color: var(--muted-2);
    letter-spacing: 0.08em;
    padding: 3px 6px;
    border-radius: 999px;
    background: var(--surface-soft);
    border: 1px solid var(--line);
    text-transform: uppercase;
    white-space: nowrap;
    flex-shrink: 0;
}
.tf-constellation .sat-body { flex: 1; min-height: 0; overflow: hidden; }
/* Content-heavy (expandable) cards soft-fade their bottom edge instead of a
   hard chop, signalling "there's more — tap to expand". Where content fits,
   the fade lands in empty space and is invisible. */
.tf-constellation .satellite.is-expandable .sat-body {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent 100%);
            mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent 100%);
}

/* ────────────── Micro atoms ────────────── */
.tf-constellation .pill {
    display: inline-flex; align-items: center;
    padding: 2px 7px; border-radius: 999px;
    font: 500 10px/1.4 var(--font-mono);
    letter-spacing: 0.02em;
}
.tf-constellation .pill.pos { background: var(--pos-bg); color: var(--pos); }
.tf-constellation .pill.warn { background: var(--warn-bg); color: var(--warn); }
.tf-constellation .pill.neu { background: var(--neu-bg); color: var(--muted); }

/* Signals list */
.tf-constellation .signals { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; }
.tf-constellation .sig-row {
    display: grid; grid-template-columns: 1fr auto auto;
    align-items: center; gap: 8px;
    padding: 5px 0;
    border-bottom: 1px solid var(--line);
    font-size: 11.5px;
}
.tf-constellation .sig-row:last-child { border-bottom: 0; }
.tf-constellation .sig-label { color: var(--cream-2); }
.tf-constellation .sig-val { color: var(--text-primary); font-weight: 500; font-variant-numeric: tabular-nums; }

/* Metrics grid */
.tf-constellation .metrics-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tf-constellation .metric {
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 9px 11px;
    background: var(--surface-soft);
}
/* Label: clean sentence-case Inter (was tiny uppercase mono that wrapped to
   two cramped lines). Bigger, looser, far easier to scan. */
.tf-constellation .metric-label {
    font: 500 10px/1.3 var(--font-ui);
    color: var(--muted-2);
    letter-spacing: 0.005em;
}
/* Value: Space Grotesk, tabular so digits align; legible where the serif wasn't. */
.tf-constellation .metric-val {
    font: 600 20px/1.1 var(--font-display);
    color: var(--text-primary);
    letter-spacing: -0.01em;
    font-variant-numeric: tabular-nums;
    margin-top: 4px;
}
.tf-constellation .metric-delta {
    font: 500 10px/1 var(--font-mono);
    margin-top: 2px; color: var(--muted);
}
.tf-constellation .metric-delta.is-up { color: var(--pos); }
.tf-constellation .metric-delta.is-down { color: var(--warn); }

/* sparkline */
.tf-constellation .spark {
    display: block; width: 100%; height: 30px; margin-top: 4px;
}

/* donut + legend */
.tf-constellation .donut-wrap { display: grid; grid-template-columns: 70px 1fr; gap: 10px; align-items: center; }
.tf-constellation .legend { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 3px; }
.tf-constellation .legend > li {
    display: grid; grid-template-columns: 8px 1fr auto;
    align-items: center; gap: 6px;
    font-size: 10.5px;
}
.tf-constellation .legend .dot { width: 8px; height: 8px; border-radius: 50%; }
.tf-constellation .legend .name { color: var(--cream-2); }
.tf-constellation .legend .val { color: var(--muted); font-family: var(--font-mono); font-size: 10px; }

/* Org chart */
.tf-constellation .org { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.tf-constellation .org-tier { display: flex; gap: 6px; }
.tf-constellation .org-card {
    background: var(--surface-soft);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 6px 8px;
    min-width: 0;
}
.tf-constellation .org-card.is-ceo { background: var(--accent-soft); border-color: var(--accent-line); }
.tf-constellation .org-card .name {
    font: 500 10.5px/1.2 var(--font-ui); color: var(--text-primary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tf-constellation .org-card .title {
    font: 400 9.5px/1.2 var(--font-mono); color: var(--muted-2);
    letter-spacing: 0.02em;
    margin-top: 2px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* News list */
.tf-constellation .news-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.tf-constellation .news-list > li { display: grid; grid-template-columns: 4px 1fr; gap: 8px; align-items: flex-start; }
.tf-constellation .news-list .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--accent); margin-top: 5px; }
.tf-constellation .news-title { font: 500 11.5px/1.35 var(--font-ui); color: var(--text-primary); }
.tf-constellation .news-src { font: 400 10.5px/1.45 var(--font-ui); color: var(--muted-2); margin-top: 1px; }

/* Role list */
.tf-constellation .role-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.tf-constellation .role-list > li { display: flex; justify-content: space-between; gap: 8px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.tf-constellation .role-list > li:last-child { border-bottom: 0; padding-bottom: 0; }
.tf-constellation .role-time { font: 400 10px/1.2 var(--font-mono); color: var(--muted-2); white-space: nowrap; }

/* Competitor table */
.tf-constellation .comp-table { width: 100%; border-collapse: collapse; }
.tf-constellation .comp-table th { font: 500 9.5px/1.2 var(--font-mono); color: var(--muted-2); text-transform: uppercase; letter-spacing: 0.06em; text-align: left; padding: 4px 0; border-bottom: 1px solid var(--line); }
.tf-constellation .comp-table th:nth-child(2), .tf-constellation .comp-table th:nth-child(3) { text-align: right; }
.tf-constellation .comp-table td { padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 11px; color: var(--cream-2); }
.tf-constellation .comp-table td:nth-child(2), .tf-constellation .comp-table td:nth-child(3) { text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; color: var(--text-primary); }
.tf-constellation .comp-table tr:last-child td { border-bottom: 0; }
.tf-constellation .comp-table tr.is-self td { color: var(--text-primary); }
.tf-constellation .comp-table tr.is-self td:first-child { font-weight: 500; }
.tf-constellation .comp-table tr.is-self .accent-dot {
    display: inline-block; width: 6px; height: 6px; border-radius: 50%;
    background: var(--accent); margin-right: 5px; vertical-align: middle;
}

/* Rec list */
.tf-constellation .rec-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.tf-constellation .rec-list > li { display: grid; grid-template-columns: 18px 1fr; gap: 8px; }
.tf-constellation .rec-ic {
    width: 18px; height: 18px; border-radius: 5px;
    background: var(--accent-soft); color: var(--accent);
    display: grid; place-items: center;
    font: 500 10px/1 var(--font-mono);
}

/* Visual palette swatches */
.tf-constellation .swatch-grid {
    display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; margin-top: 4px;
}
.tf-constellation .swatch {
    aspect-ratio: 1/1; border-radius: 6px; border: 1px solid var(--line);
}

/* Tech stack chips */
.tf-constellation .tech-row { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.tf-constellation .tech-chip {
    font: 500 10px/1.4 var(--font-mono);
    padding: 2px 8px; border-radius: 999px;
    background: var(--surface-mid); color: var(--cream-2);
    border: 1px solid var(--line);
}
/* Secondary chip variant — specialties / aesthetic descriptors. Accent-tinted
   so they read as a distinct group from the plain industry/font chips. */
.tf-constellation .tech-chip.is-spec {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--text-primary);
}

/* Brand-snapshot synthesized summary (Overview lens) — clamped so the card
   keeps its height; the full text lives in the admin view. */
.tf-constellation .snap-summary {
    margin: 0;
    font: 400 10.5px/1.5 var(--font-ui);
    color: var(--cream-2);
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
}

/* Shared pulse used by the orb-loader's active step. */
@keyframes tfc-pulse { 50% { opacity: 0.5; } }

/* ────────────── Lens dock ────────────── */
/* ── Lens picker (left sidebar, below Comparisons) ───────────────────────── */
.tf-constellation .side-lens {
    display: flex; flex-direction: column; gap: 10px;
    flex: 0 0 auto;       /* natural height — pills wrap, footer sits below */
}
.tf-constellation .side-lens-divider {
    display: flex; align-items: center; gap: 8px;
    margin-top: 2px;
}
.tf-constellation .side-lens-divider::before,
.tf-constellation .side-lens-divider::after {
    content: ""; flex: 1; height: 1px;
    background: linear-gradient(to right, transparent, var(--line-2), transparent);
}
.tf-constellation .side-lens-divider span {
    font-size: 9px; color: var(--accent); opacity: 0.85;
}
.tf-constellation .side-lens-hint { padding: 0 4px; }
.tf-constellation .side-lens-hint-title {
    font: 500 10.5px/1 var(--font-mono);
    text-transform: uppercase; letter-spacing: 0.10em;
    color: var(--muted-2); margin-bottom: 5px;
}
.tf-constellation .side-lens-hint-sub {
    font: 400 11px/1.45 var(--font-ui);
    color: var(--muted);
}
/* Pills flow naturally side by side and wrap — content-width, so the rows
   stagger into an organic mosaic rather than a rigid full-width column. */
.tf-constellation .lens-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 2px 1px;
}
.tf-constellation .lens-chip {
    --lh: var(--accent-h);
    display: flex; align-items: center; gap: 6px;
    /* Tightened from 9px 14px 9px 9px so all 10 admin-tab pills fit one row
       on a standard desktop (≥1280px). Drop the ring-icon size below too. */
    padding: 7px 11px 7px 7px;
    background: rgba(var(--card-rgb), 0.85);
    border: 1px solid var(--line);
    border-radius: 999px;
    cursor: grab;
    transition: transform 150ms, background 150ms, border-color 150ms;
    white-space: nowrap;
    user-select: none;
}
.tf-constellation .lens-chip:hover {
    background: rgba(var(--card-rgb), 0.95);
    border-color: var(--line-2);
    transform: translateY(-2px);
    box-shadow: 0 8px 18px -6px rgba(0,0,0,0.5);
}
.tf-constellation .lens-chip:active { cursor: grabbing; }
.tf-constellation .lens-chip.is-active {
    border-color: oklch(0.82 0.13 var(--lh));
    background: oklch(0.82 0.13 var(--lh) / 0.18);
}
.tf-constellation .lens-chip .ring-icon {
    width: 18px; height: 18px; border-radius: 50%;
    background:
        conic-gradient(from 180deg, oklch(0.82 0.13 var(--lh)) 0% 50%, transparent 50% 100%),
        radial-gradient(circle, oklch(0.30 0.05 var(--lh)) 60%, transparent 62%);
    border: 1px solid oklch(0.82 0.13 var(--lh) / 0.6);
    flex-shrink: 0;
}
.tf-constellation .lens-chip .lens-label { font: 500 11.5px/1 var(--font-ui); color: var(--text-primary); }

/* Sidebar pills size to their label so they tile side by side. */
.tf-constellation .side-lens .lens-clear { align-self: flex-start; margin-top: 4px; }
.tf-constellation .lens-clear {
    background: transparent; border: 1px solid var(--line); color: var(--muted);
    border-radius: 999px; padding: 6px 10px;
    font: 500 10px/1 var(--font-mono); letter-spacing: 0.06em;
    cursor: pointer; transition: color 150ms, border-color 150ms;
}
.tf-constellation .lens-clear:hover { color: var(--text-primary); border-color: var(--line-2); }

/* drag ghost */
.tf-constellation .ghost {
    position: absolute; pointer-events: none; z-index: 1000;
    transform-origin: top left;
    filter: drop-shadow(0 16px 28px rgba(0,0,0,0.55));
}

/* ────────────── Domain entry (idle / loading) ────────────── */
.tf-constellation .entry-wrap {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    z-index: 6;
}
.tf-constellation .entry-card {
    width: 480px; max-width: 90%;
    background: rgba(var(--card-rgb), 0.85);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid var(--line);
    border-radius: 18px;
    padding: 28px 28px 24px;
    display: flex; flex-direction: column; gap: 14px;
    box-shadow: 0 24px 60px -16px rgba(0,0,0,0.6);
}
.tf-constellation .entry-card .eyebrow {
    font: 500 10px/1 var(--font-mono);
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--accent);
}
.tf-constellation .entry-card h1 {
    font: 400 32px/1.05 var(--font-serif);
    color: var(--text-primary);
    margin: 0;
    letter-spacing: -0.01em;
}
.tf-constellation .entry-card h1 em { font-style: italic; color: var(--accent); }
.tf-constellation .entry-card p {
    font: 400 12.5px/1.5 var(--font-ui);
    color: var(--cream-2);
    margin: 0;
}
.tf-constellation .entry-input-row {
    display: flex; gap: 8px; margin-top: 4px;
}
.tf-constellation .entry-input {
    flex: 1;
    background: rgba(var(--page-rgb), 0.7);
    border: 1px solid var(--line-2);
    border-radius: 10px;
    padding: 11px 14px;
    color: var(--text-primary);
    font: 500 13px/1 var(--font-mono);
    letter-spacing: 0.02em;
    outline: none;
}
.tf-constellation .entry-input::placeholder { color: var(--muted-2); }
.tf-constellation .entry-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.tf-constellation .entry-go {
    background: var(--accent);
    color: var(--ink-0);
    border: 0; border-radius: 10px;
    padding: 0 18px;
    font: 600 12px/1 var(--font-ui);
    cursor: pointer;
    letter-spacing: 0.02em;
}
.tf-constellation .entry-go:hover { opacity: 0.92; }
.tf-constellation .entry-go:disabled { opacity: 0.5; cursor: not-allowed; }
.tf-constellation .entry-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.tf-constellation .entry-chip {
    font: 500 10.5px/1 var(--font-mono);
    padding: 5px 10px;
    border-radius: 999px;
    background: var(--surface-soft);
    border: 1px solid var(--line);
    color: var(--cream-2);
    cursor: pointer;
    letter-spacing: 0.02em;
}
.tf-constellation .entry-chip:hover { background: var(--line); color: var(--text-primary); border-color: var(--line-2); }
.tf-constellation .entry-error {
    font: 500 11px/1.4 var(--font-mono);
    color: var(--warn);
    background: var(--warn-bg);
    border: 1px solid oklch(0.78 0.13 50 / 0.30);
    padding: 8px 12px;
    border-radius: 8px;
    margin-top: 4px;
}

/* loading state — replaces entry card content */
.tf-constellation .loading-card { padding: 28px; }
.tf-constellation .loading-steps {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column; gap: 8px;
}
.tf-constellation .loading-steps > li {
    display: grid; grid-template-columns: 22px 1fr;
    align-items: center; gap: 10px;
    font: 500 12px/1.4 var(--font-ui);
    color: var(--muted);
    transition: color 220ms;
}
.tf-constellation .loading-steps > li.is-done { color: var(--cream-2); }
.tf-constellation .loading-steps > li.is-active { color: var(--text-primary); }
.tf-constellation .loading-steps .step-ic {
    width: 22px; height: 22px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--surface-mid);
    border: 1px solid var(--line);
    font: 500 11px/1 var(--font-mono);
}
.tf-constellation .loading-steps > li.is-active .step-ic {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--accent);
    animation: tfc-pulse 1.4s ease-in-out infinite;
}
.tf-constellation .loading-steps > li.is-done .step-ic {
    background: var(--accent);
    color: var(--ink-0);
    border-color: var(--accent);
}

/* ====================================================================
   Unsaved-result navigation guard modal — rendered at page root so it
   floats above ANY view (constellation orbit OR admin tabbed footprint).
   Token values inlined since this lives outside .tf-constellation.
   ==================================================================== */

.tfc-guard-backdrop {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    display: flex; align-items: center; justify-content: center;
    z-index: 10000;
    animation: tfc-guard-fade 220ms ease-out;
    padding: 20px;
}
@keyframes tfc-guard-fade { from { opacity: 0; } to { opacity: 1; } }

.tfc-guard-modal {
    width: min(440px, 100%);
    background: linear-gradient(160deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
    border: 1px solid var(--border);
    border-radius: 18px;
    padding: 28px 28px 22px;
    box-shadow: 0 32px 80px -20px rgba(0,0,0,0.7), 0 0 0 1px var(--border);
    color: var(--text-primary);
    animation: tfc-guard-pop 280ms cubic-bezier(.2,.7,.2,1);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
@keyframes tfc-guard-pop {
    from { opacity: 0; transform: scale(0.92) translateY(8px); }
    to   { opacity: 1; transform: none; }
}

.tfc-guard-eyebrow {
    font: 500 10.5px/1 'JetBrains Mono', ui-monospace, monospace;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: oklch(0.82 0.13 75);
    margin-bottom: 10px;
}

.tfc-guard-title {
    font: 400 28px/1.15 'Instrument Serif', 'Times New Roman', serif;
    letter-spacing: -0.01em;
    margin: 0 0 10px;
    color: var(--text-primary);
}
.tfc-guard-title em {
    font-style: italic;
    color: oklch(0.82 0.13 75);
}

.tfc-guard-body {
    font: 400 13.5px/1.55 'Inter', sans-serif;
    color: var(--text-secondary);
    margin: 0 0 22px;
}
.tfc-guard-body b {
    color: var(--text-primary);
    font-weight: 500;
}

.tfc-guard-actions {
    display: flex; flex-direction: column; gap: 8px;
}
.tfc-guard-btn {
    width: 100%;
    padding: 11px 14px;
    border-radius: 10px;
    font: 500 13px/1 'Inter', sans-serif;
    cursor: pointer;
    transition: background 150ms, border-color 150ms, transform 100ms, opacity 150ms;
    border: 1px solid transparent;
    letter-spacing: 0.005em;
}
.tfc-guard-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.tfc-guard-btn:not(:disabled):active { transform: translateY(1px); }

.tfc-guard-btn--primary {
    background: oklch(0.82 0.13 75);
    color: #07080c;
    font-weight: 600;
}
.tfc-guard-btn--primary:not(:disabled):hover {
    background: oklch(0.86 0.13 75);
}

.tfc-guard-btn--ghost {
    background: transparent;
    color: var(--text-secondary);
    border-color: var(--border);
}
.tfc-guard-btn--ghost:not(:disabled):hover {
    background: var(--bg-muted);
    color: var(--text-primary);
    border-color: var(--text-muted);
}

.tfc-guard-btn--cancel {
    background: transparent;
    color: var(--text-muted);
    border: 0;
    padding: 8px 14px;
    margin-top: 2px;
    font-size: 11.5px;
}
.tfc-guard-btn--cancel:not(:disabled):hover {
    color: var(--text-primary);
}

/* ─────────────────────────────────────────────────────────────────────
   Tap-to-expand satellite cards (postsGrid / news / roles / competitors
   / locations / org). The overlay is a sibling of the satellite map inside
   `.center`, sized to ~720×480 with scrollable body. Other satellites dim.
   ───────────────────────────────────────────────────────────────────── */

.tf-constellation .satellite.is-expandable {
    cursor: pointer;
}
.tf-constellation .satellite.is-expandable:hover {
    border-color: var(--accent);
    box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.5),
                0 0 0 1px var(--accent) inset;
}
.tf-constellation .satellite.is-hidden {
    opacity: 0;
    pointer-events: none;
    transition: opacity 180ms ease-out;
}
.tf-constellation .satellite.is-dimmed {
    opacity: 0.15;
    filter: blur(2px);
    pointer-events: none;
    transition: opacity 220ms ease-out, filter 220ms ease-out;
}

/* ── Token paywall — locked card + lens chip ─────────────────────────────── */
.tf-constellation .satellite.is-locked {
    cursor: default;
}
/* No expand-hover glow on a locked card — just a soft accent edge. */
.tf-constellation .satellite.is-locked:hover {
    border-color: var(--line-2);
    background: rgba(var(--card-rgb), 0.92);
    box-shadow: 0 12px 28px -8px rgba(0,0,0,0.45);
}
/* Corner badge becomes the lock indicator (keeps the .sat-kind pill shape). */
.tf-constellation .sat-kind.is-lock {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    border-color: oklch(from var(--accent) l c h / 0.45);
    background: oklch(from var(--accent) l c h / 0.12);
    font-size: 11px;
}
.tf-constellation .sat-lock {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 100%;
    padding: 4px 6px 8px;
    text-align: center;
}
.tf-constellation .sat-lock-icon {
    font-size: 22px;
    color: var(--accent);
    opacity: 0.9;
    margin-bottom: 1px;
}
.tf-constellation .sat-lock-title {
    font: 500 12px/1.2 var(--font-ui);
    color: var(--text-primary);
    letter-spacing: -0.005em;
}
.tf-constellation .sat-lock-msg {
    font: 400 11px/1.5 var(--font-ui);
    color: var(--muted-2);
    max-width: 200px;
}
/* Locked lens chip — disabled: not selectable, not draggable. */
.tf-constellation .lens-chip.is-locked {
    cursor: not-allowed;
    opacity: 0.5;
}
.tf-constellation .lens-chip.is-locked:hover {
    transform: none;
    border-color: var(--line);
    background: rgba(var(--card-rgb), 0.85);
    box-shadow: none;
}
.tf-constellation .lens-chip .lens-lock {
    font-size: 11px;
    color: var(--muted-2);
    margin-left: 1px;
    flex-shrink: 0;
}

.tf-constellation .expanded-backdrop {
    position: absolute;
    inset: 0;
    z-index: 50;
    background: var(--backdrop);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: tfc-expFade 200ms ease-out;
    cursor: zoom-out;
}
.tf-constellation .expanded-card {
    position: absolute;
    top: 50%;
    left: 50%;
    width: min(720px, 90%);
    height: min(480px, 78%);
    transform: translate(-50%, -50%);
    /* Same warm + lens-kiss recipe as .satellite but on the stronger surface. */
    background:
        linear-gradient(
            180deg,
            oklch(from var(--accent) l c h / var(--card-kiss)) 0%,
            transparent 50%
        ),
        var(--card-bg-strong);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--line-2);
    border-radius: 18px;
    padding: 18px 20px 14px;
    z-index: 60;
    display: flex;
    flex-direction: column;
    box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.6),
                0 0 0 1px var(--accent) inset;
    animation: tfc-expScale 260ms cubic-bezier(.2,.7,.2,1);
    color: var(--text-primary);
}
.tf-constellation .expanded-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
    padding-bottom: 12px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
}
.tf-constellation .expanded-close {
    background: var(--surface-mid);
    border: 1px solid var(--line);
    color: var(--text-primary);
    width: 30px;
    height: 30px;
    border-radius: 8px;
    cursor: pointer;
    font-size: 20px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 150ms, border-color 150ms;
}
.tf-constellation .expanded-close:hover {
    background: var(--line);
    border-color: var(--line-2);
}
.tf-constellation .expanded-body {
    flex: 1;
    overflow-y: auto;
    padding-right: 4px;
}
.tf-constellation .expanded-body::-webkit-scrollbar {
    width: 6px;
}
.tf-constellation .expanded-body::-webkit-scrollbar-thumb {
    background: var(--surface-strong);
    border-radius: 3px;
}

@keyframes tfc-expFade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes tfc-expScale {
    from { opacity: 0; transform: translate(-50%, -50%) scale(0.92); }
    to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* ─────────────────────────────────────────────────────────────────────
   Collapsed postsGrid satellite — 2×2 thumbnail preview
   ───────────────────────────────────────────────────────────────────── */

.tf-constellation .posts-mini {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px;
    height: 100%;
    width: 100%;
}
.tf-constellation .posts-mini-cell {
    background: var(--surface-soft);
    border: 1px solid var(--line);
    border-radius: 6px;
    overflow: hidden;
    aspect-ratio: 1;
    position: relative;
}
.tf-constellation .posts-mini-cell img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.tf-constellation .posts-mini-ph {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font: 600 14px/1 var(--font-display);
    color: var(--muted-2);
    background: linear-gradient(135deg, var(--surface-mid), var(--surface-soft));
}

/* ─────────────────────────────────────────────────────────────────────
   ExpandedBody — shared atoms (rows, titles, pills, tags)
   ───────────────────────────────────────────────────────────────────── */

.tf-constellation .exp-empty {
    text-align: center;
    padding: 40px 16px;
    color: var(--muted);
    font: 400 12px/1.5 var(--font-ui);
}
.tf-constellation .exp-row-title {
    font: 600 13px/1.3 var(--font-display);
    color: var(--text-primary);
    margin-bottom: 2px;
}
.tf-constellation .exp-row-sub {
    font: 400 11px/1.45 var(--font-ui);
    color: var(--muted);
}

/* Brand Snapshot — full positioning summary in the expand modal */
.tf-constellation .exp-snapshot { display: flex; flex-direction: column; gap: 14px; }
.tf-constellation .exp-snapshot-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.tf-constellation .exp-snapshot-score {
    font: 600 40px/1 var(--font-display); letter-spacing: -0.02em; color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}
.tf-constellation .exp-snapshot-max { font: 400 14px/1 var(--font-mono); color: var(--muted); margin-left: 2px; }
.tf-constellation .exp-snapshot-label { font: 400 11px/1 var(--font-ui); color: var(--muted-2); }
.tf-constellation .exp-snapshot-summary { margin: 0; font: 400 13px/1.6 var(--font-ui); color: var(--cream-2); }

/* AI Recommendations — full list in the expand modal */
.tf-constellation .exp-recs { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; }
.tf-constellation .exp-rec-row {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 12px 0; border-bottom: 1px solid var(--line);
}
.tf-constellation .exp-rec-row:first-child { padding-top: 0; }
.tf-constellation .exp-rec-row:last-child { border-bottom: 0; padding-bottom: 0; }
.tf-constellation .exp-rec-ic {
    width: 24px; height: 24px; border-radius: 6px; flex-shrink: 0;
    background: var(--accent-soft); color: var(--accent);
    display: grid; place-items: center;
    font: 500 12px/1 var(--font-mono);
}
.tf-constellation .exp-muted   { color: var(--muted-2); }
.tf-constellation .exp-tag {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--surface-mid);
    border: 1px solid var(--line);
    font: 500 9.5px/1.3 var(--font-mono);
    color: var(--muted);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.tf-constellation .exp-link-btn {
    padding: 5px 10px;
    border-radius: 6px;
    border: 1px solid var(--line-2);
    background: var(--surface-soft);
    color: var(--text-primary);
    font: 500 11px/1 var(--font-mono);
    letter-spacing: 0.04em;
    text-decoration: none;
    white-space: nowrap;
    transition: background 150ms, border-color 150ms;
}
.tf-constellation .exp-link-btn:hover {
    background: var(--surface-mid);
    border-color: var(--accent);
}

/* Posts (expanded grid) */
.tf-constellation .exp-post-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 12px;
}
.tf-constellation .exp-post-filter {
    font: 500 11px/1 var(--font-mono);
    letter-spacing: 0.04em;
    padding: 5px 11px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface-soft);
    color: var(--muted);
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.tf-constellation .exp-post-filter:hover { color: var(--text-primary); }
.tf-constellation .exp-post-filter.is-active {
    background: oklch(from var(--accent) l c h / 0.18);
    border-color: var(--accent);
    color: var(--text-primary);
}
.tf-constellation .exp-posts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 10px;
}
.tf-constellation .exp-post-cell {
    text-decoration: none;
    color: var(--text-primary);
    display: flex;
    flex-direction: column;
    gap: 6px;
    border-radius: 8px;
    overflow: hidden;
    transition: transform 150ms;
}
.tf-constellation .exp-post-cell:hover { transform: translateY(-2px); }
.tf-constellation .exp-post-img {
    position: relative;
    aspect-ratio: 1;
    background: var(--surface-soft);
    border: 1px solid var(--line);
    border-radius: 8px;
    overflow: hidden;
}
.tf-constellation .exp-post-img img {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
/* No-image posts (text-only tweets, Reddit threads): show the post text/title
   instead of a blank channel label. Padding-top clears the channel badge. */
.tf-constellation .exp-post-ph {
    width: 100%; height: 100%;
    padding: 30px 12px 12px;
    font: 500 12px/1.45 var(--font-mono);
    color: var(--muted);
    letter-spacing: 0;
    text-transform: none;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
}
.tf-constellation .exp-post-badge {
    position: absolute;
    top: 6px; left: 6px;
    padding: 2px 7px;
    border-radius: 999px;
    background: rgba(var(--page-rgb), 0.7);
    backdrop-filter: blur(4px);
    color: var(--text-primary);
    font: 500 9px/1.4 var(--font-mono);
    letter-spacing: 0.06em;
}
.tf-constellation .exp-post-meta {
    font: 400 10px/1.3 var(--font-mono);
    color: var(--muted);
    padding: 0 2px;
}

/* News (expanded list) */
.tf-constellation .exp-news {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.tf-constellation .exp-news-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface-soft);
}
.tf-constellation .exp-news-link {
    flex: 1;
    text-decoration: none;
    color: var(--text-primary);
    min-width: 0;
}
.tf-constellation .exp-news-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    flex-shrink: 0;
}

/* Roles (expanded list) */
.tf-constellation .exp-roles {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.tf-constellation .exp-role-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface-soft);
}
.tf-constellation .exp-row-l { flex: 1; min-width: 0; }

/* Competitors (expanded table) */
.tf-constellation .exp-table {
    width: 100%;
    border-collapse: collapse;
    font: 400 12px/1.4 var(--font-mono);
}
.tf-constellation .exp-table thead th {
    text-align: left;
    padding: 8px 10px;
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    font: 500 10px/1 var(--font-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.tf-constellation .exp-table tbody td {
    padding: 10px;
    border-bottom: 1px solid var(--line);
    color: var(--text-primary);
    vertical-align: middle;
}
.tf-constellation .exp-table tbody tr:last-child td { border-bottom: 0; }
.tf-constellation .exp-row-self td {
    background: var(--accent-soft);
    font-weight: 600;
}
.tf-constellation .exp-avi {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px; height: 22px;
    border-radius: 999px;
    background: var(--surface-mid);
    border: 1px solid var(--line);
    font: 600 9px/1 var(--font-mono);
    color: var(--text-primary);
    margin-right: 8px;
    letter-spacing: 0.04em;
}

/* Locations (expanded) */
.tf-constellation .exp-locations {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.tf-constellation .exp-hq {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--accent);
    border-radius: 8px;
    background: var(--surface-soft);
}
.tf-constellation .exp-hq-tag {
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--accent);
    color: #0a0c14;
    font: 700 9px/1 var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.tf-constellation .exp-country-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 2px 6px;
    border-bottom: 1px solid var(--line);
    margin-bottom: 6px;
}
.tf-constellation .exp-country-name {
    font: 600 11px/1 var(--font-mono);
    color: var(--text-primary);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.tf-constellation .exp-loc-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.tf-constellation .exp-loc-row {
    padding: 6px 8px;
    border-radius: 6px;
    background: var(--surface-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.tf-constellation .exp-loc-row-l { min-width: 0; flex: 1; }
.tf-constellation .exp-loc-row .exp-tag { flex-shrink: 0; }
.tf-constellation .exp-loc-more {
    padding: 6px 8px;
    font: 400 10px/1.4 var(--font-mono);
    color: var(--muted-2);
    text-align: center;
}

/* Org Chart (expanded grid) */
.tf-constellation .exp-org-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 10px;
}
.tf-constellation .exp-org-cell {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 10px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface-soft);
}
.tf-constellation .exp-org-avi {
    width: 32px; height: 32px;
    border-radius: 999px;
    background: var(--surface-mid);
    border: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    font: 600 10px/1 var(--font-mono);
    color: var(--text-primary);
    flex-shrink: 0;
    letter-spacing: 0.04em;
}
.tf-constellation .exp-org-meta { flex: 1; min-width: 0; }
.tf-constellation .exp-org-tags {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    margin-top: 6px;
}

/* ─────────────────────────────────────────────────────────────────────
   Maps — collapsed mini preview (satellite) + full map (expand overlay)
   ───────────────────────────────────────────────────────────────────── */

/* Collapsed satellite preview. Non-interactive: pointer-events:none lets the
   tap fall through to the satellite's expand handler instead of panning. */
.tf-constellation .tfc-mini-map {
    width: 100%;
    height: 150px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--line);
    background: var(--surface-soft);
    pointer-events: none;
}
/* Leaflet injects inline z-indexes that can sit above our satellites; clamp
   the tile/control layer so cards and the expand overlay always win. */
.tf-constellation .tfc-mini-map .leaflet-pane,
.tf-constellation .tfc-mini-map .leaflet-control { z-index: 1 !important; }
.tf-constellation .tfc-mini-map .leaflet-control-attribution {
    font-size: 8px;
    background: rgba(var(--card-rgb), 0.6);
}

/* Full map inside the expand overlay — interactive. */
.tf-constellation .exp-mapwrap {
    display: flex;
    flex-direction: column;
    gap: 10px;
    height: 100%;
}
.tf-constellation .exp-map-strip {
    display: flex;
    gap: 18px;
    flex-wrap: wrap;
    font: 400 11px/1 var(--font-mono);
    color: var(--muted);
    letter-spacing: 0.04em;
    flex-shrink: 0;
}
.tf-constellation .exp-map-strip b {
    font: 600 14px/1 var(--font-display);
    color: var(--text-primary);
    margin-right: 4px;
}
.tf-constellation .exp-map {
    flex: 1;
    min-height: 320px;
    border-radius: 10px;
    overflow: hidden;
    border: 1px solid var(--line);
    background: var(--surface-soft);
}
.tf-constellation .exp-map .leaflet-control-attribution { font-size: 9px; }

/* Competitor revenue-growth cell (expanded table) */
.tf-constellation .exp-growth { font-weight: 600; font-variant-numeric: tabular-nums; }
.tf-constellation .exp-growth.is-up   { color: var(--pos); }
.tf-constellation .exp-growth.is-down { color: var(--warn); }

/* ════════════════════════════════════════════════════════════════════════
   MOBILE — touch-first Constellation. Activated by ConstellationView when
   useIsMobile() is true (it swaps <ConstellationStage/> for
   <ConstellationMobile/> and adds .is-mobile on the root). All styles live
   under .tf-constellation so they stay scoped, and reuse the same tokens +
   atoms (.orb recipe, .pill, .sig-row, .exp-*, …) as the desktop orbit.
   ════════════════════════════════════════════════════════════════════════ */

.tf-constellation.is-mobile { font-size: 13px; }

.tf-constellation .tfm {
    position: absolute; inset: 0;
    display: flex; flex-direction: column;
    background:
        radial-gradient(700px 520px at 50% 0%, oklch(0.82 0.13 var(--accent-h) / 0.10), transparent 70%),
        radial-gradient(1200px 900px at 50% 30%, var(--bg-secondary), var(--ink-0) 80%);
    overflow: hidden;
    transition: background 1200ms cubic-bezier(.2,.7,.2,1);
}

/* ── Top bar: breadcrumb + page actions ─────────────────────────────── */
.tf-constellation .tfm-topbar {
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--line);
    background: rgba(var(--page-rgb), 0.5);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    z-index: 15;
    min-width: 0;
}
.tf-constellation .tfm-crumbs {
    display: flex; align-items: center; gap: 6px;
    font: 600 10.5px/1 var(--font-mono); letter-spacing: 0.08em;
    text-transform: uppercase;
    min-width: 0; overflow: hidden;
}
.tf-constellation .tfm-crumb-dim { color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 34vw; }
.tf-constellation .tfm-crumb-sep { color: var(--muted-2); opacity: 0.5; }
.tf-constellation .tfm-crumb-now { color: var(--accent); white-space: nowrap; }
.tf-constellation .tfm-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.tf-constellation .tfm-actions .pill-btn { padding: 6px 9px; font-size: 10px; }

/* ── Scrollable content column ──────────────────────────────────────── */
.tf-constellation .tfm-scroll {
    flex: 1; min-height: 0;
    overflow-y: auto; overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    /* Thin, themed scrollbar — the OS default rendered as a wide unstyled bar. */
    scrollbar-width: thin;
    scrollbar-color: var(--surface-strong) transparent;
}
.tf-constellation .tfm-scroll::-webkit-scrollbar { width: 5px; }
.tf-constellation .tfm-scroll::-webkit-scrollbar-track { background: transparent; }
.tf-constellation .tfm-scroll::-webkit-scrollbar-thumb {
    background: var(--surface-strong);
    border-radius: 3px;
}
.tf-constellation .tfm-scroll::-webkit-scrollbar-thumb:hover { background: var(--muted-2); }

/* ── HERO: swipeable lens carousel ──────────────────────────────────── */
.tf-constellation .tfm-hero {
    position: relative;
    /* Trimmed from a flat 330px — that left a lot of dead air above/below the
       orb. clamp scales the orbit to the phone: tighter on short screens, never
       cramped on tall ones. Chips are %-positioned so they pull in with it. */
    height: clamp(248px, 38vh, 300px);
    overflow: hidden;
    touch-action: pan-y;
    user-select: none;
    border-bottom: 1px solid var(--line);
}
.tf-constellation .tfm-hero-track {
    display: flex;
    height: 100%;
    will-change: transform;
    transition: transform 420ms cubic-bezier(.2,.7,.2,1);
}
.tf-constellation .tfm-hero-track.is-dragging { transition: none; }
.tf-constellation .tfm-slide {
    flex: 0 0 100%;
    width: 100%; height: 100%;
    position: relative;
}
.tf-constellation .tfm-hero-loading {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    padding: 16px;
}
.tf-constellation .tfm-hero-loading .orb-loader { width: min(420px, 92%); }

/* mini orbit */
.tf-constellation .tfm-mini { position: absolute; inset: 0; }
.tf-constellation .tfm-mini-ring {
    position: absolute; left: 50%; top: 50%;
    border: 1px solid var(--line);
    border-radius: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
}
.tf-constellation .tfm-mini-ring.r-a { width: 210px; height: 210px; border-style: dashed; opacity: .5; animation: tfc-rspin 90s linear infinite; }
.tf-constellation .tfm-mini-ring.r-b { width: 320px; height: 320px; opacity: .22; }

.tf-constellation .tfm-mini-orb {
    position: absolute; left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    width: 124px; height: 124px; border-radius: 50%;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    background:
        radial-gradient(circle at 35% 30%, oklch(0.95 0.05 var(--accent-h) / 0.55), oklch(0.50 0.10 var(--accent-h) / 0.18) 60%, oklch(0.20 0.05 var(--accent-h) / 0.05) 100%),
        radial-gradient(circle at 70% 80%, oklch(0.70 0.16 var(--accent-h) / 0.55), transparent 60%);
    box-shadow: 0 0 0 1px var(--accent-line), 0 0 56px 6px var(--accent-soft), inset 0 0 36px rgba(255,255,255,0.06);
    z-index: 6;
    animation: tfc-orbBreath 5s ease-in-out infinite alternate;
}
.tf-constellation .tfm-mini-logo {
    width: 56px; height: 56px; object-fit: contain; border-radius: 13px;
    filter: drop-shadow(0 4px 12px rgba(0,0,0,0.35));
    -webkit-user-drag: none;
}
.tf-constellation .tfm-mini-inits {
    font: 400 38px/1 var(--font-serif); color: var(--text-primary);
    text-shadow: 0 0 18px var(--accent-soft);
}
.tf-constellation .tfm-mini-snap {
    margin-top: 5px;
    font: 500 8px/1 var(--font-mono); letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--accent);
}
.tf-constellation .tfm-mini-name {
    margin-top: 3px;
    font: 600 13px/1.1 var(--font-display); letter-spacing: -0.01em;
    color: var(--text-primary);
    max-width: 110px; text-align: center;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tf-constellation .tfm-mini-score {
    position: absolute; bottom: -13px; left: 50%; transform: translateX(-50%);
    background: rgba(var(--card-rgb), 0.82);
    border: 1px solid var(--accent-line);
    border-radius: 999px;
    padding: 3px 10px;
    font: 500 9.5px/1 var(--font-mono); color: var(--text-primary); white-space: nowrap;
}
.tf-constellation .tfm-mini-score b { color: var(--accent); font-family: var(--font-serif); font-size: 12px; font-weight: 400; margin-right: 4px; }

/* watered-down satellite chips — title only, float around the orb */
.tf-constellation .tfm-chip {
    position: absolute; z-index: 4;
    display: inline-flex; align-items: center; gap: 6px;
    max-width: 41%;
    padding: 7px 10px;
    border-radius: 11px;
    border: 1px solid var(--line);
    background:
        linear-gradient(180deg, oklch(from var(--accent) l c h / var(--card-kiss)) 0%, transparent 70%),
        var(--card-bg);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    color: var(--text-primary);
    text-align: left;
    cursor: pointer;
    animation: tfc-satIn 460ms cubic-bezier(.2,.7,.2,1) backwards;
}
.tf-constellation .tfm-chip:active { transform: scale(0.96); }
.tf-constellation .tfm-chip-n {
    font: 500 8px/1 var(--font-mono); color: var(--muted-2); letter-spacing: 0.06em; flex-shrink: 0;
}
.tf-constellation .tfm-chip-t {
    font: 600 10.5px/1.15 var(--font-display); letter-spacing: -0.01em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tf-constellation .tfm-chip.is-locked { opacity: 0.6; }
.tf-constellation .tfm-chip-lock { font-size: 11px; color: var(--muted-2); flex-shrink: 0; }

.tf-constellation .tfm-chip.pos-1 { top: 10%;    left: 3%;  animation-delay: 40ms;  }
.tf-constellation .tfm-chip.pos-2 { top: 7%;     right: 3%; animation-delay: 90ms;  }
.tf-constellation .tfm-chip.pos-3 { top: 43%;    left: 0;   animation-delay: 140ms; }
.tf-constellation .tfm-chip.pos-4 { top: 39%;    right: 0;  animation-delay: 190ms; }
.tf-constellation .tfm-chip.pos-5 { bottom: 13%; left: 4%;  animation-delay: 240ms; }
.tf-constellation .tfm-chip.pos-6 { bottom: 10%; right: 4%; animation-delay: 290ms; }

/* slide dots */
.tf-constellation .tfm-dots {
    position: absolute; left: 0; right: 0; bottom: 8px;
    display: flex; justify-content: center; gap: 6px;
    z-index: 8; pointer-events: auto;
}
.tf-constellation .tfm-dot {
    width: 6px; height: 6px; border-radius: 50%;
    border: 0; padding: 0;
    background: var(--surface-strong);
    transition: background 200ms, width 200ms;
}
.tf-constellation .tfm-dot.is-on { background: var(--accent); width: 16px; border-radius: 3px; }

/* ── Full pre-expanded cards ────────────────────────────────────────── */
.tf-constellation .tfm-cards {
    display: flex; flex-direction: column; gap: 12px;
    padding: 14px 14px 28px;
}
.tf-constellation .tfm-card {
    background:
        linear-gradient(180deg, oklch(from var(--accent) l c h / var(--card-kiss)) 0%, transparent 42%),
        var(--card-bg-strong);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 15px 15px 16px;
    color: var(--text-primary);
    box-shadow: 0 10px 28px -18px rgba(0,0,0,0.5);
    scroll-margin-top: 12px;
    animation: tfc-tfmCardIn 420ms cubic-bezier(.2,.7,.2,1) backwards;
}
@keyframes tfc-tfmCardIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.tf-constellation .tfm-card-head {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 10px;
    padding-bottom: 11px; margin-bottom: 13px;
    border-bottom: 1px solid var(--line);
}
.tf-constellation .tfm-card-headl { min-width: 0; }
.tf-constellation .tfm-card-eyebrow {
    font: 500 9px/1 var(--font-mono); letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--accent); margin-bottom: 6px;
}
.tf-constellation .tfm-card-title {
    margin: 0; font: 600 17px/1.15 var(--font-display); letter-spacing: -0.01em;
}
.tf-constellation .tfm-card-sub {
    margin-top: 4px; font: 400 11px/1.35 var(--font-mono); color: var(--muted-2); letter-spacing: 0.02em;
}
.tf-constellation .tfm-card-kind {
    flex-shrink: 0;
    font: 500 10px/1 var(--font-mono); letter-spacing: 0.06em; color: var(--muted-2);
    padding: 4px 8px; border-radius: 999px;
    background: var(--surface-soft); border: 1px solid var(--line);
    display: inline-flex; align-items: center;
}
.tf-constellation .tfm-card-kind.is-lock { color: var(--accent); border-color: var(--accent-line); }
.tf-constellation .tfm-card-body { font-size: 12.5px; }
/* Let map / scroll modules breathe at full width inside a card */
.tf-constellation .tfm-card-body .exp-map { min-height: 240px; }

/* locked module card */
.tf-constellation .tfm-card.is-locked { opacity: 0.96; }
.tf-constellation .tfm-card-lock { text-align: center; padding: 18px 8px 10px; }
.tf-constellation .tfm-card-lock-icon { font-size: 26px; color: var(--accent); }
.tf-constellation .tfm-card-lock-title { margin-top: 8px; font: 600 14px/1.2 var(--font-display); }
.tf-constellation .tfm-card-lock-msg { margin-top: 6px; font-size: 11.5px; color: var(--muted); line-height: 1.5; max-width: 280px; margin-left: auto; margin-right: auto; }

.tf-constellation .tfm-feedback {
    margin-top: 2px;
    width: 100%;
    padding: 13px 16px;
    border-radius: 12px;
    border: 1px dashed var(--line-2);
    background: rgba(var(--page-rgb), 0.4);
    color: rgba(var(--text-rgb), 0.6);
    font: 500 12px/1 var(--font-ui);
    cursor: pointer;
}
.tf-constellation .tfm-feedback:active { background: rgba(var(--page-rgb), 0.7); }

/* ── Bottom tab bar ─────────────────────────────────────────────────── */
.tf-constellation .tfm-tabs {
    flex-shrink: 0;
    border-top: 1px solid var(--line);
    background: rgba(var(--page-rgb), 0.72);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    z-index: 20;
}
.tf-constellation .tfm-tabs-track {
    display: flex; gap: 7px;
    padding: 10px 12px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.tf-constellation .tfm-tabs-track::-webkit-scrollbar { display: none; }
.tf-constellation .tfm-tab {
    flex-shrink: 0;
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 14px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface-soft);
    color: var(--cream-2);
    font: 500 12px/1 var(--font-ui);
    cursor: pointer;
    transition: background 160ms, border-color 160ms, color 160ms;
}
.tf-constellation .tfm-tab-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: oklch(0.70 0.13 var(--accent-h));
    opacity: 0.65;
}
.tf-constellation .tfm-tab.is-on {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--text-primary);
}
.tf-constellation .tfm-tab.is-on .tfm-tab-dot { opacity: 1; box-shadow: 0 0 8px oklch(0.70 0.13 var(--accent-h)); }
.tf-constellation .tfm-tab.is-locked { opacity: 0.5; cursor: not-allowed; }
.tf-constellation .tfm-tab-lock { font-size: 12px; color: var(--muted-2); }

/* ── Tablet / landscape ──────────────────────────────────────────────────────
   The touch layout now also runs above phone widths (tablets, and phones turned
   sideways — see useIsMobile in ConstellationView). Portrait phones are < 600px,
   so this min-width block leaves them untouched and only kicks in on the wider
   surfaces: center the hero, cards, and tabs into a comfortable reading column
   instead of letting the single column stretch edge-to-edge. */
@media (min-width: 600px) {
    .tf-constellation .tfm-hero,
    .tf-constellation .tfm-cards,
    .tf-constellation .tfm-tabs-track {
        max-width: 640px;
        margin-left: auto;
        margin-right: auto;
        width: 100%;
    }
}
