mirror of
https://github.com/hectorqin/reader.git
synced 2026-11-12 22:11:03 +08:00
Implements docs/prototypes/Reader V3 主题语义令牌.md (v3.1): - 暖陶 (default), 雾蓝, 青绿 app themes plus the reading-only 黑白灰, each light and dark. Components read --color-* tokens from styles/theme-tokens.css, selected by data-theme + data-mode; the TypeScript mirror lives in shared/theme/theme.ts. - Brand is split per the spec: brand/ch-* only fill (with on-brand/on-ch on top), brand-text/ch-*-text for text. --reader-accent/--media-accent are now brand text; --reader-fill/--media-fill are brand fills. Selected segmented controls use brand-soft + brand-text. - One preference per server+account (reader.theme.v2): app theme, mode (system/light/dark), the follow-system light/dark pair, and the reading theme. V3 choices migrate per spec §8 (rose falls back to 暖陶 light). - 外观与主题 rebuilt from prototype 23: follow-system switch with the light/dark pair, app-theme cards with light/dark previews, and the reading theme (跟随应用 / 黑白灰). - Reader: 黑白灰 is set on the reader container only; the appearance panel offers 跟随应用/黑白灰 and 明暗; day/night sets the mode; the e-ink preset uses 黑白灰 light. - Video and music players wear the current theme's dark values (§4.7). - Removed the legacy light/sepia/green/dark palettes and the <html data-theme> writes from reader settings, which would now collide with data-theme="green". - Tests: theme-tokens.test.ts keeps CSS and TS values identical and checks the §5 contrast pairs for all 8 palettes; theme.test.tsx covers migration, resolution, the controller and the settings page.
44 lines
2.3 KiB
CSS
44 lines
2.3 KiB
CSS
/* Notyf owns the global stack; the app supplies its palette and compact sizing. */
|
|
body .notyf {
|
|
padding: max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
|
|
gap: .5rem;
|
|
font: inherit;
|
|
}
|
|
.notyf .global-notice {
|
|
width: fit-content;
|
|
max-width: min(28rem, calc(100vw - 2rem));
|
|
max-height: min(16rem, calc(100dvh - 2rem));
|
|
overflow: auto;
|
|
margin: 0;
|
|
padding: .65rem .8rem .65rem 1rem;
|
|
border: 1px solid var(--reader-line);
|
|
border-radius: .85rem;
|
|
color: var(--reader-ink);
|
|
box-shadow: 0 6px 24px #00000014;
|
|
font-size: .82rem;
|
|
text-align: start;
|
|
pointer-events: none;
|
|
animation-duration: .15s;
|
|
}
|
|
.global-notice .notyf__wrapper { gap: .65rem; padding: 0; }
|
|
.global-notice .notyf__message { min-width: 0; overflow-wrap: anywhere; white-space: pre-wrap; animation: none; opacity: 1; }
|
|
.global-notice .notyf__dismiss { position: relative; width: 32px; height: 32px; margin: 0; flex: none; animation: none; opacity: 1; }
|
|
.global-notice .notyf__dismiss-btn { padding: 0; border-radius: .5rem; color: var(--reader-muted); background: transparent; opacity: 1; pointer-events: auto; }
|
|
.global-notice .notyf__dismiss-btn::before, .global-notice .notyf__dismiss-btn::after { background: currentColor; }
|
|
.global-notice .notyf__dismiss-btn:hover { background: var(--reader-line); }
|
|
.global-notice .notyf__dismiss-btn:focus-visible { outline: 2px solid var(--reader-accent); outline-offset: 2px; }
|
|
.global-notice[data-kind='error'] { color: #a32c22; }
|
|
[data-mode='dark'] .global-notice[data-kind='error'] { color: #ffaaa0; }
|
|
.global-notice[data-kind='success'] { color: #326c46; }
|
|
[data-mode='dark'] .global-notice[data-kind='success'] { color: #9dd9ac; }
|
|
.global-notice[data-kind='loading'] .notyf__wrapper::before {
|
|
content: ''; width: 14px; height: 14px; flex: none; border: 2px solid var(--reader-line);
|
|
border-top-color: var(--reader-accent); border-radius: 50%; animation: notice-spin .8s linear infinite;
|
|
}
|
|
.notyf .notyf__toast--disappear { pointer-events: none; animation-delay: 0s; }
|
|
@keyframes notice-spin { to { transform: rotate(360deg); } }
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.notyf .global-notice { animation-duration: .001ms; }
|
|
.global-notice[data-kind='loading'] .notyf__wrapper::before { animation: none; }
|
|
}
|