feedBack/static/tour-engine.css
Bret Mogilefsky af2949677a
rename: slopsmith → feedBack, byron → got-feedBack (#537)
* Update GitHub repo references from feedback* to feedBack*

* rename: slopsmith -> feedBack, byron -> got-feedBack

Renames across the entire codebase:
- slopsmith/Slopsmith/SLOPSMITH/SlopSmith -> feedBack/FeedBack/FEEDBACK/FeedBack
- byron/Byron/Byrongamatos -> got-feedBack/got-feedBack/got-feedBack
- /home/byron/ -> /opt/got-feedBack/
- byron@ougsoft.com -> hi@got-feedBack.org
- github.com/byrongamatos/ -> github.com/got-feedback/
- com.byron. -> com.got-feedback.
- SLOPSMITH_ env vars -> FEEDBACK_ with backward-compat fallback
- Protocol/storage strings migrated with read-old/write-new pattern
- window.slopsmith JS API -> window.feedBack (canonical) + backward-compat alias

Refs: #rename-slopsmith

* rename: complete regen against current main + fix backward-compat alias

Regenerated the slopsmith->feedBack / byron->got-feedBack rename on top of
current main (3 commits had landed since the branch: #572/#554/#574),
resolving the four content conflicts in favour of main's newer content
(autoplay/auto-exit, accuracy-badge, Virtuoso re-home, feedpak badge).

Completion fixes on top of the mechanical rename:
- Re-apply rename to post-branch content the original rename never saw:
  window.slopsmith(.Tour) consumers in lessons.js / notifications.js /
  onboarding-tour.js, and the matching JS + python tests (autoplay_exit,
  progression_*, test_feedpak_extension FEEDBACK_* env vars). The test env
  vars now match server.py (which reads FEEDBACK_SYNC_STARTUP /
  FEEDBACK_SKIP_STARTUP_TASKS), so the sync-startup test exercises the real
  path again.
- Restore the window.slopsmith backward-compat alias dropped during conflict
  resolution, and move the bus aliases to AFTER the _feedBackExisting merge
  block so they reference the fully-assembled object (also fixes the
  loop_api.test.js API-surface regex, which the original PR latently broke).
- Drop the stray empty data/web_library.db (runtime DB lives in CONFIG_DIR)
  and gitignore it.
- Fix stale tone-source test: feed[dB]ack -> fee[dB]ack to match shipped
  source labels.

Verified locally (org CI billing-blocked): JS 819/819 pass; pytest 1669
passed / 1683 collected with 0 import errors; zero residual slopsmith/byron
except the two intentional window.slopsmith aliases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* rename: implement advertised backward-compat + prune dead community plugins

Address gaps where PR #537's "Backward compatibility" section was advertised
but not implemented, and clean up the community plugin list.

Env vars (FEEDBACK_* canonical, legacy SLOPSMITH_* honoured):
- New lib/env_compat.py (getenv_compat / env_flag_compat) + tests. server.py
  (_env_flag + all FEEDBACK_* reads), diagnostics_hardware, gp2midi and
  tailwind_rebuild now resolve the legacy alias, so existing SLOPSMITH_UI /
  SLOPSMITH_PLUGINS_DIR / etc. deployments keep working.
- Fix the rename collapsing plugins/__init__.py and minigames/routes.py from
  `FEEDBACK_PLUGINS_DIR or SLOPSMITH_PLUGINS_DIR` into a redundant
  `FEEDBACK_ or FEEDBACK_` (the fallback was silently lost).

Storage (app.js update-channel):
- Read feedBack-update-channel, fall back to legacy slopsmith-update-channel,
  and clear the legacy key on write — so a user's update-channel preference
  survives the rename instead of resetting to "stable".

Community plugin list (README): the rename rewrote third-party repo URLs we
don't own. Probed every one; their owners never renamed, so:
- Restore the 13 live community plugins to their real slopsmith-* names.
- Prune 6 that are 404 to the public (topkoa splitscreen/stems, OmikronApex
  tuner, Jafz2001 nam-rig-builder, DeathlySin song-preview, Erikcb91 shuffle).
- Fix a pre-existing Guitar Theory clone-command typo (nam-tone -> guitar-theory).

Verified: env_compat 7/7, JS 819/819, pytest 1690 collected / 0 import errors,
rename-sensitive + startup suites green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: byrongamatos <xasiklas@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 11:03:01 +02:00

272 lines
7.4 KiB
CSS

/* ── Consolidated tour menu — one floating button + popover for all tours ── */
/* Palette aligned with the v3 fee[dB]ack design tokens (tailwind.config.js):
fb-card #1e293b surfaces, fb-cardMuted #0b1220 wells, fb-primary #0ea5e9
accent, fb-border #334155 hairlines, fb-text #f8fafc / fb-textDim #94a3b8
text, fb-gold #e8c040 badge. Plain CSS (no Tailwind classes) so it needs no
stylesheet rebuild. Per CLAUDE.md → Frontend Conventions. */
.feedBack-tour-menu-btn {
position: fixed;
bottom: 12px;
right: 12px;
/* #player is z-index:100 and fixed inset:0; the menu must sit above
it (and above the controls bar at z:10 inside #player), but below
transient modals like Shepherd tooltips. */
z-index: 200;
width: 32px;
height: 32px;
border-radius: 50%;
background: #1e293b;
border: 1.5px solid #0ea5e9;
color: #f8fafc;
font-size: 15px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 0 6px #0ea5e966;
display: flex;
align-items: center;
justify-content: center;
transition: box-shadow 0.2s, transform 0.15s;
}
.feedBack-tour-menu-btn:hover {
box-shadow: 0 0 12px #0ea5e9aa;
transform: translateY(-1px);
}
.feedBack-tour-menu-btn.has-unseen {
animation: tour-pulse 2s ease-in-out infinite;
}
.feedBack-tour-menu-btn.has-unseen::after {
content: '';
position: absolute;
top: -2px;
right: -2px;
width: 10px;
height: 10px;
background: #e8c040;
border: 2px solid #1e293b;
border-radius: 50%;
}
@keyframes tour-pulse {
0%, 100% { box-shadow: 0 0 6px #0ea5e966; }
50% { box-shadow: 0 0 16px #0ea5e9cc; }
}
.feedBack-tour-menu-popover {
position: fixed;
bottom: 56px;
right: 12px;
z-index: 201;
min-width: 220px;
max-width: 320px;
/* Keep the list scrollable when many tour-enabled plugins are
relevant — without this the popover would grow past the
viewport top as the plugin ecosystem expands. 80px reserves
room for the trigger button + its bottom inset. */
max-height: calc(100vh - 80px);
overflow-y: auto;
background: #1e293b;
border: 1px solid #0ea5e944;
border-radius: 8px;
padding: 6px;
font-size: 13px;
color: #f8fafc;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
}
.feedBack-tour-menu-popover .tour-menu-header {
padding: 4px 10px 6px;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #94a3b8;
border-bottom: 1px solid #334155;
margin-bottom: 4px;
}
.feedBack-tour-menu-popover .tour-menu-empty {
padding: 10px;
color: #94a3b8;
font-style: italic;
text-align: center;
}
.feedBack-tour-menu-popover .tour-menu-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
width: 100%;
padding: 7px 10px;
background: transparent;
border: none;
border-radius: 4px;
color: #f8fafc;
font-size: 13px;
text-align: left;
cursor: pointer;
transition: background 0.12s;
}
.feedBack-tour-menu-popover .tour-menu-item:hover {
background: #334155;
color: #f8fafc;
}
/* Keyboard focus gets an explicit ring instead of relying on the hover
background — matches the :focus-visible treatment elsewhere in the
app (style.css). Pointer focus is left alone. */
.feedBack-tour-menu-popover .tour-menu-item:focus-visible {
background: #334155;
color: #f8fafc;
outline: 2px solid #0ea5e9;
outline-offset: -2px;
}
.feedBack-tour-menu-popover .tour-menu-item-label {
flex: 1;
}
.feedBack-tour-menu-popover .tour-menu-item-status {
font-size: 10px;
font-weight: 600;
padding: 2px 6px;
border-radius: 10px;
min-width: 14px;
text-align: center;
}
.feedBack-tour-menu-popover .tour-menu-item-status.is-new {
background: #e8c040;
color: #0f172a;
}
.feedBack-tour-menu-popover .tour-menu-item-status.is-seen {
background: #0b1220;
color: #94a3b8;
}
/* ── First-visit toast — anchored above the menu button ── */
.feedBack-tour-prompt {
position: fixed;
bottom: 56px;
right: 12px;
z-index: 202;
background: #1e293b;
border: 1px solid #0ea5e944;
border-radius: 8px;
padding: 10px 14px;
font-size: 13px;
color: #f8fafc;
max-width: 240px;
line-height: 1.4;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
transition: opacity 0.5s;
}
.feedBack-tour-prompt.fading {
opacity: 0;
pointer-events: none;
}
.feedBack-tour-prompt .tour-prompt-more {
margin-top: 4px;
font-size: 11px;
color: #94a3b8;
}
.feedBack-tour-prompt .tour-prompt-buttons {
display: flex;
gap: 6px;
margin-top: 8px;
}
.feedBack-tour-prompt button {
padding: 3px 10px;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
border: none;
transition: opacity 0.15s;
}
.feedBack-tour-prompt button:hover {
opacity: 0.85;
}
.feedBack-tour-prompt button[data-action="start"] {
background: #0ea5e9;
color: #fff;
font-weight: 600;
}
.feedBack-tour-prompt button[data-action="dismiss"] {
background: #334155;
color: #94a3b8;
}
/* ── Shepherd bubble theme — override the vendored light default ──────────── */
/* The vendored static/vendor/shepherd.css ships Shepherd's stock LIGHT theme
(white bubble, black text, blue buttons), which clashes with the dark v3 UI.
These overrides load after it (index.html order) and recolor the spotlight
bubbles to the fb-* tokens. The vendored file is left untouched so it stays
upgradable. */
.shepherd-element {
background: #1e293b;
border: 1px solid #334155;
border-radius: 10px;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
max-width: 360px;
}
.shepherd-content {
background: #1e293b;
border-radius: 10px;
}
.shepherd-text {
color: #cbd5e1;
font-size: 0.9rem;
line-height: 1.45;
padding: 0.85em 0.9em;
}
.shepherd-title {
color: #f8fafc;
font-size: 0.95rem;
font-weight: 700;
}
/* Title row: drop the light-grey header fill the stock theme paints behind a
titled step, so the header blends into the card. */
.shepherd-has-title .shepherd-content .shepherd-header {
background: transparent;
padding: 0.85em 0.9em 0;
}
/* Arrow must match the bubble surface (stock paints it white, and grey behind
a bottom-placed titled step). */
.shepherd-arrow:before {
background: #1e293b;
}
.shepherd-element.shepherd-has-title[data-popper-placement^="bottom"] > .shepherd-arrow:before {
background-color: #1e293b;
}
.shepherd-footer {
padding: 0 0.75rem 0.75rem;
}
/* Primary button (Next / Done) → fb-primary. */
.shepherd-button {
background: #0ea5e9;
color: #fff;
border-radius: 6px;
font-weight: 600;
padding: 0.4rem 1.1rem;
}
.shepherd-button:not(:disabled):hover {
background: #38bdf8;
color: #fff;
}
/* Secondary button (Back / Skip) → muted slate. */
.shepherd-button.shepherd-button-secondary {
background: #334155;
color: #f8fafc;
}
.shepherd-button.shepherd-button-secondary:not(:disabled):hover {
background: #475569;
color: #f8fafc;
}
.shepherd-cancel-icon {
color: #94a3b8;
}
.shepherd-cancel-icon:hover,
.shepherd-has-title .shepherd-content .shepherd-cancel-icon:hover {
color: #f8fafc;
}
.shepherd-has-title .shepherd-content .shepherd-cancel-icon {
color: #94a3b8;
}
/* Dim the page a touch more, matching the onboarding overlay (bg-black/60). */
.shepherd-modal-overlay-container.shepherd-modal-is-visible {
opacity: 0.6;
}