/*
 * The post-upload celebration, and the outcome panel that outlives it.
 * Behaviour and the reasoning live in static/js/celebrate.js.
 */

/* ---- the overlay ---------------------------------------------------------------
   pointer-events stay ON so a click anywhere skips the sequence, which also stops a
   second Upload click landing during the 3.4 s. */
.cg-celebrate {
    position: fixed;
    inset: 0;
    z-index: 2100;              /* over .dp-root.fullscreen (2000) and Bootstrap modals (1055) */
    overflow: hidden;
    cursor: pointer;
}

.cg-celebrate .cg-confetti {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.cg-celebrate .cg-digs {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 34vmin;
    min-width: 190px;
    max-width: 320px;
    translate: -50% -50%;
    opacity: 0;
    scale: .72;
    pointer-events: none;
    filter: drop-shadow(0 12px 28px rgba(0, 0, 0, .35));
}

.cg-celebrate .cg-digs.cg-in { animation: cgDigsIn 420ms cubic-bezier(.2, 1.5, .5, 1) forwards; }
.cg-celebrate .cg-digs.cg-out { animation: cgDigsOut 380ms ease-in forwards; }
@keyframes cgDigsIn { to { opacity: 1; scale: 1; } }
@keyframes cgDigsOut { from { opacity: 1; scale: 1; } to { opacity: 0; scale: .94; } }

/* ⚑ overflow:visible is what makes them fall from the top of the SCREEN rather than
   appearing at the top of Digs' own box. An <svg> clips to its viewBox by default, so a
   child translated above y=0 is invisible until it crosses that edge -- the shades were
   popping into existence just above his ears, and a 4% opacity ramp was masking it. With
   the clip lifted they travel the whole way, and the overlay's own overflow:hidden is
   what keeps them inside the viewport. */
.cg-celebrate .cg-digs { overflow: visible; }

/* No fade. They are solid the entire way down -- a pair of sunglasses does not
   materialise, it falls. -1800% of their own 30-unit height is ~540 viewBox units, which
   clears the top of the viewport at every size this renders at. They still live in the
   head's viewBox, so the landing position is the eye line by construction rather than by
   a tuned offset. */
.cg-celebrate .cg-shades {
    translate: 0 -1800%;
    opacity: 1;
}
.cg-celebrate .cg-shades.cg-in {
    animation: cgShadesDrop 1900ms cubic-bezier(.32, .04, .3, 1.01) forwards;
}
@keyframes cgShadesDrop {
    0%   { translate: 0 -1800%; }
    90%  { translate: 0 5%; }          /* a shallow overshoot, then settle */
    100% { translate: 0 0; }
}

/* prefers-reduced-motion: Digs appears and holds. No confetti is drawn at all (the JS
   skips the draw loop), no slide, no pop. */
.cg-celebrate .cg-digs.cg-static { opacity: 1; scale: 1; animation: none; }
.cg-celebrate .cg-shades.cg-static { translate: 0 0; opacity: 1; animation: none; }

@media (prefers-reduced-motion: reduce) {
    .cg-celebrate .cg-digs.cg-in,
    .cg-celebrate .cg-digs.cg-out,
    .cg-celebrate .cg-shades.cg-in { animation: none; }
    .cg-celebrate .cg-digs.cg-in { opacity: 1; scale: 1; }
    .cg-celebrate .cg-shades.cg-in { translate: 0 0; opacity: 1; }
}

/* ---- the outcome panel --------------------------------------------------------
   Deliberately not a toast. A toast fades, and on this path the redirect used to eat it
   before anyone could read it -- which is the defect this replaces. */
.cg-outcome {
    position: fixed;
    inset: 0;
    z-index: 2200;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgba(15, 14, 12, .55);
}

/* ⚑ The base carries NO outcome's colour. Amber used to live here with `-failed`
   overriding it, which meant `cg-outcome-warn` was a class the stylesheet never actually
   matched -- and a fourth outcome added later would have come out amber without anybody
   choosing that. Each variant now states its own, and
   test_the_outcome_table_and_its_classifier_cannot_drift_apart fails if one does not. */
.cg-outcome-body {
    max-width: 34rem;
    width: 100%;
    background: #fff;
    border-radius: .5rem;
    border-top: 5px solid #adb5bd;
    padding: 1.1rem 1.25rem 1rem;
    box-shadow: 0 18px 48px rgba(0, 0, 0, .3);
}
.cg-outcome-warn .cg-outcome-body { border-top-color: #997404; }
.cg-outcome-failed .cg-outcome-body { border-top-color: #b02a37; }
/* Slate, not amber and not red. "We stopped being able to see the job" is an UNKNOWN,
   and colouring it like a failure would assert the outcome the panel is saying it has. */
.cg-outcome-lost .cg-outcome-body { border-top-color: #495057; }

.cg-outcome-head {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-size: 1.12rem;
    color: #495057;
}
.cg-outcome-warn .cg-outcome-head { color: #664d03; }
.cg-outcome-failed .cg-outcome-head { color: #842029; }
.cg-outcome-lost .cg-outcome-head { color: #343a40; }

.cg-outcome-what {
    margin-top: .45rem;
    font-weight: 600;
    color: #212529;
}

.cg-outcome-detail {
    margin-top: .35rem;
    color: #495057;
    font-size: .95rem;
    max-height: 11rem;
    overflow-y: auto;
    overflow-wrap: anywhere;
}

/* The consequence, separated from the job's own message. On the `lost` outcome the detail
   line is a transport error ("Failed to fetch job status") and this is the sentence that
   actually changes what the analyst should do next, so it must not read as more of the
   same grey body text. */
.cg-outcome-note {
    margin-top: .6rem;
    padding: .5rem .65rem;
    border-radius: .3rem;
    background: #f1f3f5;
    border-left: 3px solid #495057;
    color: #343a40;
    font-size: .9rem;
}

.cg-outcome-actions {
    display: flex;
    gap: .5rem;
    margin-top: 1rem;
}
.cg-outcome-actions button {
    font: inherit;
    padding: .4rem .9rem;
    border-radius: .3rem;
    border: 1px solid #ced4da;
    background: #fff;
    color: #212529;
    cursor: pointer;
}
.cg-outcome-go {
    background: #0d6efd !important;
    border-color: #0d6efd !important;
    color: #fff !important;
    font-weight: 500;
}
.cg-outcome-actions button:focus-visible {
    outline: 2px solid #0d6efd;
    outline-offset: 2px;
}
