web: star ratings on the reel, and PICTURES becomes an album browser
The landing strip now carries a score: each look and each contributed frame shows an average, five stars the visitor can press, and how many votes it has. Votes are keyed photo:<id> or look:<TAG> and one visitor has one vote per key, so pressing a second star moves a score instead of stacking one. The API is public and rate-limited; look: scores survive a cleared pool, photo: scores are pruned with their photo. PICTURES was four destination rows; it is now an album per uploader with a search box, a recipe/rating/newest sort, a minimum-star filter, a big preview and a filmstrip of thumbnails. Deleting and slot picking still live in the big box.
This commit is contained in:
@@ -475,14 +475,78 @@ input[type="range"] { width: 100%; accent-color: var(--accent); }
|
||||
.adm-brand { display: flex; align-items: center; gap: 6px; font-weight: 650; letter-spacing: -0.01em; color: var(--text); text-decoration: none; }
|
||||
.adm-brand em { font-style: normal; font-weight: 400; color: var(--accent); }
|
||||
.adm-brand img { border-radius: 8px; }
|
||||
/* Curating pictures: the pool of uploads on the left, the three landing
|
||||
sections on the right. One picker button per destination under each photo. */
|
||||
.adm-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
|
||||
/* Curating pictures: the albums on the left, the chosen frame and its strip of
|
||||
thumbnails on the right. The album column is the narrow one — it is a list of
|
||||
names — and scrolls on its own so the strip beside it never moves. */
|
||||
.adm-cols { display: grid; grid-template-columns: minmax(200px, 280px) minmax(0, 1fr); gap: 16px; align-items: start; }
|
||||
@media (max-width: 1100px) { .adm-cols { grid-template-columns: minmax(0, 1fr); } }
|
||||
.adm-col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
|
||||
/* Wide enough for the three chips to sit on one line: the picker is the point
|
||||
of the card, so the grid gives it the width it needs. */
|
||||
.adm-cols .adm-grid { grid-template-columns: repeat(auto-fill, minmax(450px, 1fr)); }
|
||||
/* The filters over the album list: one name box, two pickers. */
|
||||
.adm-input {
|
||||
width: 100%;
|
||||
font: inherit;
|
||||
font-size: 12px;
|
||||
color: var(--text);
|
||||
background: var(--bg-sunken);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 6px 8px;
|
||||
}
|
||||
.adm-filters { display: flex; gap: 6px; }
|
||||
.adm-filters .adm-input { min-width: 0; }
|
||||
.adm-album-list { display: flex; flex-direction: column; gap: 4px; max-height: 62vh; overflow-y: auto; padding-right: 2px; }
|
||||
.adm-album {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
font: inherit;
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
color: var(--text-dim);
|
||||
background: var(--bg-sunken);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 7px 9px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.adm-album:hover { border-color: var(--accent-line); }
|
||||
.adm-album.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
|
||||
.adm-album-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.adm-album-count { font-family: var(--mono); font-size: 11px; }
|
||||
/* The frame that is up: the picture on the left, everything about it on the
|
||||
right — including the four landing sections it may appear in. */
|
||||
.adm-big {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
|
||||
gap: 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
background: var(--bg);
|
||||
padding: 10px;
|
||||
}
|
||||
.adm-big-img { width: 100%; aspect-ratio: 4 / 3; object-fit: contain; border-radius: var(--radius-sm); background: var(--bg-sunken); }
|
||||
.adm-big-side { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
|
||||
.adm-qr-inline { border-radius: var(--radius-sm); }
|
||||
/* The album's strip: thumbnails in one row, scrolled sideways when they
|
||||
overflow the pane rather than wrapping into a wall of pictures. */
|
||||
.adm-filmstrip { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
|
||||
.adm-thumb {
|
||||
flex: 0 0 132px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: var(--radius-sm);
|
||||
overflow: hidden;
|
||||
background: var(--bg-sunken);
|
||||
color: var(--text-dim);
|
||||
}
|
||||
.adm-thumb:hover { border-color: var(--accent-line); }
|
||||
.adm-thumb.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
|
||||
.adm-thumb img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
|
||||
.adm-thumb-cap { display: block; padding: 3px 6px; font-family: var(--mono); font-size: 10.5px; }
|
||||
/* The three destinations sit on one line under the photo, each an independent
|
||||
checkbox — tick all three and the photo shows in all three sections. */
|
||||
.adm-choices { display: flex; flex-wrap: wrap; gap: 5px; }
|
||||
@@ -518,9 +582,6 @@ input[type="range"] { width: 100%; accent-color: var(--accent); }
|
||||
}
|
||||
.adm-row-count { font-family: var(--mono); color: var(--text); }
|
||||
.adm-row-empty { margin: 0; }
|
||||
.adm-thumb { margin: 0; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-sunken); }
|
||||
.adm-thumb img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
|
||||
.adm-thumb figcaption { padding: 3px 6px; font-family: var(--mono); font-size: 10.5px; color: var(--text-dim); }
|
||||
/* The QR section's real artefact is the code, not the photo. Drawn on white:
|
||||
a scanner needs the quiet zone, and the dark theme has none. */
|
||||
.adm-qr { display: flex; align-items: center; justify-content: center; min-height: 88px; padding: 6px; background: #fff; }
|
||||
@@ -610,7 +671,6 @@ input[type="range"] { width: 100%; accent-color: var(--accent); }
|
||||
font-weight: 600;
|
||||
}
|
||||
.adm-face img { display: block; width: 100%; height: 100%; object-fit: cover; }
|
||||
.adm-filter { display: flex; align-items: center; gap: 8px; }
|
||||
/* Moderation state next to the account name, and the row's own actions: the
|
||||
three controls sit side by side and the pane scrolls when it runs out. */
|
||||
.adm-badge-warn { margin-left: 6px; color: var(--danger); font-size: 11px; }
|
||||
|
||||
Reference in New Issue
Block a user