Files
pictureFrame-webApp/frontend/src/styles/design-v2.scss
T
2026-05-15 15:59:40 -04:00

198 lines
7.2 KiB
SCSS

// ─── Design v2 — SPA-specific component styles ──────────────────────────
// Tokens (CSS vars), font imports, base body bg, and Twig-template overrides
// live in /public/css/wevisto-design.css — loaded by both Twig and the SPA so
// changing a v2 color flows everywhere.
//
// This file holds only the SPA-specific compositions: side rail, frame card,
// library/settings inner styling, theme swatches.
[data-design="v2"] {
// ── TopNav: shown at ALL sizes in v2 (v1 hides it below 960px).
// Mobile/tablet → slim horizontal top bar (~52px) with brand only.
// Desktop → left side rail (overrides below).
.top-nav {
display: flex !important; // beat v1 scoped style's `display: none`
align-items: center;
gap: var(--space-3);
height: 52px;
padding: 0 var(--space-4);
padding-top: env(safe-area-inset-top);
background: color-mix(in srgb, var(--color-bg) 90%, transparent);
backdrop-filter: saturate(160%) blur(18px);
-webkit-backdrop-filter: saturate(160%) blur(18px);
border-bottom-color: var(--color-border);
&__wordmark { color: var(--color-text); font-family: var(--font-display-v2); font-weight: 400; }
&__sub { display: block !important; font-family: var(--font-accent-v2); }
// Hide the nav tabs at mobile/tablet — the bottom nav handles routing
&__tabs { display: none !important; }
&__tab {
color: var(--color-text-muted);
&:hover { background: var(--color-surface); color: var(--color-text); }
&--active { background: var(--color-surface); color: var(--brand-yellow); }
}
}
// Push main content below the mobile/tablet top bar
@media (max-width: 959px) {
.top-nav { position: sticky; top: 0; z-index: 30; }
main { padding-top: var(--space-3); }
}
@media (min-width: 960px) {
.top-nav {
position: fixed;
top: 0; left: 0; bottom: 0;
width: 240px;
height: auto;
flex-direction: column;
align-items: stretch;
gap: 0;
padding: 28px 18px 24px;
padding-top: calc(28px + env(safe-area-inset-top));
background: color-mix(in srgb, var(--color-bg) 96%, transparent);
border-right: 1px solid var(--color-border);
border-bottom: 0;
z-index: 50;
&__brand {
padding-bottom: 20px;
margin-bottom: 16px;
border-bottom: 1px solid var(--color-border);
align-items: flex-start;
}
&__mark {
width: 44px !important;
height: 44px !important;
border-radius: 10px !important;
}
&__wordmark { font-size: var(--text-xl); font-family: var(--font-display-v2); font-weight: 400; }
// !important needed because TopNav's scoped style hides these by default
// at the same specificity and cascades after the main bundle.
&__sub {
display: block !important;
font-family: var(--font-accent-v2);
}
&__tabs {
display: flex !important; // re-show at desktop (mobile/tablet had display:none)
flex: 0 0 auto !important;
flex-direction: column;
gap: 4px;
align-items: stretch;
margin-left: 0;
}
&__tab {
width: 100%;
justify-content: flex-start;
padding: 12px 14px;
gap: 12px;
border-radius: var(--radius-md);
&--active {
background: var(--color-surface);
box-shadow: inset 3px 0 0 var(--brand-yellow);
}
}
}
body { padding-left: 240px; }
}
.bottom-nav {
background: color-mix(in srgb, var(--color-bg) 95%, transparent);
border-top-color: var(--color-border);
.bottom-nav__tab--active { color: var(--brand-yellow); }
}
// ── Glass cards everywhere v1 uses --color-surface ─────────────────
.frame-card,
.home-view__empty-card,
.library__tile,
.settings__section-card {
background: var(--color-surface);
border-color: var(--color-border);
box-shadow:
0 1px 0 color-mix(in srgb, var(--color-text) 8%, transparent) inset,
0 24px 48px -16px rgba(0,0,0,0.6);
}
.frame-card__hero { background: var(--color-surface-2); }
.frame-card__name {
font-family: var(--font-display-v2);
font-weight: 400;
font-size: var(--text-xl);
}
.home-view__empty-title { font-family: var(--font-display-v2); }
.library__add-btn { background: var(--color-primary); color: var(--color-primary-fg); }
// ── Settings polish ────────────────────────────────────────────────
.settings {
&__title { font-family: var(--font-display-v2); font-weight: 400; letter-spacing: 0.005em; }
&__section-title {
font-family: var(--font-mono-v2);
font-size: 11px;
letter-spacing: 0.28em;
color: var(--color-text-muted);
}
&__hint {
font-family: var(--font-accent-v2);
font-style: italic;
color: var(--color-text-muted);
}
&__install { color: var(--color-primary-fg); font-weight: 700; }
&__row,
&__action-link { border-color: var(--color-border); }
&__row-label { color: var(--color-text-muted); }
&__row-value,
&__action-link { color: var(--color-text); }
&__logout { color: var(--color-destructive); }
}
.design-toggle__opt {
background: var(--color-surface);
border-color: var(--color-border);
color: var(--color-text);
&--active { border-color: var(--brand-yellow); background: var(--color-surface-2); }
}
.design-toggle__sub { color: var(--color-text-muted); }
// ── Theme swatches preview their dusk via the harbor.jpg ───────────
// `!important` needed because Vue's scoped style on SettingsView
// (.theme-swatch__preview[data-v-xxx] { background: var(--swatch-bg) })
// ties on specificity and cascades later. v2 is opt-in so overriding is OK.
.theme-swatch {
border-color: var(--color-border);
background: var(--color-surface) !important;
color: var(--color-text);
&--active { border-color: var(--brand-yellow); }
&__label { color: var(--color-text); }
&__preview {
background: transparent !important;
background-image: url('/build/assets/harbor.jpg') !important;
background-size: cover !important;
background-position: center !important;
position: relative;
overflow: hidden;
&::after {
content: '';
position: absolute; inset: 0;
mix-blend-mode: multiply;
}
}
}
.theme-swatch[aria-label*="Warm Craft" i] .theme-swatch__preview::after { background: rgba(60, 25, 8, 0.55); }
.theme-swatch[aria-label*="Ocean Dusk" i] .theme-swatch__preview::after { background: rgba(8, 22, 38, 0.55); }
.theme-swatch[aria-label*="Sage" i] .theme-swatch__preview::after { background: rgba(20, 40, 22, 0.55); }
.theme-swatch[aria-label*="Playful" i] .theme-swatch__preview::after { background: rgba(56, 16, 38, 0.55); }
.theme-swatch[aria-label*="Dusty" i] .theme-swatch__preview::after { background: rgba(40, 18, 56, 0.55); }
.theme-swatch[aria-label*="Honey" i] .theme-swatch__preview::after { background: rgba(48, 36, 14, 0.55); }
.theme-swatch__bar,
.theme-swatch__dot { display: none; }
}