The + picker now offers the module two ways. "Now / Next" is the card as it was. "Now" is the live item on its own: the gradient comes off the card and fills the tile edge to edge, the border, radius and box go, and the playlist name and live dot float over the colour instead of sitting above it. A wall of them reads as panels of colour rather than cards on a background. Every part of the tile is now a switch in a "Show" group in the gear — playlist, live status, the NOW and NEXT labels, slide count, progress bar, the next list and its item tags. One or two words each, no descriptions. The Now entry carries its own six, since the three Next ones have nothing to act on there. Two things the tile still insists on. Trouble overrides the switches: the top row and the live chip come back the moment the feed drops, whatever is switched off, because a tile that has stopped updating must never look like one with nothing live. And at the Now tile's shortest sizes the floating top row would sit on the title, so below the height it needs it goes — the header dot and the title itself still say what is wrong. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
346 lines
10 KiB
CSS
346 lines
10 KiB
CSS
/* ProPresenter Now / Next module — the wall display's visual language,
|
|
scaled to a tile. All sizes hang off --unit (set from the tile height by
|
|
client.js); all colors come from the shell's variables. */
|
|
|
|
[data-module="propresenter-now-next"] .nn-screen {
|
|
--unit: 12px;
|
|
--nn-pad: calc(var(--unit) * 1.1);
|
|
--nn-gap: calc(var(--unit) * 0.7);
|
|
position: absolute;
|
|
inset: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--nn-gap);
|
|
padding: var(--nn-pad);
|
|
user-select: none;
|
|
-webkit-user-select: none;
|
|
}
|
|
|
|
/* With no NEXT list there is nothing below the card — centre it. */
|
|
[data-module="propresenter-now-next"] .nn-screen.no-upcoming {
|
|
justify-content: center;
|
|
}
|
|
|
|
/* NEXT switched off, or a Now tile: the list goes and the card takes the room. */
|
|
[data-module="propresenter-now-next"] .nn-screen.nn-no-next .nn-next-wrap { display: none; }
|
|
[data-module="propresenter-now-next"] .nn-screen.nn-no-next { justify-content: center; }
|
|
|
|
/* ── the "Now" tile ──
|
|
Only what is live, edge to edge: the gradient moves off the card and onto
|
|
the whole tile, the card loses its border, radius and box, and the title
|
|
sits in the middle of everything. Nothing is inset, so a wall of these
|
|
reads as panels of colour rather than cards on a background. */
|
|
[data-module="propresenter-now-next"] .nn-screen.nn-only-now {
|
|
gap: 0;
|
|
background: linear-gradient(
|
|
160deg,
|
|
color-mix(in srgb, var(--accent) 14%, transparent),
|
|
color-mix(in srgb, var(--bg) 70%, transparent)
|
|
);
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-only-now .nn-now {
|
|
flex: 1;
|
|
height: auto;
|
|
min-height: 0;
|
|
justify-content: center;
|
|
border: none;
|
|
border-radius: 0;
|
|
background: none;
|
|
padding: 0;
|
|
}
|
|
/* The live dot and playlist ride over the gradient rather than above it. */
|
|
[data-module="propresenter-now-next"] .nn-only-now .nn-top {
|
|
position: absolute;
|
|
inset: var(--nn-pad) var(--nn-pad) auto;
|
|
pointer-events: none;
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-only-now .nn-title-box { margin-top: 0; }
|
|
/* The overlay floats, so it takes no room — this keeps the title clear of it
|
|
and still centred, by holding back as much at the bottom as at the top. */
|
|
[data-module="propresenter-now-next"] .nn-only-now:not(.nn-tight) .nn-now {
|
|
padding: calc(var(--unit) * 1.4) 0;
|
|
}
|
|
/* Too short for the overlay: the title gets the whole panel to itself. */
|
|
[data-module="propresenter-now-next"] .nn-only-now.nn-tight .nn-top,
|
|
[data-module="propresenter-now-next"] .nn-only-now.nn-tight.is-offline .nn-top {
|
|
display: none !important;
|
|
}
|
|
|
|
/* ── top row ── */
|
|
|
|
[data-module="propresenter-now-next"] .nn-top {
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
gap: var(--nn-gap);
|
|
flex-shrink: 0;
|
|
min-height: 0;
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-top.hidden-row { display: none; }
|
|
|
|
/* Losing the feed is the one thing the tile MUST admit to — overrides the
|
|
"hide the top row" preference. */
|
|
[data-module="propresenter-now-next"] .is-offline .nn-top,
|
|
[data-module="propresenter-now-next"] .nn-screen.is-offline .nn-top {
|
|
display: flex !important;
|
|
}
|
|
[data-module="propresenter-now-next"] .is-offline .nn-live-text {
|
|
opacity: 1 !important;
|
|
color: var(--danger);
|
|
}
|
|
[data-module="propresenter-now-next"] .is-offline .nn-now {
|
|
border-color: color-mix(in srgb, var(--danger) 50%, transparent);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-playlist {
|
|
flex: 1;
|
|
min-width: 0;
|
|
font-size: calc(var(--unit) * 1.0);
|
|
font-weight: 700;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-playlist[hidden] { display: none; }
|
|
|
|
[data-module="propresenter-now-next"] .nn-live {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: calc(var(--unit) * 0.45);
|
|
flex-shrink: 0;
|
|
font-size: calc(var(--unit) * 0.9);
|
|
font-weight: 600;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-live[hidden] { display: none; }
|
|
|
|
[data-module="propresenter-now-next"] .nn-live-dot {
|
|
width: calc(var(--unit) * 0.6);
|
|
height: calc(var(--unit) * 0.6);
|
|
border-radius: 999px;
|
|
background: var(--border);
|
|
transition: background 0.3s ease, box-shadow 0.3s ease;
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-live.is-live .nn-live-dot {
|
|
background: var(--accent);
|
|
box-shadow: 0 0 0 calc(var(--unit) * 0.2) color-mix(in srgb, var(--accent) 18%, transparent);
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-live.is-down .nn-live-dot {
|
|
background: var(--danger);
|
|
box-shadow: 0 0 0 calc(var(--unit) * 0.2) color-mix(in srgb, var(--danger) 16%, transparent);
|
|
}
|
|
|
|
/* Idle tiles don't need a status chip staring at them — it fades once live. */
|
|
[data-module="propresenter-now-next"] .nn-live.is-live .nn-live-text {
|
|
opacity: 0;
|
|
transition: opacity 0.6s ease 1.4s;
|
|
}
|
|
|
|
/* ── NOW card ──
|
|
FIXED height so the title box is deterministic and the NOW/NEXT layout
|
|
cannot oscillate (see the wall display's notes). */
|
|
|
|
[data-module="propresenter-now-next"] .nn-now {
|
|
flex: 0 0 auto;
|
|
height: 42%;
|
|
min-height: calc(var(--unit) * 7);
|
|
display: flex;
|
|
flex-direction: column;
|
|
border: 1px solid var(--border);
|
|
border-radius: calc(var(--unit) * 0.9);
|
|
background: linear-gradient(
|
|
160deg,
|
|
color-mix(in srgb, var(--accent) 9%, transparent),
|
|
color-mix(in srgb, var(--bg) 60%, transparent)
|
|
);
|
|
padding: calc(var(--nn-pad) * 0.8) var(--nn-pad);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-label {
|
|
flex-shrink: 0;
|
|
font-size: calc(var(--unit) * 0.9);
|
|
font-weight: 800;
|
|
letter-spacing: 0.16em;
|
|
text-transform: uppercase;
|
|
color: var(--accent);
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-label[hidden] { display: none; }
|
|
|
|
[data-module="propresenter-now-next"] .nn-title-box {
|
|
flex: 1;
|
|
min-height: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
overflow: hidden;
|
|
margin-top: calc(var(--unit) * 0.3);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-title {
|
|
width: 100%;
|
|
/* Font size is set by fitNowTitle() so the title fills the box; keep
|
|
line-height ≥ the font's natural ~1.2 or large ascenders/descenders clip. */
|
|
font-size: calc(var(--unit) * 2.4);
|
|
font-weight: 700;
|
|
line-height: 1.2;
|
|
color: var(--text);
|
|
/* Wrapping is controlled by fitNowTitle(), which forbids mid-word breaks. */
|
|
overflow-wrap: normal;
|
|
word-break: normal;
|
|
}
|
|
|
|
/* Status text, not a title: readable size, never the fill-the-box treatment. */
|
|
[data-module="propresenter-now-next"] .nn-title.is-waiting {
|
|
color: var(--muted);
|
|
font-weight: 600;
|
|
font-size: calc(var(--unit) * 1.5);
|
|
white-space: normal;
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-hint {
|
|
flex-shrink: 0;
|
|
margin-top: calc(var(--unit) * 0.4);
|
|
font-size: calc(var(--unit) * 0.95);
|
|
line-height: 1.4;
|
|
color: var(--muted);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-stale {
|
|
flex-shrink: 0;
|
|
margin-top: calc(var(--unit) * 0.4);
|
|
font-size: calc(var(--unit) * 0.95);
|
|
font-weight: 600;
|
|
color: var(--danger);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-meta {
|
|
flex-shrink: 0;
|
|
margin-top: calc(var(--unit) * 0.45);
|
|
font-size: calc(var(--unit) * 1.15);
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
opacity: 0.85;
|
|
font-variant-numeric: tabular-nums;
|
|
/* Never wrap: a wrap changes the title box height, which refits the title. */
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-meta:empty { display: none; }
|
|
|
|
[data-module="propresenter-now-next"] .nn-progress {
|
|
flex-shrink: 0;
|
|
margin-top: calc(var(--unit) * 0.55);
|
|
height: calc(var(--unit) * 0.4);
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--text) 10%, transparent);
|
|
overflow: hidden;
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-progress[hidden] { display: none; }
|
|
|
|
[data-module="propresenter-now-next"] .nn-progress-fill {
|
|
height: 100%;
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--accent) 65%, var(--panel));
|
|
transition: width 0.25s ease;
|
|
}
|
|
|
|
/* ── NEXT list ── */
|
|
|
|
[data-module="propresenter-now-next"] .nn-next-wrap {
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: calc(var(--unit) * 0.5);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-next-label {
|
|
flex-shrink: 0;
|
|
font-size: calc(var(--unit) * 0.9);
|
|
font-weight: 800;
|
|
letter-spacing: 0.16em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-next-label[hidden] { display: none; }
|
|
|
|
[data-module="propresenter-now-next"] .nn-next-list {
|
|
flex: 1;
|
|
min-height: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: calc(var(--unit) * 0.45);
|
|
overflow: hidden;
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-next-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--nn-gap);
|
|
padding: calc(var(--unit) * 0.6) calc(var(--unit) * 0.85);
|
|
border: 1px solid var(--border);
|
|
border-radius: calc(var(--unit) * 0.6);
|
|
background: color-mix(in srgb, var(--bg) 70%, transparent);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-next-name {
|
|
flex: 1;
|
|
min-width: 0;
|
|
font-size: calc(var(--unit) * 1.25);
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-count-chip {
|
|
flex-shrink: 0;
|
|
min-width: calc(var(--unit) * 2);
|
|
padding: calc(var(--unit) * 0.15) calc(var(--unit) * 0.5);
|
|
text-align: center;
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--accent) 22%, transparent);
|
|
color: var(--text);
|
|
font-size: calc(var(--unit) * 0.95);
|
|
font-weight: 700;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-type-tag {
|
|
flex-shrink: 0;
|
|
font-size: calc(var(--unit) * 0.8);
|
|
font-weight: 700;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-next-item.is-header {
|
|
background: none;
|
|
border: none;
|
|
border-bottom: 1px solid var(--border);
|
|
border-radius: 0;
|
|
padding: calc(var(--unit) * 0.55) calc(var(--unit) * 0.1) calc(var(--unit) * 0.2);
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-next-item.is-header .nn-next-name {
|
|
font-size: calc(var(--unit) * 0.9);
|
|
font-weight: 800;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
|
|
[data-module="propresenter-now-next"] .nn-next-more {
|
|
flex-shrink: 0;
|
|
font-size: calc(var(--unit) * 0.9);
|
|
color: var(--muted);
|
|
font-weight: 600;
|
|
}
|
|
[data-module="propresenter-now-next"] .nn-next-more[hidden] { display: none; }
|