/**
 * JOAN Premium - Frontend Analytics Widgets Stylesheet
 *
 * Shared styling for the three frontend analytics shortcodes:
 *   [joan-analytics-globe]      - 3D interactive globe (globe.gl)
 *   [joan-analytics-map]        - 2D SVG world map (JS-driven)
 *   [joan-analytics-map-basic]  - Static SVG world map (no JS)
 *
 * Theme strategy:
 *   The widgets follow the site's current JOAN theme via the existing
 *   --joan-bg, --joan-fg, --joan-border, --joan-accent variables.
 *   The shortcode can override this per-widget with theme="light" or
 *   theme="dark", which adds the .joan-analytics-widget--theme-light
 *   or .joan-analytics-widget--theme-dark modifier.
 *
 * Sizing strategy:
 *   No inline styles are used. Heights are controlled via the
 *   .joan-analytics-widget--size-{sm|md|lg|xl} modifier set by the
 *   shortcode's height attribute.
 *
 * BEM block prefix:  .joan-analytics-widget
 *   - intentionally distinct from the admin dashboard prefix
 *     .joan-analytics-* used in analytics.css, so the two stylesheets
 *     never collide.
 *
 * @package JOAN_Premium
 * @since 2.1.3
 */

/* =========================================================================
   1. Base container and CSS custom property declarations
   ========================================================================= */

.joan-analytics-widget {
    /* Theme-controlled tokens. Defaults inherit from the JOAN site theme
       and fall back to sensible neutral values if vars are not defined. */
    --joan-aw-bg:            var(--joan-bg, #ffffff);
    --joan-aw-fg:            var(--joan-fg, #111111);
    --joan-aw-border:        var(--joan-border, rgba(127, 127, 127, 0.22));
    --joan-aw-accent:        var(--joan-accent, #2563eb);
    --joan-aw-accent-2:      var(--joan-accent-2, var(--joan-aw-accent));
    --joan-aw-muted:         rgba(127, 127, 127, 0.7);
    --joan-aw-shadow:        0 1px 3px rgba(0, 0, 0, 0.08), 0 2px 12px rgba(0, 0, 0, 0.06);

    /* Marker tokens (globe, JS map, basic SVG map) */
    --joan-aw-marker:        var(--joan-aw-accent);
    --joan-aw-marker-stroke: rgba(255, 255, 255, 0.85);

    /* World map tokens (JS map, basic SVG map)
       Defaults updated in 2.1.3 to a blue-ocean / white-land look that
       matches a typical analytics-dashboard heatmap. Themes and the
       --color-* modifiers can override these without affecting the
       marker accent. */
    --joan-aw-water:         #4a86b8;
    --joan-aw-land-fill:     #ffffff;
    --joan-aw-land-stroke:   rgba(255, 255, 255, 0.85);
    --joan-aw-ocean-fill:    var(--joan-aw-water);
    --joan-aw-globe-water:   #a8d5e8;   /* lighter for the globe sphere */
    --joan-aw-globe-land:    #ffffff;
    --joan-aw-globe-stroke:  #7ab8d4;

    /* Layout tokens */
    --joan-aw-radius:        8px;
    --joan-aw-canvas-height: 500px;

    /* Motion */
    --joan-aw-transition:    200ms ease;

    /* Container */
    display: block;
    position: relative;
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    margin: 1.5rem 0;
    color: var(--joan-aw-fg);
    background: var(--joan-aw-bg);
    border: 1px solid var(--joan-aw-border);
    border-radius: var(--joan-aw-radius);
    overflow: hidden;
    font-family: inherit;
    font-size: inherit;
    line-height: 1.4;
}

.joan-analytics-widget *,
.joan-analytics-widget *::before,
.joan-analytics-widget *::after {
    box-sizing: border-box;
}

/* =========================================================================
   2. Theme modifiers - explicit light/dark overrides
   ========================================================================= */

.joan-analytics-widget--theme-light {
    --joan-aw-bg:            #ffffff;
    --joan-aw-fg:            #111111;
    --joan-aw-border:        #e5e7eb;
    --joan-aw-muted:         rgba(17, 17, 17, 0.55);
    --joan-aw-water:         #4a86b8;
    --joan-aw-land-fill:     #ffffff;
    --joan-aw-land-stroke:   rgba(255, 255, 255, 0.85);
    --joan-aw-ocean-fill:    var(--joan-aw-water);
    --joan-aw-globe-water:   #a8d5e8;
    --joan-aw-globe-land:    #ffffff;
    --joan-aw-globe-stroke:  #7ab8d4;
    --joan-aw-marker-stroke: rgba(255, 255, 255, 0.9);
    --joan-aw-shadow:        0 1px 3px rgba(0, 0, 0, 0.08), 0 2px 12px rgba(0, 0, 0, 0.06);
}

.joan-analytics-widget--theme-dark {
    --joan-aw-bg:            #0b0f14;
    --joan-aw-fg:            #e6edf3;
    --joan-aw-border:        #1f2937;
    --joan-aw-muted:         rgba(230, 237, 243, 0.55);
    /* Dark theme keeps the ocean look but darker, with land as a soft white
       so country borders are still readable against a dark widget chrome. */
    --joan-aw-water:         #1e3a52;
    --joan-aw-land-fill:     rgba(230, 237, 243, 0.92);
    --joan-aw-land-stroke:   rgba(30, 58, 82, 0.85);
    --joan-aw-ocean-fill:    var(--joan-aw-water);
    --joan-aw-globe-water:   #1e3a52;
    --joan-aw-globe-land:    #d1e0ec;
    --joan-aw-globe-stroke:  #0c1c2a;
    --joan-aw-marker-stroke: rgba(255, 255, 255, 0.7);
    --joan-aw-shadow:        0 1px 3px rgba(0, 0, 0, 0.4), 0 2px 12px rgba(0, 0, 0, 0.3);
}

/* =========================================================================
   3. Color modifiers - explicit marker accent color (blue/green/red)
   These override the accent only. Land and text stay theme-driven so the
   color choice affects only the marker dots and the globe atmosphere glow.
   ========================================================================= */

.joan-analytics-widget--color-blue  { --joan-aw-accent: #2563eb; }
.joan-analytics-widget--color-green { --joan-aw-accent: #16a34a; }
.joan-analytics-widget--color-red   { --joan-aw-accent: #dc2626; }

/* =========================================================================
   4. Size modifiers - controls canvas height
   ========================================================================= */

.joan-analytics-widget--size-sm { --joan-aw-canvas-height: 300px; }
.joan-analytics-widget--size-md { --joan-aw-canvas-height: 500px; }
.joan-analytics-widget--size-lg { --joan-aw-canvas-height: 700px; }
.joan-analytics-widget--size-xl { --joan-aw-canvas-height: 900px; }

/* =========================================================================
   4. Title and meta line
   ========================================================================= */

.joan-analytics-widget__title {
    margin: 0;
    padding: 0.875rem 1rem 0.625rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--joan-aw-fg);
    border-bottom: 1px solid var(--joan-aw-border);
}

.joan-analytics-widget__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
    color: var(--joan-aw-muted);
    border-bottom: 1px solid var(--joan-aw-border);
}

.joan-analytics-widget__meta-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.joan-analytics-widget__meta-value {
    color: var(--joan-aw-fg);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* =========================================================================
   4b. Pageviews header (added in 2.1.3)
   Big total + date range, shown on the public frontend in place of the
   admin-style meta strip. Sits between the optional title and the canvas.
   ========================================================================= */

.joan-analytics-widget__pageviews-header {
    padding: 0.875rem 1rem 0.75rem;
    text-align: center;
    border-bottom: 1px solid var(--joan-aw-border);
    background: var(--joan-aw-bg);
}

.joan-analytics-widget__pageviews-count {
    display: block;
    margin: 0;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--joan-aw-fg);
    font-variant-numeric: tabular-nums;
}

.joan-analytics-widget__pageviews-label {
    font-size: 0.75em;
    font-weight: 500;
    color: var(--joan-aw-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-left: 0.35rem;
}

.joan-analytics-widget__pageviews-range {
    display: block;
    margin: 0.2rem 0 0;
    font-size: 0.85rem;
    color: var(--joan-aw-muted);
    font-variant-numeric: tabular-nums;
}

/* =========================================================================
   5. Canvas area (host for globe / JS map / basic SVG)
   ========================================================================= */

.joan-analytics-widget__canvas {
    position: relative;
    width: 100%;
    height: var(--joan-aw-canvas-height);
    background: var(--joan-aw-bg);
    overflow: hidden;
}

/* Map widgets get the ocean color as the canvas background so the
   blue water shows behind the white country paths. The globe is
   rendered by three.js with its own sphere material, so its canvas
   stays transparent and lets the widget chrome show through. */
.joan-analytics-widget--map .joan-analytics-widget__canvas,
.joan-analytics-widget--map-basic .joan-analytics-widget__canvas {
    background: var(--joan-aw-ocean-fill);
}

.joan-analytics-widget--globe .joan-analytics-widget__canvas {
    cursor: grab;
}

.joan-analytics-widget--globe .joan-analytics-widget__canvas:active {
    cursor: grabbing;
}

/* Mount points for the JS renderers */
.joan-analytics-widget__globe-host,
.joan-analytics-widget__map-host {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

/* SVG world (used by JS map and basic image map) */
.joan-analytics-widget__svg-map {
    display: block;
    width: 100%;
    height: 100%;
    user-select: none;
    -webkit-user-select: none;
}

.joan-analytics-widget__svg-map .joan-aw-land {
    fill: var(--joan-aw-land-fill);
    stroke: var(--joan-aw-land-stroke);
    stroke-width: 0.5;
    transition: fill var(--joan-aw-transition);
}

.joan-analytics-widget__svg-map .joan-aw-marker {
    fill: var(--joan-aw-marker);
    stroke: var(--joan-aw-marker-stroke);
    stroke-width: 1.5;
    opacity: 0.85;
    transition: opacity var(--joan-aw-transition), transform var(--joan-aw-transition);
    transform-origin: center;
    transform-box: fill-box;
    cursor: pointer;
}

.joan-analytics-widget__svg-map .joan-aw-marker:hover,
.joan-analytics-widget__svg-map .joan-aw-marker:focus-visible {
    opacity: 1;
    transform: scale(1.2);
    outline: none;
}

.joan-analytics-widget__svg-map .joan-aw-marker:focus-visible {
    stroke: var(--joan-aw-accent);
    stroke-width: 2.5;
}

/* =========================================================================
   6. Controls bar (zoom, play/pause, period selector)
   ========================================================================= */

.joan-analytics-widget__controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.75rem;
    background: var(--joan-aw-bg);
    border-top: 1px solid var(--joan-aw-border);
}

.joan-analytics-widget__controls-group {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.joan-analytics-widget__btn {
    appearance: none;
    -webkit-appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 0.6rem;
    margin: 0;
    background: transparent;
    color: var(--joan-aw-fg);
    border: 1px solid var(--joan-aw-border);
    border-radius: calc(var(--joan-aw-radius) - 4px);
    font: inherit;
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    transition: background var(--joan-aw-transition),
                border-color var(--joan-aw-transition),
                color var(--joan-aw-transition);
}

.joan-analytics-widget__btn:hover {
    background: var(--joan-aw-accent);
    color: #ffffff;
    border-color: var(--joan-aw-accent);
}

.joan-analytics-widget__btn:focus-visible {
    outline: 2px solid var(--joan-aw-accent);
    outline-offset: 2px;
}

.joan-analytics-widget__btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.joan-analytics-widget__btn[aria-pressed="true"] {
    background: var(--joan-aw-accent);
    color: #ffffff;
    border-color: var(--joan-aw-accent);
}

.joan-analytics-widget__btn-icon {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    fill: currentColor;
    flex-shrink: 0;
}

.joan-analytics-widget__btn-icon + .joan-analytics-widget__btn-label {
    margin-left: 0.4rem;
}

.joan-analytics-widget__period {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--joan-aw-muted);
    font-size: 0.85rem;
}

/* =========================================================================
   7. Legend
   ========================================================================= */

.joan-analytics-widget__legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    padding: 0.5rem 1rem;
    font-size: 0.8rem;
    color: var(--joan-aw-muted);
    border-top: 1px solid var(--joan-aw-border);
}

.joan-analytics-widget__legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.joan-analytics-widget__legend-dot {
    display: inline-block;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 50%;
    background: var(--joan-aw-marker);
    border: 1.5px solid var(--joan-aw-marker-stroke);
    flex-shrink: 0;
}

.joan-analytics-widget__legend-dot--sm { transform: scale(0.55); }
.joan-analytics-widget__legend-dot--md { transform: scale(0.85); }
.joan-analytics-widget__legend-dot--lg { transform: scale(1.15); }
.joan-analytics-widget__legend-dot--xl { transform: scale(1.5); }

/* =========================================================================
   8. Tooltip (markers on JS map and basic map)
   ========================================================================= */

.joan-analytics-widget__tooltip {
    position: absolute;
    z-index: 10;
    pointer-events: none;
    opacity: 0;
    padding: 0.4rem 0.6rem;
    background: var(--joan-aw-bg);
    color: var(--joan-aw-fg);
    border: 1px solid var(--joan-aw-border);
    border-radius: calc(var(--joan-aw-radius) - 4px);
    box-shadow: var(--joan-aw-shadow);
    font-size: 0.8rem;
    line-height: 1.3;
    white-space: nowrap;
    transition: opacity 120ms ease;
    transform: translate(-50%, calc(-100% - 8px));
}

.joan-analytics-widget__tooltip--visible {
    opacity: 1;
}

.joan-analytics-widget__tooltip-name {
    display: block;
    font-weight: 600;
}

.joan-analytics-widget__tooltip-visits {
    display: block;
    color: var(--joan-aw-muted);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

/* =========================================================================
   9. Counts list (textual companion under map / globe)
   ========================================================================= */

.joan-analytics-widget__counts {
    list-style: none;
    margin: 0;
    padding: 0.75rem 1rem;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 0.25rem 1rem;
    font-size: 0.85rem;
    border-top: 1px solid var(--joan-aw-border);
    max-height: 12rem;
    overflow-y: auto;
}

.joan-analytics-widget__counts-item {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.15rem 0;
    color: var(--joan-aw-fg);
}

.joan-analytics-widget__counts-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.joan-analytics-widget__counts-visits {
    font-variant-numeric: tabular-nums;
    color: var(--joan-aw-muted);
    font-weight: 600;
    flex-shrink: 0;
}

/* =========================================================================
   10. State indicators (loading, empty, error)
   ========================================================================= */

.joan-analytics-widget__state {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.5rem;
    min-height: 6rem;
    text-align: center;
    color: var(--joan-aw-muted);
    font-size: 0.9rem;
}

.joan-analytics-widget__state--inline {
    position: absolute;
    inset: 0;
    background: var(--joan-aw-bg);
    z-index: 5;
}

.joan-analytics-widget__spinner {
    display: inline-block;
    width: 1.5rem;
    height: 1.5rem;
    border: 2px solid var(--joan-aw-border);
    border-top-color: var(--joan-aw-accent);
    border-radius: 50%;
    animation: joan-aw-spin 0.8s linear infinite;
}

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

.joan-analytics-widget__state-message {
    margin: 0;
}

.joan-analytics-widget__state--error .joan-analytics-widget__state-message {
    color: var(--joan-aw-fg);
}

/* =========================================================================
   11. Accessibility utilities
   ========================================================================= */

.joan-analytics-widget__sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* =========================================================================
   12. Reduced motion
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
    .joan-analytics-widget__svg-map .joan-aw-marker,
    .joan-analytics-widget__btn,
    .joan-analytics-widget__tooltip {
        transition: none;
    }
    .joan-analytics-widget__spinner {
        animation-duration: 2s;
    }
}

/* =========================================================================
   13. Print styles
   ========================================================================= */

@media print {
    .joan-analytics-widget {
        page-break-inside: avoid;
        border-color: #cccccc;
        color: #000000;
        background: #ffffff;
        box-shadow: none;
    }
    .joan-analytics-widget__controls {
        display: none;
    }
    .joan-analytics-widget--globe .joan-analytics-widget__canvas {
        /* The 3D globe canvas does not print usefully. */
        display: none;
    }
}

/* =========================================================================
   14. Small viewport adjustments
   ========================================================================= */

@media (max-width: 600px) {
    .joan-analytics-widget__title {
        font-size: 0.95rem;
        padding: 0.7rem 0.85rem 0.5rem;
    }
    .joan-analytics-widget__meta,
    .joan-analytics-widget__legend {
        padding: 0.4rem 0.85rem;
    }
    .joan-analytics-widget__counts {
        grid-template-columns: 1fr;
        max-height: 9rem;
    }
    .joan-analytics-widget__controls {
        padding: 0.4rem 0.5rem;
    }
    .joan-analytics-widget__period {
        margin-left: 0;
        width: 100%;
        justify-content: flex-end;
    }
}

/* -----------------------------------------------------------------------
 * Visit-count labels on globe and map markers (added in 2.1.3)
 *
 * Renders a small count bubble next to each country marker, mapmyvisitors
 * style. Used by analytics-globe.js (HTML labels via globe.gl labelsData)
 * and analytics-map.js / shortcode-analytics-map-basic.php (SVG text).
 * --------------------------------------------------------------------- */
.joan-analytics-marker-label {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.92);
    color: #111;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: 11px;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
    pointer-events: none;
    user-select: none;
}
.joan-analytics-widget--theme-dark .joan-analytics-marker-label {
    background: rgba(20, 24, 32, 0.92);
    color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}
.joan-analytics-marker-count-text {
    fill: #ffffff;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-weight: 700;
    text-anchor: middle;
    dominant-baseline: central;
    paint-order: stroke;
    stroke: rgba(0, 0, 0, 0.45);
    stroke-width: 0.75px;
    pointer-events: none;
    user-select: none;
}

/* -----------------------------------------------------------------------
 * Tooltip city breakdown (added in 2.1.3)
 *
 * Renders the top cities for a country below the country header inside
 * the map tooltip and inside the globe.gl scene tooltip. Used by both
 * analytics-map.js (custom div) and analytics-globe.js (.scene-tooltip
 * receives the HTML returned from pointLabel).
 * --------------------------------------------------------------------- */

/* Container holding each city row. Sits below the country: visits line. */
.joan-analytics-widget__tooltip-cities,
.joan-analytics-tooltip__cities {
    margin-top: 8px;
    padding-top: 6px;
    border-top: 1px solid rgba(255, 255, 255, 0.18);
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 12px;
    line-height: 1.35;
}

/* When there is only a country header (no city block), our :empty check
 * collapses the spacing so the tooltip stays tight. */
.joan-analytics-widget__tooltip-cities:empty,
.joan-analytics-tooltip__cities:empty {
    display: none;
}

/* Each city row is a name (left) + count (right) layout. */
.joan-analytics-widget__tooltip-city,
.joan-analytics-tooltip__city {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    white-space: nowrap;
}
.joan-analytics-widget__tooltip-city-name,
.joan-analytics-tooltip__city-name {
    opacity: 0.92;
}
.joan-analytics-widget__tooltip-city-count,
.joan-analytics-tooltip__city-count {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    opacity: 0.95;
}

/* Globe (globe.gl .scene-tooltip) wraps our HTML in its own positioned
 * div. The tooltip class names below mirror our custom map tooltip so
 * the same rules style both. The country header gets a slightly larger
 * font and bottom spacing. */
.joan-analytics-tooltip {
    line-height: 1.4;
}
.joan-analytics-tooltip__country {
    font-weight: 600;
}

/* -----------------------------------------------------------------------
 * Live city-dots mode (added in 2.1.3)
 *
 * Two visual states per dot:
 *   - active (visit within active_minutes): brighter, larger, soft pulse
 *   - recent (older visit within the period): plain dot
 *
 * Always-visible city name labels float above active dots on both the
 * 3D globe (via htmlElementsData) and the 2D map (via SVG text).
 * --------------------------------------------------------------------- */

/* SVG markers - active vs recent on the 2D map */
.joan-aw-marker--active {
    /* Pulse animation drawn via box-shadow style on SVG circles uses
     * filter for the glow; the radius itself comes from the JS. */
    fill: var(--joan-aw-accent, #2563eb);
    fill-opacity: 0.95;
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 1.5;
    paint-order: stroke;
    transform-box: fill-box;
    transform-origin: center;
    animation: joan-aw-pulse 2.2s ease-in-out infinite;
}
.joan-aw-marker--recent {
    fill: var(--joan-aw-accent, #2563eb);
    fill-opacity: 0.55;
    stroke: rgba(255, 255, 255, 0.4);
    stroke-width: 0.5;
}

/* Pulse: a soft drop-shadow grow/shrink that catches the eye without
 * being distracting. We animate filter (rather than r) to avoid SVG
 * layout work on each frame. */
@keyframes joan-aw-pulse {
    0%, 100% {
        filter: drop-shadow(0 0 1.5px rgba(37, 99, 235, 0.7));
    }
    50% {
        filter: drop-shadow(0 0 4.5px rgba(37, 99, 235, 1.0));
    }
}

/* Honor reduced-motion preferences by killing the pulse. */
@media (prefers-reduced-motion: reduce) {
    .joan-aw-marker--active {
        animation: none;
        filter: drop-shadow(0 0 2px rgba(37, 99, 235, 0.85));
    }
}

/* SVG city name label (2D map) - text floats above active dots. */
.joan-analytics-marker-city-label-text {
    fill: var(--joan-aw-text, #111);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-weight: 700;
    font-size: 6px;
    paint-order: stroke;
    stroke: rgba(255, 255, 255, 0.85);
    stroke-width: 1.2px;
    stroke-linejoin: round;
    pointer-events: none;
    user-select: none;
}
.joan-analytics-widget--theme-dark .joan-analytics-marker-city-label-text {
    fill: #fff;
    stroke: rgba(0, 0, 0, 0.8);
}

/* 3D globe city name labels (htmlElementsData layer) - a positioned
 * pill that follows its dot as the globe rotates. */
.joan-analytics-city-label {
    pointer-events: none;
    transform: translate(-50%, calc(-100% - 4px));
    white-space: nowrap;
}
.joan-analytics-city-label__inner {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.96);
    color: #111;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: 11px;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
    user-select: none;
}
.joan-analytics-city-label--active .joan-analytics-city-label__inner {
    /* Soft accent halo on active labels so the eye is drawn there. */
    box-shadow:
        0 0 0 1px var(--joan-aw-accent, #2563eb),
        0 2px 6px rgba(37, 99, 235, 0.35);
}
.joan-analytics-widget--theme-dark .joan-analytics-city-label__inner {
    background: rgba(20, 24, 32, 0.96);
    color: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* Variant of the existing marker label specifically for city names (a hair
 * wider than count bubbles so longer city names do not get cramped). */
.joan-analytics-marker-label--city {
    padding-left: 8px;
    padding-right: 8px;
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Counts list active styling (when showCounts is on in cities mode). */
.joan-analytics-widget__count--active .joan-analytics-widget__count-name {
    font-weight: 700;
}
.joan-analytics-widget__count--active::before {
    /* Tiny accent dot prefixes active rows so the user can scan the list. */
    content: "";
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--joan-aw-accent, #2563eb);
    vertical-align: middle;
    box-shadow: 0 0 4px rgba(37, 99, 235, 0.7);
}

/* Active city marker inside the tooltip sibling list (also a small
 * accent dot prefix so the user can see at a glance which sibling
 * cities are currently live). */
.joan-analytics-widget__tooltip-city--active .joan-analytics-widget__tooltip-city-name::before,
.joan-analytics-tooltip__city--active .joan-analytics-tooltip__city-name::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 5px;
    border-radius: 50%;
    background: var(--joan-aw-accent, #2563eb);
    vertical-align: middle;
}
