/* ------------------------------------------------------- Earth Facts slide ---
   Epic onfiremobile-bl5wn. Contract: docs/PRD/displays/CONTRACT-slide-settings.md
   §earth_facts. Every class here is .ns-ef*. The globe (globe.js) paints its
   own canvases inside .ns-ef-stage; this file positions the card over it.

   Sizes are clamp()/vmin so one layout reads on a 1280x720 Pi panel and on a
   4K wall. Motion: the card springs in (a light overshoot on transform) and
   leaves on the house ease-out, cubic-bezier(0.33, 1, 0.68, 1); only transform
   and opacity animate, so the Pi compositor does the work. There is no
   visible countdown: the hold is timed in JS and nothing on the card ticks. */

.ns-ef {
    --ef-ease-out: cubic-bezier(0.33, 1, 0.68, 1);
    --ef-spring: cubic-bezier(0.34, 1.36, 0.64, 1);
    --ef-gap: clamp(20px, 4vmin, 64px);
    --ef-card-w: clamp(320px, 38vw, 820px);
    --ef-orange: #FF6B1F;
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #000;
    color: #fff;
    font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, sans-serif;
    isolation: isolate;
}

.ns-ef-stage {
    position: absolute;
    inset: 0;
}

/* The globe is centred on the stop. Widening the stage off the LEFT edge
   moves that centre left, clear of the card, while the starfield still fills
   the whole screen (shrinking it from the right would end the stars in a
   visible seam above and below the card). */
@media (orientation: landscape) {
    .ns-ef:not(.ns-ef-vp) .ns-ef-stage { left: calc(var(--ef-card-w) * -0.55); }
}

.ns-ef-brand {
    position: absolute;
    left: var(--ef-gap);
    top: var(--ef-gap);
    z-index: 2;
    pointer-events: none;
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.85);
}

.ns-ef-brand-title {
    font-size: clamp(18px, 2.8vmin, 44px);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: rgba(255, 255, 255, 0.86);
}

/* -------------------------------------------------------------- close-up -- */
/* The Mapbox satellite globe for the close-up. Opacity only, so the handoff
   from globe.js is a cross-fade; the inner div is the map container because
   mapbox-gl sets position:relative on its container. */
.ns-ef-mb {
    position: absolute;
    inset: 0;
    z-index: 1;
    opacity: 0;
    pointer-events: none;
    transition: opacity 700ms var(--ef-ease-out);
}
/* Two classes: mapbox-gl.css gives .mapboxgl-map position:relative, which
   would collapse an inset-only box to zero height. */
.ns-ef-mb .ns-ef-mb-map { position: absolute; inset: 0; width: 100%; height: 100%; }
.ns-ef-close .ns-ef-mb { opacity: 1; }
/* Attribution + logo are required and must both stay readable. GL JS floats
   them side by side in one corner, where the wide attribution bar covered
   the wordmark (seen live at 1920x1080): stack them instead. Portrait moves
   the pair to the top-right, off the bottom card. */
.ns-ef-mb .mapboxgl-ctrl-bottom-left {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 0 0 8px 8px;
}
.ns-ef-mb .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl { float: none; margin: 0; }
.ns-ef-mb .mapboxgl-ctrl-attrib { font-size: 11px; background: rgba(0, 0, 0, 0.45); }
.ns-ef-mb .mapboxgl-ctrl-attrib a { color: rgba(255, 255, 255, 0.85); }
@media (orientation: portrait) {
    .ns-ef-mb .mapboxgl-ctrl-bottom-left {
        bottom: auto; top: 0; left: auto; right: 0;
        align-items: flex-end;
        padding: 8px 8px 0 0;
    }
}

/* The dot while the satellite map is up: a GL JS Marker element; globe.js
   draws the same dot the rest of the time. */
.ns-ef-mbdot {
    display: block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--ef-orange);
    border: 1.5px solid rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 12px var(--ef-orange);
    pointer-events: none;
}

/* "Near Longyearbyen · 78.22° N, 15.65° E" beside the dot. */
.ns-ef-place {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 3;
    max-width: 44vw;
    padding: 0.4em 0.85em;
    border-radius: 999px;
    font-size: clamp(13px, 1.7vmin, 26px);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #fff;
    background: rgba(8, 10, 16, 0.62);
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
    font-variant-numeric: tabular-nums;
    opacity: 0;
    pointer-events: none;
    transition: opacity 500ms var(--ef-ease-out);
}
.ns-ef-place.ns-ef-place-on { opacity: 1; }
.ns-ef-place.ns-ef-place-hid { opacity: 0; }

/* ------------------------------------------------------------------ card -- */

.ns-ef-card {
    position: absolute;
    z-index: 4;
    right: var(--ef-gap);
    top: 50%;
    width: var(--ef-card-w);
    max-height: calc(100% - 2 * var(--ef-gap));
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: clamp(16px, 2.4vmin, 32px);
    background: rgba(16, 18, 24, 0.78);
    border: 1px solid rgba(255, 255, 255, 0.10);
    box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55), 0 2px 8px rgba(0, 0, 0, 0.35);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    opacity: 0;
    transform: translate(12%, -50%) scale(0.96);
    transition: opacity 420ms var(--ef-ease-out), transform 420ms var(--ef-ease-out);
    pointer-events: none;
}

.ns-ef-card.ns-ef-open {
    opacity: 1;
    transform: translate(0, -50%) scale(1);
    transition: opacity 520ms var(--ef-ease-out), transform 620ms var(--ef-spring);
}

@media (orientation: portrait) {
    .ns-ef-card {
        left: var(--ef-gap);
        right: var(--ef-gap);
        top: auto;
        bottom: var(--ef-gap);
        width: auto;
        /* The focused place sits at 25% from the top; the card must stay
           below the middle so it never covers it. */
        max-height: 46%;
        transform: translateY(12%) scale(0.96);
    }
    .ns-ef-card.ns-ef-open { transform: translateY(0) scale(1); }
    /* A full-width 16:10 photo alone would fill the capped card and clip the
       fact (seen live at 1080x1188). A wider, height-capped frame leaves the
       text its room on every portrait panel. */
    .ns-ef-media {
        aspect-ratio: auto;
        height: min(calc((100vw - 2 * var(--ef-gap)) / 2.4), 22vh);
    }
}

.ns-ef-media {
    position: relative;
    flex: 0 0 auto;
    aspect-ratio: 16 / 10;
    background: linear-gradient(135deg, #1b2230, #0d1118);
    overflow: hidden;
}

.ns-ef-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transform: scale(1.04);
    transition: opacity 600ms var(--ef-ease-out), transform 12s var(--ef-ease-out);
}

/* #slide-container prefix: the generic `#slide-container img` rule
   (object-fit: contain, max sizes) outranks a bare class and letterboxed a
   portrait photo inside the frame on the live display. */
#slide-container .ns-ef-img { max-width: none; max-height: none; object-fit: cover; }

.ns-ef-img-ready .ns-ef-img { opacity: 1; }
/* A slow Ken Burns drift while the card is open. */
.ns-ef-open.ns-ef-img-ready .ns-ef-img { transform: scale(1.12); }
.ns-ef-noimg .ns-ef-media { display: none; }

.ns-ef-chip {
    position: absolute;
    left: clamp(10px, 1.6vmin, 24px);
    top: clamp(10px, 1.6vmin, 24px);
    padding: 0.35em 0.85em;
    border-radius: 999px;
    font-size: clamp(12px, 1.5vmin, 22px);
    font-weight: 600;
    color: #fff;
    background: rgba(0, 0, 0, 0.55);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.ns-ef-body {
    padding: clamp(14px, 2.4vmin, 36px) clamp(16px, 2.8vmin, 40px) clamp(12px, 2vmin, 28px);
    display: flex;
    flex-direction: column;
    gap: clamp(4px, 0.8vmin, 12px);
    min-height: 0;
}

.ns-ef-title {
    margin: 0;
    font-size: clamp(22px, 3.6vmin, 58px);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.08;
}

.ns-ef-where {
    font-size: clamp(13px, 1.8vmin, 26px);
    font-weight: 600;
    color: var(--ef-orange);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.ns-ef-fact {
    margin: clamp(2px, 0.6vmin, 8px) 0 0;
    font-size: clamp(16px, 2.4vmin, 38px);
    line-height: 1.38;
    color: rgba(255, 255, 255, 0.92);
    text-wrap: pretty;
}

.ns-ef-credit {
    margin-top: clamp(6px, 1.2vmin, 16px);
    display: flex;
    flex-wrap: wrap;
    gap: 0.2em 1em;
    font-size: clamp(10px, 1.15vmin, 16px);
    line-height: 1.35;
    color: rgba(255, 255, 255, 0.5);
}

.ns-ef-attr {
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

/* ------------------------------------------------------------- flat map -- */

.ns-ef-flat {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(ellipse at center, #0b1220 0%, #000 75%);
}

.ns-ef-flat[hidden] { display: none; }

/* Landscape: the map shares the screen with the card instead of sitting
   under it, so a pin in Australia is never hidden behind the fact. */
@media (orientation: landscape) {
    .ns-ef-flat { right: calc(var(--ef-card-w) + var(--ef-gap)); }
}

.ns-ef-flat-map {
    position: relative;
    width: min(94%, 180vh);
    aspect-ratio: 2 / 1;
    background-size: cover;
    background-position: center;
    border-radius: clamp(8px, 1.4vmin, 20px);
    box-shadow: 0 20px 80px rgba(0, 0, 0, 0.6);
    opacity: 0.9;
}

.ns-ef-flat-pin {
    position: absolute;
    left: 50%;
    top: 50%;
    width: clamp(14px, 2vmin, 28px);
    height: clamp(14px, 2vmin, 28px);
    margin: calc(clamp(14px, 2vmin, 28px) / -2) 0 0 calc(clamp(14px, 2vmin, 28px) / -2);
    border-radius: 50%;
    background: var(--ef-orange);
    box-shadow: 0 0 0 4px rgba(255, 107, 31, 0.35), 0 0 24px rgba(255, 107, 31, 0.8);
    transition: left 2600ms cubic-bezier(0.65, 0, 0.35, 1), top 2600ms cubic-bezier(0.65, 0, 0.35, 1);
}

@media (prefers-reduced-motion: reduce) {
    .ns-ef-card, .ns-ef-card.ns-ef-open, .ns-ef-img, .ns-ef-flat-pin, .ns-ef-mb, .ns-ef-place { transition-duration: 1ms; }
    .ns-ef-open.ns-ef-img-ready .ns-ef-img { transform: scale(1.04); }
}

/* Low tier and the flat fallback: no backdrop blur. Blurring over a canvas
   that repaints every frame re-composites the whole card each frame, which
   is exactly the budget the Pi does not have. */
.ns-ef[data-tier="low"] .ns-ef-card,
.ns-ef[data-mode="flat"] .ns-ef-card {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: rgba(16, 18, 24, 0.94);
}
