Files
deepdrft/DeepDrftPublic/wwwroot/styles/deepdrft-styles.css
T
daniel-c-harvey 466084b5a3 feat: Phase 17.3 — Fixed embed queue panel with collapse/expand iframe resize (OQ1 Option A)
Read-only inline queue panel below the release embed's player bar; row-jump reuses PlayRelease. ForRelease mints a taller iframe plus a postMessage resize listener for the collapse toggle; ForTrack unchanged.
2026-06-19 16:21:45 -04:00

920 lines
32 KiB
CSS

/* DeepDrft Global Styles - Simplified & Maintainable
Note: the palette / token layer (--deepdrft-*, --theme-*, --gradient-*, and the
.deepdrft-theme-dark override block) lives in DeepDrftShared.Client and is
served at _content/DeepDrftShared.Client/styles/deepdrft-tokens.css. Link that
file BEFORE this one in App.razor — every rule below depends on those tokens. */
/* =============================================================================
1. PAGE BASELINE
============================================================================= */
/* Base page colours — use MudBlazor's theme-injected variables so they
switch automatically when IsDarkMode toggles. The --mud-palette-background
and --mud-palette-text-primary variables are injected by MudThemeProvider
and update in both light and dark modes. */
html, body {
background-color: var(--mud-palette-background);
color: var(--mud-palette-text-primary);
}
/* Ensure the theme wrapper fills the full viewport so no background gap shows. */
.deepdrft-theme-dark,
.deepdrft-theme-light {
min-height: 100vh;
}
/* =============================================================================
2. GRADIENTS
============================================================================= */
.deepdrft-gradient-primary,
.deepdrft-gradient-hero {
background: linear-gradient(135deg,
var(--gradient-base) 0%,
color-mix(in srgb, var(--gradient-base) 90%, var(--gradient-accent) 10%) 50%,
color-mix(in srgb, var(--gradient-base) 80%, var(--gradient-accent) 20%) 100%);
}
.deepdrft-gradient-soft-primary {
background: linear-gradient(45deg,
color-mix(in srgb, var(--gradient-accent) 4%, transparent) 0%,
color-mix(in srgb, var(--gradient-warm) 6%, transparent) 100%);
}
.deepdrft-gradient-soft-secondary {
background: linear-gradient(45deg,
color-mix(in srgb, var(--gradient-light) 6%, transparent) 0%,
color-mix(in srgb, var(--gradient-accent) 4%, transparent) 100%);
}
.deepdrft-gradient-soft-accent {
background: linear-gradient(135deg,
color-mix(in srgb, var(--gradient-accent) 3%, transparent) 0%,
color-mix(in srgb, var(--gradient-light) 5%, transparent) 100%);
}
.deepdrft-gradient-soft-tertiary {
background: linear-gradient(135deg,
color-mix(in srgb, var(--gradient-warm) 5%, transparent) 0%,
color-mix(in srgb, var(--gradient-accent) 3%, transparent) 100%);
}
.deepdrft-gradient-features {
background: linear-gradient(to right,
color-mix(in srgb, var(--gradient-accent) 2%, transparent) 0%,
color-mix(in srgb, var(--gradient-warm) 3%, transparent) 100%);
}
/* =============================================================================
3. TYPOGRAPHY
============================================================================= */
/* Hero text */
h1, .deepdrft-text-hero {
font-family: var(--deepdrft-font-display);
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
/* Suppress the browser focus ring that FocusOnNavigate triggers on h1 after navigation. */
h1:focus-visible { outline: none; }
/* Headers */
h2, h3, h4, h5, h6,
.deepdrft-text-subtitle {
font-family: var(--deepdrft-font-display);
}
.deepdrft-text-subtitle {
font-weight: 300;
text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
}
/* Body */
.deepdrft-text-description,
.deepdrft-text-readable {
font-family: var(--deepdrft-font-body);
}
.deepdrft-text-description {
font-weight: 400;
opacity: 0.9;
}
.deepdrft-text-bold { font-weight: bold; }
.deepdrft-text-readable { line-height: 1.6; }
/* MudBlazor font overrides */
.mud-typography-h1,
.mud-typography-h2, .mud-typography-h3, .mud-typography-h4,
.mud-typography-h5, .mud-typography-h6,
.mud-navlink-text, .mud-appbar-content {
font-family: var(--deepdrft-font-display) !important;
}
.mud-button-text,
.mud-typography-caption, .mud-typography-overline {
font-family: var(--deepdrft-font-mono) !important;
}
.mud-typography-body1, .mud-typography-body2,
.mud-input-text, .mud-select-text, .mud-form-label {
font-family: var(--deepdrft-font-body) !important;
}
/* =============================================================================
4. HERO SECTION
============================================================================= */
.deepdrft-hero-container {
min-height: 60vh;
display: flex;
flex-direction: column;
justify-content: center;
}
.deepdrft-hero-text-container {
max-width: 600px;
}
/* Light mode hero text */
.deepdrft-theme-light .deepdrft-hero-title { color: var(--deepdrft-primary); }
.deepdrft-theme-light .deepdrft-hero-subtitle { color: var(--deepdrft-secondary); }
.deepdrft-theme-light .deepdrft-hero-description { color: var(--theme-surface-soft); }
/* Dark mode hero text */
.deepdrft-theme-dark .deepdrft-hero-title { color: var(--theme-surface); }
.deepdrft-theme-dark .deepdrft-hero-subtitle { color: var(--deepdrft-tertiary); }
.deepdrft-theme-dark .deepdrft-hero-description { color: var(--theme-surface-soft); }
/* Hero buttons - Light */
.deepdrft-theme-light .deepdrft-hero-button-filled.mud-button-filled {
background-color: var(--deepdrft-primary);
color: var(--gradient-base);
}
.deepdrft-theme-light .deepdrft-hero-button-outlined.mud-button-outlined {
border-color: var(--deepdrft-primary);
color: var(--deepdrft-primary);
}
/* Hero buttons - Dark */
.deepdrft-theme-dark .deepdrft-hero-button-filled.mud-button-filled {
background-color: var(--deepdrft-primary);
color: var(--gradient-base);
}
.deepdrft-theme-dark .deepdrft-hero-button-outlined.mud-button-outlined {
border-color: var(--theme-surface);
color: var(--theme-surface);
}
/* =============================================================================
5. APPBAR
============================================================================= */
.deepdrft-theme-light .mud-appbar,
.deepdrft-theme-light .mud-appbar *,
.deepdrft-theme-light .mud-appbar .mud-icon-button {
color: var(--gradient-base);
}
.deepdrft-theme-dark .mud-appbar,
.deepdrft-theme-dark .mud-appbar *,
.deepdrft-theme-dark .mud-appbar .mud-icon-button {
color: var(--theme-surface);
}
/* =============================================================================
6. BORDERS (Only used variants)
============================================================================= */
.deepdrft-border-left-secondary { border-left: 4px solid var(--theme-secondary); }
.deepdrft-border-left-tertiary { border-left: 4px solid var(--theme-tertiary); }
.deepdrft-border-top-quaternary { border-top: 4px solid var(--theme-quaternary); }
.deepdrft-border-top-senary { border-top: 4px solid var(--theme-senary); }
/* =============================================================================
7. CARDS & TINTS (Only used variants)
============================================================================= */
.deepdrft-feature-card,
.deepdrft-about-card { height: 100%; }
.deepdrft-feature-icon-container { text-align: center; }
/* Card tints - using theme variables */
.deepdrft-card-purple-tint { background: color-mix(in srgb, var(--deepdrft-secondary) 10%, transparent); }
.deepdrft-card-pink-tint { background: color-mix(in srgb, var(--gradient-warm) 10%, transparent); }
.deepdrft-card-indigo-tint { background: color-mix(in srgb, var(--gradient-accent) 8%, transparent); }
.deepdrft-card-lavender-tint { background: color-mix(in srgb, var(--theme-quinary) 10%, transparent); }
/* =============================================================================
8. (moved to TrackCard.razor.css and TracksGallery.razor.css)
============================================================================= */
/* =============================================================================
9. CHIPS & BUTTONS
============================================================================= */
.deepdrft-chip-spacing { margin: 2px; }
.deepdrft-genre-chip { opacity: 0.9; margin-top: 4px; }
.deepdrft-button-spaced { margin: 8px; }
/* Extended palette chips */
.mud-chip.deepdrft-chip-quaternary {
background-color: var(--theme-quaternary);
color: white;
}
.mud-chip.deepdrft-chip-quinary {
background-color: var(--theme-quinary);
color: white;
}
.mud-chip.deepdrft-chip-senary {
background-color: var(--theme-senary);
color: white;
}
/* =============================================================================
10. EXTENDED PALETTE TEXT COLORS (Only used variants)
============================================================================= */
.deepdrft-text-quaternary { color: var(--theme-quaternary); }
.deepdrft-text-quinary { color: var(--theme-quinary); }
.deepdrft-text-senary { color: var(--theme-senary); }
/* =============================================================================
11. CTA SECTION
============================================================================= */
.deepdrft-cta-container {
border-radius: 16px;
text-align: center;
}
.deepdrft-cta-buttons { margin-bottom: 16px; }
/* =============================================================================
12. ICONS & UTILITIES
============================================================================= */
.deepdrft-icon-large { font-size: 3rem; }
/* =============================================================================
13. RESPONSIVE
============================================================================= */
@media (max-width: 768px) {
.deepdrft-hero-text {
font-size: clamp(1.5rem, 6vw, 3rem) !important;
}
.deepdrft-cta-buttons .mud-button {
margin: 4px !important;
width: 100%;
}
}
/* =============================================================================
14. TRACK DETAIL PAGE
============================================================================= */
.deepdrft-track-detail-container {
max-width: 760px;
margin: 0 auto;
padding: 3rem 1.5rem 4rem;
}
/* Mix detail widens its body to the Sessions detail width (MudContainer Large, ~1280px) by hosting the
scaffold inside a MudContainer Large and neutralizing the scaffold's own 760px cap for that instance.
Both classes are global, so a plain descendant selector reaches the scaffold div without ::deep. The
horizontal gutter is dropped here because the wrapping MudContainer supplies its own. Mix-scoped, so
Track detail (which also uses .deepdrft-track-detail-container) stays at 760px. */
.mix-detail-container .deepdrft-track-detail-container {
max-width: none;
padding-left: 0;
padding-right: 0;
}
.deepdrft-track-detail-back {
display: inline-flex;
align-items: center;
gap: 4px;
margin-bottom: 1.5rem;
opacity: 0.65;
transition: opacity 0.15s ease;
}
.deepdrft-track-detail-back:hover {
opacity: 1;
}
/* Square cover frame — the placeholder MudPaper fills it. */
.deepdrft-track-detail-cover {
aspect-ratio: 1 / 1;
max-width: 360px;
margin: 0 auto 2rem;
overflow: hidden;
box-shadow: 0 8px 28px color-mix(in srgb, var(--mud-palette-text-secondary) 18%, transparent);
}
/* Stat-card parallel: elevated surface with a soft secondary wash, album icon centered. */
.deepdrft-track-detail-cover-placeholder {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: var(--mud-palette-surface);
}
.deepdrft-track-detail-cover-placeholder .mud-icon-root {
font-size: 72px;
}
/* Album art fills the square frame; background-size:cover handles any aspect ratio. */
.deepdrft-track-detail-cover-art {
height: 100%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.deepdrft-track-detail-masthead {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.deepdrft-track-detail-meta {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
gap: 2rem;
margin-top: 1.5rem;
}
/* Small-caps mono labels match the caption/overline typography override. */
.deepdrft-track-detail-meta .mud-typography-overline {
font-variant: small-caps;
opacity: 0.6;
font-family: var(--deepdrft-font-mono) !important;
}
.deepdrft-share-popover-body {
padding: 0.75rem 1rem;
min-width: 280px;
max-width: 360px;
}
/* Monospace snippet so the iframe markup stays legible inside the readonly field. */
.deepdrft-share-embed-field {
flex: 1 1 auto;
}
.deepdrft-share-embed-field .mud-input-slot {
font-family: var(--deepdrft-font-mono) !important;
font-size: 0.75rem;
word-break: break-all;
}
/* =============================================================================
WAVEFORM VISUALIZER CONTROL PANEL (Phase 12 §3d-revised / §3g → Phase 15 re-layout)
The control deck hosted inside WaveformVisualizerControlPopover, now a screen-centered
tinted MudOverlay (Phase 15 §4). MudOverlay — like the former MudPopover — PORTALS its
content out of the component's DOM subtree, so Blazor CSS isolation never reaches the
rendered panel: its chrome, the three-row/section LAYOUT, the section labels, the slider,
and the toggles all live here in the global sheet, not in the scoped
WaveformVisualizerControls.razor.css. (The scoped file keeps only the legacy inline-bar
fallback Mix's old TopRowCenter mount used, which is not portaled.)
The waveform-visualizer-control-panel class is applied ONLY when the component's
PanelChrome="true" parameter is set — which the popover host does and Mix's inline mount
does NOT — so the chrome never leaks onto an inline bar.
CHROME (Phase 15 §5 — NowPlayingCard treatment): SQUARE corners, lighter-navy ground
(navy-mid), a thin LIGHT border (--deepdrft-border-light, the NowPlayingCard 0.12-alpha
light-on-dark idiom as a token). All token-sourced; no hardcoded hex.
COLOUR PRINCIPLE (§5 — green = interactive, light = non-interactive): the RadialKnob reads
--mud-palette-* for its arc/pointer/center/label; we pin --mud-palette-primary to the green
accent (interactive arcs/pointers) and --mud-palette-text-primary to light. Caption icons and
section labels are LIGHT (static). The slider track/thumb and the lamp toggles are green.
============================================================================= */
.waveform-visualizer-control-panel.mix-visualizer-controls-bar {
/* Greyed panel ground — desaturated charcoal so the blue slider reads against it (defect #1).
Token is tunable in deepdrft-tokens.css without touching this rule. */
background: var(--deepdrft-panel-ground);
/* Square corners + thin light border — NowPlayingCard chrome (§5). */
border: 1px solid var(--deepdrft-border-light);
border-radius: 0;
/* Optional backdrop blur — cheap on a small modal panel, nice over the visualizer (§5). */
backdrop-filter: blur(8px);
padding: 1rem 1.25rem;
/* Three-row sectioned deck: stack the rows top-to-bottom; conditional rows reserve no permanent
height (§3 reflow discipline). This OVERRIDES the inline-bar min-height + flex-wrap (which only
matter for Mix's non-portaled legacy mount). */
display: flex;
flex-direction: column;
gap: 0.75rem;
min-height: 0;
max-width: 420px;
/* Pin the MudBlazor palette vars the portaled RadialKnob + slider consume. */
--mud-palette-primary: var(--deepdrft-green-accent); /* knob arc/pointer + slider track/thumb (interactive) */
--mud-palette-surface: var(--deepdrft-navy); /* knob center fill — darkest navy reads against the panel */
--mud-palette-surface-variant: var(--deepdrft-muted); /* knob background track — muted-navy filler */
--mud-palette-text-primary: var(--deepdrft-white); /* knob value label — light */
}
/* ── Row layout (§3). Each row is a horizontal band. Row 1 (MODE) and row 3 (WAVE) use
space-between so the right-pinned control (color / width) hugs the far edge. Row 2 (LAVA) uses
flex-start so its label + four knobs group left rather than spreading edge-to-edge.
align-items: center so the section label and knobs vertically center with each other. ── */
.waveform-visualizer-control-panel .wvc-row {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.85rem 1rem;
}
/* Row 1 (MODE): two direct flex children — the left toggle group and the color knob tooltip wrapper.
space-between pins the color knob to the far right and keeps it there when collisions hides. */
.waveform-visualizer-control-panel .wvc-row-mode {
justify-content: space-between;
}
/* Row 2 (LAVA): label + four knobs group left — no right-pinned control. */
.waveform-visualizer-control-panel .wvc-row-section {
justify-content: flex-start;
}
/* Row 3 (WAVE): label + scroll-slider + width-knob tooltip wrappers are direct flex children.
space-between pins the width knob to the far right while the label + slider sit left. */
.waveform-visualizer-control-panel .wvc-row-wave {
justify-content: space-between;
}
/* The left group of row 1 (toggles + conditional collisions) flows left; the color knob is the
space-between right sibling, so it stays put when collisions hides (§3). */
.waveform-visualizer-control-panel .wvc-row-left {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.85rem 1rem;
}
/* ── Section label "LAVA:" / "WAVE:" (§3, §5). NowPlayingCard .np-label TYPOGRAPHY (mono, uppercase,
tracked), recoloured LIGHT — labels are static, so light by the colour principle (§5, §10.3). ── */
.waveform-visualizer-control-panel .wvc-section-label {
font-family: var(--deepdrft-font-mono);
font-size: 0.6rem;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--deepdrft-white);
align-self: center;
flex: 0 0 auto;
opacity: 0.85;
}
/* ── The toggles (§3 row 1). Two state classes control the active-state chip treatment:
ON (.wvc-toggle-on): green-accent filled chip — unmistakably active at a glance.
OFF (.wvc-toggle-off): fully transparent background, glyph at low opacity — clearly inactive.
The MudIconButton glyph is already driven green (Color.Primary → pinned green accent, interactive §5).
The chip background reinforces state without recolouring the glyph further. ── */
.waveform-visualizer-control-panel .wvc-toggle {
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
transition: background 0.15s ease;
}
.waveform-visualizer-control-panel .wvc-toggle-on {
background: color-mix(in srgb, var(--deepdrft-green-accent) 28%, transparent);
box-shadow: 0 0 0 1px color-mix(in srgb, var(--deepdrft-green-accent) 55%, transparent);
}
.waveform-visualizer-control-panel .wvc-toggle-off .mud-icon-button {
opacity: 0.38;
}
/* Caption icons render LIGHT (§5/§9: static/decorative = light). !important beats the scoped
.mix-visualizer-control ::deep .mix-visualizer-control-icon rule (which sets green for the legacy
inline mount) when the icon also carries mix-visualizer-control-icon. Lamp toggles are MudIconButton
not MudIcon so they are unaffected — they stay green (interactive, Color.Primary). (defect #3) */
.waveform-visualizer-control-panel .waveform-visualizer-control-icon {
opacity: 0.85;
translate: 0 -1rem;
}
/* ── The modal overlay (Phase 15 §4). MudOverlay is already a full-viewport flex scrim that centers its
content (.mud-overlay { display:flex; align-items:center; justify-content:center }), which gives the
screen-centered panel on every host for free — we do NOT fight that positioning. We:
(a) Raise the overlay z-index above the header (100) and the player-dock footer (1200/1300) so the
scrim tints the ENTIRE viewport uniformly — header and footer included (defect #7). The panel
content needs z-index: auto (inherits from stacking context) so it sits above the scrim naturally;
the RadialKnob capture div at 9999 remains above everything.
(b) Set the mild tint from the SINGLE --deepdrft-modal-scrim-alpha token (§10.5, defect #6).
(c) Remove overflow-y:auto on the content wrapper — it was the source of the drag scrollbar (defect #2).
The panel's max-width/flex-column already contain its size; the outer overlay clips at 100vh.
(d) Suppress body scroll while the overlay is present so no page-scroll occurs during a drag (defect #2).
The overlay portals to the body, so these are plain global rules (no scope attribute). The doubled
.mud-overlay-scrim.mud-overlay-dark selector (0,2,0) outranks MudBlazor's own .mud-overlay-dark (0,1,0),
so the tint wins regardless of stylesheet load order. ── */
/* Raise the overlay itself above the sticky header (z-index:100) and the fixed player dock (z-index:1200).
Use 1400 so it sits above the minimized-dock FAB (1300) too. The panel content inherits this context
and stacks above the scrim; the RadialKnob capture div (z-index:9999) stays highest. */
.waveform-visualizer-control-overlay {
z-index: 1400 !important;
}
.waveform-visualizer-control-overlay .mud-overlay-scrim.mud-overlay-dark {
background-color: rgba(var(--deepdrft-scrim-rgb), var(--deepdrft-modal-scrim-alpha));
}
/* No overflow-y:auto — removing it eliminates the spurious scrollbar that appeared while dragging a
knob (defect #2). The panel's flex-column layout is self-contained and never overflows the overlay. */
.waveform-visualizer-control-overlay .mud-overlay-content {
max-height: 90vh;
overflow: visible;
}
/* Lock body scroll while the controls overlay is open so the page cannot be scrolled during a
knob drag (defect #2). :has() degrades gracefully in older browsers (no lock, no crash). */
body:has(.waveform-visualizer-control-overlay) {
overflow: hidden;
}
@media (max-width: 419.98px) {
.deepdrft-track-detail-meta {
flex-direction: column;
}
}
/* =============================================================================
BUTTON UTILITIES (btn-primary, btn-ghost)
============================================================================= */
.btn-primary {
font-family: var(--deepdrft-font-mono);
font-size: 0.68rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--deepdrft-white);
background: var(--deepdrft-navy);
border: none;
padding: 1rem 2.2rem;
cursor: pointer;
text-decoration: none;
transition: background 0.25s, transform 0.2s;
display: inline-block;
}
.btn-primary:hover {
background: var(--deepdrft-green);
transform: translateY(-1px);
}
.btn-ghost {
font-family: var(--deepdrft-font-mono);
font-size: 0.68rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--deepdrft-navy);
background: transparent;
border: 1px solid var(--deepdrft-border);
padding: 1rem 2.2rem;
cursor: pointer;
text-decoration: none;
transition: border-color 0.25s, color 0.25s;
display: inline-block;
}
.btn-ghost:hover { border-color: var(--deepdrft-navy); }
@media (max-width: 599px) {
.btn-primary,
.btn-ghost {
text-align: center;
}
}
/* =============================================================================
CUT ALBUM DETAIL (/cuts/{id})
Header splits left-meta / right-cover; the cover carries an explicit theme
border (the new visual element vs. the borderless Session/Mix covers).
============================================================================= */
.cut-detail-header {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
gap: 2rem;
margin: 2rem 0 1.5rem;
}
.cut-detail-meta {
display: flex;
flex-direction: column;
gap: 0.5rem;
min-width: 0;
flex: 1 1 auto;
}
.cut-detail-subline {
display: flex;
align-items: center;
gap: 0.5rem;
opacity: 0.75;
font-family: var(--deepdrft-font-mono);
font-size: 0.85rem;
margin-top: 0.25rem;
}
.cut-detail-sep { opacity: 0.5; }
.cut-detail-actions {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.75rem;
margin-top: 1rem;
}
/* Square cover with a framed theme border — the new visual element this page introduces. */
.cut-detail-cover {
aspect-ratio: 1 / 1;
width: 260px;
flex: 0 0 auto;
overflow: hidden;
box-shadow: 0 8px 28px color-mix(in srgb, var(--mud-palette-text-secondary) 18%, transparent);
}
.cut-detail-divider { margin: 1.5rem 0 0.5rem; }
.cut-detail-empty {
opacity: 0.7;
padding: 1rem 0;
}
.cut-detail-tracklist {
display: flex;
flex-direction: column;
}
.cut-detail-track-row {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.75rem;
padding: 0.25rem 0;
border-bottom: 1px solid color-mix(in srgb, var(--mud-palette-text-secondary) 12%, transparent);
}
.cut-detail-track-row:last-child { border-bottom: none; }
.cut-detail-track-number {
width: 1.75rem;
text-align: right;
flex: 0 0 auto;
opacity: 0.55;
font-family: var(--deepdrft-font-mono);
font-size: 0.9rem;
}
.cut-detail-track-play { flex: 0 0 auto; }
.cut-detail-track-name {
flex: 1 1 auto;
min-width: 0;
}
/* Stack the header on narrow screens: cover above the meta column. */
@media (max-width: 599px) {
.cut-detail-header {
flex-direction: column-reverse;
align-items: stretch;
gap: 1.25rem;
}
.cut-detail-cover {
width: 100%;
max-width: 320px;
margin: 0 auto;
}
}
/* =============================================================================
RELEASE DESCRIPTION BLURB
Shared block rendered just below the hero/header on every release detail page
(Session, Mix, Cut). Theme-driven colours keep it legible in both palettes.
Borrows the eyebrow-label + divider-rule motif from the home page.
============================================================================= */
.deepdrft-release-description {
margin: 2rem 0 2.5rem;
}
/* Header row: eyebrow label left + thin rule filling the rest */
.deepdrft-release-description-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.25rem;
}
/* Eyebrow label — mirrors .section-label / .split-eyebrow from Home */
.deepdrft-release-description-label {
font-family: var(--deepdrft-font-mono);
font-size: 0.62rem;
letter-spacing: 0.28em;
color: var(--deepdrft-green-accent);
text-transform: uppercase;
white-space: nowrap;
flex-shrink: 0;
}
/* Thin rule to the right of the label — mirrors .divider-line from Home */
.deepdrft-release-description-rule {
flex: 1;
height: 1px;
background: color-mix(in srgb, var(--deepdrft-muted) 35%, transparent);
}
/* Body paragraph — body font, display-serif feel via generous line-height */
.deepdrft-release-description-text {
margin: 0;
font-family: var(--deepdrft-font-display);
font-size: 1.1rem;
font-weight: 300;
line-height: 1.75;
color: var(--mud-palette-text-primary);
opacity: 0.85;
}
/* =============================================================================
QUEUE OVERLAY + LIST (Phase 17 wave 17.2 — docked queue panel)
The overlay is a direct lift of the visualizer-control modal (Phase 15 §4): a centered MudOverlay
whose scrim tint + z-index + body-scroll lock match that idiom exactly. The panel chrome (square
corners, lighter-navy ground, thin light border) is the NowPlayingCard treatment (§5). MudOverlay
portals out of the component subtree to the body, so these are plain GLOBAL rules — CSS isolation
cannot reach portaled content.
============================================================================= */
/* Raise the overlay above the sticky header (100), the fixed player dock (1200), and the minimized
FAB (1300) — same stacking decision as the visualizer overlay so the scrim tints the whole viewport. */
.deepdrft-queue-overlay {
z-index: 1400 !important;
}
/* Mild modal tint from the shared scrim token. The doubled selector (0,2,0) outranks MudBlazor's own
.mud-overlay-dark (0,1,0) regardless of stylesheet load order. */
.deepdrft-queue-overlay .mud-overlay-scrim.mud-overlay-dark {
background-color: rgba(var(--deepdrft-scrim-rgb), var(--deepdrft-modal-scrim-alpha));
}
.deepdrft-queue-overlay .mud-overlay-content {
max-height: 90vh;
overflow: visible;
}
/* Lock body scroll while the queue overlay is open (matches the visualizer overlay). */
body:has(.deepdrft-queue-overlay) {
overflow: hidden;
}
/* The mostly-square panel (§3.2: min(90vw, 520px)). NowPlayingCard chrome: square corners, lighter-navy
ground, thin light border. Internal column: fixed header over a scrollable list body. */
.deepdrft-queue-modal {
display: flex;
flex-direction: column;
width: min(90vw, 520px);
height: min(90vw, 520px);
max-height: 90vh;
background: var(--deepdrft-panel-ground);
border: 1px solid var(--deepdrft-border-light);
border-radius: 0;
backdrop-filter: blur(8px);
overflow: hidden;
}
.deepdrft-queue-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.85rem 1rem;
border-bottom: 1px solid var(--deepdrft-border-light);
}
/* Mono uppercase eyebrow — the NowPlayingCard .np-label typography, recoloured light (static). */
.deepdrft-queue-modal-title {
font-family: var(--deepdrft-font-mono);
font-size: 0.72rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--deepdrft-white);
opacity: 0.85;
}
.deepdrft-queue-modal-body {
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
padding: 0.5rem 0.5rem 0.75rem;
}
/* ── The list itself (consumed by QueueList in both modes; styled here once). ── */
.deepdrft-queue-list {
display: flex;
flex-direction: column;
}
.deepdrft-queue-zone {
display: flex;
flex-direction: column;
}
.deepdrft-queue-row {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.45rem 0.5rem;
border-radius: 4px;
color: var(--deepdrft-white);
transition: background 0.15s ease;
}
.deepdrft-queue-row:hover {
background: color-mix(in srgb, var(--deepdrft-white) 6%, transparent);
}
/* Current track: a subtle green wash + left accent, matching the green = active principle. */
.deepdrft-queue-row-current {
background: color-mix(in srgb, var(--deepdrft-green-accent) 14%, transparent);
box-shadow: inset 2px 0 0 0 var(--deepdrft-green-accent);
}
.deepdrft-queue-drag-handle {
cursor: grab;
opacity: 0.45;
flex: 0 0 auto;
}
.deepdrft-queue-position {
font-family: var(--deepdrft-font-mono);
font-size: 0.72rem;
opacity: 0.6;
min-width: 1.4rem;
text-align: right;
flex: 0 0 auto;
}
/* Row body grows + truncates; clicking it jumps playback (OQ2). */
.deepdrft-queue-body {
display: flex;
flex-direction: column;
gap: 0.1rem;
flex: 1 1 auto;
min-width: 0;
cursor: pointer;
}
.deepdrft-queue-title {
font-size: 0.92rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.deepdrft-queue-artist {
font-size: 0.74rem;
opacity: 0.6;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.deepdrft-queue-nowplaying,
.deepdrft-queue-remove {
flex: 0 0 auto;
}
/* Active (open) state for the bar's Queue toggle — a soft green chip behind the glyph, matching the
visualizer toggle's on-state idiom. */
.deepdrft-queue-toggle-active {
background: color-mix(in srgb, var(--deepdrft-green-accent) 22%, transparent);
border-radius: 6px;
}
/* ── Fixed (embed) inline queue panel (Phase 17 §4, OQ6). ──
Rendered below the player controls inside the embed surface. A fixed sensible height with internal
scroll past N rows (NOT grow-to-cap): ~4.5 rows are visible, the rest scroll. A top hairline
separates it from the controls. The list rows reuse the shared .deepdrft-queue-* styles above. */
.deepdrft-queue-embed-panel {
margin-top: 0.5rem;
padding-top: 0.5rem;
border-top: 1px solid var(--deepdrft-border-light);
max-height: 184px;
overflow-y: auto;
}