diff --git a/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx b/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx index ccd47ceb81..60dcc66ecd 100644 --- a/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx +++ b/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx @@ -20,6 +20,11 @@ import DashApiError from './dash-api-error' import { ProjectCheckbox } from './table/project-checkbox' import ProjectTools from './table/project-tools/project-tools' import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox' +import { CopyProjectButtonTooltip } from './table/cells/action-buttons/copy-project-button' +import { DownloadProjectButtonTooltip } from './table/cells/action-buttons/download-project-button' +import { CompileAndDownloadProjectPDFButtonTooltip } from './table/cells/action-buttons/compile-and-download-project-pdf-button' +import { ArchiveProjectButtonTooltip } from './table/cells/action-buttons/archive-project-button' +import { TrashProjectButtonTooltip } from './table/cells/action-buttons/trash-project-button' type FormatVariant = 'latex' | 'typst' | 'quarto' | 'quarto-slides' @@ -62,31 +67,40 @@ const ProjectCard = memo(function ProjectCard({
- -
- {initial} -
-
- {project.name} -
- - {getFormatLabel(variant)} - - {ownerName && ( - - {ownerName} - - )} +
+ +
+ {initial}
- {date} +
+ {project.name} +
+ + {getFormatLabel(variant)} + + {ownerName && ( + + {ownerName} + + )} +
+ {date} +
+
+
+ + + + +
- +
) }) diff --git a/services/web/frontend/stylesheets/pages/project-list-lumiere.scss b/services/web/frontend/stylesheets/pages/project-list-lumiere.scss index a9b1187a2b..d99750ac5c 100644 --- a/services/web/frontend/stylesheets/pages/project-list-lumiere.scss +++ b/services/web/frontend/stylesheets/pages/project-list-lumiere.scss @@ -450,10 +450,10 @@ $lum-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' wi // ── Individual card ─────────────────────────────────────────────────────── + // Card container is now a
; the clickable area is .lumiere-card-link .lumiere-card { display: flex; flex-direction: column; - text-decoration: none; border-radius: 10px; background: rgba(255, 255, 255, 0.82); backdrop-filter: blur(8px); @@ -462,17 +462,58 @@ $lum-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' wi box-shadow: 0 2px 8px rgba(0, 0, 0, 0.07); transition: transform 0.18s ease, box-shadow 0.18s ease; overflow: hidden; + + &:hover, + &:focus-within { + transform: translateY(-3px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); + } + } + + // The anchor covers thumb + body, with no underline or color bleed + .lumiere-card-link { + display: flex; + flex-direction: column; + flex: 1; + text-decoration: none; color: inherit; &:hover, &:focus-visible { - transform: translateY(-3px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); text-decoration: none; color: inherit; } } + // Action strip — icon buttons that fade in when the card is hovered + .lumiere-card-actions { + display: flex; + align-items: center; + justify-content: center; + gap: 2px; + padding: 3px 6px 5px; + border-top: 1px solid rgba($lum-teal, 0.10); + opacity: 0; + transition: opacity 0.15s ease; + + // Recolour OLIconButton's action-btn class for the Lumière palette + .action-btn { + color: $lum-text-muted !important; + border-radius: 6px !important; + + &:hover, + &:focus { + color: $lum-teal !important; + background: rgba($lum-teal, 0.09) !important; + } + } + } + + .lumiere-card:hover .lumiere-card-actions, + .lumiere-card:focus-within .lumiere-card-actions { + opacity: 1; + } + // ── Card thumbnail ──────────────────────────────────────────────────────── .lumiere-card-thumb {