c28a2b1cf5
Glyph rule is (0,3,0) > (0,1,0) — beats .mud-secondary-text on specificity, not source order. ReleaseHeroOverlay spinner comment now distinguishes dead glyph clauses from the live spinner clause that produced the intentional light delta.
1114 lines
41 KiB
CSS
1114 lines
41 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);
|
|
}
|
|
|
|
/* Main-content clearance for the fixed frosted-glass nav (.dd-nav). The nav is
|
|
position:fixed (so content scrolls under its backdrop blur) and thus out of flow;
|
|
in MainLayout's flex column the content would otherwise start at the top and slide
|
|
under the bar. Pad the top by the shared --deepdrft-nav-height token so the clearance
|
|
tracks the bar exactly across breakpoints. Replaces the old hardcoded MudBlazor pt-16. */
|
|
.dd-main-content {
|
|
padding-top: var(--deepdrft-nav-height, 88px);
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/* Default MudBlazor popover surface (Phase 18, T4 — symptom #1). Selects, menus, and the
|
|
share-popover body render inside .mud-popover. (Tooltips are NOT covered here — MudBlazor
|
|
tooltips paint from --mud-palette-text, not the popover surface.) Their visible surface is the
|
|
inner .mud-paper, which paints background-color: var(--mud-palette-surface). Inspection settled
|
|
the root cause: the "too dark" is NOT --deepdrft-panel-ground leakage (the bespoke dark-glass
|
|
panels are MudOverlay .mud-overlay-content surfaces and never match .mud-popover) — it is simply
|
|
that the popover surface tracks --mud-palette-surface with no desaturated-navy treatment. So
|
|
re-point --mud-palette-surface to the theme-aware --deepdrft-popover-surface *within the popover
|
|
scope only*: a soft desaturated-navy wash in light, the existing panel-ground charcoal in dark.
|
|
Scoping the variable (not a flat background) means any inner .mud-paper, .mud-list, or menu picks
|
|
it up for free, while the global surface used elsewhere on the page is unaffected. */
|
|
.mud-popover {
|
|
--mud-palette-surface: var(--deepdrft-popover-surface);
|
|
background-color: var(--deepdrft-popover-surface);
|
|
}
|
|
|
|
.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 {
|
|
/* Theme-aware glass ground — dark charcoal in dark theme, light translucent glass in light
|
|
(so the deck reads against the light page). Tunable in deepdrft-tokens.css. */
|
|
background: var(--deepdrft-panel-surface);
|
|
/* Square corners + thin theme-aware border — NowPlayingCard chrome (§5). */
|
|
border: 1px solid var(--deepdrft-panel-border);
|
|
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-panel-text); /* knob value label — flips dark on light glass */
|
|
}
|
|
|
|
/* ── 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), coloured via --deepdrft-panel-text — theme-aware (navy in light, off-white in dark). ── */
|
|
.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-panel-text);
|
|
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 inherit the portaled panel's body text — theme-aware (dark text on light glass,
|
|
off-white on dark glass). !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;
|
|
}
|
|
}
|
|
|
|
/* Dark-mode button overrides (Phase 18, Wave 3).
|
|
In dark, --deepdrft-navy fill/text blends into the #0D1B2A page ground.
|
|
Primary: green-accent fill + navy text reads as a clear CTA (matches play-chip language).
|
|
Ghost: white text + light border stands off the dark ground. */
|
|
.deepdrft-theme-dark .btn-primary {
|
|
background: var(--deepdrft-green-accent);
|
|
color: var(--deepdrft-navy);
|
|
}
|
|
|
|
.deepdrft-theme-dark .btn-primary:hover {
|
|
background: var(--deepdrft-green-interactive);
|
|
}
|
|
|
|
.deepdrft-theme-dark .btn-ghost {
|
|
color: var(--deepdrft-page-text);
|
|
border-color: var(--deepdrft-border-light);
|
|
}
|
|
|
|
.deepdrft-theme-dark .btn-ghost:hover {
|
|
border-color: var(--deepdrft-page-text);
|
|
}
|
|
|
|
/* =============================================================================
|
|
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;
|
|
}
|
|
}
|
|
|
|
/* =============================================================================
|
|
INTERACTIVE-ACCENT ICON TREATMENT (.dd-accent-icon / .dd-accent-fill)
|
|
----------------------------------------------------------------------------
|
|
The single, reusable green-accent treatment for interactive icon affordances —
|
|
replaces the per-site dark-mode overrides that previously had to fight the palette.
|
|
|
|
WHY a class and not a palette colour: no MudBlazor Color enum is green in BOTH
|
|
themes (Dark.Secondary is off-white, Dark.Primary is green; Light.Secondary is
|
|
green, Light.Primary is navy), so every "green in both" affordance had to be
|
|
patched per-site. --deepdrft-green-accent (#3D7A68) is the brand constant — the
|
|
SAME value in both palettes — so a non-theme-scoped rule is correct: light already
|
|
renders these glyphs green-accent (via Color.Secondary → Light.Secondary), so this
|
|
keeps light pixel-identical while fixing dark.
|
|
|
|
WHY it reaches the glyph: MudBlazor colours a Color.Secondary icon by stamping
|
|
.mud-secondary-text on the inner .mud-icon-root <svg>, and that rule is `!important`
|
|
(color: var(--mud-palette-secondary) !important). Targeting only the .mud-icon-button
|
|
wrapper therefore never wins — the svg keeps its own !important colour. The documented
|
|
override bug. The glyph clause .dd-accent-icon .mud-icon-button .mud-icon-root is
|
|
specificity (0,3,0) + !important, which beats MudBlazor's standalone .mud-secondary-text
|
|
(0,1,0) + !important on specificity alone — source order is not load-bearing for the
|
|
glyph clause. The .mud-icon-button selector carries the
|
|
Color.Inherit affordances (lava-lamp glyph inherits the wrapper colour, no
|
|
.mud-secondary-text to fight); the spinner covers the PlayStateIcon loading state.
|
|
|
|
Apply .dd-accent-icon to a CONTAINER of the affordance(s); add .dd-accent-fill
|
|
alongside it when the container ALSO holds a filled MudButton whose Color.Secondary
|
|
fill must go green-accent in dark (a filled button is a background fill, not a glyph —
|
|
light already renders green-accent fill + white text, so .dd-accent-fill is DARK-ONLY
|
|
to keep light pixel-identical). The Session/Mix hero Share/Play glyphs use this class
|
|
too (they were already green-accent in light via Color.Secondary, so folding them in
|
|
keeps light pixel-identical and fixes dark — the over-image glyphs are not actually
|
|
theme-divergent). The one genuinely theme-divergent affordance (gas-lamp = inherited
|
|
nav text in light) does NOT use this class — it keeps a dark-only rule below.
|
|
|
|
The glyph rule targets glyphs inside an ICON button (.mud-icon-button .mud-icon-root)
|
|
only — the filled Play button is a .mud-button-filled (not .mud-icon-button), so its
|
|
StartIcon is naturally excluded and keeps its own contrast colour (white in light,
|
|
navy in dark). The bare .mud-icon-button selector carries the Color.Inherit case
|
|
(lava-lamp glyph inherits the wrapper colour); the spinner covers the loading state. */
|
|
.dd-accent-icon .mud-icon-button .mud-icon-root,
|
|
.dd-accent-icon .mud-icon-button,
|
|
.dd-accent-icon .mud-progress-circular {
|
|
color: var(--deepdrft-green-accent) !important;
|
|
}
|
|
|
|
/* Filled-button variant (DARK-ONLY): green-accent fill + navy glyph/label, matching the
|
|
play-chip language. In dark, Color.Secondary fill resolves to off-white (unreadable);
|
|
here it becomes a clear green CTA. Light is untouched (already green fill + white text). */
|
|
.deepdrft-theme-dark .dd-accent-fill .mud-button-filled {
|
|
background-color: var(--deepdrft-green-accent);
|
|
color: var(--deepdrft-navy);
|
|
}
|
|
|
|
.deepdrft-theme-dark .dd-accent-fill .mud-button-filled .mud-icon-root {
|
|
color: var(--deepdrft-navy) !important;
|
|
}
|
|
|
|
/* Theme-divergent affordance — gas-lamp dark-mode toggle.
|
|
Uses Color.Inherit, so in LIGHT it inherits the nav text colour (the contract to keep).
|
|
In dark theme it goes green-accent to match the convention. Scoped to .dd-nav-actions
|
|
(covers both desktop and mobile nav, which both render the gas-lamp there); dark-only. */
|
|
.deepdrft-theme-dark .dd-nav-actions .mud-icon-button {
|
|
color: var(--deepdrft-green-accent);
|
|
}
|
|
|
|
/* =============================================================================
|
|
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-surface);
|
|
border: 1px solid var(--deepdrft-panel-border);
|
|
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-panel-border);
|
|
}
|
|
|
|
/* Mono uppercase eyebrow — the NowPlayingCard .np-label typography, theme-aware (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-panel-text);
|
|
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-panel-text);
|
|
transition: background 0.15s ease;
|
|
}
|
|
|
|
.deepdrft-queue-row:hover {
|
|
background: var(--deepdrft-panel-row-hover);
|
|
}
|
|
|
|
/* 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;
|
|
color: var(--deepdrft-panel-text-muted);
|
|
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;
|
|
color: var(--deepdrft-panel-text-muted);
|
|
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;
|
|
}
|
|
|
|
/* =============================================================================
|
|
PRIVACY OVERLAY
|
|
Screen-centered modal following the same MudOverlay idiom as the visualizer
|
|
controls and queue overlays. MudOverlay portals to body — CSS isolation cannot
|
|
reach portaled content, so chrome lives here in the global sheet.
|
|
============================================================================= */
|
|
|
|
/* Raise above the sticky header (100), player dock (1200), and minimized FAB (1300). */
|
|
.deepdrft-privacy-overlay {
|
|
z-index: 1400 !important;
|
|
}
|
|
|
|
/* Mild tint: doubled selector (0,2,0) outranks MudBlazor's .mud-overlay-dark (0,1,0). */
|
|
.deepdrft-privacy-overlay .mud-overlay-scrim.mud-overlay-dark {
|
|
background-color: rgba(var(--deepdrft-scrim-rgb), var(--deepdrft-modal-scrim-alpha));
|
|
}
|
|
|
|
.deepdrft-privacy-overlay .mud-overlay-content {
|
|
max-height: 90vh;
|
|
overflow: visible;
|
|
}
|
|
|
|
/* Lock body scroll while the overlay is open. */
|
|
body:has(.deepdrft-privacy-overlay) {
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Panel: compact width, navy-panel ground, thin light border — matches queue/visualizer chrome. */
|
|
.deepdrft-privacy-modal {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: min(90vw, 480px);
|
|
background: var(--deepdrft-panel-surface);
|
|
border: 1px solid var(--deepdrft-panel-border);
|
|
border-radius: 0;
|
|
backdrop-filter: blur(8px);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.deepdrft-privacy-modal-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0.85rem 0.85rem 0.85rem 1rem;
|
|
border-bottom: 1px solid var(--deepdrft-panel-border);
|
|
}
|
|
|
|
/* Mono uppercase eyebrow — matches queue modal title. */
|
|
.deepdrft-privacy-modal-title {
|
|
font-family: var(--deepdrft-font-mono);
|
|
font-size: 0.72rem;
|
|
letter-spacing: 0.2em;
|
|
text-transform: uppercase;
|
|
color: var(--deepdrft-panel-text);
|
|
opacity: 0.85;
|
|
}
|
|
|
|
/* Tuck the close icon flush with the panel edge; keep it subtle. */
|
|
.deepdrft-privacy-modal-close {
|
|
opacity: 0.6;
|
|
color: var(--deepdrft-panel-text) !important;
|
|
}
|
|
|
|
.deepdrft-privacy-modal-close:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Privacy copy: same mono treatment as the former inline paragraph; theme-aware text colour
|
|
so it stays legible on both the dark-glass (dark) and light-glass (light) panel surfaces. */
|
|
.deepdrft-privacy-modal-body {
|
|
font-family: var(--deepdrft-font-mono);
|
|
font-size: 0.72rem;
|
|
letter-spacing: 0.06em;
|
|
line-height: 1.7;
|
|
color: var(--deepdrft-panel-text);
|
|
opacity: 0.8;
|
|
margin: 0;
|
|
padding: 1rem 1rem 1.25rem;
|
|
}
|