feat: add Cosmic theme + motion system
This commit is contained in:
parent
b93443a716
commit
76deca6a7f
4 changed files with 327 additions and 4 deletions
|
|
@ -1,4 +1,4 @@
|
|||
export type Theme = 'light' | 'dark' | 'glass' | 'neon' | 'impeccable' | 'impeccable-dark';
|
||||
export type Theme = 'light' | 'dark' | 'glass' | 'neon' | 'impeccable' | 'impeccable-dark' | 'cosmic';
|
||||
|
||||
/** Lifecycle of the NIP-46 remote signer. */
|
||||
export type SignerPhase = 'stopped' | 'connecting' | 'connected';
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ export function SettingsScreen() {
|
|||
<option value="neon">Neon</option>
|
||||
<option value="impeccable">Impeccable — Light</option>
|
||||
<option value="impeccable-dark">Impeccable — Dark</option>
|
||||
<option value="cosmic">Cosmic — Stardust</option>
|
||||
</select>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
|
|
@ -179,12 +180,14 @@ export function SettingsScreen() {
|
|||
? 'Aurora — frosted glass, cyan'
|
||||
: settings.theme === 'dark'
|
||||
? 'Dark — deep ink'
|
||||
: settings.theme === 'cosmic'
|
||||
? 'Cosmic — deep space, golden stardust'
|
||||
: 'Light — warm paper'}
|
||||
</span>
|
||||
</div>
|
||||
<p className="hint">
|
||||
“Light” and “Dark” follow your manual selection. “Aurora”, “Neon”, “Impeccable” and
|
||||
“Impeccable Dark” are aesthetic themes with distinctive color palettes.
|
||||
"Light" and "Dark" follow your manual selection. "Aurora", "Neon", "Impeccable",
|
||||
"Impeccable Dark", and "Cosmic" are aesthetic themes with distinctive color palettes.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -348,6 +348,230 @@ html[data-theme='impeccable-dark'] .sidebar {
|
|||
border-right-color: var(--border);
|
||||
}
|
||||
|
||||
/* "Cosmic" — Stardust color scheme from https://github.com/kaymade/cosmic
|
||||
Deep space backgrounds with warm golden accents.
|
||||
Fonts: Source Serif 4 for body, Cormorant Garamond for headings.
|
||||
Sidebar: Deep (darker background). Workspace: Deep Space (dramatic vignette). */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,500;0,8..60,600;0,8..60,700;1,8..60,400;1,8..60,500;1,8..60,600;1,8..60,700&display=swap');
|
||||
|
||||
:root[data-theme='cosmic'] {
|
||||
/* Stardust dark mode colors */
|
||||
--bg: #171109;
|
||||
--surface: #0d0a06;
|
||||
--surface-2: #21180c;
|
||||
--surface-hover: #140f08;
|
||||
--border: #2d2418;
|
||||
--border-strong: #3d3220;
|
||||
--text: #fff5dc;
|
||||
--text-muted: #d5bd8d;
|
||||
--primary: #efbd62;
|
||||
--primary-hover: #ffdb91;
|
||||
--primary-soft: rgba(239, 189, 98, 0.15);
|
||||
--on-primary: #171109;
|
||||
--danger: #f08e7d;
|
||||
--danger-soft: rgba(240, 142, 125, 0.15);
|
||||
--warning: #f08e7d;
|
||||
--warning-soft: rgba(240, 142, 125, 0.15);
|
||||
--success: #74d7cb;
|
||||
--success-soft: rgba(116, 215, 203, 0.15);
|
||||
--info: #74d7cb;
|
||||
--info-soft: rgba(116, 215, 203, 0.15);
|
||||
--focus: #efbd62;
|
||||
--shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
|
||||
--shadow-modal: 0 12px 40px rgba(0, 0, 0, 0.6);
|
||||
--radius: 8px;
|
||||
--radius-sm: 4px;
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Cosmic typography - Cormorant Garamond for headings, Source Serif 4 for body */
|
||||
html[data-theme='cosmic'] body {
|
||||
font-family: 'Source Serif 4', 'Georgia', serif;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] h1,
|
||||
html[data-theme='cosmic'] h2,
|
||||
html[data-theme='cosmic'] h3,
|
||||
html[data-theme='cosmic'] h4 {
|
||||
font-family: 'Cormorant Garamond', 'Georgia', serif;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] h1 {
|
||||
font-size: 28px;
|
||||
color: #efbd62;
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] h2 {
|
||||
font-size: 20px;
|
||||
color: #74d7cb;
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] h3 {
|
||||
font-size: 18px;
|
||||
color: #f08e7d;
|
||||
}
|
||||
|
||||
/* Cosmic sidebar - Deep background (darker) */
|
||||
html[data-theme='cosmic'] .sidebar {
|
||||
background: #0d0a06;
|
||||
border-right-color: var(--border);
|
||||
}
|
||||
|
||||
/* Cosmic workspace - Deep Space background with vignette effect */
|
||||
html[data-theme='cosmic'] .app-shell {
|
||||
background:
|
||||
radial-gradient(circle at 8% 13%, rgba(255, 245, 220, 0.72) 0 1px, transparent 1.7px),
|
||||
radial-gradient(circle at 27% 7%, rgba(116, 215, 203, 0.82) 0 1px, transparent 1.8px),
|
||||
radial-gradient(circle at 73% 19%, rgba(255, 245, 220, 0.68) 0 1.2px, transparent 1.9px),
|
||||
radial-gradient(circle at 91% 42%, rgba(240, 142, 125, 0.78) 0 1px, transparent 1.8px),
|
||||
radial-gradient(circle at 61% 78%, rgba(255, 245, 220, 0.64) 0 1px, transparent 1.7px),
|
||||
radial-gradient(circle at 18% 84%, rgba(239, 189, 98, 0.82) 0 1.2px, transparent 2px),
|
||||
radial-gradient(circle at 12% 4%, rgba(239, 189, 98, 0.52), transparent 58rem),
|
||||
radial-gradient(circle at 88% 12%, rgba(116, 215, 203, 0.42), transparent 46rem),
|
||||
radial-gradient(circle at 52% 100%, rgba(240, 142, 125, 0.36), transparent 50rem),
|
||||
radial-gradient(ellipse at center, transparent 34%, rgba(13, 10, 6, 0.48) 100%),
|
||||
linear-gradient(145deg, #171109, #0d0a06);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .main {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Cosmic cards and surfaces */
|
||||
html[data-theme='cosmic'] .card,
|
||||
html[data-theme='cosmic'] .profile-card,
|
||||
html[data-theme='cosmic'] .relay-row {
|
||||
background: var(--surface);
|
||||
border-color: var(--border);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .card:hover,
|
||||
html[data-theme='cosmic'] .profile-card:hover {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
/* Cosmic buttons */
|
||||
html[data-theme='cosmic'] .btn-primary {
|
||||
background: var(--primary);
|
||||
color: var(--on-primary);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .btn-primary:hover:not(:disabled) {
|
||||
background: var(--primary-hover);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .btn-secondary {
|
||||
background: var(--surface);
|
||||
border-color: var(--border-strong);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .btn-ghost {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .btn-ghost:hover {
|
||||
background: var(--surface-2);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/* Cosmic navigation */
|
||||
html[data-theme='cosmic'] .nav-item {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .nav-item:hover {
|
||||
background: var(--surface-2);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .nav-item.is-active {
|
||||
background: var(--primary-soft);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* Cosmic inputs */
|
||||
html[data-theme='cosmic'] input[type='text'],
|
||||
html[data-theme='cosmic'] input[type='search'],
|
||||
html[data-theme='cosmic'] input[type='password'],
|
||||
html[data-theme='cosmic'] select,
|
||||
html[data-theme='cosmic'] textarea {
|
||||
background: var(--surface);
|
||||
border-color: var(--border-strong);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] input:focus,
|
||||
html[data-theme='cosmic'] select:focus,
|
||||
html[data-theme='cosmic'] textarea:focus {
|
||||
border-color: var(--focus);
|
||||
box-shadow: 0 0 0 2px var(--primary-soft);
|
||||
}
|
||||
|
||||
/* Cosmic code blocks */
|
||||
html[data-theme='cosmic'] code,
|
||||
html[data-theme='cosmic'] .mono {
|
||||
background: var(--surface-2);
|
||||
border-color: var(--border);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* Cosmic badges */
|
||||
html[data-theme='cosmic'] .badge {
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .badge-neutral {
|
||||
background: var(--surface-2);
|
||||
color: var(--text-muted);
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .badge-success {
|
||||
background: var(--success-soft);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .badge-warning {
|
||||
background: var(--warning-soft);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .badge-danger {
|
||||
background: var(--danger-soft);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .badge-info {
|
||||
background: var(--info-soft);
|
||||
color: var(--info);
|
||||
}
|
||||
|
||||
/* Cosmic modal */
|
||||
html[data-theme='cosmic'] .modal {
|
||||
background: var(--surface);
|
||||
border-color: var(--border);
|
||||
box-shadow: var(--shadow-modal);
|
||||
}
|
||||
|
||||
html[data-theme='cosmic'] .modal-backdrop {
|
||||
background: rgba(13, 10, 6, 0.8);
|
||||
}
|
||||
|
||||
/* Cosmic empty state */
|
||||
html[data-theme='cosmic'] .empty-state {
|
||||
background: var(--surface);
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
|
@ -1944,3 +2168,97 @@ select {
|
|||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Motion system
|
||||
Purposeful motion for feedback, state, and continuity.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@keyframes modal-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.96) translateY(8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes modal-backdrop-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes alert-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-6px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes undo-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
animation: modal-backdrop-enter 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.modal {
|
||||
animation: modal-enter 220ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.alert {
|
||||
animation: alert-enter 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.undo-bar {
|
||||
animation: undo-enter 250ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.btn:active:not(:disabled) {
|
||||
transform: scale(0.97);
|
||||
transition: transform 80ms ease;
|
||||
}
|
||||
|
||||
.profile-card:active:not(.is-active) {
|
||||
transform: scale(0.985);
|
||||
transition: transform 100ms ease;
|
||||
}
|
||||
|
||||
.nav-item:active {
|
||||
transform: scale(0.98);
|
||||
transition: transform 80ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.modal-backdrop,
|
||||
.modal,
|
||||
.alert,
|
||||
.undo-bar {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.btn:active:not(:disabled),
|
||||
.profile-card:active:not(.is-active),
|
||||
.nav-item:active {
|
||||
transform: none;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ pub enum Theme {
|
|||
Impeccable,
|
||||
#[serde(rename = "impeccable-dark")]
|
||||
ImpeccableDark,
|
||||
Cosmic,
|
||||
}
|
||||
|
||||
impl Theme {
|
||||
|
|
@ -39,6 +40,7 @@ impl Theme {
|
|||
"neon" => Some(Self::Neon),
|
||||
"impeccable" => Some(Self::Impeccable),
|
||||
"impeccable-dark" => Some(Self::ImpeccableDark),
|
||||
"cosmic" => Some(Self::Cosmic),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue