/* 🧭 The tour (tour.js): the dim layer with its cut-out, the bobbing arrow, the bubble, and the little
   looping pictures. ChoreBoy's tour.css, with ChefBoy's pictures. Every animation is only under
   .tour-move (✨ Animations: Full, and no reduced motion); without it each picture shows how it ends. */
.tour { position: fixed; inset: 0; z-index: 500; pointer-events: auto; --tour-dim: rgba(28, 25, 23, .58); }
@media (prefers-color-scheme: dark) { .tour { --tour-dim: rgba(0, 0, 0, .7); } }
.tour.tour-none { background: var(--tour-dim); }
.tour-hole { position: fixed; border-radius: var(--radius); box-shadow: 0 0 0 3px var(--accent), 0 0 0 200vmax var(--tour-dim); pointer-events: none; }
.tour-move .tour-hole { transition: top .38s cubic-bezier(.3, .7, .2, 1), left .38s cubic-bezier(.3, .7, .2, 1), width .38s cubic-bezier(.3, .7, .2, 1), height .38s cubic-bezier(.3, .7, .2, 1); }
.tour-still .tour-hole, .tour-still .tour-bubble { transition: none !important; }
.tour-arrow { position: fixed; width: 14px; height: 14px; pointer-events: none; }
.tour-arrow::before { content: ''; position: absolute; inset: 0; background: var(--accent); clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.tour-arrow.down::before { clip-path: polygon(0 0, 100% 0, 50% 100%); }
.tour-move .tour-arrow { animation: tour-nudge 1.1s ease-in-out infinite; }
.tour-move .tour-arrow.down { animation-name: tour-nudge-down; }
@keyframes tour-nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
@keyframes tour-nudge-down { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }

.tour-bubble { position: fixed; width: min(22rem, calc(100vw - 32px)); max-height: calc(100vh - 32px); overflow-y: auto; margin: 0; padding: 1rem 1.1rem .9rem; background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.tour-move .tour-bubble { transition: top .38s cubic-bezier(.3, .7, .2, 1), left .38s cubic-bezier(.3, .7, .2, 1); }
.tour-count { margin: 0 0 .25rem; font-size: .75rem; font-weight: 650; letter-spacing: .03em; text-transform: uppercase; color: var(--text-3); }
.tour-h { margin: 0 0 .35rem; font-size: 1.08rem; line-height: 1.3; outline: none; }
.tour-text { margin: 0; font-size: .93rem; line-height: 1.45; color: var(--text-2); overflow-wrap: anywhere; }
.tour-btns { display: flex; align-items: center; gap: .5rem; margin-top: .85rem; }
.tour-skip { margin-right: auto; }
.tour-btns .btn { min-height: 2.25rem; }
.tour-docked .tour-bubble { top: auto !important; left: 16px !important; right: 16px; bottom: max(16px, env(safe-area-inset-bottom)); width: auto; max-height: 60vh; }
.tour-docked .tour-btns .btn { min-height: 2.6rem; }
html[data-fx="full"] .tour, html[data-fx="subtle"] .tour { animation: tour-in .18s ease-out; }
@keyframes tour-in { from { opacity: 0; } to { opacity: 1; } }

/* ---- the pictures ---- */
.tour-demo { margin: .7rem 0 0; }
.tour-demo-row { position: relative; display: flex; align-items: center; gap: .55rem; padding: .5rem .65rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); font-size: .9rem; }
.tour-demo-chip { flex-shrink: 0; padding: .1rem .45rem; border-radius: 999px; background: var(--accent-soft); color: var(--accent-text); font-size: .78rem; font-weight: 650; }
.tour-demo-caption { display: block; margin-top: .35rem; font-size: .78rem; color: var(--text-3); text-align: center; }

/* eat: three meals in a line; the first is ticked and goes to the back. End frame: Tue, Wed, Mon. */
.tour-demo-queue { position: relative; display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; padding: .5rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); font-size: .85rem; height: 2.6rem; }
.tour-demo-queue .tq { position: absolute; top: .5rem; width: calc((100% - 1.8rem) / 3); padding: .25rem 0; text-align: center; border-radius: var(--radius-sm); background: var(--surface); box-shadow: var(--shadow-sm); white-space: nowrap; }
.tq.b { left: .5rem; } .tq.c { left: calc(.5rem + (100% - 1.8rem) / 3 + .4rem); } .tq.a { left: calc(.5rem + 2 * ((100% - 1.8rem) / 3 + .4rem)); }
.tq.tick { width: 1.5rem; height: 1.5rem; padding: 0; top: .55rem; left: auto; right: .3rem; display: grid; place-items: center; border-radius: 50%; background: var(--good); color: #fff; font-weight: 900; opacity: 0; box-shadow: none; }
.tour-move .tq.a { animation: tq-a 3.6s cubic-bezier(.3, .7, .2, 1) infinite; }
.tour-move .tq.b { animation: tq-b 3.6s cubic-bezier(.3, .7, .2, 1) infinite; }
.tour-move .tq.c { animation: tq-c 3.6s cubic-bezier(.3, .7, .2, 1) infinite; }
.tour-move .tq.tick { animation: tq-tick 3.6s ease-out infinite; }
@keyframes tq-a { 0%, 22% { left: .5rem; background: var(--surface); opacity: 1; } 30%, 40% { left: .5rem; background: var(--good-soft); transform: scale(1.06); opacity: 1; } 62%, 92% { left: calc(.5rem + 2 * ((100% - 1.8rem) / 3 + .4rem)); transform: none; background: var(--surface); opacity: 1; } 100% { left: calc(.5rem + 2 * ((100% - 1.8rem) / 3 + .4rem)); opacity: 0;  } }
@keyframes tq-b { 0%, 40% { left: calc(.5rem + (100% - 1.8rem) / 3 + .4rem); opacity: 1; } 62%, 92% { left: .5rem; opacity: 1; } 100% { left: .5rem; opacity: 0;  } }
@keyframes tq-c { 0%, 40% { left: calc(.5rem + 2 * ((100% - 1.8rem) / 3 + .4rem)); opacity: 1; } 62%, 92% { left: calc(.5rem + (100% - 1.8rem) / 3 + .4rem); opacity: 1; } 100% { opacity: 0;  } }
@keyframes tq-tick { 0%, 22% { opacity: 0; transform: scale(.5); right: auto; left: calc(.5rem + (100% - 1.8rem) / 3 - 1.7rem); } 30% { opacity: 1; transform: scale(1.2); left: calc(.5rem + (100% - 1.8rem) / 3 - 1.7rem); } 40% { opacity: 1; transform: scale(1); left: calc(.5rem + (100% - 1.8rem) / 3 - 1.7rem); } 50%, 100% { opacity: 0; left: calc(.5rem + (100% - 1.8rem) / 3 - 1.7rem); } }

/* swap: two meals trade places. End frame: Pasta, Tacos. */
.tour-demo-swap { justify-content: center; }
.tour-demo-swap .ts { position: relative; padding: .25rem .6rem; border-radius: var(--radius-sm); background: var(--surface); box-shadow: var(--shadow-sm); white-space: nowrap; }
.tour-demo-swap .x { order: 3; } .tour-demo-swap .y { order: 1; } .ts-arrows { order: 2; color: var(--accent-text); font-weight: 800; }
.tour-move .tour-demo-swap .x { animation: ts-x 3.2s cubic-bezier(.3, .7, .2, 1) infinite; }
.tour-move .tour-demo-swap .y { animation: ts-y 3.2s cubic-bezier(.3, .7, .2, 1) infinite; }
.tour-move .ts-arrows { animation: ts-spin 3.2s ease-in-out infinite; }
@keyframes ts-x { 0%, 25% { transform: translateX(calc(-100% - 3rem)); opacity: 1; } 55%, 92% { transform: translateY(0); opacity: 1; } 100% { opacity: 0;  } }
@keyframes ts-y { 0%, 25% { transform: translateX(calc(100% + 3rem)); opacity: 1; } 55%, 92% { transform: translateY(0); opacity: 1; } 100% { opacity: 0;  } }
@keyframes ts-spin { 0%, 25% { transform: rotate(0); } 55%, 100% { transform: rotate(180deg); } }

/* week: seven days fill in, one after another. */
.tour-demo-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: .25rem; padding: .45rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); }
.twd { display: flex; flex-direction: column; align-items: center; gap: .15rem; font-size: .66rem; }
.twd b { color: var(--text-3); }
.twd i { font-style: normal; letter-spacing: -.12em; font-size: .72rem; }
.tour-move .twd i { animation: twd 3.6s ease-out infinite; animation-delay: calc(var(--n) * .18s); }
@keyframes twd { 0% { opacity: 0; transform: translateY(-6px) scale(.7); } 18%, 85% { opacity: 1; transform: none; } 100% { opacity: 0; } }

/* drag: the third meal moves to the top; the days stay. End frame: Salmon on top. */
.tour-demo-rot { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: .25rem .55rem; padding: .45rem .65rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); font-size: .8rem; }
.tr-day { color: var(--text-3); font-weight: 650; }
.tr-slot { display: block; min-height: 1.6rem; border-top: 1px dashed var(--border); padding-top: .2rem; }
.tr-card { display: inline-block; max-width: 100%; padding: .15rem .55rem; border-radius: var(--radius-sm); background: var(--surface); box-shadow: var(--shadow-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tr-moving { background: var(--accent-soft); }
.tour-move .tr-moving { animation: tr-up 3.4s cubic-bezier(.3, .7, .2, 1) infinite; }
.tour-move .tr-down1, .tour-move .tr-down2 { animation: tr-down 3.4s cubic-bezier(.3, .7, .2, 1) infinite; }
@keyframes tr-up { 0%, 15% { transform: translate(8%, 3.7rem) rotate(-2deg); box-shadow: var(--shadow-lg); opacity: 1; } 60%, 92% { transform: none; box-shadow: var(--shadow-sm); opacity: 1; } 100% { opacity: 0;  } }
@keyframes tr-down { 0%, 15% { transform: translateY(-1.85rem); opacity: 1; } 60%, 92% { transform: none; opacity: 1; } 100% { opacity: 0;  } }

/* type: an item typed in, then Claude's price and the repeat. */
.tour-demo-type, .tour-demo-parse { flex-wrap: wrap; row-gap: .35rem; }
.tour-demo-typed { flex: 1 1 auto; min-width: 0; max-width: 11ch; overflow: hidden; white-space: nowrap; color: var(--text); border-right: 2px solid transparent; }
.tour-move .tour-demo-typed { animation: tour-type 3.6s steps(11, end) infinite; }
.tour-move .tour-demo-type .tour-demo-chip, .tour-move .tour-demo-parse .tour-demo-chip { animation: tour-chip 3.6s ease-out infinite; }
.tour-move .tour-demo-chip + .tour-demo-chip { animation-delay: .15s; }
.tour-move .tour-demo-chip + .tour-demo-chip + .tour-demo-chip { animation-delay: .3s; }
@keyframes tour-type { 0% { max-width: 0; border-right-color: var(--accent); } 45% { max-width: 11ch; border-right-color: var(--accent); } 50%, 100% { max-width: 11ch; border-right-color: transparent; } }
@keyframes tour-chip { 0%, 52% { opacity: 0; transform: scale(.8); } 62%, 92% { opacity: 1; transform: scale(1); } 100% { opacity: 0; } }

/* list: three items ticked off one by one. End frame: all ticked. */
.tour-demo-list { display: flex; flex-direction: column; gap: .3rem; padding: .45rem .65rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); font-size: .82rem; }
.tl { display: flex; align-items: center; gap: .45rem; color: var(--text-3); text-decoration: line-through; }
.tl em { margin-left: auto; font-style: normal; font-weight: 650; }
.tl i { width: .95rem; height: .95rem; border-radius: 4px; border: 2px solid var(--accent); background: var(--accent); flex-shrink: 0; }
.tour-move .tl { animation: tl-row 3.6s ease-in-out infinite; }
.tour-move .tl i { animation: tl-box 3.6s ease-in-out infinite; }
.tour-move .l2, .tour-move .l2 i { animation-delay: .5s; }
.tour-move .l3, .tour-move .l3 i { animation-delay: 1s; }
@keyframes tl-row { 0%, 20% { color: var(--text); text-decoration-color: transparent; } 30%, 85% { color: var(--text-3); text-decoration-color: currentColor; } 100% { color: var(--text); text-decoration-color: transparent; } }
@keyframes tl-box { 0%, 20% { background: transparent; transform: scale(1); } 26% { background: var(--accent); transform: scale(1.25); } 32%, 85% { background: var(--accent); transform: scale(1); } 100% { background: transparent; } }

/* bars: spending by month, growing one after another. */
.tour-demo-bars { display: flex; align-items: flex-end; gap: .45rem; height: 3.6rem; padding: .4rem .65rem 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); }
.tour-demo-bar { flex: 1; height: var(--h); border-radius: 4px 4px 0 0; background: var(--accent); opacity: .8; transform-origin: bottom; }
.tour-move .tour-demo-bar { animation: tb 3.6s ease-out infinite; animation-delay: calc(var(--n) * .12s); }
@keyframes tb { 0% { transform: scaleY(0); } 25%, 88% { transform: scaleY(1); } 100% { transform: scaleY(0); } }

/* parse: a recipe line, then what was found in it. */
.tp-text { flex: 1 1 100%; color: var(--text-2); font-size: .82rem; }
.tour-move .tp-text { animation: tp 3.6s ease-in-out infinite; }
@keyframes tp { 0%, 40% { opacity: 1; } 55%, 92% { opacity: .45; } 100% { opacity: 1; } }

/* timer: a ring runs down, then the bell rings. */
.tour-demo-timer { gap: .6rem; }
.tt-ring { position: relative; width: 1.6rem; height: 1.6rem; border-radius: 50%; background: conic-gradient(var(--accent) 0 0, var(--sunken) 0); flex-shrink: 0; }
.tt-ring i { position: absolute; inset: .25rem; border-radius: 50%; background: var(--surface-2); }
.tt-step { flex: 1; min-width: 0; font-size: .85rem; }
.tt-step b { color: var(--accent-text); white-space: nowrap; }
.tt-bell { font-size: 1.2rem; }
@property --tt { syntax: '<percentage>'; inherits: false; initial-value: 0%; }
.tour-move .tt-ring { background: conic-gradient(var(--accent) var(--tt), var(--sunken) 0); animation: tt-run 3.6s linear infinite; }
.tour-move .tt-bell { animation: tt-bell 3.6s ease-in-out infinite; }
@keyframes tt-run { 0% { --tt: 100%; } 70%, 100% { --tt: 0%; } }
@keyframes tt-bell { 0%, 70% { transform: none; opacity: .35; } 74% { transform: rotate(-18deg) scale(1.2); opacity: 1; } 78% { transform: rotate(16deg) scale(1.2); } 82% { transform: rotate(-12deg) scale(1.15); } 86%, 96% { transform: none; opacity: 1; } 100% { opacity: .35; } }

@media (prefers-reduced-motion: reduce) {
  .tour, .tour *, .tour *::before, .tour *::after { animation: none !important; transition: none !important; }
}
