Dieselben verschlüsselten Listen wie der Web-Reader (annotations.py). Die Anker des Webs (Block-Index plus Zeichenposition im Rohtext) werden auf den angezeigten Text umgerechnet (marks.py, blocks.collapse_map), alte XPath-Anker über das Zitat gefunden. Im Reader: v markiert (Cursor je Wort, Anfang/Ende, Farbe oder Notiz), n legt eine Notiz an, b ein Lesezeichen, a öffnet die Liste (springen, Notiz ändern, löschen). Der Server ersetzt die Liste als Ganzes; die TUI legt ihre Änderungen vor dem Schreiben dreiwege je Eintrag-ID auf die aktuelle Liste des Servers, offline bleiben sie vorgemerkt. Geprüft: die echten resolveAnchorRange des Webs lösen 81 TUI-Anker exakt auf (tools/parity/web_anchors.cjs), 34 von 34 echten Web-Markierungen werden angezeigt, der Server-Smoke schreibt und mischt zwei Geräte. 75 Tests. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
161 lines
2.1 KiB
Text
161 lines
2.1 KiB
Text
#library-list {
|
|
height: 1fr;
|
|
}
|
|
|
|
#lib-chips {
|
|
height: auto;
|
|
padding: 0 1;
|
|
}
|
|
|
|
#lib-search {
|
|
margin: 0 1;
|
|
}
|
|
|
|
#lib-card {
|
|
height: auto;
|
|
margin: 1 1 0 1;
|
|
padding: 0 2;
|
|
border: round $primary;
|
|
}
|
|
|
|
#lib-note {
|
|
height: auto;
|
|
padding: 0 2;
|
|
color: $text-muted;
|
|
}
|
|
|
|
ChoiceScreen {
|
|
align: center middle;
|
|
}
|
|
|
|
#choice-title {
|
|
width: 50;
|
|
background: $panel;
|
|
padding: 0 2;
|
|
text-style: bold;
|
|
}
|
|
|
|
#choice-list {
|
|
width: 50;
|
|
height: auto;
|
|
max-height: 70%;
|
|
border: round $primary;
|
|
}
|
|
|
|
StatusBar {
|
|
dock: bottom;
|
|
height: 1;
|
|
padding: 0 1;
|
|
background: $panel;
|
|
color: $text-muted;
|
|
text-align: right;
|
|
}
|
|
|
|
#reader-scroll {
|
|
height: 1fr;
|
|
padding: 1 2;
|
|
align-horizontal: center;
|
|
}
|
|
|
|
#reader-loading {
|
|
height: 1fr;
|
|
}
|
|
|
|
FootnoteScreen {
|
|
align: center middle;
|
|
}
|
|
|
|
#footnote-body {
|
|
width: 80%;
|
|
max-width: 100;
|
|
height: auto;
|
|
max-height: 80%;
|
|
background: $panel;
|
|
border: round $primary;
|
|
padding: 1 2;
|
|
}
|
|
|
|
.footnote-note {
|
|
margin-bottom: 1;
|
|
}
|
|
|
|
#footnote-hint {
|
|
dock: bottom;
|
|
width: 80%;
|
|
max-width: 100;
|
|
background: $panel;
|
|
color: $text-muted;
|
|
padding: 0 2;
|
|
}
|
|
|
|
JumpOfferScreen {
|
|
align: center middle;
|
|
}
|
|
|
|
#offer-body {
|
|
width: 60;
|
|
height: auto;
|
|
background: $panel;
|
|
border: round $primary;
|
|
padding: 1 2;
|
|
}
|
|
|
|
#offer-hint {
|
|
margin-top: 1;
|
|
color: $text-muted;
|
|
}
|
|
|
|
NoteScreen {
|
|
align: center middle;
|
|
}
|
|
|
|
#note-body {
|
|
width: 70;
|
|
height: auto;
|
|
background: $panel;
|
|
border: round $primary;
|
|
padding: 1 2;
|
|
}
|
|
|
|
#note-title {
|
|
text-style: bold;
|
|
margin-bottom: 1;
|
|
}
|
|
|
|
#note-hint {
|
|
color: $text-muted;
|
|
margin-top: 1;
|
|
}
|
|
|
|
AnnotationsScreen {
|
|
align: center middle;
|
|
}
|
|
|
|
#ann-body {
|
|
width: 90%;
|
|
max-width: 110;
|
|
height: 80%;
|
|
background: $panel;
|
|
border: round $primary;
|
|
padding: 1 2;
|
|
}
|
|
|
|
#ann-title {
|
|
text-style: bold;
|
|
}
|
|
|
|
#ann-list {
|
|
height: 1fr;
|
|
}
|
|
|
|
#ann-detail {
|
|
height: auto;
|
|
max-height: 6;
|
|
color: $text-muted;
|
|
margin-top: 1;
|
|
}
|
|
|
|
#ann-hint {
|
|
color: $text-muted;
|
|
margin-top: 1;
|
|
}
|