recognition: page, palette modal, & dashboard palette unlock — TDD
- billboard/recognition/ view + template; recognition/<slug>/set-palette endpoint (no trailing slash) - recognition.html: <template>-based modal (clone on open, remove on close — Selenium find_elements compatible) - recognition-page.js: image-box → modal → swatch preview → body-click restore → OK → confirm → POST set-palette - _palettes_for_user() replaces static PALETTES; Recognition.palette unlocks swatch + populates data-shoptalk - _unlocked_palettes_for_user() wires dynamic unlock check into set_palette view - _applet-palette.html: data-shoptalk from context instead of hard-coded "Placeholder" - _recognition.scss: banner, recog-list/item, image-box, modal, palette-confirm; :not([hidden]) pattern avoids display override - FT T2 split into T2a (banner → FYI → recog page), T2b (palette modal flow), T2c (dashboard palette applet) - 684 ITs green; 7 FTs green Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
180
src/static_src/scss/_recognition.scss
Normal file
180
src/static_src/scss/_recognition.scss
Normal file
@@ -0,0 +1,180 @@
|
||||
// ── Recognition banner (slides in below page h2 after unlock) ─────────────
|
||||
|
||||
.recog-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
background: rgba(var(--priUser), 0.12);
|
||||
border-left: 3px solid rgba(var(--priUser), 0.6);
|
||||
margin-bottom: 0.75rem;
|
||||
|
||||
.recog-banner__body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.recog-banner__title {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.recog-banner__description,
|
||||
.recog-banner__timestamp {
|
||||
margin: 0.1rem 0 0;
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.recog-banner__image {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
flex-shrink: 0;
|
||||
background: rgba(var(--priUser), 0.15);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.recog-banner__nvm,
|
||||
.recog-banner__fyi {
|
||||
flex-shrink: 0;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.25rem 0.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Recognition page ───────────────────────────────────────────────────────
|
||||
|
||||
.recognition-page {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.recog-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.recog-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
padding: 0.75rem;
|
||||
background: rgba(var(--priUser), 0.06);
|
||||
border: 1px solid rgba(var(--priUser), 0.2);
|
||||
border-radius: 4px;
|
||||
width: 14rem;
|
||||
|
||||
.recog-item__title {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.recog-item__description {
|
||||
margin: 0;
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
// Image box — must have a defined size so Selenium can interact with it.
|
||||
.recog-item__image-box {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(var(--priUser), 0.12);
|
||||
border: 1px dashed rgba(var(--priUser), 0.4);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
opacity: 0.6;
|
||||
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
|
||||
// Unlocked palette swatch inside a recognition item
|
||||
.recog-item__palette {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 2px;
|
||||
border: 2px solid rgba(var(--priUser), 0.4);
|
||||
}
|
||||
|
||||
// ── Palette modal ──────────────────────────────────────────────────────────
|
||||
|
||||
.recog-palette-modal {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 200;
|
||||
background: var(--bg, #1a1a1a);
|
||||
border: 1px solid rgba(var(--priUser), 0.4);
|
||||
border-radius: 4px;
|
||||
padding: 0.75rem;
|
||||
gap: 0.5rem;
|
||||
min-width: 12rem;
|
||||
|
||||
&:not([hidden]) { display: flex; flex-direction: column; }
|
||||
|
||||
// Each palette swatch option inside the modal
|
||||
> [class*="palette-"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
.recog-swatch-body {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(var(--priUser), 0.3);
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover { border-color: rgba(var(--priUser), 0.8); }
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 0.75rem;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Palette swatch color fills ─────────────────────────────────────────────
|
||||
// These match the actual palette CSS variables — used both in modal swatches
|
||||
// and as the confirmed .recog-item__palette swatch.
|
||||
|
||||
.palette-bardo .recog-swatch-body,
|
||||
.recog-item__palette.palette-bardo {
|
||||
background: #2a1a2e;
|
||||
}
|
||||
|
||||
.palette-sheol .recog-swatch-body,
|
||||
.recog-item__palette.palette-sheol {
|
||||
background: #1a1a2e;
|
||||
}
|
||||
|
||||
// ── Confirm submenu ────────────────────────────────────────────────────────
|
||||
|
||||
.recog-palette-confirm {
|
||||
border-top: 1px solid rgba(var(--priUser), 0.2);
|
||||
padding-top: 0.5rem;
|
||||
gap: 0.4rem;
|
||||
|
||||
&:not([hidden]) { display: flex; flex-direction: column; }
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 0.8rem;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
@import 'natus';
|
||||
@import 'tray';
|
||||
@import 'billboard';
|
||||
@import 'recognition';
|
||||
@import 'tooltips';
|
||||
@import 'game-kit';
|
||||
@import 'wallet-tokens';
|
||||
|
||||
Reference in New Issue
Block a user