/* achievements.css — achievement carousel skin, shared by the demo tour
   (demo_tour.js) and the real app (Profile). Moved verbatim from
   demo_tour.css (spec 2026-09-24 §4.1); loaded on every page from
   base.html. The panel header label is set per surface via
   --ach-panel-header (demo_tour.css sets 'Demo Achievements'). */

/* Color pass (owner polish directive 1, 2026-09-13): the app's own palette
   runs blue (--primary-color #2563eb) and green (#16a34a/#22c55e) — the
   pill and carousel previously borrowed the app's neutral slate chrome,
   which read as "just another app control," not a distinct tutorial
   surface. Given a dedicated violet/indigo "tutorial accent" family here,
   used consistently across the pill, the carousel panel header/edge glow,
   and centered-item highlight color. The check-in animation (achievement
   just earned) stays GREEN per the owner's explicit carve-out — green
   still reads as "success" against a violet chrome without clashing.
   Flagged exact values for owner sign-off:
     --demo-accent:        #7c3aed  (violet-600 — pill bg, panel edge, centered-item text)
     --demo-accent-dark:   #5b21b6  (violet-800 — pill hover bg, panel header bg)
     --demo-accent-darker: #4c1e79  (deeper violet — panel header bg, denser than -dark)
     --demo-accent-soft:   #ede9fe  (violet-100 — reveal-panel/caution-row tint)
     --demo-accent-glow:   rgba(124, 58, 237, 0.55)  (edge glow / focus ring) */
:root {
    --demo-accent: #7c3aed;
    --demo-accent-dark: #5b21b6;
    --demo-accent-darker: #4c1e79;
    --demo-accent-soft: #ede9fe;
    --demo-accent-glow: rgba(124, 58, 237, 0.55);
}

/* ── Achievements carousel — re-skin of the shared VCarousel engine ──────
   The engine (vertical_carousel.js) owns deploy/backdrop/drag/snap/glide;
   only the panel's SIZE and each item's INTERNAL layout are re-skinned
   here via the panelClass hook (.vc-panel--achievements) and the
   .demo-ach-* classes achievements.js's renderRow builds. Stacked
   above the spotlight/toast (z-index 20000/20030) — same
   reason #demo-bank-picker already sits at 20040 — so the completion
   beat's "open the carousel over a kept-alive spotlight" sequencing
   (owner directive 3) reads correctly on top, not underneath. */
.vc-panel--achievements {
    z-index: 20050;
    width: min(86vw, 380px);
    /* Violet edge accent (owner directive 1) replaces the shared engine's
       plain box-shadow — reads as a distinct tutorial surface the instant
       the panel deploys, before any row content is parsed. */
    box-shadow: 6px 0 26px rgba(0, 0, 0, 0.30), inset -3px 0 0 var(--demo-accent);
}
.vc-panel--achievements-backdrop {
    z-index: 20045;
}
@media (min-width: 768px) {
    /* Desktop-capable (desktopOk:true) — every other VCarousel deployment
       is phone-only and never reaches this rule. A little wider than the
       phone default since achievement rows carry more per-row content
       (checkbox + number + title + reveal paragraph) than a plain label. */
    .vc-panel--achievements { width: min(40vw, 420px); }
}
/* Panel header band — a fixed strip the shared engine doesn't otherwise
   have (VCarousel's .vc-panel has no header of its own).
   IMPORTANT layout note: the engine's own centering math
   (vertical_carousel.js centerOffsetFor) computes
   `panel.clientHeight/2 - (item.offsetTop + item.offsetHeight/2)` and
   applies the result as .vc-strip's own translateY — it assumes .vc-strip's
   coordinate origin is coincident with .vc-panel's. Reserving header space
   via padding/margin/top on .vc-panel ITSELF (or on .vc-strip) would shift
   .vc-strip's origin without the engine's math knowing about it, silently
   mis-centering every item by the header's height — exactly the kind of
   drift the no-movement fix (directive 3) exists to eliminate elsewhere.
   So instead: .vc-panel--achievements is shrunk from the TOP via `top`
   (which genuinely reduces panel.clientHeight, so the engine's own fresh
   read of clientHeight stays internally consistent), and the header itself
   is painted on the BACKDROP element (a separate sibling the engine never
   measures for centering) as a fixed band exactly filling the gap this
   creates above the shrunk panel. */
.vc-panel--achievements { top: 38px; }
.vc-panel--achievements-backdrop::before {
    content: var(--ach-panel-header, 'Achievements');
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    width: min(86vw, 380px);
    z-index: 20051; /* above .vc-panel--achievements (20050) itself */
    background: linear-gradient(135deg, var(--demo-accent-dark), var(--demo-accent-darker));
    color: #ede9fe;
    font-weight: 700;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    padding: 10px 16px;
    border-bottom: 1px solid var(--demo-accent);
    box-sizing: border-box;
    /* Hidden until the panel/backdrop actually deploy — .vc-open is toggled
       on both simultaneously by the engine's open()/close(). */
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.28s ease;
}
.vc-panel--achievements-backdrop.vc-open::before {
    opacity: 1;
}
@media (min-width: 768px) {
    .vc-panel--achievements-backdrop::before { width: min(40vw, 420px); }
}
.demo-ach-row {
    padding: 12px 16px 12px 18px;
    cursor: pointer;
}
.demo-ach-row-head {
    display: flex;
    align-items: flex-start;
    gap: 8px;
}
.demo-ach-check {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin-top: 2px;
    color: #16a34a;
}
.demo-ach-checkbox {
    display: block;
    width: 14px;
    height: 14px;
    border: 2px solid #94a3b8;
    border-radius: 3px;
}
.demo-ach-row--earned .demo-ach-checkbox { border-color: #16a34a; }
.demo-ach-num {
    flex: 0 0 auto;
    font-weight: 700;
    color: #64748b;
    font-size: 0.85em;
    margin-top: 1px;
}
.demo-ach-title {
    font-weight: 600;
    color: #1e293b;
    line-height: 1.35;
}
/* Centered-item highlight: violet (owner directive 1), not the app's own
   --primary-color blue — this carousel is a tutorial surface, not app
   chrome, and should never read as "another blue link" among the app's own
   blue-highlighted controls. */
.vc-item--center .demo-ach-title { color: var(--demo-accent); }
/* Inert rows: Advanced achievements only, as of the click-to-navigate pass
   (owner polish directive 4, 2026-09-14) — every Basic row now has a real
   demo page and navigates on tap. Advanced keeps the muted treatment
   (same visual language as the gated nav tabs' .demo-nav-inert, which lives
   in demo_tour.css) — its detail/nav pass is explicitly deferred, not a gap. */
.demo-ach-row--inert .demo-ach-title,
.demo-ach-row--inert .demo-ach-num { opacity: 0.55; }
.demo-ach-row--explain .demo-ach-title { color: var(--demo-accent); font-weight: 700; }

/* Snap-info reveal: expands/fades in over 0.5s BELOW the title (spec
   §6.1, verbatim timing/placement) — un-reached achievements show it in
   full too (owner ruling: the carousel serves task-shoppers). Collapsed
   by default (max-height 0) so the expand reads as a real reveal, not a
   pre-laid-out block that merely fades. */
.demo-ach-reveal {
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    margin-left: 26px;
    transition: max-height 0.5s ease, opacity 0.5s ease;
}
.demo-ach-reveal--open {
    max-height: 240px;
    opacity: 1;
    margin-top: 6px;
    /* Soft violet tint + left rule (owner directive 1): the reveal panel
       is the carousel's own "content" surface, distinguished from the
       plain row list it expands out of. */
    background: var(--demo-accent-soft);
    border-left: 2px solid var(--demo-accent);
    border-radius: 0 6px 6px 0;
    padding: 8px 10px;
}
/* Requirements list (Task 6 Step 3, 2026-09-19) — REPLACES the former
   .demo-ach-reveal-wiifm prose + .demo-ach-reveal-pages line. The reveal
   now carries the achievement's Requirements bullets, which are also its
   sole award criterion (Global Constraint 13), so what the row reads is
   exactly what earns it. Single-requirement achievements (nine of the
   twelve) render as a one-item list; the bullet still helps it read as a
   checklist item rather than a sentence about the achievement. */
.demo-ach-reqs {
    margin: 0;
    padding: 0 0 0 16px;
    list-style: disc;
}
.demo-ach-req {
    font-size: 0.82rem;
    line-height: 1.45;
    color: #475569;
}
.demo-ach-req + .demo-ach-req { margin-top: 5px; }

/* Advanced caution — a sticky caption row, never a gate (copy law: states
   a sequencing suggestion, explicitly disclaims a gate in the same
   breath). Sticky rows (see vertical_carousel.js) still snap-center on
   swipe/tap but never commit a value or close the panel. */
.demo-ach-row--caution {
    cursor: default;
    background: rgba(124, 58, 237, 0.06);
    border-top: 1px solid var(--demo-accent-soft);
    border-bottom: 1px solid var(--demo-accent-soft);
}
.demo-ach-caution-label {
    font-weight: 700;
    font-size: 0.78rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 4px;
}
.demo-ach-caution-text {
    font-size: 0.8rem;
    line-height: 1.4;
    color: #64748b;
    font-style: italic;
}

/* Completion-flow check-in animation (owner directive 3: "a visible
   check-in animation, not an instant swap"). Plays once when
   runCompletionCarouselBeat swaps the empty checkbox glyph for the check
   SVG; the class is added fresh each time (demo_tour.js), so re-adding it
   after removal always restarts the keyframe. */
.demo-ach-check--checking-in {
    animation: demo-ach-check-in 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes demo-ach-check-in {
    0% { transform: scale(0.2); opacity: 0; }
    60% { transform: scale(1.25); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .demo-ach-reveal { transition: none; }
    .demo-ach-check--checking-in { animation: none; }
}

/* ── Achievement toast ──────────────────────────────────────────────────
   Per the sandbox spec §6 roster naming + game-loop doc's Reward beat
   copy law: capitalized app-domain nouns, no exclamation stacking.
   Redesigned per owner ruling (polish round 2026-09-13): a green HEADER
   band announcing "Basic Achievement Completed — <name>", with the
   payoff-receipt body below it — bottom-of-screen placement kept as-is.
   Acknowledgment mechanic (owner ruling, §1.5 mechanic 3, 2026-09-13): the
   toast never auto-dismisses — at TOAST_HOLD_MS it gains .awaiting-ack,
   which reveals the "click here to continue" line and switches the whole
   toast to a clickable affordance (any click/tap on it advances).

   SHARED WITH THE REAL APP (spec 2026-09-25 §toast-parity, owner: "I want
   the achievements toast for both the demo and the real account to look
   identical"): moved here verbatim from demo_tour.css and grouped with
   #ach-toast (achievements.js showEarnToast) so both render pixel-
   identical — same background/border/colors/padding/radius/timing. The
   demo- prefix on the child classes (.demo-toast-title/-body/-continue) is
   historical: they're a shared component now, reused as-is by the real
   toast. #ach-toast never gets .demo-toast--banner-only (a tutorial-only
   three-phase-celebration concept), so that one rule stays scoped to
   #demo-toast alone. */
#demo-toast, #ach-toast {
    position: fixed;
    left: 50%;
    bottom: 28px;
    transform: translateX(-50%) translateY(16px);
    z-index: 20030;
    background: #0f172a;
    color: #dcfce7;
    border: 1px solid #22c55e;
    border-radius: 10px;
    padding: 0;
    max-width: min(440px, calc(100vw - 32px));
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease, transform 0.3s ease;
    overflow: hidden;
}
#demo-toast.show, #ach-toast.show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
    pointer-events: auto;
}
#demo-toast.awaiting-ack, #ach-toast.awaiting-ack { cursor: pointer; }
#demo-toast.awaiting-ack:hover, #ach-toast.awaiting-ack:hover { border-color: #4ade80; }
/* Phase 1 of the three-phase celebration (owner directive round,
   2026-09-14, item 2): header-only toast — collapses the empty body block
   so the toast reads as a compact banner, not a card with a blank gap
   where the receipt text will land in Phase 3. Removed automatically the
   next time showToast() runs without opts.bannerOnly (Phase 3). Tutorial-
   only — #ach-toast never gets this class. */
#demo-toast.demo-toast--banner-only .demo-toast-body { padding: 0; }

/* REMOVED (Task 6b, 2026-09-19): .demo-toast--chip. The progress chip
   served only the five-step B3 cluster, removed with it. */

.demo-toast-title {
    background: #14532d;
    color: #dcfce7;
    font-weight: 700;
    font-size: 0.9rem;
    line-height: 1.35;
    padding: 12px 20px;
    border-bottom: 1px solid #22c55e;
}
.demo-toast-body {
    font-size: 0.82rem;
    line-height: 1.45;
    color: #d1e7d4;
    padding: 12px 20px 14px;
}
.demo-toast-continue {
    display: none;
    font-size: 0.72rem;
    font-weight: 700;
    color: #4ade80;
    padding: 0 20px 12px;
}
#demo-toast.awaiting-ack .demo-toast-continue, #ach-toast.awaiting-ack .demo-toast-continue { display: block; }

/* Real-app-only bottom row (spec 2026-09-25 §toast-parity item 2, owner:
   "keep the 'see your achievements' but add it as a new row on the bottom
   below the achievement description"): a persistent link to the Profile
   achievements card, styled as a row matching the toast (green text, same
   horizontal padding as .demo-toast-body) — always clickable, not gated
   behind .awaiting-ack the way .demo-toast-continue is. */
.ach-toast-link {
    display: block;
    font-size: 0.78rem;
    font-weight: 600;
    color: #4ade80;
    padding: 0 20px 12px;
    text-decoration: none;
}
.ach-toast-link:hover, .ach-toast-link:focus-visible { text-decoration: underline; }

@media (max-width: 767.98px) {
    #demo-toast, #ach-toast {
        left: 16px;
        right: 16px;
        max-width: none;
        width: auto;
        transform: translateY(16px);
    }
    #demo-toast.show, #ach-toast.show { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    #demo-toast, #ach-toast { transition: none !important; animation: none !important; }
}
