fix(ui): move episode info button into the card body, compact overlay actions

Three overlay buttons crowded the thumbnail on hover and the new info
button had no styling at all. Info belongs with the content text: it
now sits as a quiet ghost button at the end of the title row (revealed
on card hover, MDC touch target clamped so it cannot swallow the
play-on-click card area). Download + watched-toggle stay on the
artwork, shrunk to 28px with a subtle edge border. List view already
used the shared action style and is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5 committed 2026-07-04 20:16:11 +02:00
1 parent 98e6bec35e
commit 182d934423
2 files changed
+93 -33

No files matched your search

@@ -188,25 +188,6 @@
</button>
}
}
@if (episodeInfo?.plot) {
<button
mat-icon-button
class="info-btn"
data-testid="episode-info-button"
(click)="
openEpisodeInfo(
$event,
episode
)
"
[matTooltip]="
'PORTALS.EPISODE_INFO'
| translate
"
>
<mat-icon>info_outline</mat-icon>
</button>
}
<button
mat-icon-button
class="toggle-watched-btn"
@@ -248,10 +229,31 @@
</div>
</div>
<div class="episode-card__info">
<h4 class="episode-card__title">
{{ episode.episode_num }}.
{{ episode.title }}
</h4>
<div class="episode-card__title-row">
<h4 class="episode-card__title">
{{ episode.episode_num }}.
{{ episode.title }}
</h4>
@if (episodeInfo?.plot) {
<button
mat-icon-button
class="episode-card__info-btn"
data-testid="episode-info-button"
(click)="
openEpisodeInfo(
$event,
episode
)
"
[matTooltip]="
'PORTALS.EPISODE_INFO'
| translate
"
>
<mat-icon>info_outline</mat-icon>
</button>
}
</div>
@if (episodeInfo?.plot) {
<p class="episode-card__plot">
{{ episodeInfo?.plot }}
@@ -305,21 +305,26 @@ app-season-tabs {
.download-btn,
.toggle-watched-btn {
color: rgba(255, 255, 255, 0.7);
background: rgba(0, 0, 0, 0.5);
width: 32px;
height: 32px;
padding: 4px;
color: rgba(255, 255, 255, 0.75);
background: rgba(0, 0, 0, 0.6);
border: 1px solid rgba(255, 255, 255, 0.14);
width: 28px;
height: 28px;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
&:hover {
color: white;
background: rgba(0, 0, 0, 0.8);
background: rgba(0, 0, 0, 0.85);
}
mat-icon {
font-size: 20px;
width: 20px;
height: 20px;
font-size: 17px;
width: 17px;
height: 17px;
line-height: 17px;
}
}
@@ -382,10 +387,19 @@ app-season-tabs {
padding: 12px;
}
&__title-row {
display: flex;
align-items: flex-start;
gap: 4px;
margin-bottom: 4px;
}
&__title {
flex: 1;
min-width: 0;
font-size: 0.875rem;
font-weight: 600;
margin: 0 0 4px 0;
margin: 0;
color: var(--text-primary);
line-height: 1.4;
white-space: nowrap;
@@ -393,6 +407,50 @@ app-season-tabs {
text-overflow: ellipsis;
}
// "About the episode" lives with the text, not on the artwork: a quiet
// ghost button at the end of the title row, revealed on card hover.
&__info-btn {
flex: none;
width: 22px;
height: 22px;
padding: 0;
margin: -1px -2px 0 0;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
opacity: 0;
transition:
opacity 0.2s ease,
color 0.2s ease;
mat-icon {
font-size: 17px;
width: 17px;
height: 17px;
line-height: 17px;
}
&:hover {
color: var(--text-primary);
}
&:focus-visible {
opacity: 1;
}
// The default 48px MDC touch target would swallow clicks on the
// title around this tiny button (card click = play).
::ng-deep .mat-mdc-button-touch-target {
width: 100%;
height: 100%;
}
}
&:hover .episode-card__info-btn {
opacity: 1;
}
&__plot {
font-size: 0.75rem;
color: var(--text-secondary);