Files
picpeak/frontend/src/components/gallery/layouts/GalleryStoryLayout.css
T
Paul Nothaft 4c2eeab2f4 refactor(gallery): drop the unreachable Story feedback sheet
StoryFeedbackSheet could never open: handleOpenFeedback was the only caller
of setSelectedPhotoForFeedback and was itself never called. This was the last
remaining build:check error (TS6133).

Removed rather than wired up, on three findings:

- The sheet offered nothing PhotoLightbox does not, and was strictly worse.
  It held comments and ratings in layout-local useState and never called
  feedbackService.getPhotoFeedback, so existing server-side feedback was
  invisible; it rendered stars and a comment form unconditionally, ignoring
  allow_ratings/allow_comments; and it had no reactions, colour labels,
  identity modal or rate-limit handling. This layout already renders
  PhotoLightbox with feedbackEnabled, which does all of that against the
  server.
- It was not a mobile affordance. The CSS styled it as a fixed right-edge
  desktop drawer (right: 0; max-width: 28rem) with no media query.
- Every sibling layout routes feedback through the lightbox. Grid, Masonry,
  Timeline, Mosaic and Carousel expose a per-card onQuickComment that calls
  onOpenPhotoWithFeedback to open the parent's lightbox on the feedback tab;
  none has a standalone feedback surface. The closest sibling,
  GalleryPremiumLayout, renders its own lightbox and deliberately voids
  _onOpenPhotoWithFeedback with no per-card control -- exactly the shape
  Story now has.

Drops the component, its state and handlers, the feedbackOptions destructure
(only the sheet read it) and 251 lines of orphaned CSS. savedIdentity also
fed guest_name/guest_email into the like call; those were always undefined at
runtime since the unreachable sheet was their only writer, so no behaviour
changes.

Also widens the Story nav search input, which clipped its placeholder. At the
input's computed 14px the placeholder measures en 121px, de 145, ru 152,
fr 174 against a 128px box -- so German was 17px over and French 46px over.
8rem -> 13rem collapsed, 12rem -> 17rem focused, keeping expand-on-focus;
verified at 1280px and at the 768px breakpoint where the search appears.

Refs testplan REPORT.md A1 and the gallery-story placeholder warning.
2026-09-02 09:43:10 +02:00

503 lines
9.1 KiB
CSS

/* Gallery Story Layout - Dark cinematic aesthetic with gold accents */
.gallery-story-layout {
--story-background: #0d0d0d;
--story-foreground: #f2f2f2;
--story-primary: #c9a961;
--story-primary-foreground: #0d0d0d;
--story-muted: #1a1a1a;
--story-muted-foreground: #a3a3a3;
--story-border: #262626;
min-height: 100vh;
background-color: var(--story-background);
color: var(--story-foreground);
font-family: 'Inter', sans-serif;
-webkit-font-smoothing: antialiased;
}
.gallery-story-layout ::selection {
background-color: var(--story-primary);
color: var(--story-primary-foreground);
}
.gallery-story-layout h1,
.gallery-story-layout h2,
.gallery-story-layout h3,
.gallery-story-layout h4,
.gallery-story-layout h5,
.gallery-story-layout h6 {
font-family: 'Playfair Display', Georgia, serif;
}
/* Custom Scrollbar */
.gallery-story-layout ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.gallery-story-layout ::-webkit-scrollbar-track {
background: transparent;
}
.gallery-story-layout ::-webkit-scrollbar-thumb {
background: #404040;
border-radius: 4px;
}
.gallery-story-layout ::-webkit-scrollbar-thumb:hover {
background: #525252;
}
/* Navigation */
.story-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 50;
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.5rem;
transition: all 0.3s ease;
}
.story-nav.scrolled {
background-color: rgba(13, 13, 13, 0.8);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.story-nav-logo {
font-family: 'Playfair Display', Georgia, serif;
font-size: 1.25rem;
font-weight: 700;
letter-spacing: 0.25em;
}
.story-nav-actions {
display: flex;
align-items: center;
gap: 1.5rem;
}
.story-nav-search {
display: none;
align-items: center;
gap: 0.5rem;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 9999px;
padding: 0.375rem 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
}
@media (min-width: 768px) {
.story-nav-search {
display: flex;
}
}
/* 13rem collapsed so the placeholder still fits in the longest locale —
"Rechercher des souvenirs..." (fr) measures ~11rem at 0.875rem, and the
old 8rem clipped even the German string. */
.story-nav-search input {
background: transparent;
border: none;
outline: none;
font-size: 0.875rem;
width: 13rem;
color: var(--story-foreground);
transition: width 0.2s ease;
}
.story-nav-search input:focus {
width: 17rem;
}
.story-nav-search input::placeholder {
color: var(--story-muted-foreground);
}
.story-nav-btn {
position: relative;
padding: 0.5rem;
background: none;
border: none;
color: var(--story-foreground);
cursor: pointer;
transition: color 0.2s ease;
}
.story-nav-btn:hover {
color: var(--story-primary);
}
.story-nav-favorites-count {
position: absolute;
top: -0.25rem;
right: -0.25rem;
display: flex;
height: 0.75rem;
width: 0.75rem;
align-items: center;
justify-content: center;
border-radius: 9999px;
background-color: #ef4444;
font-size: 0.5rem;
font-weight: 700;
color: white;
}
/* Hero Section */
.story-hero {
position: relative;
height: 100vh;
width: 100%;
overflow: hidden;
}
.story-hero-bg {
position: absolute;
inset: 0;
}
.story-hero-bg img {
width: 100%;
height: 100%;
object-fit: cover;
}
.story-hero-gradient {
position: absolute;
inset: 0;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), transparent, rgba(0, 0, 0, 0.8));
}
.story-hero-content {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
color: white;
padding: 1rem;
}
.story-hero-date {
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.2em;
opacity: 0.8;
}
.story-hero-title {
font-family: 'Playfair Display', Georgia, serif;
font-size: 3.75rem;
font-style: italic;
line-height: 1.1;
mix-blend-mode: overlay;
}
@media (min-width: 768px) {
.story-hero-title {
font-size: 6rem;
}
}
@media (min-width: 1024px) {
.story-hero-title {
font-size: 8rem;
}
}
.story-hero-stats {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
font-size: 0.875rem;
font-weight: 500;
opacity: 0.7;
}
.story-hero-stats-divider {
height: 1px;
width: 3rem;
background-color: rgba(255, 255, 255, 0.5);
}
/* Scroll Indicator */
.story-scroll-indicator {
position: absolute;
bottom: 3rem;
left: 50%;
transform: translateX(-50%);
color: rgba(255, 255, 255, 0.5);
}
/* Scene Section */
.story-scene {
padding: 6rem 1rem;
max-width: 1800px;
margin: 0 auto;
}
@media (min-width: 768px) {
.story-scene {
padding: 6rem 2rem;
}
}
.story-scene.full-width {
padding-left: 0;
padding-right: 0;
max-width: 100%;
}
.story-scene-header {
margin-bottom: 3rem;
space-y: 0.5rem;
}
.story-scene-title {
font-size: 2.25rem;
color: var(--story-primary);
}
@media (min-width: 768px) {
.story-scene-title {
font-size: 3rem;
}
}
.story-scene-subtitle {
color: var(--story-muted-foreground);
font-weight: 300;
letter-spacing: 0.05em;
}
/* Gallery Grid */
.story-gallery-grid {
display: grid;
grid-template-columns: repeat(1, 1fr);
gap: 0.25rem;
grid-auto-rows: 300px;
}
@media (min-width: 768px) {
.story-gallery-grid {
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
grid-auto-rows: 400px;
}
}
.story-gallery-grid-featured {
grid-column: span 1;
grid-row: span 1;
}
@media (min-width: 768px) {
.story-gallery-grid-featured {
grid-column: span 2;
grid-row: span 2;
}
}
/* Photo Card */
.story-photo-card {
position: relative;
overflow: hidden;
border-radius: 0.125rem;
background-color: var(--story-muted);
}
.story-photo-card a {
display: block;
width: 100%;
height: 100%;
}
.story-photo-card img {
width: 100%;
height: 100%;
object-fit: cover;
transition: all 0.7s ease-out;
will-change: transform;
}
.story-photo-card:hover img {
transform: scale(1.05);
}
.story-photo-card-overlay {
position: absolute;
inset: 0;
background-color: transparent;
transition: background-color 0.3s ease;
pointer-events: none;
}
.story-photo-card:hover .story-photo-card-overlay {
background-color: rgba(0, 0, 0, 0.2);
}
.story-photo-card-actions {
position: absolute;
top: 1rem;
right: 1rem;
display: flex;
gap: 0.5rem;
opacity: 0;
transform: translateY(0.5rem);
transition: all 0.3s ease;
}
.story-photo-card:hover .story-photo-card-actions {
opacity: 1;
transform: translateY(0);
}
.story-photo-card-btn {
padding: 0.5rem;
border-radius: 9999px;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
transition: all 0.3s ease;
background-color: rgba(0, 0, 0, 0.3);
color: white;
border: none;
cursor: pointer;
}
.story-photo-card-btn:hover {
transform: scale(1.1);
background-color: white;
color: #0d0d0d;
}
.story-photo-card-btn.favorite {
background-color: rgba(239, 68, 68, 0.2);
color: #ef4444;
}
.story-photo-card-caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 1rem;
background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
opacity: 0;
transition: opacity 0.3s ease;
}
.story-photo-card:hover .story-photo-card-caption {
opacity: 1;
}
.story-photo-card-caption p {
color: white;
font-size: 0.875rem;
font-weight: 500;
font-family: 'Playfair Display', Georgia, serif;
letter-spacing: 0.05em;
}
/* Carousel */
.story-carousel {
width: 100%;
}
.story-carousel .swiper {
width: 100%;
padding: 0 1rem 3rem 1rem;
}
@media (min-width: 768px) {
.story-carousel .swiper {
padding: 0 2rem 3rem 2rem;
}
}
.story-carousel .swiper-slide {
width: auto;
}
.story-carousel-item {
width: 300px;
height: 400px;
}
@media (min-width: 768px) {
.story-carousel-item {
width: 400px;
height: 500px;
}
}
/* Scroll to Top */
.story-scroll-to-top {
position: fixed;
bottom: 2rem;
right: 2rem;
z-index: 50;
padding: 0.75rem;
border-radius: 9999px;
background-color: rgba(201, 169, 97, 0.9);
color: #0d0d0d;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.1);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
cursor: pointer;
transition: all 0.3s ease;
}
.story-scroll-to-top:hover {
background-color: var(--story-primary);
transform: scale(1.1);
}
.story-scroll-to-top:active {
transform: scale(0.95);
}
/* Footer */
.story-footer {
padding: 6rem 1rem;
text-align: center;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.story-footer-title {
font-size: 2.25rem;
margin-bottom: 1.5rem;
}
.story-footer-text {
color: var(--story-muted-foreground);
max-width: 28rem;
margin: 0 auto 3rem auto;
}
.story-footer-btn {
padding: 0.75rem 2rem;
background-color: var(--story-primary);
color: var(--story-primary-foreground);
font-weight: 500;
letter-spacing: 0.05em;
border: none;
border-radius: 0.125rem;
cursor: pointer;
transition: background-color 0.2s ease;
}
.story-footer-btn:hover {
background-color: white;
}