sol-components 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/core/activate.js +27 -0
- package/core/adopt.js +71 -0
- package/core/auth-core.js +73 -0
- package/core/auth-fetch.js +154 -0
- package/core/component-mount.js +110 -0
- package/core/defaults.js +48 -0
- package/core/define.js +15 -0
- package/core/display-target.js +166 -0
- package/core/edit-placements.js +28 -0
- package/core/editor-self.js +127 -0
- package/core/editor.js +162 -0
- package/core/events.js +27 -0
- package/core/extension-points.js +189 -0
- package/core/form-utils.js +210 -0
- package/core/from-query.js +138 -0
- package/core/from-rdf.js +52 -0
- package/core/here.js +33 -0
- package/core/include-core.js +73 -0
- package/core/inrupt-global.js +18 -0
- package/core/menu-consumer.js +41 -0
- package/core/menu-rdf.js +154 -0
- package/core/pod-ops.js +392 -0
- package/core/pod-registry.js +82 -0
- package/core/popup-proxy.js +255 -0
- package/core/rdf-core.js +280 -0
- package/core/rdf-render.js +136 -0
- package/core/rdf-utils.js +411 -0
- package/core/rdf.js +154 -0
- package/core/services.js +106 -0
- package/core/shape-to-form.js +741 -0
- package/core/sparql-safety.js +20 -0
- package/core/utils.js +196 -0
- package/dist/importmap-cdn.json +49 -0
- package/dist/importmap-local.json +49 -0
- package/dist/sol-loader.manifest.json +140 -0
- package/dist/vendor/@comunica-query-sparql.js +137851 -0
- package/dist/vendor/@inrupt-solid-client-authn-browser.js +7503 -0
- package/dist/vendor/dompurify.js +1476 -0
- package/dist/vendor/ical.js.js +9739 -0
- package/dist/vendor/marked.js +85 -0
- package/dist/vendor/n3.js +14670 -0
- package/dist/vendor/rdf-validate-shacl.js +6970 -0
- package/dist/vendor/rdflib.js +35172 -0
- package/dist/vendor/solid-logic.js +6819 -0
- package/dist/vendor/solid-ui.js +21945 -0
- package/node/sol-form.js +133 -0
- package/node/sol-include.js +55 -0
- package/node/sol-login.js +632 -0
- package/node/sol-menu.js +639 -0
- package/node/sol-query.js +116 -0
- package/package.json +133 -0
- package/web/menu-from-rdf.js +23 -0
- package/web/scripts/prefs.js +25 -0
- package/web/sol-accordion.js +114 -0
- package/web/sol-basic.js +50 -0
- package/web/sol-breadcrumb.js +131 -0
- package/web/sol-button.js +244 -0
- package/web/sol-calendar.js +465 -0
- package/web/sol-default.js +118 -0
- package/web/sol-dropdown-button.js +222 -0
- package/web/sol-feed.js +1336 -0
- package/web/sol-form.js +949 -0
- package/web/sol-full.js +43 -0
- package/web/sol-gallery.js +303 -0
- package/web/sol-include.js +246 -0
- package/web/sol-live-edit.js +415 -0
- package/web/sol-login.js +856 -0
- package/web/sol-menu.js +593 -0
- package/web/sol-modal.js +377 -0
- package/web/sol-pod-extras.js +17 -0
- package/web/sol-pod-ops.js +680 -0
- package/web/sol-pod.js +1039 -0
- package/web/sol-query.js +546 -0
- package/web/sol-rolodex.js +95 -0
- package/web/sol-search.js +402 -0
- package/web/sol-settings.js +199 -0
- package/web/sol-solidos.js +93 -0
- package/web/sol-tabs.js +445 -0
- package/web/sol-time.js +194 -0
- package/web/sol-tree-edit.js +492 -0
- package/web/sol-wac.js +456 -0
- package/web/sol-weather.js +337 -0
- package/web/sol-window.js +142 -0
- package/web/styles/buttons-css.js +108 -0
- package/web/styles/help.css +242 -0
- package/web/styles/root.css +112 -0
- package/web/styles/sol-accordion-css.js +97 -0
- package/web/styles/sol-calendar-css.js +154 -0
- package/web/styles/sol-feed-css.js +475 -0
- package/web/styles/sol-form-css.js +471 -0
- package/web/styles/sol-gallery-css.js +181 -0
- package/web/styles/sol-include-css.js +95 -0
- package/web/styles/sol-live-edit-css.js +84 -0
- package/web/styles/sol-live-edit.css +101 -0
- package/web/styles/sol-login-css.js +116 -0
- package/web/styles/sol-menu-css.js +145 -0
- package/web/styles/sol-modal-css.js +134 -0
- package/web/styles/sol-pod-css.js +187 -0
- package/web/styles/sol-pod-modal-css.js +203 -0
- package/web/styles/sol-query-css.js +140 -0
- package/web/styles/sol-query-help.css +267 -0
- package/web/styles/sol-query-one-pager.css +67 -0
- package/web/styles/sol-search-css.js +157 -0
- package/web/styles/sol-solidos-css.js +7 -0
- package/web/styles/sol-tabs-css.js +114 -0
- package/web/styles/sol-time-css.js +30 -0
- package/web/styles/sol-wac-css.js +73 -0
- package/web/styles/sol-weather-css.js +59 -0
- package/web/styles/solid-logo.svg +9 -0
- package/web/styles/view-accordion-css.js +66 -0
- package/web/styles/view-anchorlist-css.js +22 -0
- package/web/styles/view-autocomplete-css.js +59 -0
- package/web/styles/view-rolodex-css.js +102 -0
- package/web/styles/view-select-css.js +21 -0
- package/web/utils/calendar-fetch.js +388 -0
- package/web/utils/code-mirror-editor.js +82 -0
- package/web/utils/commons-fetch.js +108 -0
- package/web/utils/feed-edit.js +159 -0
- package/web/utils/feed-edit.smoke.mjs +74 -0
- package/web/utils/feed-fetch.js +573 -0
- package/web/utils/live-edit-help/csv.js +64 -0
- package/web/utils/live-edit-help/graphviz.js +41 -0
- package/web/utils/live-edit-help/jsonld.js +55 -0
- package/web/utils/live-edit-help/markdown.js +52 -0
- package/web/utils/live-edit-help/mermaid.js +48 -0
- package/web/utils/live-edit-help/turtle.js +85 -0
- package/web/utils/rdf-config.js +125 -0
- package/web/utils/renderers/csv.js +124 -0
- package/web/utils/renderers/d3-force.js +82 -0
- package/web/utils/renderers/graphviz.js +13 -0
- package/web/utils/renderers/html.js +10 -0
- package/web/utils/renderers/jsonld.js +63 -0
- package/web/utils/renderers/markdown.js +19 -0
- package/web/utils/renderers/mermaid.js +54 -0
- package/web/utils/renderers/turtle.js +51 -0
- package/web/utils/sol-query-triple-patterns.js +151 -0
- package/web/utils/sol-query-ui.js +250 -0
- package/web/utils/sol-query-views.js +32 -0
- package/web/views/_helpers.js +34 -0
- package/web/views/accordion.js +133 -0
- package/web/views/anchorlist.js +59 -0
- package/web/views/auto-complete.js +183 -0
- package/web/views/dl.js +38 -0
- package/web/views/list.js +19 -0
- package/web/views/menu.js +56 -0
- package/web/views/rolodex.js +126 -0
- package/web/views/select.js +79 -0
- package/web/views/table.js +73 -0
- package/web/views/tabs.js +57 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
// Styles for <sol-feed>'s shadow root. Exports the raw `CSS` string plus a
|
|
2
|
+
// constructable `sheet` (null in non-DOM envs) — the same shape as the
|
|
3
|
+
// other web/styles/*-css.js modules. All colours and metrics reference the
|
|
4
|
+
// shared design tokens so the component themes with the rest of the suite.
|
|
5
|
+
import { sheetFrom } from '../../core/adopt.js';
|
|
6
|
+
|
|
7
|
+
export const CSS = `
|
|
8
|
+
:host {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
/* Respect whatever height the container gives us; with no container
|
|
12
|
+
height, fall back to this viewport cap. Either way the article list
|
|
13
|
+
scrolls inside the component and never overflows its container. */
|
|
14
|
+
height: 100%;
|
|
15
|
+
max-height: 100vh;
|
|
16
|
+
font-family: var(--font-ui, system-ui, -apple-system, sans-serif);
|
|
17
|
+
font-size: var(--font-size, 20px);
|
|
18
|
+
color: var(--text, #212121);
|
|
19
|
+
}
|
|
20
|
+
* { box-sizing: border-box; }
|
|
21
|
+
|
|
22
|
+
/* The component owns its own scrolling: each view puts the scrollbar on
|
|
23
|
+
its own list/grid, so the status line and news picker stay pinned. */
|
|
24
|
+
.sol-feed { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
|
|
25
|
+
|
|
26
|
+
/* ── status / loading / empty ───────────────────────────────────────── */
|
|
27
|
+
.sol-feed-status {
|
|
28
|
+
flex: 0 0 auto;
|
|
29
|
+
padding: .5rem .75rem;
|
|
30
|
+
color: var(--text-muted, #7f8c8d);
|
|
31
|
+
font-size: .85em;
|
|
32
|
+
}
|
|
33
|
+
.sol-feed-status[data-error] { color: var(--error, #e74c3c); }
|
|
34
|
+
.sol-feed-empty {
|
|
35
|
+
padding: 1rem .75rem;
|
|
36
|
+
color: var(--text-muted, #7f8c8d);
|
|
37
|
+
font-style: italic;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* ── feed + topic link lists ─────────────────────────────────────────── */
|
|
41
|
+
/* Both feed and topic stack vertically and fill the host. Topic puts a
|
|
42
|
+
fixed-height source pane on top (~5 entries, scrolling for more) and
|
|
43
|
+
the article list below. */
|
|
44
|
+
.sol-feed-list {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
flex: 1 1 auto;
|
|
48
|
+
min-height: 0;
|
|
49
|
+
}
|
|
50
|
+
.sol-feed-list.feed { gap: 0; }
|
|
51
|
+
.sol-feed-list.topic { gap: .9rem; }
|
|
52
|
+
|
|
53
|
+
.feed-sources,
|
|
54
|
+
.feed-items {
|
|
55
|
+
margin: 0;
|
|
56
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
57
|
+
border-radius: 6px;
|
|
58
|
+
background: var(--surface, #fff);
|
|
59
|
+
}
|
|
60
|
+
/* Topic view: a touch darker border so the two floating panels stand
|
|
61
|
+
apart from the page; the slightly taller .9rem gap above gives them
|
|
62
|
+
breathing room. */
|
|
63
|
+
.sol-feed-list.topic .feed-sources,
|
|
64
|
+
.sol-feed-list.topic .feed-items { border-color: #6e6e6e; }
|
|
65
|
+
/* topic: the sources pane shows ~5 entries; the rest scroll inside it */
|
|
66
|
+
.feed-sources { flex: 0 0 11rem; overflow: auto; }
|
|
67
|
+
/* the articles list fills whatever height is left in the column */
|
|
68
|
+
.feed-items {
|
|
69
|
+
list-style: none;
|
|
70
|
+
padding: 0;
|
|
71
|
+
flex: 1 1 auto;
|
|
72
|
+
min-height: 0;
|
|
73
|
+
overflow: auto;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.feed-source-list { list-style: none; margin: 0; padding: 0; }
|
|
77
|
+
.feed-source-list li + li,
|
|
78
|
+
.feed-items li + li { border-top: 1px solid var(--border, #eee); }
|
|
79
|
+
|
|
80
|
+
.feed-link {
|
|
81
|
+
display: block;
|
|
82
|
+
padding: .45rem .7rem;
|
|
83
|
+
/* Article and source links use the theme's link colour (themed
|
|
84
|
+
in root.css for light + dark), with --accent as the legacy
|
|
85
|
+
fallback for pages that load sol-feed without root.css. */
|
|
86
|
+
color: var(--link, var(--accent, #2980b9));
|
|
87
|
+
text-decoration: none;
|
|
88
|
+
line-height: 1.35;
|
|
89
|
+
}
|
|
90
|
+
.feed-link:hover { background: var(--hover, #eaf2fb); text-decoration: underline; }
|
|
91
|
+
.feed-link.selected {
|
|
92
|
+
background: var(--focus-bg, #ebf5fb);
|
|
93
|
+
/* Text on the selection fill. Defaults to the normal link colour so
|
|
94
|
+
existing consumers are unchanged; hosts that tint --focus-bg with
|
|
95
|
+
a strong colour can set --selected-fg for a readable contrast. */
|
|
96
|
+
color: var(--selected-fg, var(--link, var(--accent, #2980b9)));
|
|
97
|
+
font-weight: 600;
|
|
98
|
+
}
|
|
99
|
+
.feed-link .feed-link-meta {
|
|
100
|
+
display: block;
|
|
101
|
+
font-size: .72em;
|
|
102
|
+
color: var(--text-muted, #7f8c8d);
|
|
103
|
+
font-weight: 400;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* ── topics view ─────────────────────────────────────────────────────── */
|
|
107
|
+
/* A "newsstand": one column per topic across the top (each listing its
|
|
108
|
+
sources), with the shared .feed-articles card grid below. The columns
|
|
109
|
+
band reuses the all-view's darker top-bar tint; together with the
|
|
110
|
+
lighter articles strip they read as one two-tone panel. */
|
|
111
|
+
.sol-feed-list.topics { gap: 0; }
|
|
112
|
+
.feed-topic-columns {
|
|
113
|
+
flex: 0 0 auto;
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-wrap: wrap;
|
|
116
|
+
align-items: flex-start;
|
|
117
|
+
gap: .6rem;
|
|
118
|
+
padding: .8rem .9rem;
|
|
119
|
+
background: var(--feed-top-bar-bg,
|
|
120
|
+
color-mix(in srgb, var(--bg, #f5f5f5) 75%, #000));
|
|
121
|
+
border-radius: var(--radius-md, 6px) var(--radius-md, 6px) 0 0;
|
|
122
|
+
}
|
|
123
|
+
.feed-topic-column {
|
|
124
|
+
flex: 1 1 12rem;
|
|
125
|
+
min-width: 0;
|
|
126
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
127
|
+
border-radius: 6px;
|
|
128
|
+
background: var(--surface, #fff);
|
|
129
|
+
display: flex;
|
|
130
|
+
flex-direction: column;
|
|
131
|
+
overflow: hidden;
|
|
132
|
+
}
|
|
133
|
+
.feed-topic-head {
|
|
134
|
+
margin: 0;
|
|
135
|
+
padding: .4rem .7rem;
|
|
136
|
+
font-size: .74em;
|
|
137
|
+
font-weight: 700;
|
|
138
|
+
text-transform: uppercase;
|
|
139
|
+
letter-spacing: .04em;
|
|
140
|
+
color: var(--text-muted, #7f8c8d);
|
|
141
|
+
border-bottom: 1px solid var(--border, #d0d0d0);
|
|
142
|
+
}
|
|
143
|
+
/* Caps each column ~6 sources tall; the rest scroll within the column. */
|
|
144
|
+
.feed-topic-col-list { max-height: 14rem; overflow: auto; }
|
|
145
|
+
|
|
146
|
+
/* News cards: shorter boxes; the title tracks the host font size
|
|
147
|
+
(1em = --font-size, set by the text-size setter) rather than the
|
|
148
|
+
all-view's smaller .88em. Scoped to topics so other views are
|
|
149
|
+
unchanged. */
|
|
150
|
+
.sol-feed-list.topics .feed-card { aspect-ratio: 9 / 4; }
|
|
151
|
+
.sol-feed-list.topics .feed-card-title {
|
|
152
|
+
font-size: 1em;
|
|
153
|
+
-webkit-line-clamp: 3;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* ── all view ───────────────────────────────────────────────────────── */
|
|
157
|
+
/* Two-tone defaults: a darker strip behind the top-bar (controls)
|
|
158
|
+
and a lighter strip behind the articles grid, both relative to
|
|
159
|
+
the page --bg via color-mix. Override via
|
|
160
|
+
--feed-top-bar-bg / --feed-articles-bg (or by re-styling the
|
|
161
|
+
"top-bar" / "articles" shadow parts from outside) when the
|
|
162
|
+
defaults don't suit. The two strips sit flush so they read as
|
|
163
|
+
one continuous two-tone panel, rounded at the outer corners. */
|
|
164
|
+
.feed-top-bar {
|
|
165
|
+
flex: 0 0 auto;
|
|
166
|
+
display: flex;
|
|
167
|
+
align-items: center;
|
|
168
|
+
gap: .6rem;
|
|
169
|
+
margin: 0;
|
|
170
|
+
padding: .8rem .9rem;
|
|
171
|
+
background: var(--feed-top-bar-bg,
|
|
172
|
+
color-mix(in srgb, var(--bg, #f5f5f5) 75%, #000));
|
|
173
|
+
border-radius: var(--radius-md, 6px) var(--radius-md, 6px) 0 0;
|
|
174
|
+
}
|
|
175
|
+
.feed-source-buttons {
|
|
176
|
+
flex: 1 1 auto;
|
|
177
|
+
display: flex;
|
|
178
|
+
flex-wrap: wrap;
|
|
179
|
+
gap: .35rem;
|
|
180
|
+
min-width: 0;
|
|
181
|
+
}
|
|
182
|
+
.feed-source-btn {
|
|
183
|
+
font: inherit;
|
|
184
|
+
font-size: .85em;
|
|
185
|
+
padding: .3rem .9rem;
|
|
186
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
187
|
+
border-radius: 999px;
|
|
188
|
+
background: var(--surface, #fff);
|
|
189
|
+
color: var(--text, #212121);
|
|
190
|
+
cursor: pointer;
|
|
191
|
+
white-space: nowrap;
|
|
192
|
+
}
|
|
193
|
+
.feed-source-btn:hover { background: var(--hover, #eaf2fb); }
|
|
194
|
+
.feed-source-btn.selected {
|
|
195
|
+
background: var(--accent, #3498db);
|
|
196
|
+
color: #fff;
|
|
197
|
+
border-color: var(--accent, #3498db);
|
|
198
|
+
}
|
|
199
|
+
.feed-source-btn:focus-visible {
|
|
200
|
+
outline: 2px solid var(--accent, #3498db);
|
|
201
|
+
outline-offset: 2px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.feed-picker-toggle {
|
|
205
|
+
font: inherit;
|
|
206
|
+
font-size: 1.2em;
|
|
207
|
+
line-height: 1;
|
|
208
|
+
padding: .25rem .5rem;
|
|
209
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
210
|
+
border-radius: 6px;
|
|
211
|
+
background: var(--surface, #fff);
|
|
212
|
+
color: var(--text, #212121);
|
|
213
|
+
cursor: pointer;
|
|
214
|
+
}
|
|
215
|
+
.feed-picker-toggle:hover { background: var(--hover, #eaf2fb); }
|
|
216
|
+
.feed-picker-toggle:focus-visible {
|
|
217
|
+
outline: 2px solid var(--accent, #3498db);
|
|
218
|
+
outline-offset: 2px;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Two-column picker: left = instruction + topic fieldsets; right = the
|
|
222
|
+
"add topic / add source" forms. */
|
|
223
|
+
.feed-picker {
|
|
224
|
+
flex: 0 0 auto;
|
|
225
|
+
align-self: center;
|
|
226
|
+
width: 100%;
|
|
227
|
+
max-width: 1280px;
|
|
228
|
+
display: grid;
|
|
229
|
+
/* left column carries the topic fieldsets — give it room so each
|
|
230
|
+
fieldset can fit several checkboxes side-by-side. */
|
|
231
|
+
grid-template-columns: 2fr 1fr;
|
|
232
|
+
gap: 1rem;
|
|
233
|
+
margin: 2rem 0 1rem;
|
|
234
|
+
}
|
|
235
|
+
.feed-picker[hidden] { display: none; }
|
|
236
|
+
.feed-picker-left,
|
|
237
|
+
.feed-picker-right { display: flex; flex-direction: column; gap: .55rem; min-width: 0; }
|
|
238
|
+
.feed-picker-instruct {
|
|
239
|
+
margin: 0;
|
|
240
|
+
font-style: italic;
|
|
241
|
+
color: var(--text-muted, #7f8c8d);
|
|
242
|
+
font-size: .9em;
|
|
243
|
+
}
|
|
244
|
+
.feed-picker-note {
|
|
245
|
+
margin: 0;
|
|
246
|
+
font-size: .75em;
|
|
247
|
+
color: var(--text-muted, #7f8c8d);
|
|
248
|
+
}
|
|
249
|
+
.feed-picker-note[data-error] { color: var(--error, #e74c3c); }
|
|
250
|
+
|
|
251
|
+
/* Add-topic / add-feed forms are <form>s wrapping a <fieldset>; the
|
|
252
|
+
fieldset carries the visible chrome so its legend sits on the top
|
|
253
|
+
border, matching the .feed-topic source-picker boxes. */
|
|
254
|
+
.feed-add-wrap { margin: 0; }
|
|
255
|
+
.feed-add-form {
|
|
256
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
257
|
+
border-radius: 6px;
|
|
258
|
+
background: var(--surface, #fff);
|
|
259
|
+
margin: 0;
|
|
260
|
+
padding: .2rem .8rem .55rem; /* match .feed-topic */
|
|
261
|
+
display: flex;
|
|
262
|
+
flex-direction: column;
|
|
263
|
+
gap: .35rem;
|
|
264
|
+
}
|
|
265
|
+
.feed-add-form legend {
|
|
266
|
+
font-size: .74em;
|
|
267
|
+
font-weight: 700;
|
|
268
|
+
text-transform: uppercase;
|
|
269
|
+
letter-spacing: .04em;
|
|
270
|
+
color: var(--text-muted, #7f8c8d);
|
|
271
|
+
padding: 0 .3rem;
|
|
272
|
+
}
|
|
273
|
+
.feed-add-form label {
|
|
274
|
+
display: flex;
|
|
275
|
+
flex-direction: column;
|
|
276
|
+
gap: .15rem;
|
|
277
|
+
font-size: .8em;
|
|
278
|
+
color: var(--text, #212121);
|
|
279
|
+
}
|
|
280
|
+
.feed-add-form input,
|
|
281
|
+
.feed-add-form select {
|
|
282
|
+
font: inherit;
|
|
283
|
+
font-size: .9em;
|
|
284
|
+
padding: .2rem .35rem;
|
|
285
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
286
|
+
border-radius: 4px;
|
|
287
|
+
background: var(--surface, #fff);
|
|
288
|
+
color: var(--text, #212121);
|
|
289
|
+
}
|
|
290
|
+
.feed-add-form button[type="submit"] {
|
|
291
|
+
align-self: flex-end;
|
|
292
|
+
font: inherit;
|
|
293
|
+
font-size: .8em;
|
|
294
|
+
padding: .25rem .8rem;
|
|
295
|
+
border: 1px solid var(--accent, #3498db);
|
|
296
|
+
border-radius: 6px;
|
|
297
|
+
background: var(--accent, #3498db);
|
|
298
|
+
color: #fff;
|
|
299
|
+
cursor: pointer;
|
|
300
|
+
margin-top: .15rem;
|
|
301
|
+
}
|
|
302
|
+
.feed-add-form button[type="submit"]:hover { filter: brightness(.94); }
|
|
303
|
+
.feed-topic {
|
|
304
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
305
|
+
border-radius: 6px;
|
|
306
|
+
background: var(--surface, #fff);
|
|
307
|
+
margin: 0;
|
|
308
|
+
padding: .2rem .8rem .5rem;
|
|
309
|
+
display: flex;
|
|
310
|
+
flex-wrap: wrap;
|
|
311
|
+
gap: .1rem 1.15rem;
|
|
312
|
+
}
|
|
313
|
+
.feed-topic legend {
|
|
314
|
+
font-size: .74em;
|
|
315
|
+
font-weight: 700;
|
|
316
|
+
text-transform: uppercase;
|
|
317
|
+
letter-spacing: .04em;
|
|
318
|
+
color: var(--text-muted, #7f8c8d);
|
|
319
|
+
padding: 0 .3rem;
|
|
320
|
+
}
|
|
321
|
+
.feed-topic label {
|
|
322
|
+
display: inline-flex;
|
|
323
|
+
align-items: center;
|
|
324
|
+
gap: .35rem;
|
|
325
|
+
font-size: .82em;
|
|
326
|
+
cursor: pointer;
|
|
327
|
+
padding: .1rem 0;
|
|
328
|
+
}
|
|
329
|
+
.feed-topic input { cursor: pointer; }
|
|
330
|
+
|
|
331
|
+
/* Articles container — a grid of horizontal cards for the active
|
|
332
|
+
feed. Sits flush against the top-bar above; together they form a
|
|
333
|
+
two-tone panel (darker strip / lighter strip) framed by rounded
|
|
334
|
+
outer corners. Override --feed-articles-bg to retint, or
|
|
335
|
+
re-style the "articles" shadow part from outside. */
|
|
336
|
+
.feed-articles {
|
|
337
|
+
flex: 1 1 auto;
|
|
338
|
+
min-height: 0;
|
|
339
|
+
overflow: auto;
|
|
340
|
+
display: grid;
|
|
341
|
+
grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
|
|
342
|
+
grid-auto-rows: min-content;
|
|
343
|
+
gap: 1rem;
|
|
344
|
+
padding: 1.4rem 1rem 1rem;
|
|
345
|
+
background: var(--feed-articles-bg,
|
|
346
|
+
color-mix(in srgb, var(--bg, #f5f5f5) 88%, #000));
|
|
347
|
+
border-radius: 0 0 var(--radius-md, 6px) var(--radius-md, 6px);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/* Horizontal card: image on the left, title on the right. The outer
|
|
351
|
+
dimensions are fixed so image-less cards keep the same footprint —
|
|
352
|
+
a coloured placeholder block stands in for the missing image. */
|
|
353
|
+
.feed-card {
|
|
354
|
+
display: flex;
|
|
355
|
+
flex-direction: row;
|
|
356
|
+
width: 17rem;
|
|
357
|
+
aspect-ratio: 3 / 2;
|
|
358
|
+
border-radius: 8px;
|
|
359
|
+
overflow: hidden;
|
|
360
|
+
background: var(--surface, #fff);
|
|
361
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
362
|
+
box-shadow: 0 1px 4px var(--shadow, rgba(0,0,0,0.08));
|
|
363
|
+
text-decoration: none;
|
|
364
|
+
color: var(--text, #212121);
|
|
365
|
+
}
|
|
366
|
+
.feed-card-img {
|
|
367
|
+
flex: 0 0 6rem;
|
|
368
|
+
width: 6rem;
|
|
369
|
+
height: 100%;
|
|
370
|
+
object-fit: cover;
|
|
371
|
+
display: block;
|
|
372
|
+
}
|
|
373
|
+
/* Stand-in for cards without an image, same size as .feed-card-img. */
|
|
374
|
+
.feed-card.no-image::before {
|
|
375
|
+
content: '';
|
|
376
|
+
flex: 0 0 6rem;
|
|
377
|
+
background: linear-gradient(135deg, var(--accent, #3498db), var(--accent-dark, #2980b9));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.feed-card-title {
|
|
381
|
+
flex: 1 1 auto;
|
|
382
|
+
margin: 0;
|
|
383
|
+
padding: .55rem .7rem;
|
|
384
|
+
font-family: var(--font-ui, system-ui, sans-serif);
|
|
385
|
+
font-size: .88em;
|
|
386
|
+
font-weight: 400;
|
|
387
|
+
line-height: 1.3;
|
|
388
|
+
/* Article titles are link text — use the theme's link colour
|
|
389
|
+
(themed in root.css for light + dark) so they read as clickable
|
|
390
|
+
even though the whole card is the click target. */
|
|
391
|
+
color: var(--link, var(--accent, #2980b9));
|
|
392
|
+
overflow: hidden;
|
|
393
|
+
display: -webkit-box;
|
|
394
|
+
-webkit-line-clamp: 5;
|
|
395
|
+
-webkit-box-orient: vertical;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* ── focus visibility ───────────────────────────────────────────────── */
|
|
399
|
+
.feed-link:focus-visible,
|
|
400
|
+
.feed-card:focus-visible,
|
|
401
|
+
.feed-topic input:focus-visible {
|
|
402
|
+
outline: 2px solid var(--accent, #3498db);
|
|
403
|
+
outline-offset: -2px;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/* ── editing affordances (view="topics" + [editable]) ────────────────── */
|
|
407
|
+
.feed-topic-headwrap { display: flex; align-items: center; gap: .25rem; }
|
|
408
|
+
.feed-topic-headwrap .feed-topic-head { flex: 1 1 auto; min-width: 0; }
|
|
409
|
+
.feed-topic-head.editable { cursor: text; border-radius: 4px; }
|
|
410
|
+
.feed-topic-head.editable:hover { background: var(--hover, rgba(0,0,0,.06)); }
|
|
411
|
+
.feed-add-source {
|
|
412
|
+
flex: 0 0 auto; width: 1.4em; height: 1.4em; line-height: 1; padding: 0;
|
|
413
|
+
border: 1px solid var(--border, #d0d0d0); border-radius: 5px; cursor: pointer;
|
|
414
|
+
background: var(--surface, #fff); color: var(--text-muted, #7f8c8d); font-size: .9em;
|
|
415
|
+
}
|
|
416
|
+
.feed-add-source:hover { background: var(--accent, #3498db); color: #fff; border-color: transparent; }
|
|
417
|
+
.feed-topic-rename {
|
|
418
|
+
width: 100%; font: inherit; font-weight: 700; padding: .15rem .3rem;
|
|
419
|
+
border: 1px solid var(--accent, #3498db); border-radius: 4px;
|
|
420
|
+
background: var(--bg, #fff); color: var(--text, #111);
|
|
421
|
+
}
|
|
422
|
+
.feed-add-form { display: flex; flex-direction: column; gap: .3rem; padding: .35rem .4rem; }
|
|
423
|
+
.feed-add-input {
|
|
424
|
+
font: inherit; font-size: .82em; padding: .3rem .4rem; border: 1px solid var(--border, #c0c0c0);
|
|
425
|
+
border-radius: 5px; background: var(--bg, #fff); color: var(--text, #111);
|
|
426
|
+
}
|
|
427
|
+
.feed-add-row { display: flex; gap: .3rem; }
|
|
428
|
+
.feed-add-row button {
|
|
429
|
+
font: inherit; font-size: .8em; padding: .25rem .6rem; border-radius: 5px; cursor: pointer;
|
|
430
|
+
border: 1px solid var(--border, #c0c0c0); background: var(--surface, #fff); color: inherit;
|
|
431
|
+
}
|
|
432
|
+
.feed-add-row button.primary { background: var(--accent, #3498db); color: #fff; border-color: transparent; }
|
|
433
|
+
|
|
434
|
+
.feed-source-list .editable-row { display: flex; align-items: center; gap: .15rem; }
|
|
435
|
+
.editable-row .feed-link { flex: 1 1 auto; min-width: 0; cursor: grab; }
|
|
436
|
+
.editable-row.dragging { opacity: .45; }
|
|
437
|
+
.feed-del {
|
|
438
|
+
flex: 0 0 auto; background: transparent; border: none; cursor: pointer; padding: 0 .25rem;
|
|
439
|
+
color: var(--text-muted, #9aa0a6); font-size: .85em; line-height: 1;
|
|
440
|
+
}
|
|
441
|
+
.feed-del:hover { color: var(--error, #e74c3c); }
|
|
442
|
+
.feed-topic-column.drop-target { outline: 2px dashed var(--accent, #3498db); outline-offset: -3px; border-radius: 6px; }
|
|
443
|
+
|
|
444
|
+
/* delete confirm (inline, replaces the row) */
|
|
445
|
+
.feed-del-confirm { display: flex; align-items: center; flex-wrap: wrap; gap: .3rem; padding: .15rem 0; width: 100%; }
|
|
446
|
+
.feed-del-q { flex: 1 1 100%; font-size: .8em; }
|
|
447
|
+
.feed-del-confirm button { font: inherit; font-size: .76em; padding: .15rem .55rem; border-radius: 5px; cursor: pointer; border: 1px solid var(--border, #c0c0c0); background: var(--surface, #fff); color: inherit; }
|
|
448
|
+
.feed-del-yes { background: var(--error, #e74c3c) !important; color: #fff !important; border-color: transparent !important; }
|
|
449
|
+
|
|
450
|
+
/* reorder insertion indicator (drop before/after a row) */
|
|
451
|
+
.editable-row.drop-before { box-shadow: inset 0 2px 0 0 var(--accent, #3498db); }
|
|
452
|
+
.editable-row.drop-after { box-shadow: inset 0 -2px 0 0 var(--accent, #3498db); }
|
|
453
|
+
|
|
454
|
+
/* deleted-bin view */
|
|
455
|
+
.feed-bin-bar { display: flex; align-items: center; gap: .8rem; padding: .5rem .7rem; border-bottom: 1px solid var(--border, #d0d0d0); }
|
|
456
|
+
.feed-bin-back { font: inherit; font-size: .85em; cursor: pointer; background: none; border: none; color: var(--link, #2980b9); padding: 0; }
|
|
457
|
+
.feed-bin-title { font-weight: 700; }
|
|
458
|
+
.feed-bin-list { padding: .5rem .7rem; }
|
|
459
|
+
.feed-bin-row { display: flex; align-items: center; gap: .5rem; padding: .25rem 0; }
|
|
460
|
+
.feed-bin-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
461
|
+
.feed-bin-restore-to { font: inherit; font-size: .82em; }
|
|
462
|
+
.feed-bin-restore {
|
|
463
|
+
font: inherit; font-size: .8em; padding: .2rem .6rem; border-radius: 5px; cursor: pointer;
|
|
464
|
+
border: 1px solid var(--border, #c0c0c0); background: var(--surface, #fff); color: inherit;
|
|
465
|
+
}
|
|
466
|
+
.feed-bin-restore:hover { background: var(--accent, #3498db); color: #fff; border-color: transparent; }
|
|
467
|
+
.feed-bin-purge {
|
|
468
|
+
font: inherit; font-size: .8em; padding: .2rem .6rem; border-radius: 5px; cursor: pointer;
|
|
469
|
+
border: 1px solid var(--error, #e74c3c); background: transparent; color: var(--error, #e74c3c);
|
|
470
|
+
}
|
|
471
|
+
.feed-bin-purge:hover { background: var(--error, #e74c3c); color: #fff; }
|
|
472
|
+
|
|
473
|
+
`;
|
|
474
|
+
|
|
475
|
+
export const sheet = sheetFrom(CSS);
|