/* ── Shared tour system (Sprint 9 §3 Task 1) ──────────────────────────
   Existing custom properties only (--gold, --bg-card, --border,
   --radius-lg, --text/--text-muted/--text-hint) -- no hardcoded colors,
   same rule every other stylesheet in this codebase follows. z-index sits
   above the desktop profile menu (1100) so a tour step can highlight it,
   but below the branded app-entrance overlay (2000) -- entrance and the
   tour should never legitimately overlap, but if they somehow did,
   entrance (a more foundational "app is still loading" state) wins. */

.gf-tour-dim {
    position: fixed;
    inset: 0;
    z-index: 1499;
    background: rgba(0, 0, 0, 0.55);
}

/* Purely decorative highlight ring -- positioned over a real nav element
   via getBoundingClientRect() (js/tour.js), never modifies that element
   itself. aria-hidden since the same information is always in the dialog
   text too (never the only source of meaning). */
.gf-tour-ring {
    position: fixed;
    z-index: 1500;
    border: 2px solid var(--gold);
    border-radius: var(--radius-md);
    box-shadow: 0 0 0 4px var(--gold-dim);
    pointer-events: none;
    transition: left 0.15s ease, top 0.15s ease, width 0.15s ease, height 0.15s ease;
}

.gf-tour-dialog {
    position: fixed;
    z-index: 1501;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: min(360px, calc(100vw - 32px));
    max-height: min(480px, calc(100vh - 32px));
    overflow-y: auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 24px 22px 18px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
    /* Safe-area awareness on mobile, per the mobile-behavior rules. */
    margin-bottom: env(safe-area-inset-bottom, 0px);
}

/* Adaptive placement (manual-testing correction pass): anchored steps no
   longer always render the dialog dead-center over the highlighted target,
   which could cover it entirely. applyTourDialogPlacement() (js/tour.js)
   adds exactly one of these modifier classes and sets the one inline
   top/bottom pixel value each mode needs; the base .gf-tour-dialog rule
   above still fully applies for unanchored steps and as the (rare) desktop
   fallback when neither side has room. Horizontal centering (left: 50%,
   inherited from the base rule) is shared by every mode -- only the
   vertical anchor, and on mobile the size, change. */
.gf-tour-dialog--below,
.gf-tour-dialog--above,
.gf-tour-dialog--sheet {
    top: auto;
    transform: translateX(-50%);
}

.gf-tour-dialog--below,
.gf-tour-dialog--above {
    width: min(400px, calc(100vw - 32px));
}

@media (max-width: 900px) {
    .gf-tour-dialog--below,
    .gf-tour-dialog--above,
    .gf-tour-dialog--sheet {
        width: calc(100vw - 32px);
        max-height: 48vh;
    }
}

.gf-tour-step-count {
    font-size: 12px;
    color: var(--text-hint);
    margin-bottom: 8px;
}

.gf-tour-title {
    font-size: 1.15rem;
    color: var(--text);
    margin: 0 0 10px;
    outline: none; /* focused programmatically, not via keyboard/mouse click */
}

.gf-tour-body {
    font-size: 0.9rem;
    color: var(--text-muted);
    line-height: 1.5;
    margin: 0 0 20px;
}

/* Interaction-bug correction pass: explicit keyboard/AT-accessible
   equivalent of clicking the active fallback target (js/tour.js
   updateTourFallbackInteraction()). A real button, so it's automatically
   covered by the existing dialog focus trap -- js/tour.js toggles its own
   style.display directly (matching the existing Back-button convention),
   so this class only supplies layout for when it's actually shown. */
.gf-tour-action-btn {
    display: block;
    width: 100%;
    margin: -8px 0 20px;
}

.gf-tour-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.gf-tour-footer-right {
    display: flex;
    gap: 8px;
}

.gf-tour-btn {
    min-height: 44px;
    min-width: 44px;
    padding: 8px 18px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    font-family: 'Inter', sans-serif;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: filter 0.15s, background 0.15s, color 0.15s;
}

.gf-tour-btn-primary {
    background: var(--gold);
    color: #1a1200;
}

.gf-tour-btn-primary:hover {
    filter: brightness(1.1);
}

.gf-tour-btn-ghost {
    background: transparent;
    color: var(--text-muted);
    border-color: var(--border);
}

.gf-tour-btn-ghost:hover {
    color: var(--text);
    border-color: var(--border-hover);
}

/* Finish flourish -- reuses the SAME global .gf-loader--form-fade mark
   (js/nav.js GF_MARK_SVG, css/style.css) rather than a second animation
   implementation. Reduced motion is already handled entirely by that
   shared primitive's own reduced-motion rule -- nothing extra needed here. */
.gf-tour-complete {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 12px 0 8px;
    text-align: center;
    /* Refinement pass: real opacity fade before removal (mirrors, does not
       modify, .gf-app-entry's own opacity transition in css/style.css) --
       timed and removed by runTourCompletionFlourish()/
       startTourCompletionFade() in js/tour.js. */
    opacity: 1;
    transition: opacity 0.3s ease-out;
}

.gf-tour-complete.gf-tour-complete-out {
    opacity: 0;
}

@media (max-width: 900px) {
    .gf-tour-dialog {
        width: calc(100vw - 24px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .gf-tour-ring {
        transition: none;
    }
    /* Refinement pass: minimal opacity-only motion for the completion fade
       under reduced motion -- same shortened-duration approach
       .gf-app-entry already uses in css/style.css, not a new pattern. The
       JS side (runTourCompletionFlourish()) separately skips the
       animationend draw-wait entirely under reduced motion; this shortens
       the fade itself to match. */
    .gf-tour-complete {
        transition: opacity 0.15s ease-out;
    }
}
