/* ============================================================================
   The photo wizard — shared by signup2.php, add-site.php and app/setup.php.

   Deliberately self-contained and prefixed `apxw-`. It renders over three pages
   with three different design systems (signup's dark checkout, add-site's
   variant of it, and the app's light/dark themed dashboard), so it brings its
   own surface rather than trying to inherit from whichever one it lands on.

   Tokens are read with fallbacks — var(--accent-primary, #38bdf8) — so where a
   host page does define an accent, the wizard picks it up and looks like it
   belongs there.
   ============================================================================ */

.apxw-lock { overflow: hidden; }

.apxw {
    position: fixed;
    inset: 0;
    z-index: 2147483000;          /* above the app's own overlays and the FAB */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.apxw-scrim {
    position: absolute;
    inset: 0;
    background: rgba(2, 6, 23, .74);
    backdrop-filter: blur(3px);
}
.apxw-panel {
    position: relative;
    width: 100%;
    max-width: 520px;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
    background: #0e1628;
    color: #e2e8f0;
    border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 18px;
    box-shadow: 0 24px 70px rgba(2, 6, 23, .6);
    font: 15px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
    animation: apxw-in .22s cubic-bezier(.2, .9, .3, 1);
}
@keyframes apxw-in { from { opacity: 0; transform: translateY(10px) scale(.985); } }
@media (prefers-reduced-motion: reduce) {
    .apxw-panel { animation: none; }
}
.apxw-body { padding: 26px 26px 22px; }

/* ── type ─────────────────────────────────────────────────────────────── */
.apxw-eyebrow {
    font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    color: #64748b; margin-bottom: 8px;
}
.apxw-eyebrow.apxw-ok { color: var(--accent-success, #10b981); }
.apxw-h {
    font-size: 22px; line-height: 1.2; font-weight: 800; color: #fff;
    margin: 0 0 10px; letter-spacing: -.01em;
}
.apxw-lead { color: #a8b6c9; margin: 0 0 16px; font-size: 14.5px; }

.apxw-steps { list-style: none; counter-reset: apxw; margin: 0 0 20px; padding: 0; }
/* Three items sit in this row, not two: the ::before counter, the <b> title and
   the <span> description. All three are placed explicitly — leaving it to grid
   auto-placement dropped the description into the 26px counter column and wrapped
   it one word per line, which is how the intro screen came to be four screens
   tall with its buttons below the fold. Row gap stays 0; the 2px under the title
   is the only space the pair wants. */
.apxw-steps li {
    counter-increment: apxw;
    display: grid; grid-template-columns: 26px 1fr; gap: 0 12px;
    padding: 11px 0; border-top: 1px solid rgba(255, 255, 255, .07);
}
.apxw-steps li::before {
    content: counter(apxw);
    grid-column: 1; grid-row: 1 / span 2; align-self: start;
    font-size: 12px; font-weight: 700; color: var(--accent-primary, #38bdf8);
    padding-top: 2px;
}
.apxw-steps b { grid-column: 2; grid-row: 1; display: block; color: #e2e8f0; font-size: 14.5px; font-weight: 700; }
.apxw-steps span { grid-column: 2; grid-row: 2; display: block; color: #8496ad; font-size: 13.5px; margin-top: 2px; }

.apxw-tips { margin: 14px 0 4px; padding: 0 0 0 18px; color: #8496ad; font-size: 13.5px; }
.apxw-tips li { margin-bottom: 4px; }

/* ── the stage: camera preview or the captured still ──────────────────── */
.apxw-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;
    /* Square is the right frame — it is what the circle guide is composed
       inside, and what snap() crops to. But on a narrow, tall panel a square
       stage is as tall as the panel is wide, which pushed "Use my camera" below
       the fold at 560px: the one action the step exists for, out of sight.
       Capping the height lets the box go wide rather than tall; the video still
       covers it, and the guides below size themselves off the short edge so the
       circle stays a circle. */
    max-height: 46vh;
    border-radius: 14px;
    overflow: hidden;
    background: #060c17;
    border: 1px solid rgba(255, 255, 255, .08);
    display: flex; align-items: center; justify-content: center;
}
.apxw-video, .apxw-shot {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
/* Mirrored preview only. People frame themselves in a mirror; the capture
   un-mirrors before saving (see snap() in brand-wizard.js). */
.apxw-video { transform: scaleX(-1); }
.apxw-stage:not(.apxw-live) .apxw-video { display: none; }
.apxw-stage:not(.apxw-live):not(.apxw-still)::after {
    content: "Camera off";
    color: #475569; font-size: 13px;
}

/* ── the framing guides ───────────────────────────────────────────────── */
/* Passport-booth grammar: a shape to put yourself inside, with everything
   outside it dimmed so the target is unmistakable. Built from a radial or
   linear mask on a single element rather than an image, so it scales cleanly
   and costs no request. */
.apxw-guide {
    position: absolute; inset: 0; pointer-events: none;
}
.apxw-guide-circle {
    /* a dimmed field with a clean hole punched through it */
    background: radial-gradient(
        circle at 50% 44%,
        transparent 0 32%,
        rgba(2, 6, 23, .55) 32.4% 100%
    );
}
.apxw-guide-circle::after {
    content: "";
    position: absolute;
    left: 50%; top: 44%;
    /* height-driven, so a wide stage still gets a circle rather than an ellipse
       squeezed to the box */
    height: 76%; aspect-ratio: 1; width: auto;
    transform: translate(-50%, -50%);
    border: 2px dashed var(--accent-primary, #38bdf8);
    border-radius: 50%;
    opacity: .85;
}
.apxw-guide-figure {
    background: linear-gradient(
        to right,
        rgba(2, 6, 23, .55) 0 26%,
        transparent 26% 74%,
        rgba(2, 6, 23, .55) 74% 100%
    );
}
.apxw-guide-figure::after {
    content: "";
    position: absolute;
    left: 50%; top: 6%;
    height: 88%; aspect-ratio: 0.46; width: auto; max-width: 60%;
    transform: translateX(-50%);
    border: 2px dashed var(--accent-primary, #38bdf8);
    border-radius: 46% 46% 22% 22% / 26% 26% 8% 8%;
    opacity: .85;
}
.apxw-guide-faint { opacity: .35; }

.apxw-hint {
    position: absolute; left: 0; right: 0; bottom: 10px;
    text-align: center; font-size: 12px; font-weight: 700;
    letter-spacing: .04em; text-transform: uppercase;
    color: rgba(255, 255, 255, .82);
    text-shadow: 0 1px 4px rgba(2, 6, 23, .9);
}
.apxw-stage:not(.apxw-live) .apxw-hint { display: none; }

/* ── result strip ─────────────────────────────────────────────────────── */
.apxw-strip { display: flex; gap: 10px; margin: 4px 0 16px; flex-wrap: wrap; }
.apxw-strip img {
    width: 88px; height: 112px; object-fit: cover;
    border-radius: 10px; border: 1px solid rgba(255, 255, 255, .12);
    background: #060c17;
}

/* ── actions ──────────────────────────────────────────────────────────── */
.apxw-actions {
    display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
    margin-top: 18px;
}
.apxw-btn {
    appearance: none; border: 0; border-radius: 10px; cursor: pointer;
    font: inherit; font-weight: 700; font-size: 14.5px;
    padding: 11px 20px;
    display: inline-flex; align-items: center; gap: 8px;
    transition: filter .15s, background .15s;
}
.apxw-btn:focus-visible { outline: 2px solid var(--accent-primary, #38bdf8); outline-offset: 2px; }
.apxw-btn[disabled] { opacity: .6; cursor: default; }
.apxw-primary { background: var(--accent-primary, #38bdf8); color: #04121f; }
.apxw-primary:hover:not([disabled]) { filter: brightness(1.08); }
.apxw-ghost {
    background: rgba(255, 255, 255, .06); color: #e2e8f0;
    border: 1px solid rgba(255, 255, 255, .12);
}
.apxw-ghost:hover { background: rgba(255, 255, 255, .1); }
.apxw-quiet { background: none; color: #64748b; padding-left: 6px; padding-right: 6px; }
.apxw-quiet:hover { color: #a8b6c9; }

.apxw-msg { min-height: 18px; margin-top: 12px; font-size: 13.5px; color: var(--accent-success, #10b981); }
.apxw-msg.bad { color: #fca5a5; }

/* ── progress dots ────────────────────────────────────────────────────── */
.apxw-prog { display: flex; gap: 6px; margin-bottom: 14px; }
.apxw-dot {
    width: 26px; height: 3px; border-radius: 2px;
    background: rgba(255, 255, 255, .13);
}
.apxw-dot.now  { background: var(--accent-primary, #38bdf8); }
.apxw-dot.done { background: var(--accent-success, #10b981); }

/* ── spinner ──────────────────────────────────────────────────────────── */
.apxw-spinner {
    width: 34px; height: 34px; margin: 22px auto 8px;
    border: 3px solid rgba(255, 255, 255, .12);
    border-top-color: var(--accent-primary, #38bdf8);
    border-radius: 50%;
    animation: apxw-spin .9s linear infinite;
}
@keyframes apxw-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .apxw-spinner { animation-duration: 2.4s; }
}

/* ── phones ───────────────────────────────────────────────────────────── */
/* Most people meet this on a phone, holding it at arm's length. The panel goes
   full-bleed and the actions stack, so the shutter is never a small target. */
@media (max-width: 560px) {
    .apxw { padding: 0; }
    .apxw-panel { max-width: none; max-height: 100vh; height: 100vh; border-radius: 0; border: 0; }
    .apxw-body { padding: 20px 18px 26px; }
    .apxw-actions { flex-direction: column; align-items: stretch; }
    .apxw-btn { justify-content: center; padding: 14px 20px; }
}

/* ── the choice at the end ────────────────────────────────────────────── */
/* Shown side by side, always. The published picture is AI-made and will not be
   an exact likeness, so presenting it alone would be presenting it as the
   photograph — and the person would find out otherwise on their own homepage. */
.apxw-pair { margin: 0 0 16px; }
.apxw-pair-t {
    font-size: 12px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: #64748b; margin-bottom: 7px;
}
.apxw-pair-opts { display: flex; gap: 10px; }
.apxw-pair-busy { opacity: .5; pointer-events: none; }
.apxw-pick {
    flex: 1; min-width: 0; appearance: none; cursor: pointer;
    background: rgba(255, 255, 255, .04);
    border: 2px solid rgba(255, 255, 255, .10);
    border-radius: 12px; padding: 8px; font: inherit;
    display: flex; flex-direction: column; gap: 7px; align-items: center;
    transition: border-color .15s, background .15s;
}
.apxw-pick img {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover;
    border-radius: 8px; background: #060c17; display: block;
}
.apxw-pick span { font-size: 12.5px; font-weight: 700; color: #a8b6c9; }
.apxw-pick:hover { border-color: rgba(255, 255, 255, .22); }
.apxw-pick.on { border-color: var(--accent-primary, #38bdf8); background: rgba(56, 189, 248, .10); }
.apxw-pick.on span { color: #fff; }
.apxw-pick.on::after {
    content: "In use"; font-size: 10.5px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--accent-primary, #38bdf8);
}

/* A photo we could not make a picture from.
 *
 * Boxed and set apart from the ordinary pairs on purpose: this one is not a
 * choice between two good outcomes, it is a photograph that is NOT on the
 * customer's site and will not go up until they say so. Reading past it by
 * accident is the failure mode to design against. */
.apxw-unmade {
    border: 1px solid rgba(248, 113, 113, .35);
    background: rgba(248, 113, 113, .06);
    border-radius: 12px;
    padding: 12px;
}
.apxw-unmade .apxw-pair-opts { max-width: 132px; }
.apxw-unmade .apxw-pick { cursor: default; }
.apxw-unmade .apxw-msg { margin: 9px 0 0; }
.apxw-unmade .apxw-actions { margin-top: 11px; gap: 8px; }
.apxw-unmade .apxw-btn { flex: 0 0 auto; }
