feat(reader): shortcuts help modal + desktop edge page-turn zones
Help menu (the reader had a growing shortcut/gesture vocabulary with no discoverability): a ? topbar button, the '?' key, and F1 open a glass modal listing navigation, zoom/pan, highlight, and touch gesture reference — format-aware (fixed-layout/PDF rows appear only where they apply), Esc closes it first in the dismiss chain. Desktop edge zones: clickable page-turn strips on the left/right viewport edges (8% width, 44-72px), desktop only (hover+fine-pointer media query — touch devices use tap zones, avoiding double paging). Hovering reveals a chevron arrow and a subtle edge gradient. Zones disable (pointer-events pass-through) while a fixed-layout page is zoomed so edge clicks belong to content: panning, selection, highlight editing. fxZoomed tracks zoom state via the renderer zoom event, reset/fit actions, and init.
This commit is contained in:
@@ -1074,6 +1074,144 @@
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* Desktop edge page-turn zones: only on hover-capable fine-pointer
|
||||
devices (touch uses tap zones instead). Arrow + subtle edge gradient
|
||||
appear on hover. */
|
||||
.reader-edge-zone {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 8%;
|
||||
max-width: 72px;
|
||||
min-width: 44px;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.reader-edge-zone.left {
|
||||
left: 0;
|
||||
justify-content: flex-start;
|
||||
padding-left: 0.75rem;
|
||||
}
|
||||
.reader-edge-zone.right {
|
||||
right: 0;
|
||||
justify-content: flex-end;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
.reader-edge-zone::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
.reader-edge-zone.left::before {
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0.08), transparent);
|
||||
}
|
||||
.reader-edge-zone.right::before {
|
||||
background: linear-gradient(to left, rgba(255, 255, 255, 0.08), transparent);
|
||||
}
|
||||
.reader-edge-zone .reader-icon {
|
||||
color: #ffffff;
|
||||
filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
.reader-edge-zone:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
.reader-edge-zone:hover .reader-icon {
|
||||
opacity: 0.85;
|
||||
}
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.reader-edge-zone {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shortcuts help modal */
|
||||
.reader-help-backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 70;
|
||||
}
|
||||
.reader-help {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: min(34rem, calc(100vw - 2rem));
|
||||
max-height: min(38rem, calc(100vh - 4rem));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: color-mix(in srgb, var(--bg-primary) 90%, transparent);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(1.3);
|
||||
backdrop-filter: blur(20px) saturate(1.3);
|
||||
border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
|
||||
border-radius: 0.875rem;
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
|
||||
z-index: 71;
|
||||
}
|
||||
.reader-help-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.875rem 1.25rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.reader-help-body {
|
||||
overflow-y: auto;
|
||||
padding: 1rem 1.25rem;
|
||||
}
|
||||
.reader-help-section {
|
||||
font-size: 0.7rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--text-secondary);
|
||||
margin: 1.1rem 0 0.4rem;
|
||||
}
|
||||
.reader-help-body .reader-help-section:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.help-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 0.3rem 0;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.help-row > span:first-child {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.help-keys {
|
||||
text-align: right;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.8rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.help-note {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.kbd {
|
||||
display: inline-block;
|
||||
min-width: 1.4rem;
|
||||
text-align: center;
|
||||
padding: 0.05rem 0.4rem;
|
||||
margin: 0 0.1rem;
|
||||
border-radius: 0.3rem;
|
||||
border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
|
||||
border-bottom-width: 2px;
|
||||
background-color: color-mix(in srgb, currentColor 8%, transparent);
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.72rem;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
|
||||
/* In-book search */
|
||||
.reader-search-bar {
|
||||
display: flex;
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user