@brftech/filex-core 0.42.1 → 0.43.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 +14 -2
- package/dist/ArchiveViewer-BqU761Wk.js +149 -0
- package/dist/ArchiveViewer-BqU761Wk.js.map +1 -0
- package/dist/CsvViewer-ByHVK5ga.js +172 -0
- package/dist/CsvViewer-ByHVK5ga.js.map +1 -0
- package/dist/{DrawioViewer-BuhZOAx6.js → DrawioViewer-Bgrj8-zG.js} +45 -44
- package/dist/DrawioViewer-Bgrj8-zG.js.map +1 -0
- package/dist/{EpubViewer-DS3mb3k8.js → EpubViewer-DJwUKlHW.js} +50 -50
- package/dist/EpubViewer-DJwUKlHW.js.map +1 -0
- package/dist/IpynbViewer-Bz0eJ4NS.js +184 -0
- package/dist/IpynbViewer-Bz0eJ4NS.js.map +1 -0
- package/dist/MermaidViewer-CEDTD_pp.js +136 -0
- package/dist/MermaidViewer-CEDTD_pp.js.map +1 -0
- package/dist/PsdViewer-CZcxUpZO.js +121 -0
- package/dist/PsdViewer-CZcxUpZO.js.map +1 -0
- package/dist/TiffViewer-BwI62CbQ.js +141 -0
- package/dist/TiffViewer-BwI62CbQ.js.map +1 -0
- package/dist/{Viewer3D-CIrOn63I.js → Viewer3D-DoeZcuMm.js} +16 -16
- package/dist/Viewer3D-DoeZcuMm.js.map +1 -0
- package/dist/filex-core.js +475 -219
- package/dist/filex-core.umd.cjs +165 -108
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/fonts/caveat-latin-ext.woff2 +0 -0
- package/dist/fonts/caveat-latin.woff2 +0 -0
- package/dist/fonts/dancing-script-latin-ext.woff2 +0 -0
- package/dist/fonts/dancing-script-latin.woff2 +0 -0
- package/dist/fonts/homemade-apple-latin.woff2 +0 -0
- package/dist/fonts/source-serif-4-latin-ext.woff2 +0 -0
- package/dist/fonts/source-serif-4-latin.woff2 +0 -0
- package/dist/index-DuWnGuv5.js +35901 -0
- package/dist/index-DuWnGuv5.js.map +1 -0
- package/dist/index.d.ts +5241 -553
- package/dist/pdf-CaPYsOUo.js +21302 -0
- package/dist/pdf-CaPYsOUo.js.map +1 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/FileExplorer.vue +1207 -343
- package/src/assets/fonts/LICENSE-Apache-2.0.txt +202 -0
- package/src/assets/fonts/LICENSE-OFL-1.1.txt +93 -0
- package/src/assets/fonts/README.md +58 -0
- package/src/assets/fonts/caveat-latin-ext.woff2 +0 -0
- package/src/assets/fonts/caveat-latin.woff2 +0 -0
- package/src/assets/fonts/dancing-script-latin-ext.woff2 +0 -0
- package/src/assets/fonts/dancing-script-latin.woff2 +0 -0
- package/src/assets/fonts/homemade-apple-latin.woff2 +0 -0
- package/src/assets/fonts/source-serif-4-latin-ext.woff2 +0 -0
- package/src/assets/fonts/source-serif-4-latin.woff2 +0 -0
- package/src/components/AdvancedSearch.vue +49 -0
- package/src/components/Breadcrumb.vue +5 -5
- package/src/components/ChoiceButtons.vue +152 -0
- package/src/components/CommandPalette.vue +5 -5
- package/src/components/ConnectionGuideView.vue +1 -1
- package/src/components/ConnectionNotice.vue +59 -0
- package/src/components/ConnectionsPanel.vue +30 -568
- package/src/components/ContextMenu.vue +31 -5
- package/src/components/DataTable.vue +1331 -0
- package/src/components/FilePane.vue +3 -0
- package/src/components/FilterBar.vue +12 -5
- package/src/components/GalleryView.vue +50 -2
- package/src/components/GridView.vue +51 -3
- package/src/components/HomeView.vue +18 -6
- package/src/components/InspectorPanel.vue +134 -17
- package/src/components/ListView.vue +366 -900
- package/src/components/LogoMark.vue +57 -0
- package/src/components/NFSExportsPanel.vue +76 -28
- package/src/components/OnboardingTour.vue +19 -7
- package/src/components/OperationsCenter.vue +77 -1
- package/src/components/PendingOpsTray.vue +59 -5
- package/src/components/PresenceBar.vue +7 -7
- package/src/components/ProductVersion.vue +31 -0
- package/src/components/QuickLook.vue +10 -14
- package/src/components/RecentlyOpened.vue +47 -17
- package/src/components/RecoveryKeyModal.vue +1 -1
- package/src/components/RowActions.vue +134 -0
- package/src/components/S3KeysPanel.vue +98 -56
- package/src/components/SSHKeysPanel.vue +79 -26
- package/src/components/SideNav.vue +260 -96
- package/src/components/StarButton.vue +1 -0
- package/src/components/StorageFields.vue +74 -6
- package/src/components/StorageTags.vue +62 -0
- package/src/components/TabBar.vue +1 -1
- package/src/components/TagKindIcon.vue +56 -0
- package/src/components/TagPicker.vue +226 -40
- package/src/components/ThemePalette.vue +4 -4
- package/src/components/TimeZonePicker.vue +29 -10
- package/src/components/TokensPanel.vue +82 -27
- package/src/components/Toolbar.vue +28 -6
- package/src/components/plugin/PluginConfirmModal.vue +54 -0
- package/src/components/plugin/PluginInspectorSection.vue +149 -0
- package/src/components/plugin/PluginPageView.vue +339 -0
- package/src/components/plugin/PluginViewModal.vue +159 -0
- package/src/components/plugin/SurfaceConversation.vue +76 -0
- package/src/components/plugin/SurfaceFooterButtons.vue +73 -0
- package/src/components/plugin/SurfaceRenderer.vue +299 -0
- package/src/components/plugin/SurfaceSections.vue +91 -0
- package/src/components/plugin/nodes/PdfFieldEditor.vue +509 -0
- package/src/components/plugin/nodes/SurfaceFileChooser.vue +94 -0
- package/src/components/plugin/nodes/SurfaceForm.vue +82 -0
- package/src/components/plugin/nodes/SurfaceList.vue +127 -0
- package/src/components/plugin/nodes/SurfacePdfFields.vue +1285 -0
- package/src/components/plugin/nodes/SurfacePeoplePicker.vue +213 -0
- package/src/components/plugin/nodes/SurfacePinInput.vue +57 -0
- package/src/components/plugin/nodes/SurfacePreview.vue +119 -0
- package/src/components/plugin/nodes/SurfaceProgress.vue +48 -0
- package/src/components/plugin/nodes/SurfaceSignaturePad.vue +472 -0
- package/src/components/plugin/nodes/SurfaceSteps.vue +53 -0
- package/src/components/public/PublicLanguagePicker.vue +58 -0
- package/src/components/public/PublicLinkPage.vue +286 -0
- package/src/components/public/PublicLinkPreview.vue +85 -0
- package/src/components/public/PublicPinGate.vue +108 -0
- package/src/components/public/PublicRequestBody.vue +204 -0
- package/src/components/public/PublicShareBody.vue +188 -0
- package/src/components/public/PublicShell.vue +332 -0
- package/src/composables/useConnections.ts +8 -2
- package/src/composables/useFileApi.ts +183 -44
- package/src/composables/useLocale.ts +277 -41
- package/src/composables/useNFSExports.ts +8 -10
- package/src/composables/useOperations.ts +44 -3
- package/src/composables/usePendingOps.ts +59 -8
- package/src/composables/usePluginActions.ts +121 -0
- package/src/composables/usePluginSurface.ts +223 -0
- package/src/composables/usePublicBranding.ts +172 -0
- package/src/composables/usePublicLink.ts +573 -0
- package/src/composables/usePublicPage.ts +61 -0
- package/src/composables/useS3Keys.ts +17 -12
- package/src/composables/useSSHKeys.ts +8 -10
- package/src/composables/useTokens.ts +8 -12
- package/src/composables/useUploadChunked.ts +18 -8
- package/src/composables/useViewerFetch.ts +6 -3
- package/src/index.ts +404 -8
- package/src/lib/actionIcons.ts +46 -1
- package/src/lib/advSearch.ts +14 -7
- package/src/lib/appLock.ts +130 -0
- package/src/lib/connection.ts +110 -0
- package/src/lib/destinationTree.ts +19 -3
- package/src/lib/direction.ts +353 -0
- package/src/lib/dragGhost.ts +6 -0
- package/src/lib/dropLimits.ts +69 -0
- package/src/lib/errorWords.ts +394 -0
- package/src/lib/externalReach.ts +5 -1
- package/src/lib/fileFilters.ts +7 -2
- package/src/lib/fileIcons.ts +4 -0
- package/src/lib/internalPaths.ts +77 -0
- package/src/lib/listInput.ts +64 -0
- package/src/lib/listing.ts +58 -23
- package/src/lib/modalStack.ts +26 -0
- package/src/lib/nodeRow.ts +121 -0
- package/src/lib/pdfFieldRules.ts +126 -0
- package/src/lib/pdfFields.ts +589 -0
- package/src/lib/pdfFieldsGeom.ts +203 -0
- package/src/lib/pdfjsLoader.ts +51 -0
- package/src/lib/personName.ts +47 -0
- package/src/lib/pluginApplies.ts +123 -0
- package/src/lib/pluginLabel.ts +72 -0
- package/src/lib/pluginMenu.ts +253 -0
- package/src/lib/pluginPage.ts +58 -0
- package/src/lib/plural.ts +181 -0
- package/src/lib/popupLayer.ts +103 -0
- package/src/lib/prefs.ts +563 -0
- package/src/lib/productVersion.ts +35 -0
- package/src/lib/publicLayout.ts +39 -0
- package/src/lib/serviceGate.ts +104 -0
- package/src/lib/shareTtl.ts +25 -11
- package/src/lib/signFonts.ts +85 -0
- package/src/lib/signaturePad.ts +111 -0
- package/src/lib/sortOrder.ts +100 -38
- package/src/lib/star.ts +7 -1
- package/src/lib/surfaceCell.ts +41 -0
- package/src/lib/surfaceConditions.ts +156 -0
- package/src/lib/surfaceOpen.ts +106 -0
- package/src/lib/surfaceSteps.ts +68 -0
- package/src/lib/surfaceValues.ts +191 -0
- package/src/lib/symlink.ts +150 -0
- package/src/lib/tableColumns.ts +493 -0
- package/src/lib/tableEnv.ts +34 -0
- package/src/lib/tablePrefs.ts +84 -0
- package/src/lib/tags.ts +121 -12
- package/src/lib/themes.ts +286 -18
- package/src/lib/tour.ts +152 -0
- package/src/lib/trashEmpty.ts +111 -0
- package/src/lib/trashTimeLeft.ts +23 -0
- package/src/lib/uiLocales.ts +460 -0
- package/src/lib/viewPrefs.ts +696 -660
- package/src/lib/viewPrefsHttp.ts +78 -0
- package/src/locales/en.ts +522 -119
- package/src/locales/resolve.ts +17 -8
- package/src/locales/tr.ts +539 -155
- package/src/modals/ConvertModal.vue +62 -11
- package/src/modals/DestinationPickerModal.vue +59 -16
- package/src/modals/Modal.vue +113 -23
- package/src/modals/NewDocumentModal.vue +16 -6
- package/src/modals/NewFolderModal.vue +8 -0
- package/src/modals/PermissionsModal.vue +272 -163
- package/src/modals/PreviewModal.vue +119 -20
- package/src/modals/RenameModal.vue +37 -1
- package/src/styles/base.css +2895 -241
- package/src/styles/sign-fonts.css +118 -0
- package/src/styles/variables.css +60 -0
- package/src/types/Connections.ts +17 -0
- package/src/types/ExplorerConfig.ts +117 -1
- package/src/types/FileNode.ts +58 -0
- package/src/types/Plugins.ts +494 -0
- package/src/types/Public.ts +212 -0
- package/src/viewers/ArchiveViewer.vue +93 -48
- package/src/viewers/CsvViewer.vue +99 -53
- package/src/viewers/DrawioViewer.vue +35 -9
- package/src/viewers/EpubViewer.vue +7 -8
- package/src/viewers/IpynbViewer.vue +3 -1
- package/src/viewers/MermaidViewer.vue +4 -5
- package/src/viewers/PdfViewer.vue +8 -17
- package/src/viewers/PsdViewer.vue +2 -4
- package/src/viewers/TiffViewer.vue +4 -5
- package/src/viewers/Viewer3D.vue +1 -1
- package/LICENSE +0 -21
- package/dist/ArchiveViewer-CLNevfPE.js +0 -124
- package/dist/ArchiveViewer-CLNevfPE.js.map +0 -1
- package/dist/CsvViewer-K8XA3z7N.js +0 -141
- package/dist/CsvViewer-K8XA3z7N.js.map +0 -1
- package/dist/DrawioViewer-BuhZOAx6.js.map +0 -1
- package/dist/EpubViewer-DS3mb3k8.js.map +0 -1
- package/dist/IpynbViewer-BTk7p4Dn.js +0 -184
- package/dist/IpynbViewer-BTk7p4Dn.js.map +0 -1
- package/dist/MermaidViewer-DqucH_io.js +0 -137
- package/dist/MermaidViewer-DqucH_io.js.map +0 -1
- package/dist/PsdViewer-CwiVENmq.js +0 -122
- package/dist/PsdViewer-CwiVENmq.js.map +0 -1
- package/dist/TiffViewer-CpewSVmQ.js +0 -142
- package/dist/TiffViewer-CpewSVmQ.js.map +0 -1
- package/dist/Viewer3D-CIrOn63I.js.map +0 -1
- package/dist/index-Dx0IbBcI.js +0 -26831
- package/dist/index-Dx0IbBcI.js.map +0 -1
- package/dist/useViewerFetch-czqbd2Lj.js +0 -25
- package/dist/useViewerFetch-czqbd2Lj.js.map +0 -1
package/src/styles/base.css
CHANGED
|
@@ -7,6 +7,80 @@
|
|
|
7
7
|
reported). The general default comes first, the component writes its own
|
|
8
8
|
exception afterwards. */
|
|
9
9
|
|
|
10
|
+
/* === RTL — the one sign every direction-bearing MOTION reads ==========
|
|
11
|
+
Layout here is written in logical properties (margin-inline-start,
|
|
12
|
+
inset-inline-end, text-align: start …), and those turn by themselves under
|
|
13
|
+
`dir="rtl"`. What does not turn by itself is anything written as an
|
|
14
|
+
x-OFFSET: a translateX, a box-shadow's first length. Those multiply by this
|
|
15
|
+
sign instead — `translateX(calc(8px * var(--filex-dir-x, 1)))` — so the
|
|
16
|
+
inspector still slides in from ITS edge, a switch's knob still travels
|
|
17
|
+
toward "on", and a pinned column's edge still falls on the side the rows
|
|
18
|
+
scroll under. In LTR it is `* 1`: the same pixels as before.
|
|
19
|
+
|
|
20
|
+
⚠ Set on the element that CARRIES `dir` and inherited from there, so the
|
|
21
|
+
NEAREST `dir` wins — which is the nesting rule (an English explorer inside
|
|
22
|
+
an Arabic page keeps +1; see lib/direction).
|
|
23
|
+
|
|
24
|
+
⚠⚠ Never in document space. A PDF page, an image, a drawing, a signature
|
|
25
|
+
box has its own coordinates; a box at the left of a page is at the left of
|
|
26
|
+
the page in every language (lib/pdfFieldsGeom). */
|
|
27
|
+
[dir='ltr'] { --filex-dir-x: 1; }
|
|
28
|
+
[dir='rtl'] { --filex-dir-x: -1; }
|
|
29
|
+
|
|
30
|
+
/* ⚠ RTL — MACHINE text reads left to right in every language: a command, a
|
|
31
|
+
path, a URL, an address, a key. The connection guides print
|
|
32
|
+
`sftp -P 2022 {user}@host` with the placeholder translated; laid out right
|
|
33
|
+
to left the command's words swap places and the line cannot be typed back.
|
|
34
|
+
Isolated, so the Arabic around it stays right to left and an Arabic word
|
|
35
|
+
inside it (a translated placeholder) stays a readable word.
|
|
36
|
+
Keyed on `[dir='rtl']` so an LTR page is untouched — this rule does not
|
|
37
|
+
exist for English or Turkish. */
|
|
38
|
+
[dir='rtl'] :is(pre, code, kbd, samp, .font-mono, .tbl-mono, .fe-share__url, .fe-inspector__share-url) {
|
|
39
|
+
direction: ltr;
|
|
40
|
+
unicode-bidi: isolate;
|
|
41
|
+
}
|
|
42
|
+
/* A plain-text file and a notebook's raw markdown are the person's PROSE in a
|
|
43
|
+
<pre>: each line decides its own direction (declared after the rule above,
|
|
44
|
+
which it overrides for exactly these two). */
|
|
45
|
+
[dir='rtl'] :is(.fe-preview__pre, .filex-viewer-ipynb__md-raw) {
|
|
46
|
+
unicode-bidi: plaintext;
|
|
47
|
+
}
|
|
48
|
+
/* An app's own sentences are in the APP's language, which is not always the
|
|
49
|
+
interface's: an English hint inside an Arabic wizard keeps its full stop at
|
|
50
|
+
its end. `plaintext` lets each paragraph take the direction of its own first
|
|
51
|
+
letter — for English or Turkish in an LTR page that is exactly what it was. */
|
|
52
|
+
:is(.fe-surface__text, .fe-surface__error) {
|
|
53
|
+
unicode-bidi: plaintext;
|
|
54
|
+
}
|
|
55
|
+
/* …and what a person TYPES decides its own direction: an e-mail, a URL, a
|
|
56
|
+
file name or `tag:invoice` in a right-to-left form reads left to right,
|
|
57
|
+
Arabic reads right to left, and a placeholder follows its own words.
|
|
58
|
+
`plaintext` is `dir="auto"` for every field at once, without touching the
|
|
59
|
+
markup of each. RTL only, so no English or Turkish field changes. */
|
|
60
|
+
[dir='rtl'] :is(input:not([type]), input[type='text'], input[type='search'], input[type='email'], input[type='url'], input[type='tel'], textarea) {
|
|
61
|
+
unicode-bidi: plaintext;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* ⚠ RTL — icons that MEAN a direction, mirrored in one place. The set is
|
|
65
|
+
decided where the glyph is drawn: lib/actionIcons marks its directional
|
|
66
|
+
keys `fe-aicon--dir`; the few glyphs drawn inline are listed here — the
|
|
67
|
+
viewer's previous / next chevrons (which now sit at the start / end edges)
|
|
68
|
+
and the destination picker's "go into" chevron.
|
|
69
|
+
`:dir(rtl)` on the ICON, never `[dir='rtl'] .icon`: an English explorer
|
|
70
|
+
inside an Arabic page keeps its arrows. Text arrows need nothing — the `›`
|
|
71
|
+
of a breadcrumb and the `‹ ›` of a pager are bidi-MIRRORED characters and
|
|
72
|
+
the browser turns them itself. */
|
|
73
|
+
:is(.fe-aicon--dir, .fe-viewer__chev > svg, .fe-destpick__rowinto):dir(rtl) {
|
|
74
|
+
transform: scaleX(-1);
|
|
75
|
+
}
|
|
76
|
+
/* A sideways disclosure caret points the way the line reads while closed
|
|
77
|
+
(left, in RTL) and DOWN when open in both directions. Turned rather than
|
|
78
|
+
mirrored so the open state's `rotate(90deg)` (declared later, same weight)
|
|
79
|
+
animates the short way round. */
|
|
80
|
+
:is(.fe-share__caret, .fe-pinsp__chev):dir(rtl) {
|
|
81
|
+
transform: rotate(180deg);
|
|
82
|
+
}
|
|
83
|
+
|
|
10
84
|
/* === ui-fix — scrollbars ==============================================
|
|
11
85
|
The platform scrollbar ignores the theme completely: on Terminal Green or
|
|
12
86
|
any dark variant it paints a wide light-grey slab down the edge of the
|
|
@@ -129,6 +203,16 @@ filex-explorer {
|
|
|
129
203
|
border-bottom: 1px solid var(--fe-border, rgba(0, 0, 0, 0.06));
|
|
130
204
|
}
|
|
131
205
|
|
|
206
|
+
/* "More results than shown" — a search answer the server cut (FileExplorer's
|
|
207
|
+
* banners slot). Quiet on purpose: it qualifies the list, it is not an error. */
|
|
208
|
+
.fe-search-cut {
|
|
209
|
+
flex: 0 0 auto;
|
|
210
|
+
padding: 0.375rem 0.75rem;
|
|
211
|
+
border-bottom: 1px solid var(--fe-border, rgba(0, 0, 0, 0.06));
|
|
212
|
+
color: var(--fe-text-muted);
|
|
213
|
+
font-size: 0.8125rem;
|
|
214
|
+
}
|
|
215
|
+
|
|
132
216
|
/* Initial-load spinner (shown until the first listing arrives). */
|
|
133
217
|
.fe__loading {
|
|
134
218
|
display: flex;
|
|
@@ -194,7 +278,7 @@ filex-explorer {
|
|
|
194
278
|
|
|
195
279
|
.fe__file-input {
|
|
196
280
|
position: absolute;
|
|
197
|
-
|
|
281
|
+
inset-inline-start: -9999px;
|
|
198
282
|
width: 1px;
|
|
199
283
|
height: 1px;
|
|
200
284
|
opacity: 0;
|
|
@@ -379,7 +463,7 @@ filex-explorer {
|
|
|
379
463
|
}
|
|
380
464
|
/* Edit pencil button — V1.5, verbatim (translated): "let me type a path and go" */
|
|
381
465
|
.fe-breadcrumb__edit {
|
|
382
|
-
margin-
|
|
466
|
+
margin-inline-start: auto;
|
|
383
467
|
background: none;
|
|
384
468
|
border: 1px solid transparent;
|
|
385
469
|
color: var(--fe-text-muted);
|
|
@@ -612,7 +696,7 @@ filex-explorer {
|
|
|
612
696
|
-webkit-box-orient: vertical;
|
|
613
697
|
overflow: hidden;
|
|
614
698
|
overflow-wrap: anywhere;
|
|
615
|
-
text-align:
|
|
699
|
+
text-align: start;
|
|
616
700
|
}
|
|
617
701
|
.fe-grid__empty {
|
|
618
702
|
grid-column: 1 / -1;
|
|
@@ -651,7 +735,7 @@ filex-explorer {
|
|
|
651
735
|
|
|
652
736
|
.fe-upload {
|
|
653
737
|
position: absolute;
|
|
654
|
-
|
|
738
|
+
inset-inline-end: 16px;
|
|
655
739
|
bottom: 16px;
|
|
656
740
|
width: min(360px, calc(100% - 32px));
|
|
657
741
|
background: var(--fe-bg);
|
|
@@ -751,7 +835,7 @@ filex-explorer {
|
|
|
751
835
|
* two stacks don't overlap when both are active. */
|
|
752
836
|
.fe-ops {
|
|
753
837
|
position: absolute;
|
|
754
|
-
|
|
838
|
+
inset-inline-start: 16px;
|
|
755
839
|
bottom: 16px;
|
|
756
840
|
width: min(320px, calc(100% - 32px));
|
|
757
841
|
display: flex;
|
|
@@ -863,7 +947,7 @@ filex-explorer {
|
|
|
863
947
|
color: var(--fe-text);
|
|
864
948
|
font: inherit;
|
|
865
949
|
width: 100%;
|
|
866
|
-
text-align:
|
|
950
|
+
text-align: start;
|
|
867
951
|
cursor: pointer;
|
|
868
952
|
}
|
|
869
953
|
.fe-ctx__item:hover:not(.is-disabled) {
|
|
@@ -889,13 +973,23 @@ filex-explorer {
|
|
|
889
973
|
}
|
|
890
974
|
.fe-ctx__key {
|
|
891
975
|
flex: 0 0 auto;
|
|
892
|
-
margin-
|
|
893
|
-
padding-
|
|
976
|
+
margin-inline-start: auto;
|
|
977
|
+
padding-inline-start: 16px;
|
|
894
978
|
color: var(--fe-text-muted);
|
|
895
979
|
font-size: 11px;
|
|
896
980
|
font-family: var(--fe-font-mono);
|
|
897
981
|
white-space: nowrap;
|
|
898
982
|
}
|
|
983
|
+
/* A key on a touch screen is an instruction nobody holding it can follow:
|
|
984
|
+
* the phone's row sheet listed "Enter", "Ctrl+X", "F2" beside every verb (QA,
|
|
985
|
+
* 2026-09-21). The same test the explorer uses to open the menu as a sheet
|
|
986
|
+
* (`(pointer: coarse)`), so every menu — the sheet, the New menu, the
|
|
987
|
+
* toolbar's — answers alike. */
|
|
988
|
+
@media (pointer: coarse) {
|
|
989
|
+
.fe-ctx__key {
|
|
990
|
+
display: none;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
899
993
|
.fe-ctx__sep {
|
|
900
994
|
height: 1px;
|
|
901
995
|
background: var(--fe-border);
|
|
@@ -1022,7 +1116,7 @@ filex-explorer {
|
|
|
1022
1116
|
line-height: 1.6;
|
|
1023
1117
|
background: var(--fe-bg, #fff);
|
|
1024
1118
|
color: var(--fe-text, #111);
|
|
1025
|
-
border-
|
|
1119
|
+
border-inline-end: 1px solid var(--fe-border, #e2e6ed);
|
|
1026
1120
|
overflow: auto;
|
|
1027
1121
|
tab-size: 2;
|
|
1028
1122
|
}
|
|
@@ -1050,7 +1144,7 @@ filex-explorer {
|
|
|
1050
1144
|
grid-template-rows: 1fr 1fr;
|
|
1051
1145
|
}
|
|
1052
1146
|
.fe-preview__md-split-input {
|
|
1053
|
-
border-
|
|
1147
|
+
border-inline-end: 0;
|
|
1054
1148
|
border-bottom: 1px solid var(--fe-border, #e2e6ed);
|
|
1055
1149
|
}
|
|
1056
1150
|
}
|
|
@@ -1246,7 +1340,7 @@ filex-explorer {
|
|
|
1246
1340
|
letter-spacing: 0.04em;
|
|
1247
1341
|
}
|
|
1248
1342
|
.fe-preview__code-toolbar > .fe-btn {
|
|
1249
|
-
margin-
|
|
1343
|
+
margin-inline-start: auto;
|
|
1250
1344
|
}
|
|
1251
1345
|
.fe-preview__code-status {
|
|
1252
1346
|
font-size: 12px;
|
|
@@ -1266,6 +1360,15 @@ filex-explorer {
|
|
|
1266
1360
|
.fe-preview__code-editor .cm-scroller {
|
|
1267
1361
|
font-family: var(--fe-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
1268
1362
|
}
|
|
1363
|
+
/* An administrator's second line under a viewer failure — the raw words
|
|
1364
|
+
behind the sentence (lib/errorWords). Nobody else is given it. */
|
|
1365
|
+
.fe-preview__error-detail {
|
|
1366
|
+
font-family: var(--fe-font-mono, ui-monospace, monospace);
|
|
1367
|
+
font-size: 11px;
|
|
1368
|
+
color: var(--fe-text-muted);
|
|
1369
|
+
overflow-wrap: anywhere;
|
|
1370
|
+
max-width: 60ch;
|
|
1371
|
+
}
|
|
1269
1372
|
.fe-preview__fallback {
|
|
1270
1373
|
text-align: center;
|
|
1271
1374
|
color: var(--fe-text-muted);
|
|
@@ -1350,10 +1453,10 @@ filex-explorer {
|
|
|
1350
1453
|
}
|
|
1351
1454
|
.fe-preview__md pre code { background: transparent; padding: 0; }
|
|
1352
1455
|
.fe-preview__md ul,
|
|
1353
|
-
.fe-preview__md ol { padding-
|
|
1456
|
+
.fe-preview__md ol { padding-inline-start: 2em; margin: 0.8em 0; }
|
|
1354
1457
|
.fe-preview__md li { margin: 0.3em 0; }
|
|
1355
1458
|
.fe-preview__md blockquote {
|
|
1356
|
-
border-
|
|
1459
|
+
border-inline-start: 3px solid var(--fe-border-strong);
|
|
1357
1460
|
padding: 0 1em;
|
|
1358
1461
|
color: var(--fe-text-muted);
|
|
1359
1462
|
margin: 0.8em 0;
|
|
@@ -1367,7 +1470,7 @@ filex-explorer {
|
|
|
1367
1470
|
.fe-preview__md td {
|
|
1368
1471
|
border: 1px solid var(--fe-border);
|
|
1369
1472
|
padding: 6px 10px;
|
|
1370
|
-
text-align:
|
|
1473
|
+
text-align: start;
|
|
1371
1474
|
}
|
|
1372
1475
|
.fe-preview__md th { background: var(--fe-bg-elev); }
|
|
1373
1476
|
.fe-preview__md img { max-width: 100%; }
|
|
@@ -1377,7 +1480,7 @@ filex-explorer {
|
|
|
1377
1480
|
.fe-toast {
|
|
1378
1481
|
position: absolute;
|
|
1379
1482
|
bottom: 24px;
|
|
1380
|
-
left: 50%;
|
|
1483
|
+
left: 50%; /* rtl-physical: centred by translate(-50%) — the same place in both directions */
|
|
1381
1484
|
transform: translateX(-50%);
|
|
1382
1485
|
background: var(--fe-text);
|
|
1383
1486
|
color: var(--fe-bg);
|
|
@@ -1394,7 +1497,7 @@ filex-explorer {
|
|
|
1394
1497
|
.fe-toast-enter-from,
|
|
1395
1498
|
.fe-toast-leave-to {
|
|
1396
1499
|
opacity: 0;
|
|
1397
|
-
transform: translate(-50%, 10px);
|
|
1500
|
+
transform: translate(-50%, 10px); /* rtl-physical: centred (see .fe-toast) */
|
|
1398
1501
|
}
|
|
1399
1502
|
|
|
1400
1503
|
/* ---------- Responsive ---------- */
|
|
@@ -1623,7 +1726,7 @@ filex-explorer {
|
|
|
1623
1726
|
align-items: center;
|
|
1624
1727
|
gap: 10px;
|
|
1625
1728
|
width: 100%;
|
|
1626
|
-
text-align:
|
|
1729
|
+
text-align: start;
|
|
1627
1730
|
background: transparent;
|
|
1628
1731
|
border: 0;
|
|
1629
1732
|
border-radius: var(--fe-radius-sm);
|
|
@@ -1747,7 +1850,7 @@ filex-explorer {
|
|
|
1747
1850
|
.fe-breadcrumb__menu {
|
|
1748
1851
|
position: absolute;
|
|
1749
1852
|
top: calc(100% + 4px);
|
|
1750
|
-
|
|
1853
|
+
inset-inline-start: 0;
|
|
1751
1854
|
z-index: 80;
|
|
1752
1855
|
min-width: 160px;
|
|
1753
1856
|
max-width: 280px;
|
|
@@ -1762,7 +1865,7 @@ filex-explorer {
|
|
|
1762
1865
|
box-shadow: var(--fe-shadow);
|
|
1763
1866
|
}
|
|
1764
1867
|
.fe-breadcrumb__menu-item {
|
|
1765
|
-
text-align:
|
|
1868
|
+
text-align: start;
|
|
1766
1869
|
background: transparent;
|
|
1767
1870
|
border: 0;
|
|
1768
1871
|
padding: 6px 10px;
|
|
@@ -1831,7 +1934,8 @@ filex-explorer {
|
|
|
1831
1934
|
content: '';
|
|
1832
1935
|
position: absolute;
|
|
1833
1936
|
inset: 0;
|
|
1834
|
-
|
|
1937
|
+
/* ⚠ RTL: the sweep runs the way the line reads (--filex-dir-x, top of file). */
|
|
1938
|
+
transform: translateX(calc(-100% * var(--filex-dir-x, 1)));
|
|
1835
1939
|
background: linear-gradient(
|
|
1836
1940
|
90deg,
|
|
1837
1941
|
transparent,
|
|
@@ -1841,7 +1945,7 @@ filex-explorer {
|
|
|
1841
1945
|
animation: fe-skel-shimmer 1.4s ease-in-out infinite;
|
|
1842
1946
|
}
|
|
1843
1947
|
@keyframes fe-skel-shimmer {
|
|
1844
|
-
to { transform: translateX(100%); }
|
|
1948
|
+
to { transform: translateX(calc(100% * var(--filex-dir-x, 1))); }
|
|
1845
1949
|
}
|
|
1846
1950
|
@media (prefers-reduced-motion: reduce) {
|
|
1847
1951
|
/* Static faint blocks — no sweep. */
|
|
@@ -1954,7 +2058,7 @@ filex-explorer {
|
|
|
1954
2058
|
display: flex;
|
|
1955
2059
|
align-items: center;
|
|
1956
2060
|
gap: 14px;
|
|
1957
|
-
padding: 8px
|
|
2061
|
+
padding-block: 8px; padding-inline: 14px 10px;
|
|
1958
2062
|
cursor: pointer;
|
|
1959
2063
|
max-width: min(480px, calc(100% - 32px));
|
|
1960
2064
|
}
|
|
@@ -2007,6 +2111,67 @@ filex-explorer {
|
|
|
2007
2111
|
background: var(--fe-warning, #f59e0b);
|
|
2008
2112
|
}
|
|
2009
2113
|
|
|
2114
|
+
/* The one line a page shows while the SERVER cannot be reached at all —
|
|
2115
|
+
components/ConnectionNotice.vue, drawn from the shared folding rule in
|
|
2116
|
+
lib/connection instead of a toast per failed request.
|
|
2117
|
+
⚠⚠ Here and not in the component's own `<style>`: a single-file component's
|
|
2118
|
+
styles are emitted only into a bundle that IMPORTS it, and the web-component
|
|
2119
|
+
distribution mounts the explorer without this one — so the sheet it ships
|
|
2120
|
+
lost these rules while core's kept them, and
|
|
2121
|
+
web/tests/deploy/packageLook.test.ts ("the two shipped stylesheets have
|
|
2122
|
+
drifted") caught it. base.css is in both.
|
|
2123
|
+
⚠ Logical properties only; web/tests/quality/rtlLogical.test.ts refuses the
|
|
2124
|
+
physical spellings, and this strip is drawn in Arabic too.
|
|
2125
|
+
⚠ Only tokens declared in styles/variables.css — a `--fe-*` invented at a
|
|
2126
|
+
call site is a phantom to every other reader of the theme
|
|
2127
|
+
(web/tests/api/themeTokens.test.ts). The amber is carried by the border and
|
|
2128
|
+
the dot, the way the connection badge above says it. */
|
|
2129
|
+
.fe-connlost {
|
|
2130
|
+
position: fixed;
|
|
2131
|
+
inset-block-start: 0;
|
|
2132
|
+
inset-inline: 0;
|
|
2133
|
+
z-index: 60;
|
|
2134
|
+
display: flex;
|
|
2135
|
+
align-items: center;
|
|
2136
|
+
justify-content: center;
|
|
2137
|
+
gap: 8px;
|
|
2138
|
+
padding: 6px 12px;
|
|
2139
|
+
font-size: 13px;
|
|
2140
|
+
line-height: 1.4;
|
|
2141
|
+
text-align: center;
|
|
2142
|
+
color: var(--fe-text);
|
|
2143
|
+
background: var(--fe-bg-elev);
|
|
2144
|
+
border-block-end: 1px solid var(--fe-warning);
|
|
2145
|
+
/* A statement, not a control: it must never take a click from what is
|
|
2146
|
+
underneath it. */
|
|
2147
|
+
pointer-events: none;
|
|
2148
|
+
}
|
|
2149
|
+
.fe-connlost__dot {
|
|
2150
|
+
flex: 0 0 auto;
|
|
2151
|
+
width: 7px;
|
|
2152
|
+
height: 7px;
|
|
2153
|
+
border-radius: 50%;
|
|
2154
|
+
background: var(--fe-warning);
|
|
2155
|
+
}
|
|
2156
|
+
.fe-connlost__text {
|
|
2157
|
+
min-width: 0;
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
/* `filex 0.43.0` — which filex this is, at the foot of an account menu and in
|
|
2161
|
+
the user settings dialog's head (components/ProductVersion.vue). A quiet
|
|
2162
|
+
line: the muted colour and the smallest size, selectable so it can be
|
|
2163
|
+
copied into a bug report. ⚠ Here, not in the component: see `.fe-connlost`
|
|
2164
|
+
above for why (lesson #416). */
|
|
2165
|
+
.fe-version {
|
|
2166
|
+
margin: 0;
|
|
2167
|
+
font-size: var(--fe-text-xs);
|
|
2168
|
+
line-height: 1.4;
|
|
2169
|
+
color: var(--fe-text-muted);
|
|
2170
|
+
font-variant-numeric: tabular-nums;
|
|
2171
|
+
user-select: text;
|
|
2172
|
+
white-space: nowrap;
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2010
2175
|
/* === bul:s3 === */
|
|
2011
2176
|
|
|
2012
2177
|
/* Palette — "Everywhere" hit rows (name + crumb + snippet stack). */
|
|
@@ -2135,7 +2300,7 @@ filex-explorer {
|
|
|
2135
2300
|
/* Upload FAB — bottom-right corner of the explorer (narrow mode only). */
|
|
2136
2301
|
.fe-fab {
|
|
2137
2302
|
position: absolute;
|
|
2138
|
-
|
|
2303
|
+
inset-inline-end: 16px;
|
|
2139
2304
|
bottom: 16px;
|
|
2140
2305
|
width: 56px;
|
|
2141
2306
|
height: 56px;
|
|
@@ -2174,8 +2339,8 @@ filex-explorer {
|
|
|
2174
2339
|
}
|
|
2175
2340
|
.fe-sheet {
|
|
2176
2341
|
position: fixed;
|
|
2177
|
-
|
|
2178
|
-
|
|
2342
|
+
inset-inline-start: 0;
|
|
2343
|
+
inset-inline-end: 0;
|
|
2179
2344
|
bottom: 0;
|
|
2180
2345
|
max-height: 70vh;
|
|
2181
2346
|
display: flex;
|
|
@@ -2184,8 +2349,8 @@ filex-explorer {
|
|
|
2184
2349
|
color: var(--fe-text);
|
|
2185
2350
|
border: 1px solid var(--fe-border);
|
|
2186
2351
|
border-bottom: 0;
|
|
2187
|
-
border-
|
|
2188
|
-
border-
|
|
2352
|
+
border-start-start-radius: var(--fe-radius-lg);
|
|
2353
|
+
border-start-end-radius: var(--fe-radius-lg);
|
|
2189
2354
|
box-shadow: 0 -10px 32px rgba(15, 23, 42, 0.28);
|
|
2190
2355
|
padding: 0 8px calc(8px + env(safe-area-inset-bottom, 0px));
|
|
2191
2356
|
outline: none;
|
|
@@ -2268,7 +2433,7 @@ filex-explorer {
|
|
|
2268
2433
|
min-height: 0;
|
|
2269
2434
|
display: flex;
|
|
2270
2435
|
flex-direction: column;
|
|
2271
|
-
border-
|
|
2436
|
+
border-inline-start: 1px solid var(--fe-border);
|
|
2272
2437
|
background: var(--fe-bg);
|
|
2273
2438
|
color: var(--fe-text);
|
|
2274
2439
|
}
|
|
@@ -2279,7 +2444,7 @@ filex-explorer {
|
|
|
2279
2444
|
inset: 0;
|
|
2280
2445
|
z-index: 60;
|
|
2281
2446
|
width: auto;
|
|
2282
|
-
border-
|
|
2447
|
+
border-inline-start: none;
|
|
2283
2448
|
}
|
|
2284
2449
|
|
|
2285
2450
|
.fe-inspector__head {
|
|
@@ -2402,7 +2567,7 @@ filex-explorer {
|
|
|
2402
2567
|
text-overflow: ellipsis;
|
|
2403
2568
|
white-space: nowrap;
|
|
2404
2569
|
direction: rtl; /* keep the tail (basename) visible when truncated */
|
|
2405
|
-
text-align:
|
|
2570
|
+
text-align: start;
|
|
2406
2571
|
}
|
|
2407
2572
|
.fe-inspector__mime {
|
|
2408
2573
|
font-family: var(--fe-font-mono);
|
|
@@ -2558,7 +2723,8 @@ filex-explorer {
|
|
|
2558
2723
|
@keyframes fe-inspector-in {
|
|
2559
2724
|
from {
|
|
2560
2725
|
opacity: 0;
|
|
2561
|
-
|
|
2726
|
+
/* From the inspector's own edge — the inline END, left in RTL. */
|
|
2727
|
+
transform: translateX(calc(8px * var(--filex-dir-x, 1)));
|
|
2562
2728
|
}
|
|
2563
2729
|
to {
|
|
2564
2730
|
opacity: 1;
|
|
@@ -2575,7 +2741,7 @@ filex-explorer {
|
|
|
2575
2741
|
color: var(--fe-text-muted);
|
|
2576
2742
|
}
|
|
2577
2743
|
.fe-shortcuts__custom {
|
|
2578
|
-
margin-
|
|
2744
|
+
margin-inline-start: 4px;
|
|
2579
2745
|
font-size: 9px;
|
|
2580
2746
|
vertical-align: 2px;
|
|
2581
2747
|
color: var(--fe-primary);
|
|
@@ -2663,7 +2829,7 @@ filex-explorer {
|
|
|
2663
2829
|
}
|
|
2664
2830
|
/* tus:t1 — "Desktop app only" on a combo the browser keeps for itself. */
|
|
2665
2831
|
.fe-shortset__reserved {
|
|
2666
|
-
margin-
|
|
2832
|
+
margin-inline-start: 6px;
|
|
2667
2833
|
font-size: 10.5px;
|
|
2668
2834
|
color: var(--fe-text-muted);
|
|
2669
2835
|
border: 1px dashed var(--fe-border);
|
|
@@ -2715,7 +2881,7 @@ filex-explorer {
|
|
|
2715
2881
|
* the pill grew to the full viewport height inside the admin UI. */
|
|
2716
2882
|
.fe.fe-ql-hint {
|
|
2717
2883
|
position: fixed;
|
|
2718
|
-
left: 50%;
|
|
2884
|
+
left: 50%; /* rtl-physical: centred by translate(-50%) — the same place in both directions */
|
|
2719
2885
|
bottom: 14px;
|
|
2720
2886
|
transform: translateX(-50%);
|
|
2721
2887
|
z-index: 72;
|
|
@@ -2761,7 +2927,7 @@ filex-explorer {
|
|
|
2761
2927
|
|
|
2762
2928
|
.fe-opc {
|
|
2763
2929
|
position: absolute;
|
|
2764
|
-
|
|
2930
|
+
inset-inline-end: 16px;
|
|
2765
2931
|
bottom: 16px;
|
|
2766
2932
|
z-index: 45;
|
|
2767
2933
|
display: flex;
|
|
@@ -2775,7 +2941,7 @@ filex-explorer {
|
|
|
2775
2941
|
display: flex;
|
|
2776
2942
|
align-items: center;
|
|
2777
2943
|
gap: 8px;
|
|
2778
|
-
padding: 8px
|
|
2944
|
+
padding-block: 8px; padding-inline: 10px 14px;
|
|
2779
2945
|
border-radius: 999px;
|
|
2780
2946
|
border: 1px solid var(--fe-border);
|
|
2781
2947
|
background: var(--fe-bg);
|
|
@@ -2922,6 +3088,26 @@ filex-explorer {
|
|
|
2922
3088
|
.fe-opc__item.is-error .fe-opc__state {
|
|
2923
3089
|
color: var(--fe-danger);
|
|
2924
3090
|
}
|
|
3091
|
+
/* An administrator's second line under a failure: the raw words behind the
|
|
3092
|
+
sentence (lib/errorWords). Muted and monospace — it is evidence, not the
|
|
3093
|
+
message. */
|
|
3094
|
+
.fe-opc__sub--detail {
|
|
3095
|
+
font-family: var(--fe-font-mono, ui-monospace, monospace);
|
|
3096
|
+
font-size: 10.5px;
|
|
3097
|
+
overflow-wrap: anywhere;
|
|
3098
|
+
}
|
|
3099
|
+
/* An app job's output mode ("new file" / "new version") — the one fact a
|
|
3100
|
+
finished row cannot show any other way, because in `version` mode "Open"
|
|
3101
|
+
lands on the file the job started from. */
|
|
3102
|
+
.fe-opc__outmode {
|
|
3103
|
+
flex: 0 0 auto;
|
|
3104
|
+
padding: 0 5px;
|
|
3105
|
+
border: 1px solid var(--fe-border);
|
|
3106
|
+
border-radius: 8px;
|
|
3107
|
+
line-height: 15px;
|
|
3108
|
+
white-space: nowrap;
|
|
3109
|
+
cursor: help;
|
|
3110
|
+
}
|
|
2925
3111
|
.fe-opc__state {
|
|
2926
3112
|
overflow: hidden;
|
|
2927
3113
|
text-overflow: ellipsis;
|
|
@@ -3029,8 +3215,8 @@ filex-explorer {
|
|
|
3029
3215
|
/* Narrow / embedded: clear the FAB and behave like a bottom sheet —
|
|
3030
3216
|
* badge stays compact at the right, panel stretches edge to edge. */
|
|
3031
3217
|
.fe--narrow .fe-opc {
|
|
3032
|
-
|
|
3033
|
-
|
|
3218
|
+
inset-inline-start: 12px;
|
|
3219
|
+
inset-inline-end: 12px;
|
|
3034
3220
|
bottom: 84px;
|
|
3035
3221
|
max-width: none;
|
|
3036
3222
|
}
|
|
@@ -3117,7 +3303,7 @@ filex-explorer {
|
|
|
3117
3303
|
margin-top: 10px;
|
|
3118
3304
|
max-width: 480px;
|
|
3119
3305
|
font-size: 12px;
|
|
3120
|
-
text-align:
|
|
3306
|
+
text-align: start;
|
|
3121
3307
|
}
|
|
3122
3308
|
.fe-state__details-summary {
|
|
3123
3309
|
cursor: pointer;
|
|
@@ -3183,7 +3369,7 @@ filex-explorer {
|
|
|
3183
3369
|
}
|
|
3184
3370
|
.fe-tour__card--center {
|
|
3185
3371
|
top: 50%;
|
|
3186
|
-
left: 50%;
|
|
3372
|
+
left: 50%; /* rtl-physical: centred by translate(-50%) — the same place in both directions */
|
|
3187
3373
|
transform: translate(-50%, -50%);
|
|
3188
3374
|
width: min(360px, calc(100vw - 24px));
|
|
3189
3375
|
}
|
|
@@ -3322,7 +3508,7 @@ filex-explorer {
|
|
|
3322
3508
|
gap: 6px;
|
|
3323
3509
|
max-width: 180px;
|
|
3324
3510
|
min-width: 72px;
|
|
3325
|
-
padding: 4px
|
|
3511
|
+
padding-block: 4px; padding-inline: 10px 6px;
|
|
3326
3512
|
font-size: 12px;
|
|
3327
3513
|
color: var(--fe-text-muted);
|
|
3328
3514
|
background: transparent;
|
|
@@ -3346,8 +3532,8 @@ filex-explorer {
|
|
|
3346
3532
|
.fe-tabs__tab.is-active::after {
|
|
3347
3533
|
content: '';
|
|
3348
3534
|
position: absolute;
|
|
3349
|
-
|
|
3350
|
-
|
|
3535
|
+
inset-inline-start: 0;
|
|
3536
|
+
inset-inline-end: 0;
|
|
3351
3537
|
bottom: -1px;
|
|
3352
3538
|
height: 1px;
|
|
3353
3539
|
background: var(--fe-bg);
|
|
@@ -3454,7 +3640,7 @@ filex-explorer {
|
|
|
3454
3640
|
min-height: 0;
|
|
3455
3641
|
display: flex;
|
|
3456
3642
|
flex-direction: column;
|
|
3457
|
-
border-
|
|
3643
|
+
border-inline-start: 1px solid var(--fe-border);
|
|
3458
3644
|
background: var(--fe-bg);
|
|
3459
3645
|
color: var(--fe-text);
|
|
3460
3646
|
}
|
|
@@ -3677,8 +3863,8 @@ filex-explorer {
|
|
|
3677
3863
|
title is enough). */
|
|
3678
3864
|
.fe-gal__meta {
|
|
3679
3865
|
position: absolute;
|
|
3680
|
-
|
|
3681
|
-
|
|
3866
|
+
inset-inline-start: 0;
|
|
3867
|
+
inset-inline-end: 0;
|
|
3682
3868
|
bottom: 0;
|
|
3683
3869
|
display: flex;
|
|
3684
3870
|
flex-direction: column;
|
|
@@ -3766,7 +3952,7 @@ filex-explorer {
|
|
|
3766
3952
|
min-width: 16px;
|
|
3767
3953
|
height: 16px;
|
|
3768
3954
|
padding: 0 4px;
|
|
3769
|
-
margin-
|
|
3955
|
+
margin-inline-start: 6px;
|
|
3770
3956
|
border-radius: 8px;
|
|
3771
3957
|
font-size: 10px;
|
|
3772
3958
|
font-weight: 600;
|
|
@@ -3950,7 +4136,7 @@ filex-explorer {
|
|
|
3950
4136
|
font-size: 12.5px;
|
|
3951
4137
|
color: var(--fe-primary);
|
|
3952
4138
|
cursor: pointer;
|
|
3953
|
-
text-align:
|
|
4139
|
+
text-align: start;
|
|
3954
4140
|
}
|
|
3955
4141
|
.fe-e2e-optlink:hover {
|
|
3956
4142
|
text-decoration: underline;
|
|
@@ -3994,7 +4180,7 @@ filex-explorer {
|
|
|
3994
4180
|
}
|
|
3995
4181
|
.fe-e2e-rk__escrow {
|
|
3996
4182
|
border: 1px solid var(--fe-border);
|
|
3997
|
-
border-
|
|
4183
|
+
border-inline-start: 3px solid var(--fe-warning, var(--fe-primary));
|
|
3998
4184
|
border-radius: var(--fe-radius-sm);
|
|
3999
4185
|
padding: 8px 10px;
|
|
4000
4186
|
font-size: 12.5px;
|
|
@@ -4038,7 +4224,7 @@ filex-explorer {
|
|
|
4038
4224
|
line-height: 1.45;
|
|
4039
4225
|
color: var(--fe-text);
|
|
4040
4226
|
border: 1px solid var(--fe-border);
|
|
4041
|
-
border-
|
|
4227
|
+
border-inline-start: 3px solid var(--fe-warning, #f59e0b);
|
|
4042
4228
|
border-radius: var(--fe-radius);
|
|
4043
4229
|
background: var(--fe-bg-elev);
|
|
4044
4230
|
}
|
|
@@ -4090,7 +4276,7 @@ filex-explorer {
|
|
|
4090
4276
|
margin: 0 0 10px;
|
|
4091
4277
|
padding: 10px 12px;
|
|
4092
4278
|
border: 1px solid var(--fe-border);
|
|
4093
|
-
border-
|
|
4279
|
+
border-inline-start: 3px solid var(--fe-primary);
|
|
4094
4280
|
border-radius: var(--fe-radius-sm);
|
|
4095
4281
|
background: color-mix(in srgb, var(--fe-primary) 6%, transparent);
|
|
4096
4282
|
}
|
|
@@ -4120,7 +4306,7 @@ filex-explorer {
|
|
|
4120
4306
|
accepting hands the operator a permanent second key. Amber rather than
|
|
4121
4307
|
the recovery offer's primary tint, so it does not read as routine. */
|
|
4122
4308
|
.fe-e2e-upgrade--escrow {
|
|
4123
|
-
border-
|
|
4309
|
+
border-inline-start-color: var(--fe-warning, #f59e0b);
|
|
4124
4310
|
background: color-mix(in srgb, var(--fe-warning, #f59e0b) 7%, transparent);
|
|
4125
4311
|
}
|
|
4126
4312
|
/* The link to the honest long version has to LOOK like a link: it inherits
|
|
@@ -4248,7 +4434,7 @@ filex-explorer {
|
|
|
4248
4434
|
.fe-keepbadge {
|
|
4249
4435
|
flex: 0 0 auto;
|
|
4250
4436
|
display: inline-block;
|
|
4251
|
-
margin-
|
|
4437
|
+
margin-inline-start: 4px;
|
|
4252
4438
|
font-size: 11px;
|
|
4253
4439
|
line-height: 1;
|
|
4254
4440
|
vertical-align: middle;
|
|
@@ -4278,8 +4464,8 @@ filex-explorer {
|
|
|
4278
4464
|
pointer-events none — it reports, it never blocks a click. */
|
|
4279
4465
|
.fe-keep-strip {
|
|
4280
4466
|
position: absolute;
|
|
4281
|
-
|
|
4282
|
-
|
|
4467
|
+
inset-inline-start: 12px;
|
|
4468
|
+
inset-inline-end: 12px;
|
|
4283
4469
|
bottom: 10px;
|
|
4284
4470
|
z-index: 30;
|
|
4285
4471
|
display: flex;
|
|
@@ -4332,7 +4518,7 @@ filex-explorer {
|
|
|
4332
4518
|
min-height: 0;
|
|
4333
4519
|
display: flex;
|
|
4334
4520
|
flex-direction: column;
|
|
4335
|
-
border-
|
|
4521
|
+
border-inline-end: 1px solid var(--fe-border);
|
|
4336
4522
|
/* No `background: var(--fe-bg)` here on purpose — see .fe-conn. This one IS
|
|
4337
4523
|
inside the full-screen explorer, whose root already paints --fe-bg, so a
|
|
4338
4524
|
second identical fill would only be a second chance to disagree with it. */
|
|
@@ -4410,7 +4596,7 @@ filex-explorer {
|
|
|
4410
4596
|
font: inherit;
|
|
4411
4597
|
font-size: 13.5px;
|
|
4412
4598
|
cursor: pointer;
|
|
4413
|
-
text-align:
|
|
4599
|
+
text-align: start;
|
|
4414
4600
|
white-space: nowrap;
|
|
4415
4601
|
overflow: hidden;
|
|
4416
4602
|
}
|
|
@@ -4480,7 +4666,7 @@ filex-explorer {
|
|
|
4480
4666
|
font: inherit;
|
|
4481
4667
|
font-size: 13.5px;
|
|
4482
4668
|
cursor: pointer;
|
|
4483
|
-
text-align:
|
|
4669
|
+
text-align: start;
|
|
4484
4670
|
white-space: nowrap;
|
|
4485
4671
|
overflow: hidden;
|
|
4486
4672
|
}
|
|
@@ -4519,7 +4705,7 @@ filex-explorer {
|
|
|
4519
4705
|
}
|
|
4520
4706
|
/* "Shared" marker on a storage the caller only reaches through a grant. */
|
|
4521
4707
|
.fe-sidenav__tag {
|
|
4522
|
-
margin-
|
|
4708
|
+
margin-inline-start: auto;
|
|
4523
4709
|
flex: 0 0 auto;
|
|
4524
4710
|
padding: 1px 6px;
|
|
4525
4711
|
border-radius: 999px;
|
|
@@ -4529,6 +4715,23 @@ filex-explorer {
|
|
|
4529
4715
|
font-weight: 600;
|
|
4530
4716
|
letter-spacing: 0.02em;
|
|
4531
4717
|
}
|
|
4718
|
+
/* The read-only mark (StorageTags, the one tag for that fact on every
|
|
4719
|
+
surface): at the row's end in the side panel; on a Home card, under the
|
|
4720
|
+
size line, from the start edge, and never wider than the card. */
|
|
4721
|
+
.fe-sidenav__stags {
|
|
4722
|
+
margin-inline-start: auto;
|
|
4723
|
+
flex: 0 0 auto;
|
|
4724
|
+
}
|
|
4725
|
+
.fe-home__storage-ro {
|
|
4726
|
+
align-self: flex-start;
|
|
4727
|
+
margin-top: 3px;
|
|
4728
|
+
max-width: 100%;
|
|
4729
|
+
}
|
|
4730
|
+
.fe-home__storage-ro .fe-stag {
|
|
4731
|
+
max-width: 100%;
|
|
4732
|
+
overflow: hidden;
|
|
4733
|
+
text-overflow: ellipsis;
|
|
4734
|
+
}
|
|
4532
4735
|
|
|
4533
4736
|
/* === etiket:t1 — the Tags section ==================================== */
|
|
4534
4737
|
/* A tag row is an ordinary panel item; only its label wraps differently,
|
|
@@ -4536,6 +4739,23 @@ filex-explorer {
|
|
|
4536
4739
|
.fe-sidenav__item--tag .fe-sidenav__text {
|
|
4537
4740
|
text-transform: none;
|
|
4538
4741
|
}
|
|
4742
|
+
/* etiket:k2 — "Personal" / "Team" under the Tags caption: quieter than the
|
|
4743
|
+
caption itself (no capitals, no tracking) and carrying the kind's glyph, the
|
|
4744
|
+
same one on every row below it and on every chip on a file. Logical
|
|
4745
|
+
properties, so a right-to-left language mirrors it for free. */
|
|
4746
|
+
.fe-sidenav__subheading {
|
|
4747
|
+
display: flex;
|
|
4748
|
+
align-items: center;
|
|
4749
|
+
gap: 6px;
|
|
4750
|
+
margin: 6px 0 0;
|
|
4751
|
+
padding-inline: 18px;
|
|
4752
|
+
font-size: 11px;
|
|
4753
|
+
font-weight: 600;
|
|
4754
|
+
color: var(--fe-text-muted);
|
|
4755
|
+
}
|
|
4756
|
+
.fe-sidenav__subheading .fe-tagkind {
|
|
4757
|
+
flex: none;
|
|
4758
|
+
}
|
|
4539
4759
|
/* "Show all (12)" / "Show fewer" — a link, not a button: it changes what this
|
|
4540
4760
|
section shows, it is not a destination. */
|
|
4541
4761
|
.fe-sidenav__more {
|
|
@@ -4549,7 +4769,7 @@ filex-explorer {
|
|
|
4549
4769
|
color: var(--fe-primary);
|
|
4550
4770
|
font: inherit;
|
|
4551
4771
|
font-size: 12.5px;
|
|
4552
|
-
text-align:
|
|
4772
|
+
text-align: start;
|
|
4553
4773
|
cursor: pointer;
|
|
4554
4774
|
}
|
|
4555
4775
|
.fe-sidenav__more:hover {
|
|
@@ -4576,7 +4796,7 @@ filex-explorer {
|
|
|
4576
4796
|
.fe-gal__star {
|
|
4577
4797
|
position: absolute;
|
|
4578
4798
|
top: 6px;
|
|
4579
|
-
|
|
4799
|
+
inset-inline-end: 6px;
|
|
4580
4800
|
z-index: 2;
|
|
4581
4801
|
/* Hidden until the tile is hovered or something inside it is focused —
|
|
4582
4802
|
EXCEPT when the file is starred, which is the whole point: the mark has
|
|
@@ -4671,7 +4891,7 @@ filex-explorer {
|
|
|
4671
4891
|
.fe-gal__check {
|
|
4672
4892
|
position: absolute;
|
|
4673
4893
|
top: 6px;
|
|
4674
|
-
|
|
4894
|
+
inset-inline-start: 6px;
|
|
4675
4895
|
z-index: 2;
|
|
4676
4896
|
}
|
|
4677
4897
|
|
|
@@ -4711,7 +4931,7 @@ filex-explorer {
|
|
|
4711
4931
|
position: absolute;
|
|
4712
4932
|
top: 0;
|
|
4713
4933
|
bottom: 0;
|
|
4714
|
-
|
|
4934
|
+
inset-inline-start: 0;
|
|
4715
4935
|
width: min(280px, 84%);
|
|
4716
4936
|
flex: none;
|
|
4717
4937
|
/* Same layer as .fe-inspector--overlay: above the listing and the FAB (45),
|
|
@@ -4719,7 +4939,7 @@ filex-explorer {
|
|
|
4719
4939
|
appended to <body> and would paint over anything lower anyway. */
|
|
4720
4940
|
z-index: 60;
|
|
4721
4941
|
background: var(--fe-bg);
|
|
4722
|
-
border-
|
|
4942
|
+
border-inline-end: 1px solid var(--fe-border);
|
|
4723
4943
|
box-shadow: var(--fe-shadow);
|
|
4724
4944
|
}
|
|
4725
4945
|
.fe-sidenav__scrim {
|
|
@@ -4851,7 +5071,7 @@ filex-explorer {
|
|
|
4851
5071
|
flex-wrap: wrap;
|
|
4852
5072
|
}
|
|
4853
5073
|
.fe-tokform__row .fe-s3keys__btn {
|
|
4854
|
-
margin-
|
|
5074
|
+
margin-inline-start: auto;
|
|
4855
5075
|
}
|
|
4856
5076
|
/* --- /gezinti:g1 --- */
|
|
4857
5077
|
|
|
@@ -4889,7 +5109,7 @@ filex-explorer {
|
|
|
4889
5109
|
flex: 1 1 auto;
|
|
4890
5110
|
min-width: 0;
|
|
4891
5111
|
max-width: 720px;
|
|
4892
|
-
padding: 0
|
|
5112
|
+
padding-block: 0; padding-inline: 12px 10px;
|
|
4893
5113
|
height: 40px;
|
|
4894
5114
|
border-radius: 999px;
|
|
4895
5115
|
border: 1px solid transparent;
|
|
@@ -4959,7 +5179,7 @@ filex-explorer {
|
|
|
4959
5179
|
font: inherit;
|
|
4960
5180
|
font-size: 14px;
|
|
4961
5181
|
font-weight: 600;
|
|
4962
|
-
text-align:
|
|
5182
|
+
text-align: start;
|
|
4963
5183
|
white-space: nowrap;
|
|
4964
5184
|
overflow: hidden;
|
|
4965
5185
|
cursor: pointer;
|
|
@@ -5044,7 +5264,7 @@ filex-explorer {
|
|
|
5044
5264
|
display: flex;
|
|
5045
5265
|
align-items: center;
|
|
5046
5266
|
gap: 6px;
|
|
5047
|
-
padding-
|
|
5267
|
+
padding-inline-end: 8px;
|
|
5048
5268
|
}
|
|
5049
5269
|
|
|
5050
5270
|
/* ── the filter row ───────────────────────────────────────────────────── */
|
|
@@ -5070,7 +5290,7 @@ filex-explorer {
|
|
|
5070
5290
|
align-items: center;
|
|
5071
5291
|
gap: 4px;
|
|
5072
5292
|
height: 32px;
|
|
5073
|
-
padding: 0
|
|
5293
|
+
padding-block: 0; padding-inline: 12px 10px;
|
|
5074
5294
|
border: 1px solid var(--fe-border-strong);
|
|
5075
5295
|
border-radius: 999px;
|
|
5076
5296
|
background: transparent;
|
|
@@ -5116,8 +5336,8 @@ filex-explorer {
|
|
|
5116
5336
|
}
|
|
5117
5337
|
.fe-filterbar__count {
|
|
5118
5338
|
flex: 0 0 auto;
|
|
5119
|
-
margin-
|
|
5120
|
-
padding-
|
|
5339
|
+
margin-inline-start: auto;
|
|
5340
|
+
padding-inline-start: 8px;
|
|
5121
5341
|
font-size: 12px;
|
|
5122
5342
|
color: var(--fe-text-muted);
|
|
5123
5343
|
white-space: nowrap;
|
|
@@ -5151,7 +5371,7 @@ filex-explorer {
|
|
|
5151
5371
|
color: inherit;
|
|
5152
5372
|
font: inherit;
|
|
5153
5373
|
font-size: 13px;
|
|
5154
|
-
text-align:
|
|
5374
|
+
text-align: start;
|
|
5155
5375
|
cursor: pointer;
|
|
5156
5376
|
}
|
|
5157
5377
|
.fe-filterpop__item:hover {
|
|
@@ -5290,7 +5510,7 @@ filex-explorer {
|
|
|
5290
5510
|
max-width: none;
|
|
5291
5511
|
}
|
|
5292
5512
|
.fe--narrow .fe-subhead__actions {
|
|
5293
|
-
padding-
|
|
5513
|
+
padding-inline-end: 4px;
|
|
5294
5514
|
}
|
|
5295
5515
|
.fe--narrow .fe-filterbar {
|
|
5296
5516
|
padding: 6px 8px;
|
|
@@ -5435,12 +5655,12 @@ filex-explorer {
|
|
|
5435
5655
|
}
|
|
5436
5656
|
.fe-grid__card--folder .fe-grid__foot {
|
|
5437
5657
|
min-height: 54px;
|
|
5438
|
-
padding: 0 var(--fe-gap
|
|
5658
|
+
padding-block: 0; padding-inline: var(--fe-gap) var(--fe-gap-xs);
|
|
5439
5659
|
gap: var(--fe-gap);
|
|
5440
5660
|
}
|
|
5441
5661
|
.fe-grid__card--file .fe-grid__foot {
|
|
5442
5662
|
min-height: 56px;
|
|
5443
|
-
padding: 0 var(--fe-gap-
|
|
5663
|
+
padding-block: 0; padding-inline: var(--fe-gap-sm) var(--fe-gap-xs);
|
|
5444
5664
|
gap: var(--fe-gap-sm);
|
|
5445
5665
|
}
|
|
5446
5666
|
|
|
@@ -5648,7 +5868,7 @@ filex-explorer {
|
|
|
5648
5868
|
.fe-drivesearch {
|
|
5649
5869
|
height: var(--fe-h-lg);
|
|
5650
5870
|
max-width: 560px;
|
|
5651
|
-
padding: 0 var(--fe-gap
|
|
5871
|
+
padding-block: 0; padding-inline: var(--fe-gap) var(--fe-gap-sm);
|
|
5652
5872
|
gap: var(--fe-gap-sm);
|
|
5653
5873
|
border-radius: var(--fe-radius);
|
|
5654
5874
|
border: 1px solid var(--fe-border);
|
|
@@ -5726,7 +5946,7 @@ filex-explorer {
|
|
|
5726
5946
|
}
|
|
5727
5947
|
.fe-subhead__actions {
|
|
5728
5948
|
gap: var(--fe-gap-sm);
|
|
5729
|
-
padding-
|
|
5949
|
+
padding-inline-end: var(--fe-gap);
|
|
5730
5950
|
}
|
|
5731
5951
|
.fe-breadcrumb {
|
|
5732
5952
|
gap: var(--fe-gap-xs);
|
|
@@ -5781,7 +6001,7 @@ filex-explorer {
|
|
|
5781
6001
|
caret that says it opens something. */
|
|
5782
6002
|
.fe-filterbar__chip {
|
|
5783
6003
|
height: var(--fe-h-sm);
|
|
5784
|
-
padding: 0 var(--fe-gap
|
|
6004
|
+
padding-block: 0; padding-inline: var(--fe-gap) var(--fe-gap-sm);
|
|
5785
6005
|
gap: var(--fe-gap-xs);
|
|
5786
6006
|
border-radius: var(--fe-radius);
|
|
5787
6007
|
border-color: var(--fe-border);
|
|
@@ -5969,7 +6189,7 @@ filex-explorer {
|
|
|
5969
6189
|
.fe-selbar__measure {
|
|
5970
6190
|
position: absolute;
|
|
5971
6191
|
top: 0;
|
|
5972
|
-
|
|
6192
|
+
inset-inline-start: 0;
|
|
5973
6193
|
display: flex;
|
|
5974
6194
|
align-items: center;
|
|
5975
6195
|
gap: var(--fe-gap-xs);
|
|
@@ -6062,12 +6282,12 @@ filex-explorer {
|
|
|
6062
6282
|
.fe-list__check.is-on::after {
|
|
6063
6283
|
content: '';
|
|
6064
6284
|
position: absolute;
|
|
6065
|
-
left: 6px;
|
|
6285
|
+
left: 6px; /* rtl-physical: a tick reads the same in every script — it is not an arrow */
|
|
6066
6286
|
top: 2.5px;
|
|
6067
6287
|
width: 4px;
|
|
6068
6288
|
height: 9px;
|
|
6069
6289
|
border: solid var(--fe-text-on-primary);
|
|
6070
|
-
border-width: 0 2px 2px 0;
|
|
6290
|
+
border-width: 0 2px 2px 0; /* rtl-physical: the tick's two strokes (see `left` above) */
|
|
6071
6291
|
transform: rotate(45deg);
|
|
6072
6292
|
}
|
|
6073
6293
|
.fe-list__check:focus-visible {
|
|
@@ -6187,10 +6407,12 @@ filex-explorer {
|
|
|
6187
6407
|
.fe--narrow .fe-list__col--type,
|
|
6188
6408
|
.fe--narrow .fe-list__col--owner,
|
|
6189
6409
|
.fe--narrow .fe-list__col--mod,
|
|
6410
|
+
.fe--narrow .fe-list__col--remaining,
|
|
6190
6411
|
.fe--narrow .fe-list__col--star,
|
|
6191
6412
|
.fe--narrow .fe-list__head .fe-list__col--type,
|
|
6192
6413
|
.fe--narrow .fe-list__head .fe-list__col--owner,
|
|
6193
6414
|
.fe--narrow .fe-list__head .fe-list__col--mod,
|
|
6415
|
+
.fe--narrow .fe-list__head .fe-list__col--remaining,
|
|
6194
6416
|
.fe--narrow .fe-list__head .fe-list__col--star {
|
|
6195
6417
|
display: none;
|
|
6196
6418
|
}
|
|
@@ -6204,6 +6426,7 @@ filex-explorer {
|
|
|
6204
6426
|
.fe-list__col--type,
|
|
6205
6427
|
.fe-list__col--owner,
|
|
6206
6428
|
.fe-list__col--mod,
|
|
6429
|
+
.fe-list__col--remaining,
|
|
6207
6430
|
.fe-list__col--star,
|
|
6208
6431
|
/* ⚠ The header's cells need the same two-class weight as the rule that
|
|
6209
6432
|
lays them out (`.fe-list__head .fe-list__col`), or they stay visible and
|
|
@@ -6212,6 +6435,7 @@ filex-explorer {
|
|
|
6212
6435
|
.fe-list__head .fe-list__col--type,
|
|
6213
6436
|
.fe-list__head .fe-list__col--owner,
|
|
6214
6437
|
.fe-list__head .fe-list__col--mod,
|
|
6438
|
+
.fe-list__head .fe-list__col--remaining,
|
|
6215
6439
|
.fe-list__head .fe-list__col--star {
|
|
6216
6440
|
display: none;
|
|
6217
6441
|
}
|
|
@@ -6240,7 +6464,7 @@ filex-explorer {
|
|
|
6240
6464
|
font-size: 8.5px;
|
|
6241
6465
|
line-height: 11px;
|
|
6242
6466
|
color: var(--fe-text-muted);
|
|
6243
|
-
text-align:
|
|
6467
|
+
text-align: start;
|
|
6244
6468
|
white-space: pre;
|
|
6245
6469
|
overflow: hidden;
|
|
6246
6470
|
/* The box always ends mid-file, so END it. A hard crop through a line of
|
|
@@ -6532,13 +6756,13 @@ filex-explorer {
|
|
|
6532
6756
|
background: var(--fe-bg-hover);
|
|
6533
6757
|
color: var(--fe-text);
|
|
6534
6758
|
}
|
|
6535
|
-
.fe-viewer__chev--prev {
|
|
6536
|
-
.fe-viewer__chev--next {
|
|
6759
|
+
.fe-viewer__chev--prev { inset-inline-start: var(--fe-gap); }
|
|
6760
|
+
.fe-viewer__chev--next { inset-inline-end: var(--fe-gap); }
|
|
6537
6761
|
|
|
6538
6762
|
/* ---- Zoom pill ---- */
|
|
6539
6763
|
.fe-viewer__zoom {
|
|
6540
6764
|
position: absolute;
|
|
6541
|
-
left: 50%;
|
|
6765
|
+
left: 50%; /* rtl-physical: centred by translate(-50%) — the same place in both directions */
|
|
6542
6766
|
bottom: 20px;
|
|
6543
6767
|
transform: translateX(-50%);
|
|
6544
6768
|
display: inline-flex;
|
|
@@ -6607,8 +6831,8 @@ filex-explorer {
|
|
|
6607
6831
|
gap: var(--fe-gap-sm);
|
|
6608
6832
|
padding: 0 var(--fe-gap-sm);
|
|
6609
6833
|
}
|
|
6610
|
-
.fe-viewer__chev--prev {
|
|
6611
|
-
.fe-viewer__chev--next {
|
|
6834
|
+
.fe-viewer__chev--prev { inset-inline-start: var(--fe-gap-xs); }
|
|
6835
|
+
.fe-viewer__chev--next { inset-inline-end: var(--fe-gap-xs); }
|
|
6612
6836
|
}
|
|
6613
6837
|
/* === /gorunum:v1-viewer === */
|
|
6614
6838
|
|
|
@@ -6794,6 +7018,42 @@ filex-explorer {
|
|
|
6794
7018
|
.fe-advsearch__hint--block {
|
|
6795
7019
|
margin: 0;
|
|
6796
7020
|
}
|
|
7021
|
+
/* etiket:k2 — the known tags under the Tags box: one-click picks, each with
|
|
7022
|
+
its kind's glyph, grouped Personal then Team like the navigation panel. */
|
|
7023
|
+
.fe-advsearch__tagpicks {
|
|
7024
|
+
display: flex;
|
|
7025
|
+
flex-wrap: wrap;
|
|
7026
|
+
align-items: center;
|
|
7027
|
+
gap: 4px 6px;
|
|
7028
|
+
margin-top: 6px;
|
|
7029
|
+
}
|
|
7030
|
+
.fe-advsearch__tagkind {
|
|
7031
|
+
display: inline-flex;
|
|
7032
|
+
align-items: center;
|
|
7033
|
+
gap: 4px;
|
|
7034
|
+
font-size: 11px;
|
|
7035
|
+
font-weight: 600;
|
|
7036
|
+
color: var(--fe-text-muted);
|
|
7037
|
+
margin-inline-end: 2px;
|
|
7038
|
+
}
|
|
7039
|
+
.fe-advsearch__tagpick {
|
|
7040
|
+
display: inline-flex;
|
|
7041
|
+
align-items: center;
|
|
7042
|
+
gap: 4px;
|
|
7043
|
+
padding: 2px 8px;
|
|
7044
|
+
border: 1px solid var(--fe-border);
|
|
7045
|
+
border-radius: 999px;
|
|
7046
|
+
background: transparent;
|
|
7047
|
+
color: var(--fe-text);
|
|
7048
|
+
font: inherit;
|
|
7049
|
+
font-size: 12px;
|
|
7050
|
+
cursor: pointer;
|
|
7051
|
+
}
|
|
7052
|
+
.fe-advsearch__tagpick:hover,
|
|
7053
|
+
.fe-advsearch__tagpick:focus-visible {
|
|
7054
|
+
border-color: var(--fe-primary);
|
|
7055
|
+
color: var(--fe-primary);
|
|
7056
|
+
}
|
|
6797
7057
|
|
|
6798
7058
|
/* The live count. Boxed, because it is a measurement and not a caption: the
|
|
6799
7059
|
number and the sentence explaining what it cost belong to each other. */
|
|
@@ -6831,7 +7091,7 @@ filex-explorer {
|
|
|
6831
7091
|
|
|
6832
7092
|
/* Reset sits apart from Cancel/Search: it changes the form, they leave it. */
|
|
6833
7093
|
.fe-advsearch__reset {
|
|
6834
|
-
margin-
|
|
7094
|
+
margin-inline-end: auto;
|
|
6835
7095
|
}
|
|
6836
7096
|
|
|
6837
7097
|
/* One column on a narrow viewport — two 1fr fields at 390px leave a date
|
|
@@ -7029,7 +7289,7 @@ filex-explorer {
|
|
|
7029
7289
|
the crumbs ended at x=381 and the pencil sat at x=1242. It belongs beside the
|
|
7030
7290
|
chevron, which is where the reference puts it. */
|
|
7031
7291
|
.fe-breadcrumb__edit {
|
|
7032
|
-
margin-
|
|
7292
|
+
margin-inline-start: 0;
|
|
7033
7293
|
}
|
|
7034
7294
|
.fe-breadcrumb__edit .fe-icon,
|
|
7035
7295
|
.fe-breadcrumb__edit .fe-aicon {
|
|
@@ -7215,7 +7475,7 @@ filex-explorer {
|
|
|
7215
7475
|
.fe-share__knob {
|
|
7216
7476
|
position: absolute;
|
|
7217
7477
|
top: 2px;
|
|
7218
|
-
|
|
7478
|
+
inset-inline-start: 2px;
|
|
7219
7479
|
width: 18px;
|
|
7220
7480
|
height: 18px;
|
|
7221
7481
|
border-radius: 50%;
|
|
@@ -7224,7 +7484,8 @@ filex-explorer {
|
|
|
7224
7484
|
}
|
|
7225
7485
|
.fe-share__switch[aria-checked='true'] .fe-share__knob {
|
|
7226
7486
|
background: var(--fe-text-on-primary);
|
|
7227
|
-
|
|
7487
|
+
/* Toward "on" = toward the inline end, in either direction. */
|
|
7488
|
+
transform: translateX(calc(16px * var(--filex-dir-x, 1)));
|
|
7228
7489
|
}
|
|
7229
7490
|
|
|
7230
7491
|
/* The sentence. Full-strength text on purpose: it is the answer to the
|
|
@@ -7270,27 +7531,38 @@ filex-explorer {
|
|
|
7270
7531
|
background: var(--fe-bg-elev);
|
|
7271
7532
|
}
|
|
7272
7533
|
.fe-share__copy {
|
|
7534
|
+
/* ⚠⚠ THE copy button — every "Copy" in this dialog (the link, the PIN, the
|
|
7535
|
+
command line, an older link, the upload link) is this one control. There
|
|
7536
|
+
were three: a filled primary button, a small text button and the same
|
|
7537
|
+
small button beside a revoke cross (QA, 2026-09-21). Same glyph, same
|
|
7538
|
+
words, same "Copied" answer; only the row decides the height. */
|
|
7273
7539
|
flex: 0 0 auto;
|
|
7274
7540
|
display: inline-flex;
|
|
7275
7541
|
align-items: center;
|
|
7276
7542
|
gap: var(--fe-gap-xs);
|
|
7277
|
-
height: var(--fe-h-
|
|
7278
|
-
padding: 0 var(--fe-gap);
|
|
7279
|
-
border: 1px solid var(--fe-
|
|
7543
|
+
height: var(--fe-h-md);
|
|
7544
|
+
padding: 0 var(--fe-gap-sm);
|
|
7545
|
+
border: 1px solid var(--fe-border);
|
|
7280
7546
|
border-radius: var(--fe-radius);
|
|
7281
|
-
background: var(--fe-
|
|
7282
|
-
color: var(--fe-text
|
|
7547
|
+
background: var(--fe-bg);
|
|
7548
|
+
color: var(--fe-text);
|
|
7283
7549
|
font-family: inherit;
|
|
7284
|
-
font-size: var(--fe-text-
|
|
7550
|
+
font-size: var(--fe-text-sm);
|
|
7285
7551
|
font-weight: 500;
|
|
7552
|
+
white-space: nowrap;
|
|
7286
7553
|
cursor: pointer;
|
|
7287
7554
|
}
|
|
7288
7555
|
.fe-share__copy .fe-aicon {
|
|
7289
7556
|
color: inherit;
|
|
7557
|
+
width: 14px;
|
|
7558
|
+
height: 14px;
|
|
7290
7559
|
}
|
|
7291
7560
|
.fe-share__copy:hover {
|
|
7292
|
-
background: var(--fe-
|
|
7293
|
-
border-color: var(--fe-
|
|
7561
|
+
background: var(--fe-bg-hover);
|
|
7562
|
+
border-color: var(--fe-border-strong);
|
|
7563
|
+
}
|
|
7564
|
+
.fe-share__linkrow > .fe-share__copy {
|
|
7565
|
+
height: var(--fe-h-lg);
|
|
7294
7566
|
}
|
|
7295
7567
|
|
|
7296
7568
|
.fe-share__pinrow {
|
|
@@ -7334,7 +7606,7 @@ filex-explorer {
|
|
|
7334
7606
|
font-family: inherit;
|
|
7335
7607
|
font-size: var(--fe-text-md);
|
|
7336
7608
|
font-weight: 500;
|
|
7337
|
-
text-align:
|
|
7609
|
+
text-align: start;
|
|
7338
7610
|
cursor: pointer;
|
|
7339
7611
|
}
|
|
7340
7612
|
.fe-share__sechead:hover .fe-share__seclabel {
|
|
@@ -7363,7 +7635,7 @@ filex-explorer {
|
|
|
7363
7635
|
.fe-share__secmeta {
|
|
7364
7636
|
flex: 1 1 auto;
|
|
7365
7637
|
min-width: 0;
|
|
7366
|
-
text-align:
|
|
7638
|
+
text-align: end;
|
|
7367
7639
|
font-size: var(--fe-text-xs);
|
|
7368
7640
|
font-weight: 400;
|
|
7369
7641
|
color: var(--fe-text-muted);
|
|
@@ -7374,7 +7646,7 @@ filex-explorer {
|
|
|
7374
7646
|
/* Indented to the label, not to the caret: the panel belongs to the heading
|
|
7375
7647
|
it opened from. */
|
|
7376
7648
|
.fe-share__panel {
|
|
7377
|
-
padding: 0
|
|
7649
|
+
padding-block: 0 var(--fe-gap); padding-inline: calc(var(--fe-gap-lg) + var(--fe-gap-sm)) 0;
|
|
7378
7650
|
}
|
|
7379
7651
|
|
|
7380
7652
|
/* ---- fields ---- */
|
|
@@ -7384,7 +7656,7 @@ filex-explorer {
|
|
|
7384
7656
|
gap: var(--fe-gap-sm) var(--fe-gap);
|
|
7385
7657
|
align-items: end;
|
|
7386
7658
|
}
|
|
7387
|
-
.fe-share__opts > .fe-
|
|
7659
|
+
.fe-share__opts > .fe-share__togglerow {
|
|
7388
7660
|
grid-column: 1 / -1;
|
|
7389
7661
|
}
|
|
7390
7662
|
.fe-share__field {
|
|
@@ -7416,6 +7688,13 @@ filex-explorer {
|
|
|
7416
7688
|
outline: none;
|
|
7417
7689
|
border-color: var(--fe-primary);
|
|
7418
7690
|
}
|
|
7691
|
+
/* Greyed with its reason above it (RBAC off on the storage): it has to LOOK
|
|
7692
|
+
unusable, not merely refuse the click. */
|
|
7693
|
+
.fe-share__select:disabled,
|
|
7694
|
+
.fe-share__input:disabled {
|
|
7695
|
+
opacity: 0.55;
|
|
7696
|
+
cursor: not-allowed;
|
|
7697
|
+
}
|
|
7419
7698
|
/* The per-row level select sits in a 34px row and takes that height rather
|
|
7420
7699
|
than stretching the row it lives in. */
|
|
7421
7700
|
.fe-share__select--sm {
|
|
@@ -7428,14 +7707,21 @@ filex-explorer {
|
|
|
7428
7707
|
width: 140px;
|
|
7429
7708
|
height: var(--fe-h-md);
|
|
7430
7709
|
}
|
|
7431
|
-
.
|
|
7432
|
-
|
|
7710
|
+
/* A yes/no option: its words, then the dialog's one switch. The whole row is
|
|
7711
|
+
the label, so a click on the words flips it too. */
|
|
7712
|
+
.fe-share__togglerow {
|
|
7713
|
+
display: flex;
|
|
7433
7714
|
align-items: center;
|
|
7434
|
-
|
|
7715
|
+
justify-content: space-between;
|
|
7716
|
+
gap: var(--fe-gap);
|
|
7717
|
+
min-height: var(--fe-h-md);
|
|
7435
7718
|
font-size: var(--fe-text-md);
|
|
7436
7719
|
color: var(--fe-text);
|
|
7437
7720
|
cursor: pointer;
|
|
7438
7721
|
}
|
|
7722
|
+
.fe-share__togglelabel {
|
|
7723
|
+
min-width: 0;
|
|
7724
|
+
}
|
|
7439
7725
|
|
|
7440
7726
|
/* ---- buttons ---- */
|
|
7441
7727
|
.fe-share__btn {
|
|
@@ -7478,22 +7764,6 @@ filex-explorer {
|
|
|
7478
7764
|
.fe-share__btn .fe-aicon {
|
|
7479
7765
|
color: inherit;
|
|
7480
7766
|
}
|
|
7481
|
-
.fe-share__mini {
|
|
7482
|
-
flex: 0 0 auto;
|
|
7483
|
-
height: var(--fe-h-sm);
|
|
7484
|
-
padding: 0 var(--fe-gap-sm);
|
|
7485
|
-
border: 1px solid var(--fe-border);
|
|
7486
|
-
border-radius: var(--fe-radius-sm);
|
|
7487
|
-
background: var(--fe-bg);
|
|
7488
|
-
color: var(--fe-text);
|
|
7489
|
-
font-family: inherit;
|
|
7490
|
-
font-size: var(--fe-text-xs);
|
|
7491
|
-
white-space: nowrap;
|
|
7492
|
-
cursor: pointer;
|
|
7493
|
-
}
|
|
7494
|
-
.fe-share__mini:hover {
|
|
7495
|
-
background: var(--fe-bg-hover);
|
|
7496
|
-
}
|
|
7497
7767
|
/* A verb rendered as text, for the two doors that lead somewhere else
|
|
7498
7768
|
("just send a link", "upload limits") rather than acting here. */
|
|
7499
7769
|
.fe-share__linkbtn {
|
|
@@ -7505,7 +7775,7 @@ filex-explorer {
|
|
|
7505
7775
|
color: var(--fe-primary);
|
|
7506
7776
|
font-family: inherit;
|
|
7507
7777
|
font-size: var(--fe-text-sm);
|
|
7508
|
-
text-align:
|
|
7778
|
+
text-align: start;
|
|
7509
7779
|
cursor: pointer;
|
|
7510
7780
|
}
|
|
7511
7781
|
.fe-share__linkbtn:hover {
|
|
@@ -7553,8 +7823,8 @@ filex-explorer {
|
|
|
7553
7823
|
.fe-share__suggest {
|
|
7554
7824
|
position: absolute;
|
|
7555
7825
|
top: calc(100% + var(--fe-gap-xs));
|
|
7556
|
-
|
|
7557
|
-
|
|
7826
|
+
inset-inline-start: 0;
|
|
7827
|
+
inset-inline-end: 0;
|
|
7558
7828
|
z-index: 5;
|
|
7559
7829
|
margin: 0;
|
|
7560
7830
|
padding: var(--fe-gap-xs);
|
|
@@ -7829,13 +8099,13 @@ filex-explorer {
|
|
|
7829
8099
|
control in the row for a control that did not move. */
|
|
7830
8100
|
.fe-toolbar__brand--gutter {
|
|
7831
8101
|
min-width: calc(var(--fe-sidenav-w) - 12px);
|
|
7832
|
-
padding-
|
|
8102
|
+
padding-inline-end: var(--fe-gap-sm);
|
|
7833
8103
|
}
|
|
7834
8104
|
/* At 390px there is no room to reserve anything: the row is toggle · field ·
|
|
7835
8105
|
"⋯" and the brand mark is not rendered at all (Toolbar.vue). */
|
|
7836
8106
|
.fe--narrow .fe-toolbar__brand--gutter {
|
|
7837
8107
|
min-width: 0;
|
|
7838
|
-
padding-
|
|
8108
|
+
padding-inline-end: 0;
|
|
7839
8109
|
}
|
|
7840
8110
|
/* The host's mark. It is a slot, so this styles whatever arrives: enough room
|
|
7841
8111
|
for a 22px logo beside a word, ellipsised rather than wrapped — a two-line
|
|
@@ -7883,7 +8153,7 @@ filex-explorer {
|
|
|
7883
8153
|
flex: 1 1 auto;
|
|
7884
8154
|
min-width: 0;
|
|
7885
8155
|
margin: 0;
|
|
7886
|
-
padding-
|
|
8156
|
+
padding-inline-start: var(--fe-gap-xs);
|
|
7887
8157
|
font-size: var(--fe-text-md);
|
|
7888
8158
|
font-weight: 600;
|
|
7889
8159
|
line-height: 1.3;
|
|
@@ -7909,7 +8179,9 @@ filex-explorer {
|
|
|
7909
8179
|
grid-template-columns: repeat(auto-fill, 186px);
|
|
7910
8180
|
gap: var(--fe-gap);
|
|
7911
8181
|
align-content: start;
|
|
7912
|
-
|
|
8182
|
+
/* A read-only card carries one more line (its tag); its row-mates grow
|
|
8183
|
+
with it rather than standing short beside it. */
|
|
8184
|
+
align-items: stretch;
|
|
7913
8185
|
}
|
|
7914
8186
|
/* The storage card IS the grid's folder card — 186×56, the solid glyph inset
|
|
7915
8187
|
12px — because in the explorer's own root listing a storage is a folder row.
|
|
@@ -7922,7 +8194,7 @@ filex-explorer {
|
|
|
7922
8194
|
width: 186px;
|
|
7923
8195
|
min-height: 56px;
|
|
7924
8196
|
padding: 0 var(--fe-gap);
|
|
7925
|
-
text-align:
|
|
8197
|
+
text-align: start;
|
|
7926
8198
|
border: 1px solid var(--fe-border);
|
|
7927
8199
|
border-radius: var(--fe-radius-md);
|
|
7928
8200
|
background: var(--fe-bg);
|
|
@@ -7991,7 +8263,7 @@ filex-explorer {
|
|
|
7991
8263
|
min-height: 0;
|
|
7992
8264
|
height: auto;
|
|
7993
8265
|
align-items: flex-start;
|
|
7994
|
-
text-align:
|
|
8266
|
+
text-align: start;
|
|
7995
8267
|
padding: var(--fe-gap) 2px var(--fe-gap-lg);
|
|
7996
8268
|
}
|
|
7997
8269
|
/* The grids inside Home are GridView's, and GridView fills its pane. Inside a
|
|
@@ -8083,7 +8355,7 @@ filex-explorer {
|
|
|
8083
8355
|
justify-content: center;
|
|
8084
8356
|
width: var(--fe-h-sm);
|
|
8085
8357
|
height: var(--fe-h-sm);
|
|
8086
|
-
margin: -2px -
|
|
8358
|
+
margin-block: -2px 0; margin-inline: 0 -4px;
|
|
8087
8359
|
padding: 0;
|
|
8088
8360
|
border: 0;
|
|
8089
8361
|
border-radius: var(--fe-radius-sm);
|
|
@@ -8128,12 +8400,12 @@ filex-explorer {
|
|
|
8128
8400
|
align-items: center;
|
|
8129
8401
|
justify-content: center;
|
|
8130
8402
|
border-radius: 0;
|
|
8131
|
-
border-
|
|
8403
|
+
border-inline-end: 1px solid var(--fe-border);
|
|
8132
8404
|
padding: 0 var(--fe-gap-sm);
|
|
8133
8405
|
min-width: 0;
|
|
8134
8406
|
}
|
|
8135
8407
|
.fe-advsearch__seg--tabs .fe-advsearch__seg-btn:last-child {
|
|
8136
|
-
border-
|
|
8408
|
+
border-inline-end: 0;
|
|
8137
8409
|
}
|
|
8138
8410
|
.fe-advsearch__seg--tabs .fe-advsearch__seg-btn.is-active {
|
|
8139
8411
|
background: var(--fe-primary-soft);
|
|
@@ -8261,13 +8533,17 @@ filex-explorer {
|
|
|
8261
8533
|
.fe-advsearch__viewall::after {
|
|
8262
8534
|
content: ' \2192';
|
|
8263
8535
|
}
|
|
8536
|
+
/* ⚠ RTL: "view all" points the way the line reads. */
|
|
8537
|
+
.fe-advsearch__viewall:dir(rtl)::after {
|
|
8538
|
+
content: ' \2190';
|
|
8539
|
+
}
|
|
8264
8540
|
.fe-advsearch__viewall:hover {
|
|
8265
8541
|
text-decoration: underline;
|
|
8266
8542
|
}
|
|
8267
8543
|
|
|
8268
8544
|
.fe-advsearch__btn-icon {
|
|
8269
8545
|
display: inline-flex;
|
|
8270
|
-
margin-
|
|
8546
|
+
margin-inline-end: 6px;
|
|
8271
8547
|
vertical-align: -3px;
|
|
8272
8548
|
}
|
|
8273
8549
|
.fe-advsearch__btn-icon .fe-aicon {
|
|
@@ -8410,7 +8686,7 @@ filex-explorer {
|
|
|
8410
8686
|
.fe-inspector__close {
|
|
8411
8687
|
font-size: 0;
|
|
8412
8688
|
padding: 0;
|
|
8413
|
-
margin-
|
|
8689
|
+
margin-inline-end: -4px;
|
|
8414
8690
|
}
|
|
8415
8691
|
|
|
8416
8692
|
/* Tabs: two equal halves under the head, the active one underlined. */
|
|
@@ -8602,10 +8878,10 @@ filex-explorer {
|
|
|
8602
8878
|
.fe-thumb__play {
|
|
8603
8879
|
position: absolute;
|
|
8604
8880
|
top: 50%;
|
|
8605
|
-
left: 50%;
|
|
8881
|
+
left: 50%; /* rtl-physical: centred by the negative margins below — symmetric */
|
|
8606
8882
|
width: 34px;
|
|
8607
8883
|
height: 34px;
|
|
8608
|
-
margin: -17px 0 0 -17px;
|
|
8884
|
+
margin: -17px 0 0 -17px; /* rtl-physical: half the disc, to centre it */
|
|
8609
8885
|
border-radius: 50%;
|
|
8610
8886
|
background: color-mix(in srgb, var(--fe-bg-elev) 88%, transparent);
|
|
8611
8887
|
box-shadow: 0 1px 4px color-mix(in srgb, var(--fe-text) 22%, transparent);
|
|
@@ -8617,22 +8893,22 @@ filex-explorer {
|
|
|
8617
8893
|
content: '';
|
|
8618
8894
|
position: absolute;
|
|
8619
8895
|
top: 50%;
|
|
8620
|
-
left: 50%;
|
|
8621
|
-
margin: -6px 0 0 -4px;
|
|
8896
|
+
left: 50%; /* rtl-physical: ⚠ PLAY points the way media plays, in every language — never mirrored */
|
|
8897
|
+
margin: -6px 0 0 -4px; /* rtl-physical: optical centre of the play triangle */
|
|
8622
8898
|
border-style: solid;
|
|
8623
|
-
border-width: 6px 0 6px 10px;
|
|
8624
|
-
border-color: transparent transparent transparent var(--fe-text);
|
|
8899
|
+
border-width: 6px 0 6px 10px; /* rtl-physical: the play triangle, pointing right */
|
|
8900
|
+
border-color: transparent transparent transparent var(--fe-text); /* rtl-physical: the play triangle */
|
|
8625
8901
|
}
|
|
8626
8902
|
/* The gallery tile is several times the area of a grid card's preview box, so
|
|
8627
8903
|
the badge scales with it. Scale only: one badge, one rule, two sizes. */
|
|
8628
8904
|
.fe-gal__thumb .fe-thumb__play {
|
|
8629
8905
|
width: 46px;
|
|
8630
8906
|
height: 46px;
|
|
8631
|
-
margin: -23px 0 0 -23px;
|
|
8907
|
+
margin: -23px 0 0 -23px; /* rtl-physical: half the disc, to centre it */
|
|
8632
8908
|
}
|
|
8633
8909
|
.fe-gal__thumb .fe-thumb__play::after {
|
|
8634
|
-
margin: -8px 0 0 -5px;
|
|
8635
|
-
border-width: 8px 0 8px 13px;
|
|
8910
|
+
margin: -8px 0 0 -5px; /* rtl-physical: optical centre of the play triangle */
|
|
8911
|
+
border-width: 8px 0 8px 13px; /* rtl-physical: the play triangle, pointing right */
|
|
8636
8912
|
}
|
|
8637
8913
|
/* === /gorunum:v1-preview === */
|
|
8638
8914
|
|
|
@@ -8667,17 +8943,17 @@ filex-explorer {
|
|
|
8667
8943
|
/* The trailing edge. ⚠ `.fe-filterbar__count` carried this same `auto`
|
|
8668
8944
|
while it was the last child; leaving both would split the free space
|
|
8669
8945
|
between them and park the count in mid-row the moment a filter is set. */
|
|
8670
|
-
margin-
|
|
8946
|
+
margin-inline-start: auto;
|
|
8671
8947
|
display: flex;
|
|
8672
8948
|
align-items: center;
|
|
8673
8949
|
/* Flush, deliberately: the chevron belongs TO the button on its left — it
|
|
8674
8950
|
opens the menu that changes what that button says. A gap would read as
|
|
8675
8951
|
two unrelated controls. */
|
|
8676
8952
|
gap: 0;
|
|
8677
|
-
padding-
|
|
8953
|
+
padding-inline-start: var(--fe-gap-sm);
|
|
8678
8954
|
}
|
|
8679
8955
|
.fe-filterbar__count {
|
|
8680
|
-
margin-
|
|
8956
|
+
margin-inline-start: 0;
|
|
8681
8957
|
}
|
|
8682
8958
|
|
|
8683
8959
|
.fe-filterbar__sortdir {
|
|
@@ -8808,9 +9084,11 @@ filex-explorer {
|
|
|
8808
9084
|
under a transparent button. */
|
|
8809
9085
|
.fe-filterbar__actions {
|
|
8810
9086
|
position: sticky;
|
|
8811
|
-
|
|
9087
|
+
inset-inline-end: 0;
|
|
8812
9088
|
background: var(--fe-bg);
|
|
8813
|
-
|
|
9089
|
+
/* The fade falls on the START side of this end-pinned cell, where the chips
|
|
9090
|
+
slide under it. */
|
|
9091
|
+
box-shadow: calc(-8px * var(--filex-dir-x, 1)) 0 8px -6px var(--fe-bg);
|
|
8814
9092
|
}
|
|
8815
9093
|
.fe-filterbar__actions:hover,
|
|
8816
9094
|
.fe-filterbar__actions[aria-expanded='true'] {
|
|
@@ -8942,7 +9220,7 @@ filex-explorer {
|
|
|
8942
9220
|
.fe-toolbar__soon-tip {
|
|
8943
9221
|
position: absolute;
|
|
8944
9222
|
top: calc(100% + var(--fe-gap-xs));
|
|
8945
|
-
|
|
9223
|
+
inset-inline-end: 0;
|
|
8946
9224
|
z-index: 6;
|
|
8947
9225
|
padding: 4px 8px;
|
|
8948
9226
|
border: 1px solid var(--fe-border);
|
|
@@ -9262,7 +9540,7 @@ filex-explorer {
|
|
|
9262
9540
|
color: var(--fe-text);
|
|
9263
9541
|
font: inherit;
|
|
9264
9542
|
font-size: var(--fe-text-md);
|
|
9265
|
-
text-align:
|
|
9543
|
+
text-align: start;
|
|
9266
9544
|
cursor: pointer;
|
|
9267
9545
|
}
|
|
9268
9546
|
.fe-newdoc__row:hover {
|
|
@@ -9372,9 +9650,14 @@ filex-explorer {
|
|
|
9372
9650
|
the label beside it. */
|
|
9373
9651
|
.fe-list__resize {
|
|
9374
9652
|
position: absolute;
|
|
9653
|
+
/* Above the pinned ⋮ cell (z-index 1): the LAST column's handle straddles
|
|
9654
|
+
into it, and under it the edge could not be grabbed at all — measured in
|
|
9655
|
+
LTR and RTL alike (elementFromPoint at the handle = the column-menu
|
|
9656
|
+
button). Below the frozen lead (3). */
|
|
9657
|
+
z-index: 2;
|
|
9375
9658
|
top: 0;
|
|
9376
9659
|
bottom: 0;
|
|
9377
|
-
|
|
9660
|
+
inset-inline-end: calc(var(--fe-gap-sm) / -2 - 1px);
|
|
9378
9661
|
width: 9px;
|
|
9379
9662
|
cursor: col-resize;
|
|
9380
9663
|
/* ⚠ `touch-action: none` or a drag on a touchscreen scrolls the listing
|
|
@@ -9387,7 +9670,7 @@ filex-explorer {
|
|
|
9387
9670
|
position: absolute;
|
|
9388
9671
|
top: 20%;
|
|
9389
9672
|
bottom: 20%;
|
|
9390
|
-
|
|
9673
|
+
inset-inline-start: 4px;
|
|
9391
9674
|
width: 1px;
|
|
9392
9675
|
background: var(--fe-border);
|
|
9393
9676
|
opacity: 0;
|
|
@@ -9470,7 +9753,7 @@ filex-explorer {
|
|
|
9470
9753
|
background: transparent;
|
|
9471
9754
|
color: inherit;
|
|
9472
9755
|
font: inherit;
|
|
9473
|
-
text-align:
|
|
9756
|
+
text-align: start;
|
|
9474
9757
|
cursor: pointer;
|
|
9475
9758
|
}
|
|
9476
9759
|
.fe-colmenu__row:hover {
|
|
@@ -9529,6 +9812,13 @@ filex-explorer {
|
|
|
9529
9812
|
.fe-trashbar__action {
|
|
9530
9813
|
flex: 0 0 auto;
|
|
9531
9814
|
}
|
|
9815
|
+
/* A purge that goes on in the background, counted as it goes. */
|
|
9816
|
+
.fe-trashbar__progress {
|
|
9817
|
+
flex: 0 0 auto;
|
|
9818
|
+
margin: 0;
|
|
9819
|
+
color: var(--fe-text);
|
|
9820
|
+
font-variant-numeric: tabular-nums;
|
|
9821
|
+
}
|
|
9532
9822
|
|
|
9533
9823
|
/* tablo:t1 — the row's real thumbnail. Exactly the type tile's box (24px), so
|
|
9534
9824
|
turning a glyph into a picture does not move a single row. */
|
|
@@ -9684,10 +9974,10 @@ filex-explorer {
|
|
|
9684
9974
|
background: var(--fe-primary);
|
|
9685
9975
|
}
|
|
9686
9976
|
.fe-list__col.is-drop-before::before {
|
|
9687
|
-
|
|
9977
|
+
inset-inline-start: calc(var(--fe-gap-sm) / -2 - 1px);
|
|
9688
9978
|
}
|
|
9689
9979
|
.fe-list__col.is-drop-after::after {
|
|
9690
|
-
|
|
9980
|
+
inset-inline-end: calc(var(--fe-gap-sm) / -2 - 1px);
|
|
9691
9981
|
}
|
|
9692
9982
|
|
|
9693
9983
|
/* ══ tasi:m1 — the destination picker ("Move to" / "Copy to") ══════════
|
|
@@ -9809,7 +10099,7 @@ filex-explorer {
|
|
|
9809
10099
|
background: transparent;
|
|
9810
10100
|
color: var(--fe-text);
|
|
9811
10101
|
font-size: var(--fe-text-md);
|
|
9812
|
-
text-align:
|
|
10102
|
+
text-align: start;
|
|
9813
10103
|
cursor: pointer;
|
|
9814
10104
|
}
|
|
9815
10105
|
.fe-destpick__row:hover:not(:disabled) {
|
|
@@ -10016,7 +10306,7 @@ filex-explorer {
|
|
|
10016
10306
|
display: flex;
|
|
10017
10307
|
align-items: center;
|
|
10018
10308
|
gap: 2px;
|
|
10019
|
-
padding-
|
|
10309
|
+
padding-inline-end: var(--fe-gap-xs);
|
|
10020
10310
|
}
|
|
10021
10311
|
.fe-colmenu__line .fe-colmenu__row {
|
|
10022
10312
|
flex: 1 1 auto;
|
|
@@ -10084,7 +10374,7 @@ filex-explorer {
|
|
|
10084
10374
|
* and that only the second one can be closed.
|
|
10085
10375
|
*/
|
|
10086
10376
|
.fe-pane--split {
|
|
10087
|
-
border-
|
|
10377
|
+
border-inline-start: 1px solid var(--fe-border);
|
|
10088
10378
|
}
|
|
10089
10379
|
/* The pane's × — the one control the main pane does not have. Sized like the
|
|
10090
10380
|
view switcher beside it so the address row keeps its 37px height, which is
|
|
@@ -10323,6 +10613,22 @@ filex-explorer {
|
|
|
10323
10613
|
display: block;
|
|
10324
10614
|
height: 100%;
|
|
10325
10615
|
overflow: auto;
|
|
10616
|
+
/* ⚠⚠ Reserve the vertical scrollbar's room even when it is not showing
|
|
10617
|
+
(PR #39, Berk Başarır). Every table in the product (DataTable) lays itself
|
|
10618
|
+
out against THIS box's width, and the layout decides whether the box
|
|
10619
|
+
needs scrollbars — so without the reserve there is a loop waiting to
|
|
10620
|
+
close: the table overflows by a pixel, the horizontal bar takes a row's
|
|
10621
|
+
height, the vertical bar comes, the box is a scrollbar narrower, the table
|
|
10622
|
+
fits, both bars go, the box is wide again — every frame. Reported from a
|
|
10623
|
+
Windows PC (a 12-file folder froze the tab); not reproduced on v0.42.2 or
|
|
10624
|
+
v0.43.0, whose widths round to the pixel the box snaps to. But a table
|
|
10625
|
+
that is told it has 2px more than it does on alternate width bands loops
|
|
10626
|
+
exactly like that in a pane its rows just fit — and stops looping with
|
|
10627
|
+
this one line (e2e 139 measures both). The reserve is what makes the
|
|
10628
|
+
table's width independent of its own vertical scrollbar, so no future
|
|
10629
|
+
width rule can close the loop. Overlay scrollbars (macOS by default,
|
|
10630
|
+
phones) take no room, so there it reserves nothing. */
|
|
10631
|
+
scrollbar-gutter: stable;
|
|
10326
10632
|
}
|
|
10327
10633
|
|
|
10328
10634
|
/* ⚠⚠ FLEX ROWS, not grid rows. A sticky GRID item is confined to its own grid
|
|
@@ -10391,8 +10697,9 @@ filex-explorer {
|
|
|
10391
10697
|
display: contents;
|
|
10392
10698
|
}
|
|
10393
10699
|
/* Location was never in the muted-value rule above it — it is a value like
|
|
10394
|
-
Type and Owner and reads like one. */
|
|
10395
|
-
.fe-list__col--location
|
|
10700
|
+
Type and Owner and reads like one. So is the Trash's "time left". */
|
|
10701
|
+
.fe-list__col--location,
|
|
10702
|
+
.fe-list__col--remaining {
|
|
10396
10703
|
overflow: hidden;
|
|
10397
10704
|
text-overflow: ellipsis;
|
|
10398
10705
|
white-space: nowrap;
|
|
@@ -10420,15 +10727,12 @@ filex-explorer {
|
|
|
10420
10727
|
.fe-list__row,
|
|
10421
10728
|
.fe--density-compact .fe-list__head,
|
|
10422
10729
|
.fe--density-compact .fe-list__row {
|
|
10423
|
-
padding-
|
|
10730
|
+
padding-inline-end: 0;
|
|
10424
10731
|
}
|
|
10425
10732
|
.fe-list__head .fe-list__col--menu,
|
|
10426
10733
|
.fe-list__row .fe-list__col--menu {
|
|
10427
|
-
position: sticky;
|
|
10428
|
-
right: 0;
|
|
10429
|
-
z-index: 1;
|
|
10430
10734
|
flex: 0 0 calc(var(--fe-h-sm) + var(--fe-gap));
|
|
10431
|
-
padding-
|
|
10735
|
+
padding-inline-end: var(--fe-gap);
|
|
10432
10736
|
justify-content: center;
|
|
10433
10737
|
background: var(--fe-bg);
|
|
10434
10738
|
}
|
|
@@ -10441,97 +10745,498 @@ filex-explorer {
|
|
|
10441
10745
|
.fe-list__row.is-droptarget .fe-list__col--menu {
|
|
10442
10746
|
background: var(--fe-bg-selected);
|
|
10443
10747
|
}
|
|
10748
|
+
/* Frozen to the end edge — but only while it leaves the columns sliding
|
|
10749
|
+
under it somewhere to be (DataTable: `pinMenu` / PIN_MENU_ROOM).
|
|
10750
|
+
|
|
10751
|
+
⚠⚠ The cell carries an opaque ground, as a sticky cell must, so what it
|
|
10752
|
+
covers is GONE, not dimmed. At 104px of a 265px inspector panel it covered
|
|
10753
|
+
both columns an app's list was drawing and its signer table read as names
|
|
10754
|
+
and buttons with a blank gap between them (v0.43.0). Below the threshold
|
|
10755
|
+
nothing is pinned and the row scrolls as one piece — the same answer the
|
|
10756
|
+
frozen lead gives, for the same reason. */
|
|
10757
|
+
.fe-list.is-pin-menu .fe-list__head .fe-list__col--menu,
|
|
10758
|
+
.fe-list.is-pin-menu .fe-list__row .fe-list__col--menu {
|
|
10759
|
+
position: sticky;
|
|
10760
|
+
inset-inline-end: 0;
|
|
10761
|
+
z-index: 1;
|
|
10762
|
+
}
|
|
10763
|
+
|
|
10444
10764
|
/* The edge, only while there is something scrolled underneath. A permanent
|
|
10445
10765
|
divider would claim the column is floating when it is simply the last cell
|
|
10446
10766
|
of a table that fits. `box-shadow` rather than a border so turning it on
|
|
10447
10767
|
moves nothing. */
|
|
10448
|
-
.fe-list.is-scrolled-x .fe-list__col--menu {
|
|
10449
|
-
|
|
10768
|
+
.fe-list.is-pin-menu.is-scrolled-x .fe-list__col--menu {
|
|
10769
|
+
/* On the cell's START side — the side the rows scroll under (left in LTR,
|
|
10770
|
+
right in RTL, where the ⋮ is pinned to the left edge). */
|
|
10771
|
+
box-shadow: calc(-1px * var(--filex-dir-x, 1)) 0 0 0 var(--fe-border);
|
|
10772
|
+
}
|
|
10773
|
+
|
|
10774
|
+
/* ══ THE FROZEN LEAD: the tick and Name ═══════════════════════════════
|
|
10775
|
+
(owner, 2026-09-20: "yatay kaydırmada ad solda, işlemler sağda kalsın;
|
|
10776
|
+
ikisinin de kendi gölgesi olsun")
|
|
10777
|
+
|
|
10778
|
+
The ⋮ has ridden the right edge since this became a table; the left edge was
|
|
10779
|
+
never frozen, so a listing scrolled sideways to reach Size or Modified lost
|
|
10780
|
+
the one column that says WHICH FILE each row is, and read as a wall of
|
|
10781
|
+
`PDF document · Sep 20, 2026`. Name is the row's handle — the tick, the type
|
|
10782
|
+
tile, the click target — so the tick freezes with it rather than sliding out
|
|
10783
|
+
from under its own checkboxes.
|
|
10784
|
+
|
|
10785
|
+
The same three parts as the ⋮, mirrored:
|
|
10786
|
+
|
|
10787
|
+
1. The padding moves INTO the cell. `sticky; left: 0` pulls the cell to the
|
|
10788
|
+
scrollport's edge, so a 12px inset living on the ROW would be scrolled
|
|
10789
|
+
away and the ticks would sit against the glass. The tick's track is
|
|
10790
|
+
`28 + 12` with the 12 as its own padding — the same total width, so
|
|
10791
|
+
`tableLayout`'s arithmetic is untouched (exactly the trade the ⋮ makes).
|
|
10792
|
+
|
|
10793
|
+
2. Opaque grounds, hover and selection included, or the columns sliding
|
|
10794
|
+
underneath show through the frozen cells.
|
|
10795
|
+
|
|
10796
|
+
3. An edge only while something is actually scrolled under it.
|
|
10797
|
+
|
|
10798
|
+
⚠⚠ GATED ON `.is-pin-lead`, which ListView computes. Name is the person's to
|
|
10799
|
+
resize, and a sticky cell WIDER than the pane covers the pane: 900px of Name
|
|
10800
|
+
frozen in a 706px list paints over every column it was frozen to keep
|
|
10801
|
+
company. The class is set only while the frozen lead leaves at least 160px
|
|
10802
|
+
of pane for the columns that slide under it; below that nothing is pinned
|
|
10803
|
+
and the table scrolls as one piece, which is the honest answer.
|
|
10804
|
+
|
|
10805
|
+
⚠ `--fe-list-lead` (Name's offset) is inline on `.fe-list`, because it is
|
|
10806
|
+
the tick's track plus the flex gap and only the component knows the first. */
|
|
10807
|
+
/* ⚠ The loading ghosts are deliberately NOT in this list: they have no cells
|
|
10808
|
+
of their own to carry the padding, so taking it off the row would start them
|
|
10809
|
+
12px left of the rows they stand in for and the swap to real rows would
|
|
10810
|
+
jump. They keep the ordinary inset and line up either way. */
|
|
10811
|
+
.fe-list.is-pin-lead .fe-list__head,
|
|
10812
|
+
.fe-list.is-pin-lead .fe-list__row,
|
|
10813
|
+
.fe--density-compact .fe-list.is-pin-lead .fe-list__head,
|
|
10814
|
+
.fe--density-compact .fe-list.is-pin-lead .fe-list__row {
|
|
10815
|
+
padding-inline-start: 0;
|
|
10816
|
+
}
|
|
10817
|
+
.fe-list.is-pin-lead .fe-list__col--check {
|
|
10818
|
+
position: sticky;
|
|
10819
|
+
inset-inline-start: 0;
|
|
10820
|
+
z-index: 2;
|
|
10821
|
+
flex: 0 0 calc(var(--fe-h-sm) + var(--fe-gap));
|
|
10822
|
+
padding-inline-start: var(--fe-gap);
|
|
10823
|
+
background: var(--fe-bg);
|
|
10450
10824
|
}
|
|
10451
|
-
|
|
10452
|
-
/* The date headings travel with the horizontal scroll rather than sliding off
|
|
10453
|
-
the left edge — they are `max-content` wide so sticky has somewhere to move
|
|
10454
|
-
them to (a full-width block has none). */
|
|
10455
|
-
.fe-list__group {
|
|
10825
|
+
.fe-list.is-pin-lead .fe-list__col--lead {
|
|
10456
10826
|
position: sticky;
|
|
10457
|
-
|
|
10458
|
-
|
|
10459
|
-
|
|
10827
|
+
inset-inline-start: var(--fe-list-lead, calc(var(--fe-h-sm) + var(--fe-gap) + var(--fe-gap-sm)));
|
|
10828
|
+
z-index: 2;
|
|
10829
|
+
background: var(--fe-bg);
|
|
10460
10830
|
}
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
.fe-
|
|
10467
|
-
|
|
10468
|
-
|
|
10831
|
+
.fe-list.is-pin-lead .fe-list__row:hover .fe-list__col--check,
|
|
10832
|
+
.fe-list.is-pin-lead .fe-list__row:hover .fe-list__col--lead {
|
|
10833
|
+
background: var(--fe-bg-hover);
|
|
10834
|
+
}
|
|
10835
|
+
.fe-list.is-pin-lead .fe-list__row.is-selected .fe-list__col--check,
|
|
10836
|
+
.fe-list.is-pin-lead .fe-list__row.is-selected .fe-list__col--lead,
|
|
10837
|
+
.fe-list.is-pin-lead .fe-list__row.is-droptarget .fe-list__col--check,
|
|
10838
|
+
.fe-list.is-pin-lead .fe-list__row.is-droptarget .fe-list__col--lead {
|
|
10839
|
+
background: var(--fe-bg-selected);
|
|
10840
|
+
}
|
|
10841
|
+
/* Its own edge, mirroring the ⋮'s — drawn on Name's trailing side, and only
|
|
10842
|
+
while there is something scrolled underneath it. */
|
|
10843
|
+
.fe-list.is-pin-lead.is-scrolled-x .fe-list__col--lead {
|
|
10844
|
+
/* Name's END side, whichever physical side that is. */
|
|
10845
|
+
box-shadow: calc(1px * var(--filex-dir-x, 1)) 0 0 0 var(--fe-border);
|
|
10846
|
+
}
|
|
10847
|
+
/* ⚠ The header's frozen cells sit ABOVE the rows' (the head is drawn first and
|
|
10848
|
+
a row's sticky cell would otherwise paint over it while the head is the
|
|
10849
|
+
thing being scrolled past). Same reason the header's ⋮ outranks a row's. */
|
|
10850
|
+
.fe-list.is-pin-lead .fe-list__head .fe-list__col--check,
|
|
10851
|
+
.fe-list.is-pin-lead .fe-list__head .fe-list__col--lead {
|
|
10852
|
+
z-index: 3;
|
|
10469
10853
|
}
|
|
10470
|
-
/* === /tablo:t2 === */
|
|
10471
10854
|
|
|
10855
|
+
/* ══ THE ONE TABLE — what DataTable adds over the explorer's list ═════════
|
|
10856
|
+
(packages/core/src/components/DataTable.vue)
|
|
10472
10857
|
|
|
10473
|
-
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
10478
|
-
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
* a flex one).
|
|
10483
|
-
* ==================================================================== */
|
|
10858
|
+
The rules above were written for the explorer's listing, and since
|
|
10859
|
+
2026-09-21 they are the stylesheet of EVERY table in the product: the
|
|
10860
|
+
explorer's list renders through DataTable, and so does every admin page,
|
|
10861
|
+
the connection panels and an app's `list` node. The owner: "Artık explore
|
|
10862
|
+
tablomuz bizim her yerde kullanacağımız tablo yapısıdır." What follows is
|
|
10863
|
+
only what a table that is not a file listing needs on top — the frozen lead
|
|
10864
|
+
is `.fe-list__col--lead` (the explorer's Name carries both classes), a table
|
|
10865
|
+
with no tick column freezes its lead at the glass, cells that are plain
|
|
10866
|
+
text, a card for the admin pages, and the pager.
|
|
10484
10867
|
|
|
10485
|
-
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10868
|
+
⚠ Every value is a `--fe-*` token. A Tailwind colour cannot follow the
|
|
10869
|
+
palette the person picked, and the panel following it was half of the
|
|
10870
|
+
complaint that started the admin-table work ("admin panel seçili renk
|
|
10871
|
+
paletinden etkilenmiyor, etkilenmeli"). */
|
|
10872
|
+
|
|
10873
|
+
/* The explorer's listing is not framed: the wrapper generates no box, so its
|
|
10874
|
+
pane lays `.fe-list` out exactly as it did before there was a wrapper. */
|
|
10875
|
+
.fe-table--bare {
|
|
10876
|
+
display: contents;
|
|
10494
10877
|
}
|
|
10495
|
-
|
|
10496
|
-
|
|
10497
|
-
|
|
10878
|
+
/* An admin page's table is a card: the toolbar, the table and the pager in one
|
|
10879
|
+
box. `--tbl-bg` is the ground the frozen cells paint with, so a table on a
|
|
10880
|
+
raised panel (the connection panels) can say so once. */
|
|
10881
|
+
.fe-table--framed {
|
|
10882
|
+
display: block;
|
|
10883
|
+
min-width: 0;
|
|
10884
|
+
background: var(--tbl-bg, var(--fe-bg));
|
|
10885
|
+
border: 1px solid var(--fe-border-soft);
|
|
10886
|
+
border-radius: var(--fe-radius-lg);
|
|
10887
|
+
overflow: hidden;
|
|
10498
10888
|
}
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10889
|
+
/* ⚠ Not the explorer's `height: 100%`: a card on a page is as tall as its rows,
|
|
10890
|
+
and a percentage of an auto-height parent is nothing. It still owns the
|
|
10891
|
+
sideways scroll. */
|
|
10892
|
+
.fe-table--framed .fe-list {
|
|
10893
|
+
height: auto;
|
|
10894
|
+
overflow-x: auto;
|
|
10895
|
+
overflow-y: hidden;
|
|
10502
10896
|
}
|
|
10503
|
-
|
|
10504
|
-
|
|
10505
|
-
|
|
10506
|
-
|
|
10507
|
-
|
|
10508
|
-
|
|
10509
|
-
.filex-viewer-fallback__icon {
|
|
10510
|
-
display: flex;
|
|
10511
|
-
align-items: center;
|
|
10512
|
-
justify-content: center;
|
|
10897
|
+
.fe-table--framed .fe-list__head,
|
|
10898
|
+
.fe-table--framed .fe-list__head .fe-list__col--menu,
|
|
10899
|
+
.fe-table--framed .fe-list__row .fe-list__col--menu,
|
|
10900
|
+
.fe-table--framed .fe-list.is-pin-lead .fe-list__col--lead,
|
|
10901
|
+
.fe-table--framed .fe-list.is-pin-lead .fe-list__col--check {
|
|
10902
|
+
background: var(--tbl-bg, var(--fe-bg));
|
|
10513
10903
|
}
|
|
10514
|
-
.fe-
|
|
10515
|
-
.
|
|
10516
|
-
|
|
10517
|
-
|
|
10904
|
+
.fe-table--framed .fe-list__row:hover .fe-list__col--menu,
|
|
10905
|
+
.fe-table--framed .fe-list.is-pin-lead .fe-list__row:hover .fe-list__col--lead,
|
|
10906
|
+
.fe-table--framed .fe-list.is-pin-lead .fe-list__row:hover .fe-list__col--check {
|
|
10907
|
+
background: var(--fe-bg-hover);
|
|
10518
10908
|
}
|
|
10519
|
-
|
|
10520
|
-
|
|
10521
|
-
|
|
10522
|
-
.fe-preview__fallback-icon--spin .fe-aicon,
|
|
10523
|
-
.filex-viewer-fallback__icon--spin .fe-aicon {
|
|
10524
|
-
animation: fe-spin 0.9s linear infinite;
|
|
10909
|
+
.fe-table--framed .fe-list.is-pin-lead .fe-list__row.is-selected .fe-list__col--lead,
|
|
10910
|
+
.fe-table--framed .fe-list__row.is-selected .fe-list__col--menu {
|
|
10911
|
+
background: var(--fe-bg-selected);
|
|
10525
10912
|
}
|
|
10526
|
-
|
|
10527
|
-
|
|
10528
|
-
|
|
10529
|
-
animation-duration: 2.4s;
|
|
10530
|
-
}
|
|
10913
|
+
/* The last row's hairline would double the card's own border. */
|
|
10914
|
+
.fe-table--framed .fe-list__row:last-child {
|
|
10915
|
+
border-bottom: 0;
|
|
10531
10916
|
}
|
|
10532
|
-
|
|
10533
|
-
|
|
10534
|
-
|
|
10917
|
+
.fe-table--framed .tbl-bar {
|
|
10918
|
+
border-bottom: 1px solid var(--fe-border-soft);
|
|
10919
|
+
}
|
|
10920
|
+
|
|
10921
|
+
/* With no tick in front of it, a frozen lead sits at the glass and takes the
|
|
10922
|
+
row's leading padding INTO itself (DataTable adds the 12px to its track) —
|
|
10923
|
+
the same trade the ⋮ makes on the right, so the table's arithmetic is
|
|
10924
|
+
untouched. */
|
|
10925
|
+
.fe-list.is-pin-lead.fe-list--nocheck .fe-list__col--lead {
|
|
10926
|
+
inset-inline-start: 0;
|
|
10927
|
+
padding-inline-start: var(--fe-gap);
|
|
10928
|
+
}
|
|
10929
|
+
|
|
10930
|
+
/* A plain cell: one line, cut with an ellipsis, the whole value in its title.
|
|
10931
|
+
⚠ `min-width: 0` on the text too, or one long unbroken value would push its
|
|
10932
|
+
cell past the track the header allocated. */
|
|
10933
|
+
/* ⚠ `:where()`, zero specificity: the explorer's own cells carry this class AND
|
|
10934
|
+
`fe-list__col--type` / `--owner` / `--mod` / `--size`, whose muted colour is
|
|
10935
|
+
written earlier in this file at one class of weight. A plain `.fe-list__cell`
|
|
10936
|
+
here would out-rank them by source order and turn every file's Type and
|
|
10937
|
+
Size into body-coloured text. */
|
|
10938
|
+
:where(.fe-list__cell) {
|
|
10939
|
+
font-size: var(--fe-text-md);
|
|
10940
|
+
color: var(--fe-text);
|
|
10941
|
+
overflow: hidden;
|
|
10942
|
+
}
|
|
10943
|
+
.fe-list__cell.is-right {
|
|
10944
|
+
justify-content: flex-end;
|
|
10945
|
+
text-align: end;
|
|
10946
|
+
}
|
|
10947
|
+
.fe-list__cell.is-center {
|
|
10948
|
+
justify-content: center;
|
|
10949
|
+
text-align: center;
|
|
10950
|
+
}
|
|
10951
|
+
.fe-list__cell-text {
|
|
10952
|
+
min-width: 0;
|
|
10953
|
+
overflow: hidden;
|
|
10954
|
+
text-overflow: ellipsis;
|
|
10955
|
+
white-space: nowrap;
|
|
10956
|
+
}
|
|
10957
|
+
.fe-list__col--lead .fe-list__cell-text {
|
|
10958
|
+
font-weight: 500;
|
|
10959
|
+
}
|
|
10960
|
+
/* A labelled Actions control is wider than the explorer's ⋮ and reads best
|
|
10961
|
+
flush with the row's right edge; the header's column ⋮ lines up with it. */
|
|
10962
|
+
.fe-list__head .fe-list__col--menu.is-wide,
|
|
10963
|
+
.fe-list__row .fe-list__col--menu.is-wide {
|
|
10964
|
+
justify-content: flex-end;
|
|
10965
|
+
}
|
|
10966
|
+
.fe-list__row.is-clickable {
|
|
10967
|
+
cursor: pointer;
|
|
10968
|
+
}
|
|
10969
|
+
/* A row the page wants to quieten (a notification already read, a key that
|
|
10970
|
+
is disabled). Opacity rather than a colour, so it reads the same under
|
|
10971
|
+
every palette. */
|
|
10972
|
+
.fe-list__row.is-muted {
|
|
10973
|
+
opacity: 0.65;
|
|
10974
|
+
}
|
|
10975
|
+
/* Whatever a page puts in a cell may shrink below its content, or one long
|
|
10976
|
+
value would push its cell past the track the header allocated. Zero
|
|
10977
|
+
specificity, so a component's own rule still wins. */
|
|
10978
|
+
:where(.fe-list__cell) > * {
|
|
10979
|
+
min-width: 0;
|
|
10980
|
+
}
|
|
10981
|
+
/* The admin pages' "do not let free text stretch the table" helper: inside a
|
|
10982
|
+
cell of fixed width the cell IS the clamp, so it only has to fill it. */
|
|
10983
|
+
.fe-list__cell .tbl-clamp {
|
|
10984
|
+
max-width: 100%;
|
|
10985
|
+
}
|
|
10986
|
+
/* A cell whose slot puts secondary text (`.tbl-sub`) straight under its main
|
|
10987
|
+
value: stack them. A cell lays its children out in a ROW, so without this
|
|
10988
|
+
the value and the line meant to sit under it were drawn side by side — the
|
|
10989
|
+
Panel's Recent activity read "Profil: güncellendiProfil" and Duplicates put
|
|
10990
|
+
a file's path beside its name (release-candidate sweep, 2026-09-22). */
|
|
10991
|
+
.fe-list__cell:has(> .tbl-sub) {
|
|
10992
|
+
flex-direction: column;
|
|
10993
|
+
align-items: flex-start;
|
|
10994
|
+
justify-content: center;
|
|
10995
|
+
}
|
|
10996
|
+
.fe-list__empty--loading {
|
|
10997
|
+
color: var(--fe-text-muted);
|
|
10998
|
+
}
|
|
10999
|
+
.tbl-pager {
|
|
11000
|
+
display: flex;
|
|
11001
|
+
align-items: center;
|
|
11002
|
+
gap: var(--fe-gap-xs);
|
|
11003
|
+
}
|
|
11004
|
+
.tbl-pager__at {
|
|
11005
|
+
padding: 0 var(--fe-gap-xs);
|
|
11006
|
+
}
|
|
11007
|
+
|
|
11008
|
+
/* ==================================================================
|
|
11009
|
+
THE ONE TABLE'S CELL VOCABULARY — and what is left of "the admin table".
|
|
11010
|
+
|
|
11011
|
+
Until 2026-09-21 this block was a second table: `web/src/components/ui/
|
|
11012
|
+
Table.vue` drew a real <table class="tbl"> with these rules, frozen edges
|
|
11013
|
+
of its own (`.tbl-lead`, `.tbl-actions`, `.tbl-scroll`) and a sort button
|
|
11014
|
+
of its own. It IMITATED the explorer's list and never got what lives in
|
|
11015
|
+
the explorer's code — resizing, the column menu, persistence. The owner:
|
|
11016
|
+
"Admin tabloları hâlâ explore tablolarıyla AYNI KODDA DEĞİL … tablo
|
|
11017
|
+
sütunları düzenlenebilir değil, büyütme küçültme yok, sıralama yok." Every
|
|
11018
|
+
table is DataTable now (components/DataTable.vue, styled by the
|
|
11019
|
+
`fe-list` rules above), and those table rules are deleted rather than kept
|
|
11020
|
+
"just in case": a stylesheet for a table nobody draws is an invitation to
|
|
11021
|
+
draw one.
|
|
11022
|
+
|
|
11023
|
+
What remains is what a CELL or the card around a table uses, whichever
|
|
11024
|
+
page draws it:
|
|
11025
|
+
· `.tbl-sub` / `.tbl-clamp` / `.tbl-mono` — secondary text, a
|
|
11026
|
+
free-text value that must not stretch its column, a technical value;
|
|
11027
|
+
· `.tbl-rowactions*` — the row's ONE labelled Actions control
|
|
11028
|
+
(components/RowActions.vue), the admin counterpart of the ⋮;
|
|
11029
|
+
· `.tbl-bar` / `.tbl-foot` / `.tbl-page` — the toolbar above a framed
|
|
11030
|
+
table and the pager below it (DataTable draws both).
|
|
11031
|
+
|
|
11032
|
+
⚠ EVERY COLOUR IS A `--fe-*` TOKEN: "admin panel seçili renk paletinden
|
|
11033
|
+
etkilenmiyor, etkilenmeli" was half of the complaint that started this.
|
|
11034
|
+
================================================================== */
|
|
11035
|
+
|
|
11036
|
+
/* The raised box a connection panel draws is not the page's ground, and the
|
|
11037
|
+
table's frozen cells paint with `--tbl-bg` — so the token moves, not the
|
|
11038
|
+
rules. */
|
|
11039
|
+
.fe-s3keys .fe-table--framed {
|
|
11040
|
+
--tbl-bg: var(--fe-bg-elev);
|
|
11041
|
+
}
|
|
11042
|
+
|
|
11043
|
+
/* Secondary text inside a cell — a path under a name, a timestamp under a
|
|
11044
|
+
badge. One class rather than a `text-xs text-zinc-500` in twelve files. */
|
|
11045
|
+
.tbl-sub {
|
|
11046
|
+
display: block;
|
|
11047
|
+
margin-top: 2px;
|
|
11048
|
+
font-size: var(--fe-text-xs);
|
|
11049
|
+
color: var(--fe-text-muted);
|
|
11050
|
+
}
|
|
11051
|
+
/* A cell that must not be allowed to stretch the table: `min-width:
|
|
11052
|
+
max-content` means a free-text column otherwise sets the table's width and
|
|
11053
|
+
pushes every other column off the right-hand edge. */
|
|
11054
|
+
.tbl-clamp {
|
|
11055
|
+
display: block;
|
|
11056
|
+
max-width: 28rem;
|
|
11057
|
+
overflow: hidden;
|
|
11058
|
+
text-overflow: ellipsis;
|
|
11059
|
+
white-space: nowrap;
|
|
11060
|
+
}
|
|
11061
|
+
.tbl-mono {
|
|
11062
|
+
font-family: var(--fe-font-mono);
|
|
11063
|
+
font-size: var(--fe-text-xs);
|
|
11064
|
+
}
|
|
11065
|
+
|
|
11066
|
+
/* The row's ONE control, and the label the owner asked for. The explorer's
|
|
11067
|
+
handle is the ⋮ glyph; the admin panel's says what it is, because an
|
|
11068
|
+
admin row's verbs (revoke a token, reset a password, purge a version) are
|
|
11069
|
+
not guessable from a glyph. Sized to the row so a table of them does not
|
|
11070
|
+
grow taller than one without. */
|
|
11071
|
+
.tbl-rowactions {
|
|
11072
|
+
display: inline-flex;
|
|
11073
|
+
justify-content: flex-end;
|
|
11074
|
+
width: 100%;
|
|
11075
|
+
}
|
|
11076
|
+
.tbl-rowactions__btn {
|
|
11077
|
+
display: inline-flex;
|
|
11078
|
+
align-items: center;
|
|
11079
|
+
gap: var(--fe-gap-xs);
|
|
11080
|
+
height: var(--fe-h-sm);
|
|
11081
|
+
padding: 0 var(--fe-gap-sm);
|
|
11082
|
+
border: 1px solid var(--fe-border);
|
|
11083
|
+
border-radius: var(--fe-radius-sm);
|
|
11084
|
+
background: transparent;
|
|
11085
|
+
color: var(--fe-text);
|
|
11086
|
+
font: inherit;
|
|
11087
|
+
font-size: var(--fe-text-md);
|
|
11088
|
+
line-height: 1;
|
|
11089
|
+
white-space: nowrap;
|
|
11090
|
+
cursor: pointer;
|
|
11091
|
+
}
|
|
11092
|
+
.tbl-rowactions__btn:hover:not(:disabled) {
|
|
11093
|
+
background: var(--fe-bg-hover);
|
|
11094
|
+
border-color: var(--fe-border-strong);
|
|
11095
|
+
}
|
|
11096
|
+
.tbl-rowactions__btn:focus-visible {
|
|
11097
|
+
outline: 2px solid var(--fe-primary);
|
|
11098
|
+
outline-offset: 1px;
|
|
11099
|
+
}
|
|
11100
|
+
.tbl-rowactions__btn:disabled {
|
|
11101
|
+
opacity: 0.45;
|
|
11102
|
+
cursor: not-allowed;
|
|
11103
|
+
}
|
|
11104
|
+
.tbl-rowactions__caret {
|
|
11105
|
+
font-size: 10px;
|
|
11106
|
+
color: var(--fe-text-muted);
|
|
11107
|
+
}
|
|
11108
|
+
|
|
11109
|
+
|
|
11110
|
+
/* The bar above the table (search, filters) and the one below it (the pager).
|
|
11111
|
+
Part of the same card, so they carry the card's ground and its hairlines. */
|
|
11112
|
+
.tbl-bar {
|
|
11113
|
+
display: flex;
|
|
11114
|
+
align-items: center;
|
|
11115
|
+
flex-wrap: wrap;
|
|
11116
|
+
gap: var(--fe-gap-sm);
|
|
11117
|
+
padding: var(--fe-gap-sm) var(--fe-gap);
|
|
11118
|
+
border-bottom: 1px solid var(--fe-border-soft);
|
|
11119
|
+
}
|
|
11120
|
+
.tbl-foot {
|
|
11121
|
+
display: flex;
|
|
11122
|
+
align-items: center;
|
|
11123
|
+
justify-content: space-between;
|
|
11124
|
+
gap: var(--fe-gap-sm);
|
|
11125
|
+
padding: var(--fe-gap-sm) var(--fe-gap);
|
|
11126
|
+
border-top: 1px solid var(--fe-border-soft);
|
|
11127
|
+
font-size: var(--fe-text-md);
|
|
11128
|
+
color: var(--fe-text-muted);
|
|
11129
|
+
}
|
|
11130
|
+
.tbl-page {
|
|
11131
|
+
display: inline-flex;
|
|
11132
|
+
align-items: center;
|
|
11133
|
+
justify-content: center;
|
|
11134
|
+
min-width: var(--fe-h-sm);
|
|
11135
|
+
height: var(--fe-h-sm);
|
|
11136
|
+
padding: 0 var(--fe-gap-sm);
|
|
11137
|
+
border: 0;
|
|
11138
|
+
border-radius: var(--fe-radius-sm);
|
|
11139
|
+
background: transparent;
|
|
11140
|
+
color: inherit;
|
|
11141
|
+
font: inherit;
|
|
11142
|
+
cursor: pointer;
|
|
11143
|
+
}
|
|
11144
|
+
.tbl-page:hover:not(:disabled) {
|
|
11145
|
+
background: var(--fe-bg-hover);
|
|
11146
|
+
color: var(--fe-text);
|
|
11147
|
+
}
|
|
11148
|
+
.tbl-page:focus-visible {
|
|
11149
|
+
outline: 2px solid var(--fe-primary);
|
|
11150
|
+
outline-offset: -2px;
|
|
11151
|
+
}
|
|
11152
|
+
.tbl-page:disabled {
|
|
11153
|
+
opacity: 0.4;
|
|
11154
|
+
cursor: not-allowed;
|
|
11155
|
+
}
|
|
11156
|
+
|
|
11157
|
+
/* The date headings travel with the horizontal scroll rather than sliding off
|
|
11158
|
+
the left edge — they are `max-content` wide so sticky has somewhere to move
|
|
11159
|
+
them to (a full-width block has none). */
|
|
11160
|
+
.fe-list__group {
|
|
11161
|
+
position: sticky;
|
|
11162
|
+
inset-inline-start: 0;
|
|
11163
|
+
width: max-content;
|
|
11164
|
+
max-width: 100%;
|
|
11165
|
+
}
|
|
11166
|
+
|
|
11167
|
+
/* Name's handle sits on its trailing edge like every other column's. The cell
|
|
11168
|
+
is `display: flex` with the sort button as its first child, so without this
|
|
11169
|
+
the absolutely positioned handle would have no positioned ancestor inside
|
|
11170
|
+
the header row. */
|
|
11171
|
+
.fe-list__head .fe-list__col--name {
|
|
11172
|
+
position: relative;
|
|
11173
|
+
overflow: visible;
|
|
11174
|
+
}
|
|
11175
|
+
/* === /tablo:t2 === */
|
|
11176
|
+
|
|
11177
|
+
|
|
11178
|
+
/* === ikon:emoji =======================================================
|
|
11179
|
+
* The boxes that used to hold an emoji and now hold a drawing.
|
|
11180
|
+
*
|
|
11181
|
+
* Sizing only — every mark here comes from `lib/actionIcons.ts` or
|
|
11182
|
+
* `lib/fileIcons.ts` and paints on `currentColor`, so the surface it sits in
|
|
11183
|
+
* keeps deciding its colour. Two shapes need a box: `.fe-aicon` is a fixed
|
|
11184
|
+
* 16px (right for a menu row, far too small for a 48px fallback screen), and
|
|
11185
|
+
* `.fe-ftile` is `1em` (so its box is the `font-size` the slot already had —
|
|
11186
|
+
* which is why most of the rules below only have to switch a text span into
|
|
11187
|
+
* a flex one).
|
|
11188
|
+
* ==================================================================== */
|
|
11189
|
+
|
|
11190
|
+
/* --- the command palette's 20px column ------------------------------- */
|
|
11191
|
+
.fe-cmdp__icon {
|
|
11192
|
+
display: inline-flex;
|
|
11193
|
+
align-items: center;
|
|
11194
|
+
justify-content: center;
|
|
11195
|
+
/* The em the file tiles size themselves from. Slightly over the 16px an
|
|
11196
|
+
action icon draws at, because a tile is the full box and a stroked glyph
|
|
11197
|
+
is not — at a shared 20 the tiles shouted over the commands. */
|
|
11198
|
+
font-size: 18px;
|
|
11199
|
+
}
|
|
11200
|
+
.fe-cmdp__icon .fe-aicon {
|
|
11201
|
+
width: 18px;
|
|
11202
|
+
height: 18px;
|
|
11203
|
+
}
|
|
11204
|
+
.fe-cmdp__del .fe-aicon {
|
|
11205
|
+
width: 15px;
|
|
11206
|
+
height: 15px;
|
|
11207
|
+
}
|
|
11208
|
+
|
|
11209
|
+
/* --- the viewer / preview fallback screen ---------------------------- */
|
|
11210
|
+
/* Both slots were `font-size: 48px` text boxes. A tile obeys that already; an
|
|
11211
|
+
action icon has to be told, and both need centring once they are elements
|
|
11212
|
+
rather than glyphs on a text baseline. */
|
|
11213
|
+
.fe-preview__fallback-icon,
|
|
11214
|
+
.filex-viewer-fallback__icon {
|
|
11215
|
+
display: flex;
|
|
11216
|
+
align-items: center;
|
|
11217
|
+
justify-content: center;
|
|
11218
|
+
}
|
|
11219
|
+
.fe-preview__fallback-icon .fe-aicon,
|
|
11220
|
+
.filex-viewer-fallback__icon .fe-aicon {
|
|
11221
|
+
width: 44px;
|
|
11222
|
+
height: 44px;
|
|
11223
|
+
}
|
|
11224
|
+
/* "Still loading" cannot be said by a still picture: the open ring turns.
|
|
11225
|
+
`fe-spin` is the keyframe the initial-load spinner at the top of this file
|
|
11226
|
+
already uses, so there is one rotation in the package. */
|
|
11227
|
+
.fe-preview__fallback-icon--spin .fe-aicon,
|
|
11228
|
+
.filex-viewer-fallback__icon--spin .fe-aicon {
|
|
11229
|
+
animation: fe-spin 0.9s linear infinite;
|
|
11230
|
+
}
|
|
11231
|
+
@media (prefers-reduced-motion: reduce) {
|
|
11232
|
+
.fe-preview__fallback-icon--spin .fe-aicon,
|
|
11233
|
+
.filex-viewer-fallback__icon--spin .fe-aicon {
|
|
11234
|
+
animation-duration: 2.4s;
|
|
11235
|
+
}
|
|
11236
|
+
}
|
|
11237
|
+
/* The one state that is an ERROR rather than a kind of file keeps saying so
|
|
11238
|
+
in colour, which the emoji it replaces could not do (a colour emoji paints
|
|
11239
|
+
its own palette and ignores the row it is in). */
|
|
10535
11240
|
.fe-preview__fallback-icon--alert .fe-aicon {
|
|
10536
11241
|
color: var(--fe-danger);
|
|
10537
11242
|
}
|
|
@@ -10645,7 +11350,7 @@ filex-explorer {
|
|
|
10645
11350
|
}
|
|
10646
11351
|
.filex-viewer-ipynb__md ul,
|
|
10647
11352
|
.filex-viewer-ipynb__md ol {
|
|
10648
|
-
padding-
|
|
11353
|
+
padding-inline-start: 2em;
|
|
10649
11354
|
}
|
|
10650
11355
|
|
|
10651
11356
|
/* 2. A form field with a visible name (EncryptedFolderModal, NewFolderModal).
|
|
@@ -10662,3 +11367,1952 @@ filex-explorer {
|
|
|
10662
11367
|
color: var(--fe-text-muted);
|
|
10663
11368
|
}
|
|
10664
11369
|
/* === /agent-fix2 === */
|
|
11370
|
+
|
|
11371
|
+
/* === App plugins — a plugin's declarative screen (components/plugin/) ===
|
|
11372
|
+
* Drawn from data with our own elements; the classes here are the whole
|
|
11373
|
+
* vocabulary a surface can reach, which is the point. */
|
|
11374
|
+
.fe-surface {
|
|
11375
|
+
display: flex;
|
|
11376
|
+
flex-direction: column;
|
|
11377
|
+
gap: 10px;
|
|
11378
|
+
}
|
|
11379
|
+
.fe-surface__text {
|
|
11380
|
+
margin: 0;
|
|
11381
|
+
font-size: var(--fe-text-sm);
|
|
11382
|
+
line-height: 1.5;
|
|
11383
|
+
white-space: pre-wrap;
|
|
11384
|
+
}
|
|
11385
|
+
.fe-surface__text--heading {
|
|
11386
|
+
font-size: var(--fe-text-md, 15px);
|
|
11387
|
+
font-weight: 600;
|
|
11388
|
+
}
|
|
11389
|
+
.fe-surface__text--muted {
|
|
11390
|
+
color: var(--fe-text-muted);
|
|
11391
|
+
}
|
|
11392
|
+
.fe-surface__text--danger {
|
|
11393
|
+
color: var(--fe-danger);
|
|
11394
|
+
}
|
|
11395
|
+
.fe-surface__text--info {
|
|
11396
|
+
color: var(--fe-primary);
|
|
11397
|
+
}
|
|
11398
|
+
.fe-surface__divider {
|
|
11399
|
+
border: 0;
|
|
11400
|
+
border-top: 1px solid var(--fe-border);
|
|
11401
|
+
margin: 4px 0;
|
|
11402
|
+
}
|
|
11403
|
+
.fe-surface__row {
|
|
11404
|
+
display: flex;
|
|
11405
|
+
flex-wrap: wrap;
|
|
11406
|
+
gap: 10px;
|
|
11407
|
+
align-items: flex-start;
|
|
11408
|
+
}
|
|
11409
|
+
.fe-surface__row > .fe-surface {
|
|
11410
|
+
flex-direction: row;
|
|
11411
|
+
flex-wrap: wrap;
|
|
11412
|
+
}
|
|
11413
|
+
.fe-surface__unknown {
|
|
11414
|
+
margin: 0;
|
|
11415
|
+
padding: 8px 10px;
|
|
11416
|
+
border: 1px dashed var(--fe-border-strong);
|
|
11417
|
+
border-radius: var(--fe-radius-sm);
|
|
11418
|
+
color: var(--fe-text-muted);
|
|
11419
|
+
font-size: 12px;
|
|
11420
|
+
}
|
|
11421
|
+
.fe-surface__error {
|
|
11422
|
+
color: var(--fe-danger);
|
|
11423
|
+
font-size: 12px;
|
|
11424
|
+
margin: 0;
|
|
11425
|
+
}
|
|
11426
|
+
.fe-plugin-view {
|
|
11427
|
+
min-width: 0;
|
|
11428
|
+
}
|
|
11429
|
+
/* === /App plugins === */
|
|
11430
|
+
|
|
11431
|
+
/* === App plugins — M2 surface components (components/plugin/nodes/*) === */
|
|
11432
|
+
.fe-surface__form {
|
|
11433
|
+
min-width: 0;
|
|
11434
|
+
}
|
|
11435
|
+
.fe-steps {
|
|
11436
|
+
list-style: none;
|
|
11437
|
+
margin: 0;
|
|
11438
|
+
padding: 0;
|
|
11439
|
+
display: flex;
|
|
11440
|
+
flex-wrap: wrap;
|
|
11441
|
+
gap: 6px 18px;
|
|
11442
|
+
}
|
|
11443
|
+
.fe-steps__item {
|
|
11444
|
+
display: inline-flex;
|
|
11445
|
+
align-items: center;
|
|
11446
|
+
gap: 8px;
|
|
11447
|
+
font-size: var(--fe-text-sm);
|
|
11448
|
+
color: var(--fe-text-muted);
|
|
11449
|
+
}
|
|
11450
|
+
.fe-steps__item.is-active {
|
|
11451
|
+
color: var(--fe-text);
|
|
11452
|
+
font-weight: 600;
|
|
11453
|
+
}
|
|
11454
|
+
.fe-steps__item.is-done {
|
|
11455
|
+
color: var(--fe-text);
|
|
11456
|
+
}
|
|
11457
|
+
.fe-steps__marker {
|
|
11458
|
+
display: inline-flex;
|
|
11459
|
+
align-items: center;
|
|
11460
|
+
justify-content: center;
|
|
11461
|
+
width: 22px;
|
|
11462
|
+
height: 22px;
|
|
11463
|
+
border-radius: 50%;
|
|
11464
|
+
border: 1px solid var(--fe-border-strong);
|
|
11465
|
+
font-size: 12px;
|
|
11466
|
+
font-weight: 600;
|
|
11467
|
+
flex: 0 0 auto;
|
|
11468
|
+
}
|
|
11469
|
+
.fe-steps__marker .fe-ficon {
|
|
11470
|
+
width: 14px;
|
|
11471
|
+
height: 14px;
|
|
11472
|
+
}
|
|
11473
|
+
.fe-steps__item.is-active .fe-steps__marker {
|
|
11474
|
+
border-color: var(--fe-primary);
|
|
11475
|
+
background: var(--fe-primary);
|
|
11476
|
+
color: #fff;
|
|
11477
|
+
}
|
|
11478
|
+
.fe-steps__item.is-done .fe-steps__marker {
|
|
11479
|
+
border-color: var(--fe-primary);
|
|
11480
|
+
color: var(--fe-primary);
|
|
11481
|
+
}
|
|
11482
|
+
/* The plugin surfaces' `list` node draws `.tbl` — the one admin table — so
|
|
11483
|
+
everything `.fe-slist__table` used to say (12px/600 headers, 6px 8px cells,
|
|
11484
|
+
`--fe-border`, a `text-align: right` actions cell that was never actually
|
|
11485
|
+
pinned) is deleted rather than tuned. What is left is the node's own box:
|
|
11486
|
+
it must be allowed to be narrower than its content so the table inside can
|
|
11487
|
+
scroll instead of squeezing a surface into a column of single words. */
|
|
11488
|
+
.fe-slist {
|
|
11489
|
+
min-width: 0;
|
|
11490
|
+
}
|
|
11491
|
+
|
|
11492
|
+
.fe-sprogress {
|
|
11493
|
+
display: flex;
|
|
11494
|
+
flex-direction: column;
|
|
11495
|
+
gap: 6px;
|
|
11496
|
+
}
|
|
11497
|
+
.fe-sprogress__head {
|
|
11498
|
+
display: flex;
|
|
11499
|
+
justify-content: space-between;
|
|
11500
|
+
gap: 10px;
|
|
11501
|
+
font-size: var(--fe-text-sm);
|
|
11502
|
+
}
|
|
11503
|
+
.fe-sprogress__pct {
|
|
11504
|
+
color: var(--fe-text-muted);
|
|
11505
|
+
font-variant-numeric: tabular-nums;
|
|
11506
|
+
}
|
|
11507
|
+
.fe-sprogress__track {
|
|
11508
|
+
position: relative;
|
|
11509
|
+
height: 6px;
|
|
11510
|
+
border-radius: 3px;
|
|
11511
|
+
background: var(--fe-border);
|
|
11512
|
+
overflow: hidden;
|
|
11513
|
+
}
|
|
11514
|
+
.fe-sprogress__bar {
|
|
11515
|
+
height: 100%;
|
|
11516
|
+
background: var(--fe-primary);
|
|
11517
|
+
border-radius: 3px;
|
|
11518
|
+
transition: width 0.2s ease;
|
|
11519
|
+
}
|
|
11520
|
+
.fe-sprogress__track.is-indeterminate .fe-sprogress__bar {
|
|
11521
|
+
position: absolute;
|
|
11522
|
+
width: 35%;
|
|
11523
|
+
animation: fe-sprogress-slide 1.2s ease-in-out infinite;
|
|
11524
|
+
}
|
|
11525
|
+
@keyframes fe-sprogress-slide {
|
|
11526
|
+
0% {
|
|
11527
|
+
inset-inline-start: -35%;
|
|
11528
|
+
}
|
|
11529
|
+
100% {
|
|
11530
|
+
inset-inline-start: 100%;
|
|
11531
|
+
}
|
|
11532
|
+
}
|
|
11533
|
+
.fe-speople {
|
|
11534
|
+
display: flex;
|
|
11535
|
+
flex-direction: column;
|
|
11536
|
+
gap: 8px;
|
|
11537
|
+
min-width: 0;
|
|
11538
|
+
}
|
|
11539
|
+
.fe-speople__chips {
|
|
11540
|
+
list-style: none;
|
|
11541
|
+
margin: 0;
|
|
11542
|
+
padding: 0;
|
|
11543
|
+
display: flex;
|
|
11544
|
+
flex-wrap: wrap;
|
|
11545
|
+
gap: 6px;
|
|
11546
|
+
}
|
|
11547
|
+
.fe-speople__chip {
|
|
11548
|
+
display: inline-flex;
|
|
11549
|
+
align-items: center;
|
|
11550
|
+
gap: 6px;
|
|
11551
|
+
padding-block: 3px; padding-inline: 3px 6px;
|
|
11552
|
+
border-radius: 999px;
|
|
11553
|
+
border: 1px solid var(--fe-border-strong);
|
|
11554
|
+
background: var(--fe-bg-elev);
|
|
11555
|
+
font-size: 12.5px;
|
|
11556
|
+
max-width: 100%;
|
|
11557
|
+
}
|
|
11558
|
+
.fe-speople__av {
|
|
11559
|
+
display: inline-flex;
|
|
11560
|
+
align-items: center;
|
|
11561
|
+
justify-content: center;
|
|
11562
|
+
width: 20px;
|
|
11563
|
+
height: 20px;
|
|
11564
|
+
border-radius: 50%;
|
|
11565
|
+
background: var(--fe-primary);
|
|
11566
|
+
color: #fff;
|
|
11567
|
+
font-size: 11px;
|
|
11568
|
+
font-weight: 600;
|
|
11569
|
+
flex: 0 0 auto;
|
|
11570
|
+
}
|
|
11571
|
+
.fe-speople__name {
|
|
11572
|
+
overflow: hidden;
|
|
11573
|
+
text-overflow: ellipsis;
|
|
11574
|
+
white-space: nowrap;
|
|
11575
|
+
}
|
|
11576
|
+
.fe-speople__remove {
|
|
11577
|
+
border: 0;
|
|
11578
|
+
background: none;
|
|
11579
|
+
color: var(--fe-text-muted);
|
|
11580
|
+
cursor: pointer;
|
|
11581
|
+
padding: 0;
|
|
11582
|
+
display: inline-flex;
|
|
11583
|
+
align-items: center;
|
|
11584
|
+
}
|
|
11585
|
+
.fe-speople__remove .fe-ficon {
|
|
11586
|
+
width: 14px;
|
|
11587
|
+
height: 14px;
|
|
11588
|
+
}
|
|
11589
|
+
.fe-speople__remove:hover {
|
|
11590
|
+
color: var(--fe-danger);
|
|
11591
|
+
}
|
|
11592
|
+
.fe-speople__addwrap {
|
|
11593
|
+
position: relative;
|
|
11594
|
+
display: flex;
|
|
11595
|
+
gap: 6px;
|
|
11596
|
+
align-items: stretch;
|
|
11597
|
+
}
|
|
11598
|
+
.fe-speople__input {
|
|
11599
|
+
flex: 1 1 auto;
|
|
11600
|
+
}
|
|
11601
|
+
.fe-speople__suggest {
|
|
11602
|
+
top: 100%;
|
|
11603
|
+
inset-inline-start: 0;
|
|
11604
|
+
inset-inline-end: 0;
|
|
11605
|
+
}
|
|
11606
|
+
.fe-speople.is-invalid .fe-speople__input {
|
|
11607
|
+
border-color: var(--fe-danger);
|
|
11608
|
+
}
|
|
11609
|
+
.fe-spin {
|
|
11610
|
+
display: flex;
|
|
11611
|
+
flex-direction: column;
|
|
11612
|
+
gap: 5px;
|
|
11613
|
+
}
|
|
11614
|
+
.fe-spin__input {
|
|
11615
|
+
width: auto;
|
|
11616
|
+
max-width: calc(var(--spin-len, 6) * 1.6ch + 24px);
|
|
11617
|
+
letter-spacing: 0.5ch;
|
|
11618
|
+
font-size: 18px;
|
|
11619
|
+
text-align: center;
|
|
11620
|
+
}
|
|
11621
|
+
.fe-spin__input.is-invalid {
|
|
11622
|
+
border-color: var(--fe-danger);
|
|
11623
|
+
}
|
|
11624
|
+
.fe-sfile {
|
|
11625
|
+
display: flex;
|
|
11626
|
+
align-items: center;
|
|
11627
|
+
gap: 8px;
|
|
11628
|
+
flex-wrap: wrap;
|
|
11629
|
+
min-width: 0;
|
|
11630
|
+
}
|
|
11631
|
+
.fe-sfile__value {
|
|
11632
|
+
flex: 1 1 160px;
|
|
11633
|
+
min-width: 0;
|
|
11634
|
+
overflow: hidden;
|
|
11635
|
+
text-overflow: ellipsis;
|
|
11636
|
+
white-space: nowrap;
|
|
11637
|
+
font-size: var(--fe-text-sm);
|
|
11638
|
+
padding: 6px 10px;
|
|
11639
|
+
border: 1px solid var(--fe-border-strong);
|
|
11640
|
+
border-radius: var(--fe-radius);
|
|
11641
|
+
background: var(--fe-bg);
|
|
11642
|
+
}
|
|
11643
|
+
.fe-sfile__value--empty {
|
|
11644
|
+
color: var(--fe-text-muted);
|
|
11645
|
+
}
|
|
11646
|
+
.fe-sfile.is-invalid .fe-sfile__value {
|
|
11647
|
+
border-color: var(--fe-danger);
|
|
11648
|
+
}
|
|
11649
|
+
.fe-destpick__row.is-file .fe-destpick__rowname {
|
|
11650
|
+
color: var(--fe-text);
|
|
11651
|
+
}
|
|
11652
|
+
.fe-destpick__row.is-picked {
|
|
11653
|
+
background: var(--fe-primary-soft, rgba(37, 99, 235, 0.12));
|
|
11654
|
+
outline: 1px solid var(--fe-primary);
|
|
11655
|
+
}
|
|
11656
|
+
.fe-spreview {
|
|
11657
|
+
margin: 0;
|
|
11658
|
+
display: flex;
|
|
11659
|
+
flex-direction: column;
|
|
11660
|
+
align-items: center;
|
|
11661
|
+
gap: 6px;
|
|
11662
|
+
min-width: 0;
|
|
11663
|
+
}
|
|
11664
|
+
.fe-spreview__media {
|
|
11665
|
+
max-width: 100%;
|
|
11666
|
+
max-height: 320px;
|
|
11667
|
+
border-radius: var(--fe-radius);
|
|
11668
|
+
object-fit: contain;
|
|
11669
|
+
background: var(--fe-bg-elev);
|
|
11670
|
+
}
|
|
11671
|
+
.fe-spreview__audio {
|
|
11672
|
+
width: 100%;
|
|
11673
|
+
}
|
|
11674
|
+
.fe-spreview__tile {
|
|
11675
|
+
display: inline-flex;
|
|
11676
|
+
width: 48px;
|
|
11677
|
+
height: 48px;
|
|
11678
|
+
}
|
|
11679
|
+
.fe-spreview__tile > * {
|
|
11680
|
+
width: 100%;
|
|
11681
|
+
height: 100%;
|
|
11682
|
+
}
|
|
11683
|
+
.fe-spreview__name {
|
|
11684
|
+
font-size: 12px;
|
|
11685
|
+
color: var(--fe-text-muted);
|
|
11686
|
+
max-width: 100%;
|
|
11687
|
+
overflow: hidden;
|
|
11688
|
+
text-overflow: ellipsis;
|
|
11689
|
+
white-space: nowrap;
|
|
11690
|
+
}
|
|
11691
|
+
/* inspector placement */
|
|
11692
|
+
.fe-pinsp__heading {
|
|
11693
|
+
margin: 0;
|
|
11694
|
+
}
|
|
11695
|
+
.fe-pinsp__toggle {
|
|
11696
|
+
display: inline-flex;
|
|
11697
|
+
align-items: center;
|
|
11698
|
+
gap: 6px;
|
|
11699
|
+
border: 0;
|
|
11700
|
+
background: none;
|
|
11701
|
+
padding: 0;
|
|
11702
|
+
font: inherit;
|
|
11703
|
+
color: inherit;
|
|
11704
|
+
cursor: pointer;
|
|
11705
|
+
text-align: start;
|
|
11706
|
+
}
|
|
11707
|
+
.fe-pinsp__chev {
|
|
11708
|
+
width: 14px;
|
|
11709
|
+
height: 14px;
|
|
11710
|
+
transition: transform 0.15s ease;
|
|
11711
|
+
}
|
|
11712
|
+
.fe-pinsp__chev.is-open {
|
|
11713
|
+
transform: rotate(90deg);
|
|
11714
|
+
}
|
|
11715
|
+
.fe-pinsp__body {
|
|
11716
|
+
margin-top: 10px;
|
|
11717
|
+
display: flex;
|
|
11718
|
+
flex-direction: column;
|
|
11719
|
+
gap: 10px;
|
|
11720
|
+
}
|
|
11721
|
+
.fe-pinsp__actions {
|
|
11722
|
+
display: flex;
|
|
11723
|
+
flex-wrap: wrap;
|
|
11724
|
+
gap: 6px;
|
|
11725
|
+
}
|
|
11726
|
+
/* home placement — the "Apps" rows */
|
|
11727
|
+
.fe-sidenav__appicon {
|
|
11728
|
+
display: inline-flex;
|
|
11729
|
+
flex: 0 0 auto;
|
|
11730
|
+
}
|
|
11731
|
+
.fe-sidenav__appicon .fe-aicon,
|
|
11732
|
+
.fe-sidenav__appicon svg {
|
|
11733
|
+
width: 18px;
|
|
11734
|
+
height: 18px;
|
|
11735
|
+
}
|
|
11736
|
+
/* === /App plugins M2 === */
|
|
11737
|
+
|
|
11738
|
+
/* === App plugins — M3 sign track (signature-pad, pdf-fields) + the public page === */
|
|
11739
|
+
.fe-ssig {
|
|
11740
|
+
display: flex;
|
|
11741
|
+
flex-direction: column;
|
|
11742
|
+
gap: 8px;
|
|
11743
|
+
min-width: 0;
|
|
11744
|
+
}
|
|
11745
|
+
.fe-ssig__modes {
|
|
11746
|
+
display: flex;
|
|
11747
|
+
flex-wrap: wrap;
|
|
11748
|
+
gap: 6px;
|
|
11749
|
+
}
|
|
11750
|
+
.fe-ssig__padwrap,
|
|
11751
|
+
.fe-ssig__typewrap,
|
|
11752
|
+
.fe-ssig__uploadwrap {
|
|
11753
|
+
display: flex;
|
|
11754
|
+
flex-direction: column;
|
|
11755
|
+
gap: 6px;
|
|
11756
|
+
min-width: 0;
|
|
11757
|
+
}
|
|
11758
|
+
.fe-ssig__canvas,
|
|
11759
|
+
.fe-ssig__preview {
|
|
11760
|
+
display: block;
|
|
11761
|
+
width: 100%;
|
|
11762
|
+
border: 1px dashed var(--fe-border-strong);
|
|
11763
|
+
border-radius: var(--fe-radius);
|
|
11764
|
+
/* Paper, on both palettes: the ink is black and lands on a document. */
|
|
11765
|
+
background: #fff;
|
|
11766
|
+
touch-action: none;
|
|
11767
|
+
cursor: crosshair;
|
|
11768
|
+
}
|
|
11769
|
+
.fe-ssig__preview {
|
|
11770
|
+
cursor: default;
|
|
11771
|
+
display: flex;
|
|
11772
|
+
align-items: center;
|
|
11773
|
+
justify-content: center;
|
|
11774
|
+
overflow: hidden;
|
|
11775
|
+
min-height: 48px;
|
|
11776
|
+
}
|
|
11777
|
+
.fe-ssig__img {
|
|
11778
|
+
max-width: 100%;
|
|
11779
|
+
max-height: 200px;
|
|
11780
|
+
display: block;
|
|
11781
|
+
}
|
|
11782
|
+
.fe-ssig.is-invalid .fe-ssig__canvas,
|
|
11783
|
+
.fe-ssig.is-invalid .fe-ssig__preview {
|
|
11784
|
+
border-color: var(--fe-danger);
|
|
11785
|
+
}
|
|
11786
|
+
.fe-ssig.is-disabled .fe-ssig__canvas {
|
|
11787
|
+
cursor: not-allowed;
|
|
11788
|
+
opacity: 0.6;
|
|
11789
|
+
}
|
|
11790
|
+
.fe-ssig__hint {
|
|
11791
|
+
margin: 0;
|
|
11792
|
+
font-size: 12px;
|
|
11793
|
+
color: var(--fe-text-muted);
|
|
11794
|
+
}
|
|
11795
|
+
.fe-ssig__pick {
|
|
11796
|
+
position: relative;
|
|
11797
|
+
overflow: hidden;
|
|
11798
|
+
align-self: flex-start;
|
|
11799
|
+
}
|
|
11800
|
+
.fe-ssig__file {
|
|
11801
|
+
position: absolute;
|
|
11802
|
+
inset: 0;
|
|
11803
|
+
opacity: 0;
|
|
11804
|
+
cursor: pointer;
|
|
11805
|
+
}
|
|
11806
|
+
.fe-ssig__foot {
|
|
11807
|
+
display: flex;
|
|
11808
|
+
align-items: center;
|
|
11809
|
+
gap: 10px;
|
|
11810
|
+
}
|
|
11811
|
+
.fe-ssig__signed {
|
|
11812
|
+
font-size: 12px;
|
|
11813
|
+
color: var(--fe-ok);
|
|
11814
|
+
}
|
|
11815
|
+
|
|
11816
|
+
.fe-spdf {
|
|
11817
|
+
display: flex;
|
|
11818
|
+
flex-direction: column;
|
|
11819
|
+
gap: 8px;
|
|
11820
|
+
min-width: 0;
|
|
11821
|
+
}
|
|
11822
|
+
.fe-spdf__bar {
|
|
11823
|
+
display: flex;
|
|
11824
|
+
flex-wrap: wrap;
|
|
11825
|
+
align-items: center;
|
|
11826
|
+
justify-content: space-between;
|
|
11827
|
+
gap: 6px;
|
|
11828
|
+
}
|
|
11829
|
+
.fe-spdf__palette,
|
|
11830
|
+
.fe-spdf__zoom,
|
|
11831
|
+
.fe-spdf__props {
|
|
11832
|
+
display: flex;
|
|
11833
|
+
flex-wrap: wrap;
|
|
11834
|
+
align-items: center;
|
|
11835
|
+
gap: 6px;
|
|
11836
|
+
}
|
|
11837
|
+
.fe-spdf__zoomval {
|
|
11838
|
+
min-width: 52px;
|
|
11839
|
+
font-variant-numeric: tabular-nums;
|
|
11840
|
+
}
|
|
11841
|
+
.fe-spdf__hint {
|
|
11842
|
+
margin: 0;
|
|
11843
|
+
}
|
|
11844
|
+
/* ⚠⚠ The `place` step's one strip (component: `fe-spdf__strip`). Its height
|
|
11845
|
+
* is CONSTANT whatever it says — a hint, the selected box's controls, or an
|
|
11846
|
+
* idle line — because in a `page` layout the document is fitted to the pane
|
|
11847
|
+
* below it, and a strip that came and went re-fitted and redrew the whole
|
|
11848
|
+
* page on every tap (measured 2026-09-21: 383px → 349px wide mid-gesture).
|
|
11849
|
+
* One line of controls, scrolled sideways on a phone rather than wrapped to
|
|
11850
|
+
* a second line, for the same reason. */
|
|
11851
|
+
.fe-spdf__strip {
|
|
11852
|
+
min-height: 44px;
|
|
11853
|
+
display: flex;
|
|
11854
|
+
align-items: center;
|
|
11855
|
+
min-width: 0;
|
|
11856
|
+
}
|
|
11857
|
+
.fe-spdf__strip > .fe-spdf__props {
|
|
11858
|
+
flex: 1 1 auto;
|
|
11859
|
+
flex-wrap: nowrap;
|
|
11860
|
+
overflow-x: auto;
|
|
11861
|
+
white-space: nowrap;
|
|
11862
|
+
min-width: 0;
|
|
11863
|
+
}
|
|
11864
|
+
.fe-spdf__strip > .fe-spdf__hint {
|
|
11865
|
+
display: -webkit-box;
|
|
11866
|
+
-webkit-line-clamp: 2;
|
|
11867
|
+
-webkit-box-orient: vertical;
|
|
11868
|
+
overflow: hidden;
|
|
11869
|
+
line-height: 18px;
|
|
11870
|
+
}
|
|
11871
|
+
.fe-spdf__props {
|
|
11872
|
+
padding: 6px 8px;
|
|
11873
|
+
border: 1px solid var(--fe-border);
|
|
11874
|
+
border-radius: var(--fe-radius);
|
|
11875
|
+
background: var(--fe-bg-elev);
|
|
11876
|
+
font-size: var(--fe-text-sm);
|
|
11877
|
+
}
|
|
11878
|
+
.fe-spdf__propname {
|
|
11879
|
+
font-weight: 600;
|
|
11880
|
+
}
|
|
11881
|
+
.fe-spdf__prop {
|
|
11882
|
+
display: inline-flex;
|
|
11883
|
+
align-items: center;
|
|
11884
|
+
gap: 4px;
|
|
11885
|
+
}
|
|
11886
|
+
.fe-spdf__select {
|
|
11887
|
+
width: auto;
|
|
11888
|
+
padding: 2px 6px;
|
|
11889
|
+
height: 26px;
|
|
11890
|
+
}
|
|
11891
|
+
.fe-spdf__num {
|
|
11892
|
+
width: 72px;
|
|
11893
|
+
padding: 2px 6px;
|
|
11894
|
+
height: 26px;
|
|
11895
|
+
}
|
|
11896
|
+
/* The field's own name (v3 §3.1). Wide enough for "Yetkili imzası" and no
|
|
11897
|
+
wider: the property row is a strip over the document, not a form. */
|
|
11898
|
+
.fe-spdf__name {
|
|
11899
|
+
width: 160px;
|
|
11900
|
+
padding: 2px 6px;
|
|
11901
|
+
height: 26px;
|
|
11902
|
+
}
|
|
11903
|
+
/* The choice rows in the property strip are small — they sit beside the
|
|
11904
|
+
document rather than on a form of their own. */
|
|
11905
|
+
.fe-spdf__prop .fe-choice {
|
|
11906
|
+
gap: 4px;
|
|
11907
|
+
}
|
|
11908
|
+
.fe-spdf__prop .fe-choice__btn {
|
|
11909
|
+
padding: 3px 8px;
|
|
11910
|
+
font-size: var(--fe-text-xs);
|
|
11911
|
+
}
|
|
11912
|
+
.fe-spdf__prop .fe-choice__label {
|
|
11913
|
+
font-weight: 500;
|
|
11914
|
+
}
|
|
11915
|
+
/* What a text box will accept, or what is wrong with what is in it. ⚠ Drawn
|
|
11916
|
+
OUTSIDE the box: a field is a few millimetres of a page, and a hint inside
|
|
11917
|
+
it would cover the value it is about. */
|
|
11918
|
+
.fe-spdf__rule {
|
|
11919
|
+
position: absolute;
|
|
11920
|
+
top: 100%;
|
|
11921
|
+
inset-inline-start: 0;
|
|
11922
|
+
margin-top: 2px;
|
|
11923
|
+
padding: 1px 4px;
|
|
11924
|
+
max-width: 240px;
|
|
11925
|
+
border-radius: var(--fe-radius-sm);
|
|
11926
|
+
background: var(--fe-bg-elev);
|
|
11927
|
+
border: 1px solid var(--fe-border);
|
|
11928
|
+
color: var(--fe-text-muted);
|
|
11929
|
+
font-size: 10px;
|
|
11930
|
+
line-height: 1.3;
|
|
11931
|
+
white-space: nowrap;
|
|
11932
|
+
overflow: hidden;
|
|
11933
|
+
text-overflow: ellipsis;
|
|
11934
|
+
pointer-events: none;
|
|
11935
|
+
z-index: 2;
|
|
11936
|
+
}
|
|
11937
|
+
.fe-spdf__rule.is-bad {
|
|
11938
|
+
color: var(--fe-danger);
|
|
11939
|
+
border-color: var(--fe-danger);
|
|
11940
|
+
}
|
|
11941
|
+
.fe-spdf__scroll {
|
|
11942
|
+
overflow: auto;
|
|
11943
|
+
max-height: 70vh;
|
|
11944
|
+
border: 1px solid var(--fe-border);
|
|
11945
|
+
border-radius: var(--fe-radius);
|
|
11946
|
+
background: var(--fe-bg-hover);
|
|
11947
|
+
padding: 12px;
|
|
11948
|
+
min-width: 0;
|
|
11949
|
+
}
|
|
11950
|
+
|
|
11951
|
+
/* ⚠⚠ v3 §3.2 — `page` placement: the node owns the screen.
|
|
11952
|
+
*
|
|
11953
|
+
* The complaint that started this round was a signature page you had to
|
|
11954
|
+
* scroll in two directions to read: the document was fitted to the column's
|
|
11955
|
+
* WIDTH, so a portrait page in a landscape window ran off the bottom, and
|
|
11956
|
+
* the boxes were found by hunting. Here the node is a column of its own
|
|
11957
|
+
* height (`--spdf-h`, handed down by the frame), the toolbar and the
|
|
11958
|
+
* property strip keep their natural size, and the document takes the rest —
|
|
11959
|
+
* with the drawn width fitted to that remainder (component: `fitWidth`).
|
|
11960
|
+
*
|
|
11961
|
+
* `min-height: 0` is not decoration: without it a flex child refuses to
|
|
11962
|
+
* shrink below its content and the scroll area grows past the box instead
|
|
11963
|
+
* of scrolling inside it. */
|
|
11964
|
+
/* ── define: the boxes as cards, no document ──────────────────────────
|
|
11965
|
+
*
|
|
11966
|
+
* The step that asks WHAT is being asked of whom. Each card carries the
|
|
11967
|
+
* signer's colour down its edge, so the same box is recognisable on the
|
|
11968
|
+
* next step when it is dropped on the page. */
|
|
11969
|
+
.fe-spdf.is-define {
|
|
11970
|
+
gap: 12px;
|
|
11971
|
+
}
|
|
11972
|
+
.fe-spdf__define {
|
|
11973
|
+
display: flex;
|
|
11974
|
+
flex-direction: column;
|
|
11975
|
+
gap: 10px;
|
|
11976
|
+
}
|
|
11977
|
+
.fe-spdf__card {
|
|
11978
|
+
position: relative;
|
|
11979
|
+
display: flex;
|
|
11980
|
+
align-items: flex-start;
|
|
11981
|
+
gap: 10px;
|
|
11982
|
+
padding-block: 10px; padding-inline: 14px 12px;
|
|
11983
|
+
border: 1px solid var(--fe-border);
|
|
11984
|
+
border-inline-start: 3px solid var(--spdf-color, var(--fe-primary));
|
|
11985
|
+
border-radius: var(--fe-radius-md, 8px);
|
|
11986
|
+
background: var(--fe-bg-elev);
|
|
11987
|
+
}
|
|
11988
|
+
.fe-spdf__card .fe-spdf__props {
|
|
11989
|
+
flex: 1 1 auto;
|
|
11990
|
+
min-width: 0;
|
|
11991
|
+
margin: 0;
|
|
11992
|
+
padding: 0;
|
|
11993
|
+
border: 0;
|
|
11994
|
+
background: none;
|
|
11995
|
+
/* Row by row rather than one long line: a card is read, not scanned. */
|
|
11996
|
+
row-gap: 8px;
|
|
11997
|
+
column-gap: 10px;
|
|
11998
|
+
}
|
|
11999
|
+
.fe-spdf__card .fe-spdf__propname {
|
|
12000
|
+
flex: 0 0 auto;
|
|
12001
|
+
min-width: 84px;
|
|
12002
|
+
font-weight: 600;
|
|
12003
|
+
}
|
|
12004
|
+
.fe-spdf__card .fe-spdf__name {
|
|
12005
|
+
min-width: 180px;
|
|
12006
|
+
}
|
|
12007
|
+
/* The face row starts a line of its own — five buttons in the middle of a
|
|
12008
|
+
sentence of controls read as noise. */
|
|
12009
|
+
.fe-spdf__card .fe-signfonts {
|
|
12010
|
+
flex-basis: 100%;
|
|
12011
|
+
}
|
|
12012
|
+
/* What is printed under a signature: the choice, and the plugin's own words
|
|
12013
|
+
for it underneath — a card previews the paper, it does not describe it. */
|
|
12014
|
+
/* The date a box will carry, under the two answers that make it. Plain
|
|
12015
|
+
text, never a control: it is the result, not a third question. */
|
|
12016
|
+
.fe-spdf__dateex {
|
|
12017
|
+
margin: 0;
|
|
12018
|
+
display: flex;
|
|
12019
|
+
align-items: baseline;
|
|
12020
|
+
gap: 6px;
|
|
12021
|
+
flex-wrap: wrap;
|
|
12022
|
+
font-size: var(--fe-text-sm);
|
|
12023
|
+
}
|
|
12024
|
+
.fe-spdf__dateex-title {
|
|
12025
|
+
color: var(--fe-text-muted);
|
|
12026
|
+
}
|
|
12027
|
+
.fe-spdf__dateex-value {
|
|
12028
|
+
font-family: var(--fe-font-mono);
|
|
12029
|
+
font-weight: 600;
|
|
12030
|
+
}
|
|
12031
|
+
.fe-spdf__lines {
|
|
12032
|
+
flex-basis: 100%;
|
|
12033
|
+
flex-wrap: wrap;
|
|
12034
|
+
align-items: flex-start;
|
|
12035
|
+
row-gap: 6px;
|
|
12036
|
+
}
|
|
12037
|
+
.fe-spdf__linepreview {
|
|
12038
|
+
flex-basis: 100%;
|
|
12039
|
+
display: flex;
|
|
12040
|
+
flex-direction: column;
|
|
12041
|
+
gap: 1px;
|
|
12042
|
+
padding: 6px 10px;
|
|
12043
|
+
border: 1px dashed var(--fe-border-strong, var(--fe-border));
|
|
12044
|
+
border-radius: var(--fe-radius);
|
|
12045
|
+
background: var(--fe-bg);
|
|
12046
|
+
font-size: var(--fe-text-xs, 11px);
|
|
12047
|
+
line-height: 1.35;
|
|
12048
|
+
color: var(--fe-text);
|
|
12049
|
+
}
|
|
12050
|
+
.fe-spdf__linepreview-title {
|
|
12051
|
+
color: var(--fe-text-muted);
|
|
12052
|
+
font-weight: 600;
|
|
12053
|
+
margin-bottom: 2px;
|
|
12054
|
+
}
|
|
12055
|
+
.fe-spdf__linepreview-line.is-none {
|
|
12056
|
+
color: var(--fe-text-muted);
|
|
12057
|
+
font-style: italic;
|
|
12058
|
+
}
|
|
12059
|
+
.fe-spdf__propwho {
|
|
12060
|
+
font-size: var(--fe-text-sm);
|
|
12061
|
+
color: var(--fe-text-muted);
|
|
12062
|
+
}
|
|
12063
|
+
.fe-spdf__cardno {
|
|
12064
|
+
flex: 0 0 auto;
|
|
12065
|
+
width: 22px;
|
|
12066
|
+
height: 22px;
|
|
12067
|
+
border-radius: 50%;
|
|
12068
|
+
display: grid;
|
|
12069
|
+
place-items: center;
|
|
12070
|
+
font-size: var(--fe-text-xs, 11px);
|
|
12071
|
+
font-weight: 600;
|
|
12072
|
+
color: var(--fe-text-on-primary);
|
|
12073
|
+
background: var(--spdf-color, var(--fe-primary));
|
|
12074
|
+
}
|
|
12075
|
+
.fe-spdf__add {
|
|
12076
|
+
display: flex;
|
|
12077
|
+
align-items: center;
|
|
12078
|
+
flex-wrap: wrap;
|
|
12079
|
+
gap: 6px;
|
|
12080
|
+
padding-top: 2px;
|
|
12081
|
+
}
|
|
12082
|
+
.fe-spdf__addlbl {
|
|
12083
|
+
font-size: var(--fe-text-sm);
|
|
12084
|
+
color: var(--fe-text-muted);
|
|
12085
|
+
margin-inline-end: 4px;
|
|
12086
|
+
}
|
|
12087
|
+
.fe-spdf__empty {
|
|
12088
|
+
padding: 14px;
|
|
12089
|
+
border: 1px dashed var(--fe-border);
|
|
12090
|
+
border-radius: var(--fe-radius-md, 8px);
|
|
12091
|
+
color: var(--fe-text-muted);
|
|
12092
|
+
font-size: var(--fe-text-sm);
|
|
12093
|
+
line-height: 1.5;
|
|
12094
|
+
}
|
|
12095
|
+
.fe-spdf__done {
|
|
12096
|
+
font-size: var(--fe-text-sm);
|
|
12097
|
+
color: var(--fe-text-muted);
|
|
12098
|
+
align-self: center;
|
|
12099
|
+
}
|
|
12100
|
+
/* A waiting box wears its signer's colour, so the toolbar and the page
|
|
12101
|
+
agree about which box is which. */
|
|
12102
|
+
.fe-spdf__palette .fe-btn[style*='--spdf-color'] {
|
|
12103
|
+
border-inline-start: 3px solid var(--spdf-color, var(--fe-primary));
|
|
12104
|
+
}
|
|
12105
|
+
|
|
12106
|
+
.fe-spdf--page {
|
|
12107
|
+
display: flex;
|
|
12108
|
+
flex-direction: column;
|
|
12109
|
+
height: var(--spdf-h, 100%);
|
|
12110
|
+
min-height: 0;
|
|
12111
|
+
}
|
|
12112
|
+
.fe-spdf--page .fe-spdf__scroll {
|
|
12113
|
+
flex: 1 1 auto;
|
|
12114
|
+
max-height: none;
|
|
12115
|
+
min-height: 0;
|
|
12116
|
+
}
|
|
12117
|
+
/* Centred, because a fitted page is narrower than the box it is fitted in
|
|
12118
|
+
and a document pinned to the left edge of a wide screen reads as broken. */
|
|
12119
|
+
.fe-spdf--page .fe-spdf__pages {
|
|
12120
|
+
align-items: center;
|
|
12121
|
+
}
|
|
12122
|
+
.fe-spdf__pages {
|
|
12123
|
+
display: flex;
|
|
12124
|
+
flex-direction: column;
|
|
12125
|
+
align-items: flex-start;
|
|
12126
|
+
gap: 12px;
|
|
12127
|
+
}
|
|
12128
|
+
/* ⚠⚠ DOCUMENT SPACE from here in. A page is the PDF's own coordinate system:
|
|
12129
|
+
its boxes are placed with PHYSICAL inline `left`/`top` in % of the page
|
|
12130
|
+
(SurfacePdfFields, lib/pdfFieldsGeom → the signer stamps at those
|
|
12131
|
+
fractions), so a box at the left of the page is at the left of the page in
|
|
12132
|
+
Arabic too. Nothing inside a page may use logical properties or read
|
|
12133
|
+
`--filex-dir-x` — the RTL guard (web/tests/quality/rtlLogical.test.ts)
|
|
12134
|
+
allow-lists exactly these rules. */
|
|
12135
|
+
.fe-spdf__page {
|
|
12136
|
+
position: relative;
|
|
12137
|
+
background: #fff;
|
|
12138
|
+
box-shadow: var(--fe-shadow-sm);
|
|
12139
|
+
flex: 0 0 auto;
|
|
12140
|
+
touch-action: pan-y;
|
|
12141
|
+
user-select: none;
|
|
12142
|
+
}
|
|
12143
|
+
.fe-spdf.is-placing .fe-spdf__page {
|
|
12144
|
+
cursor: crosshair;
|
|
12145
|
+
}
|
|
12146
|
+
.fe-spdf__canvas {
|
|
12147
|
+
position: absolute;
|
|
12148
|
+
inset: 0;
|
|
12149
|
+
width: 100%;
|
|
12150
|
+
height: 100%;
|
|
12151
|
+
display: block;
|
|
12152
|
+
}
|
|
12153
|
+
.fe-spdf__field {
|
|
12154
|
+
position: absolute;
|
|
12155
|
+
box-sizing: border-box;
|
|
12156
|
+
border: 1.5px solid var(--spdf-color, var(--fe-primary));
|
|
12157
|
+
background: color-mix(in srgb, var(--spdf-color, var(--fe-primary)) 12%, transparent);
|
|
12158
|
+
border-radius: 2px;
|
|
12159
|
+
display: flex;
|
|
12160
|
+
align-items: center;
|
|
12161
|
+
justify-content: center;
|
|
12162
|
+
overflow: hidden;
|
|
12163
|
+
font-size: 11px;
|
|
12164
|
+
line-height: 1.15;
|
|
12165
|
+
color: var(--spdf-color, var(--fe-primary));
|
|
12166
|
+
cursor: pointer;
|
|
12167
|
+
}
|
|
12168
|
+
.fe-spdf.is-edit .fe-spdf__field {
|
|
12169
|
+
cursor: move;
|
|
12170
|
+
/* ⚠ A finger that drags a box must move the BOX. The page allows vertical
|
|
12171
|
+
panning (`pan-y`) so a signer can scroll a document with a finger; on a
|
|
12172
|
+
box that same pan was taken by the browser, which then cancelled the
|
|
12173
|
+
pointer — the box stopped half way and the pane scrolled instead. */
|
|
12174
|
+
touch-action: none;
|
|
12175
|
+
}
|
|
12176
|
+
.fe-spdf.is-edit.is-placing .fe-spdf__page {
|
|
12177
|
+
touch-action: none;
|
|
12178
|
+
}
|
|
12179
|
+
.fe-spdf__field.is-selected {
|
|
12180
|
+
outline: 2px solid var(--fe-primary);
|
|
12181
|
+
outline-offset: 1px;
|
|
12182
|
+
z-index: 2;
|
|
12183
|
+
}
|
|
12184
|
+
.fe-spdf__field.is-foreign {
|
|
12185
|
+
border-style: dashed;
|
|
12186
|
+
border-color: var(--fe-border-strong);
|
|
12187
|
+
background: rgba(128, 128, 128, 0.12);
|
|
12188
|
+
color: var(--fe-text-muted);
|
|
12189
|
+
cursor: default;
|
|
12190
|
+
pointer-events: none;
|
|
12191
|
+
}
|
|
12192
|
+
.fe-spdf__field.is-required::after {
|
|
12193
|
+
content: '*';
|
|
12194
|
+
position: absolute;
|
|
12195
|
+
top: 0;
|
|
12196
|
+
right: 3px; /* rtl-physical: ⚠⚠ DOCUMENT SPACE — drawn on the page, which never mirrors */
|
|
12197
|
+
font-weight: 700;
|
|
12198
|
+
}
|
|
12199
|
+
.fe-spdf__field--ghost {
|
|
12200
|
+
pointer-events: none;
|
|
12201
|
+
border-style: dotted;
|
|
12202
|
+
z-index: 3;
|
|
12203
|
+
}
|
|
12204
|
+
.fe-spdf__label {
|
|
12205
|
+
text-align: center;
|
|
12206
|
+
padding: 0 4px;
|
|
12207
|
+
display: flex;
|
|
12208
|
+
flex-direction: column;
|
|
12209
|
+
align-items: center;
|
|
12210
|
+
gap: 1px;
|
|
12211
|
+
white-space: nowrap;
|
|
12212
|
+
overflow: hidden;
|
|
12213
|
+
text-overflow: ellipsis;
|
|
12214
|
+
max-width: 100%;
|
|
12215
|
+
}
|
|
12216
|
+
.fe-spdf__who {
|
|
12217
|
+
font-size: 9px;
|
|
12218
|
+
opacity: 0.8;
|
|
12219
|
+
}
|
|
12220
|
+
.fe-spdf__sig {
|
|
12221
|
+
max-width: 100%;
|
|
12222
|
+
max-height: 100%;
|
|
12223
|
+
object-fit: contain;
|
|
12224
|
+
pointer-events: none;
|
|
12225
|
+
}
|
|
12226
|
+
.fe-spdf__text {
|
|
12227
|
+
width: 100%;
|
|
12228
|
+
height: 100%;
|
|
12229
|
+
border: 0;
|
|
12230
|
+
background: transparent;
|
|
12231
|
+
color: #111;
|
|
12232
|
+
font: inherit;
|
|
12233
|
+
font-size: 12px;
|
|
12234
|
+
padding: 0 4px;
|
|
12235
|
+
outline: none;
|
|
12236
|
+
min-width: 0;
|
|
12237
|
+
}
|
|
12238
|
+
.fe-spdf__check .fe-aicon {
|
|
12239
|
+
width: 90%;
|
|
12240
|
+
height: 90%;
|
|
12241
|
+
color: #111;
|
|
12242
|
+
}
|
|
12243
|
+
.fe-spdf__val {
|
|
12244
|
+
color: #111;
|
|
12245
|
+
font-variant-numeric: tabular-nums;
|
|
12246
|
+
}
|
|
12247
|
+
.fe-spdf__handle {
|
|
12248
|
+
position: absolute;
|
|
12249
|
+
/* ⚠⚠ DOCUMENT SPACE. The box sits at its PDF coordinates (inline `left`/`top`
|
|
12250
|
+
in % of the page, SurfacePdfFields) and grows right and down from there in
|
|
12251
|
+
every UI language — the resize maths reads the pointer against the page's
|
|
12252
|
+
own left edge. A handle mirrored to the box's left corner would drag the
|
|
12253
|
+
RIGHT edge while the pointer sits on the left one. */
|
|
12254
|
+
right: -5px; /* rtl-physical: document space (above) */
|
|
12255
|
+
bottom: -5px;
|
|
12256
|
+
width: 12px;
|
|
12257
|
+
height: 12px;
|
|
12258
|
+
border-radius: 50%;
|
|
12259
|
+
background: var(--spdf-color, var(--fe-primary));
|
|
12260
|
+
border: 2px solid #fff;
|
|
12261
|
+
cursor: nwse-resize;
|
|
12262
|
+
z-index: 3;
|
|
12263
|
+
}
|
|
12264
|
+
.fe-spdf__pad {
|
|
12265
|
+
display: flex;
|
|
12266
|
+
flex-direction: column;
|
|
12267
|
+
gap: 8px;
|
|
12268
|
+
padding: 10px;
|
|
12269
|
+
border: 1px solid var(--fe-border);
|
|
12270
|
+
border-radius: var(--fe-radius);
|
|
12271
|
+
background: var(--fe-bg-elev);
|
|
12272
|
+
}
|
|
12273
|
+
.fe-spdf__pad > .fe-btn {
|
|
12274
|
+
align-self: flex-end;
|
|
12275
|
+
}
|
|
12276
|
+
.fe-spreview__embed {
|
|
12277
|
+
width: 100%;
|
|
12278
|
+
height: 60vh;
|
|
12279
|
+
max-height: none;
|
|
12280
|
+
}
|
|
12281
|
+
|
|
12282
|
+
/* ── The outward-facing page ─────────────────────────────────────────────
|
|
12283
|
+
*
|
|
12284
|
+
* A share, a file request and an app plugin's public page are ONE page with
|
|
12285
|
+
* three bodies (v3 §1), and this is what that page LOOKS like. The shape is
|
|
12286
|
+
* the one the Go-rendered PIN gate had until v0.42.2 — a calm centred card
|
|
12287
|
+
* on a soft ground, the instance's mark above it, a tinted round badge, a
|
|
12288
|
+
* heading, a quiet line under it, a full-width field and a full-width accent
|
|
12289
|
+
* button — restored here so that unifying the pages levelled them UP.
|
|
12290
|
+
*
|
|
12291
|
+
* ⚠⚠ It was levelled DOWN in v0.43.0 (owner, 2026-09-23: "iki sayfa aynı
|
|
12292
|
+
* olsun dediğim için ikisini de kötü hale çevirmişsin"). The measurements
|
|
12293
|
+
* that had been lost, and are back: the card is 400px and CENTRED in the
|
|
12294
|
+
* viewport rather than 720px glued to the top; it is LIGHTER than the ground
|
|
12295
|
+
* (v0.43.0 drew `--fe-bg-elev`, the app's *sunken* tone, on `--fe-bg` — a
|
|
12296
|
+
* card you cannot see); 16px radius and 32/28 padding, not 12 and 20; a
|
|
12297
|
+
* 64px badge; a 20px/700 heading; and the primary button and the PIN box
|
|
12298
|
+
* span the card instead of hugging its left edge.
|
|
12299
|
+
*
|
|
12300
|
+
* Three widths, one family — exactly the old stylesheet's three cards:
|
|
12301
|
+
* · `--gate` 400px, centred text: the PIN gate, "this link is not
|
|
12302
|
+
* available", an error, an acceptance, and a single document.
|
|
12303
|
+
* · `--form` 520px, text from the start edge: a file request.
|
|
12304
|
+
* · `--wide` 880px: a folder's listing, and an app's screen.
|
|
12305
|
+
* The mode is the SHELL's (`layout`, forced to `gate` for every state that
|
|
12306
|
+
* is not `ready`), so no body carries a layout of its own.
|
|
12307
|
+
*
|
|
12308
|
+
* ⚠ The ground and the card are the public page's own tokens rather than
|
|
12309
|
+
* `--fe-bg`/`--fe-bg-elev`: in the app those two mean "surface" and "sunken
|
|
12310
|
+
* strip", and a card has to sit ABOVE its ground, not below it.
|
|
12311
|
+
* ⚠ Logical properties only (`padding-inline`, `margin-inline`): the page is
|
|
12312
|
+
* opened in Arabic too, and web/tests/quality/rtlLogical.test.ts says so. */
|
|
12313
|
+
.fe.fe-ppage {
|
|
12314
|
+
/* The ground, the card and the three widths are declared in
|
|
12315
|
+
styles/variables.css (light + dark) — see the note there. */
|
|
12316
|
+
min-height: 100vh;
|
|
12317
|
+
height: auto;
|
|
12318
|
+
border: 0;
|
|
12319
|
+
border-radius: 0;
|
|
12320
|
+
overflow: visible;
|
|
12321
|
+
display: flex;
|
|
12322
|
+
flex-direction: column;
|
|
12323
|
+
align-items: center;
|
|
12324
|
+
/* ⚠ `safe center` and not plain `center`: a tall body (an app's wizard with
|
|
12325
|
+
a document in it) is taller than the window, and a plainly centred flex
|
|
12326
|
+
column overflows past the TOP of the scrollport, where nothing can scroll
|
|
12327
|
+
it back. `safe` falls back to start alignment exactly then. The plain
|
|
12328
|
+
value stays as the fallback for anything that does not know the keyword. */
|
|
12329
|
+
justify-content: center;
|
|
12330
|
+
justify-content: safe center;
|
|
12331
|
+
gap: 18px;
|
|
12332
|
+
padding: 40px 16px;
|
|
12333
|
+
background: linear-gradient(160deg, var(--fe-ppage-ground-1), var(--fe-ppage-ground-2));
|
|
12334
|
+
color: var(--fe-text);
|
|
12335
|
+
}
|
|
12336
|
+
/* The instance's mark, ABOVE the card and centred on it — the first thing a
|
|
12337
|
+
* stranger reads, and (v3 §1.2) theirs, not ours. */
|
|
12338
|
+
.fe-ppage__brand {
|
|
12339
|
+
display: flex;
|
|
12340
|
+
align-items: center;
|
|
12341
|
+
justify-content: center;
|
|
12342
|
+
gap: 10px;
|
|
12343
|
+
max-width: 100%;
|
|
12344
|
+
min-width: 0;
|
|
12345
|
+
}
|
|
12346
|
+
.fe-ppage__logo {
|
|
12347
|
+
height: 34px;
|
|
12348
|
+
width: auto;
|
|
12349
|
+
max-width: 200px;
|
|
12350
|
+
object-fit: contain;
|
|
12351
|
+
display: block;
|
|
12352
|
+
flex: none;
|
|
12353
|
+
}
|
|
12354
|
+
.fe-ppage__brandname {
|
|
12355
|
+
font-size: 17px;
|
|
12356
|
+
font-weight: 700;
|
|
12357
|
+
letter-spacing: -0.01em;
|
|
12358
|
+
color: var(--fe-text);
|
|
12359
|
+
overflow-wrap: anywhere;
|
|
12360
|
+
}
|
|
12361
|
+
|
|
12362
|
+
.fe-ppage__card {
|
|
12363
|
+
width: 100%;
|
|
12364
|
+
max-width: var(--fe-ppage-max);
|
|
12365
|
+
background: var(--fe-ppage-card);
|
|
12366
|
+
border: 1px solid var(--fe-border);
|
|
12367
|
+
border-radius: 16px;
|
|
12368
|
+
box-shadow: var(--fe-ppage-shadow);
|
|
12369
|
+
padding: 28px 24px;
|
|
12370
|
+
display: flex;
|
|
12371
|
+
flex-direction: column;
|
|
12372
|
+
gap: 14px;
|
|
12373
|
+
min-width: 0;
|
|
12374
|
+
}
|
|
12375
|
+
.fe-ppage--gate .fe-ppage__card {
|
|
12376
|
+
padding: 32px 28px;
|
|
12377
|
+
text-align: center;
|
|
12378
|
+
gap: 12px;
|
|
12379
|
+
}
|
|
12380
|
+
|
|
12381
|
+
/* The round, accent-tinted badge the card opens with. One element with three
|
|
12382
|
+
* tones, so "protected", "gone" and "done" are the same shape in a different
|
|
12383
|
+
* colour rather than three drawings. */
|
|
12384
|
+
.fe-ppage__badge {
|
|
12385
|
+
width: 64px;
|
|
12386
|
+
height: 64px;
|
|
12387
|
+
margin-block-end: 2px;
|
|
12388
|
+
margin-inline: auto;
|
|
12389
|
+
border-radius: 50%;
|
|
12390
|
+
display: grid;
|
|
12391
|
+
place-items: center;
|
|
12392
|
+
flex: none;
|
|
12393
|
+
background: var(--fe-primary-soft);
|
|
12394
|
+
color: var(--fe-primary-ink);
|
|
12395
|
+
}
|
|
12396
|
+
.fe-ppage__badge svg {
|
|
12397
|
+
width: 30px;
|
|
12398
|
+
height: 30px;
|
|
12399
|
+
}
|
|
12400
|
+
.fe-ppage__badge--ok {
|
|
12401
|
+
background: color-mix(in srgb, var(--fe-ppage-ok) 14%, transparent);
|
|
12402
|
+
color: var(--fe-ppage-ok);
|
|
12403
|
+
}
|
|
12404
|
+
.fe-ppage__badge--err {
|
|
12405
|
+
background: color-mix(in srgb, var(--fe-danger) 12%, transparent);
|
|
12406
|
+
color: var(--fe-danger);
|
|
12407
|
+
}
|
|
12408
|
+
.fe-ppage__spinner {
|
|
12409
|
+
width: 26px;
|
|
12410
|
+
height: 26px;
|
|
12411
|
+
border: 2.5px solid currentColor;
|
|
12412
|
+
border-inline-end-color: transparent;
|
|
12413
|
+
border-radius: 50%;
|
|
12414
|
+
animation: fe-ppage-spin 0.8s linear infinite;
|
|
12415
|
+
opacity: 0.6;
|
|
12416
|
+
}
|
|
12417
|
+
@keyframes fe-ppage-spin {
|
|
12418
|
+
to {
|
|
12419
|
+
transform: rotate(360deg);
|
|
12420
|
+
}
|
|
12421
|
+
}
|
|
12422
|
+
@media (prefers-reduced-motion: reduce) {
|
|
12423
|
+
.fe-ppage__spinner {
|
|
12424
|
+
animation-duration: 2.4s;
|
|
12425
|
+
}
|
|
12426
|
+
}
|
|
12427
|
+
|
|
12428
|
+
.fe-ppage__head {
|
|
12429
|
+
display: flex;
|
|
12430
|
+
flex-direction: column;
|
|
12431
|
+
gap: 6px;
|
|
12432
|
+
}
|
|
12433
|
+
.fe-ppage__title {
|
|
12434
|
+
margin: 0;
|
|
12435
|
+
font-size: 20px;
|
|
12436
|
+
font-weight: 700;
|
|
12437
|
+
line-height: 1.3;
|
|
12438
|
+
letter-spacing: -0.01em;
|
|
12439
|
+
overflow-wrap: anywhere;
|
|
12440
|
+
}
|
|
12441
|
+
.fe-ppage__subject {
|
|
12442
|
+
margin: 0;
|
|
12443
|
+
color: var(--fe-text-muted);
|
|
12444
|
+
font-size: 14px;
|
|
12445
|
+
line-height: 1.5;
|
|
12446
|
+
overflow-wrap: anywhere;
|
|
12447
|
+
}
|
|
12448
|
+
.fe-ppage__state {
|
|
12449
|
+
display: flex;
|
|
12450
|
+
flex-direction: column;
|
|
12451
|
+
gap: 6px;
|
|
12452
|
+
}
|
|
12453
|
+
.fe-ppage__state-title {
|
|
12454
|
+
margin: 0;
|
|
12455
|
+
font-size: 20px;
|
|
12456
|
+
font-weight: 700;
|
|
12457
|
+
line-height: 1.3;
|
|
12458
|
+
letter-spacing: -0.01em;
|
|
12459
|
+
}
|
|
12460
|
+
.fe-ppage__state--ok .fe-ppage__state-title {
|
|
12461
|
+
color: var(--fe-ppage-ok);
|
|
12462
|
+
}
|
|
12463
|
+
/* The shell's OWN paragraphs at the reading size the old page used (0.9rem)
|
|
12464
|
+
* rather than the app's 13px table type.
|
|
12465
|
+
* ⚠ Scoped to the card's own children and to the shell's states — NOT to
|
|
12466
|
+
* every `.fe-surface__text` under `.fe-ppage`. An app plugin's screen is the
|
|
12467
|
+
* same `SurfaceConversation` a signed-in person sees, and resizing its text
|
|
12468
|
+
* only on a public link is exactly the surface-specific divergence the one
|
|
12469
|
+
* shell exists to prevent. */
|
|
12470
|
+
.fe-ppage__card > .fe-surface__text,
|
|
12471
|
+
.fe-ppage__state > .fe-surface__text,
|
|
12472
|
+
.fe-ppage__pin > .fe-surface__text,
|
|
12473
|
+
.fe-ppage__pin .fe-ppage__state > .fe-surface__text,
|
|
12474
|
+
.fe-pdrop > .fe-surface__text,
|
|
12475
|
+
.fe-pdrop__zone > .fe-surface__text,
|
|
12476
|
+
.fe-ppage__file-one > .fe-surface__text {
|
|
12477
|
+
font-size: 14px;
|
|
12478
|
+
line-height: 1.5;
|
|
12479
|
+
}
|
|
12480
|
+
|
|
12481
|
+
/* ⚠ On the gate the primary act spans the card: a 4-digit box and a
|
|
12482
|
+
* "Continue" hugging the left edge of a 400px card is what v0.43.0 shipped,
|
|
12483
|
+
* and it reads as a form fragment rather than the one thing to do. */
|
|
12484
|
+
.fe-ppage--gate .fe-btn {
|
|
12485
|
+
justify-content: center;
|
|
12486
|
+
}
|
|
12487
|
+
.fe-ppage--gate .fe-btn--primary {
|
|
12488
|
+
width: 100%;
|
|
12489
|
+
padding-block: 11px;
|
|
12490
|
+
font-size: 15px;
|
|
12491
|
+
font-weight: 600;
|
|
12492
|
+
border-radius: 10px;
|
|
12493
|
+
}
|
|
12494
|
+
.fe-ppage__pin {
|
|
12495
|
+
display: flex;
|
|
12496
|
+
flex-direction: column;
|
|
12497
|
+
gap: 12px;
|
|
12498
|
+
}
|
|
12499
|
+
/* The code box: the whole width, big, spaced and centred, as it was. A PIN is
|
|
12500
|
+
* read off a message and typed once — it is not a text field among others. */
|
|
12501
|
+
.fe-ppage__pinput.fe-ppage__pinput {
|
|
12502
|
+
box-sizing: border-box;
|
|
12503
|
+
width: 100%;
|
|
12504
|
+
max-width: none;
|
|
12505
|
+
height: auto;
|
|
12506
|
+
padding: 12px;
|
|
12507
|
+
font-size: 22px;
|
|
12508
|
+
font-weight: 600;
|
|
12509
|
+
letter-spacing: 0.32em;
|
|
12510
|
+
text-indent: 0.32em;
|
|
12511
|
+
text-align: center;
|
|
12512
|
+
border: 1.5px solid var(--fe-border-strong);
|
|
12513
|
+
border-radius: 10px;
|
|
12514
|
+
background: transparent;
|
|
12515
|
+
color: inherit;
|
|
12516
|
+
font-family: inherit;
|
|
12517
|
+
}
|
|
12518
|
+
.fe-ppage__pinput:focus {
|
|
12519
|
+
outline: none;
|
|
12520
|
+
border-color: var(--fe-primary);
|
|
12521
|
+
box-shadow: 0 0 0 3px var(--fe-primary-soft);
|
|
12522
|
+
}
|
|
12523
|
+
.fe-ppage__pinput.is-invalid {
|
|
12524
|
+
border-color: var(--fe-danger);
|
|
12525
|
+
}
|
|
12526
|
+
/* Named for a screen reader, not for the eye: the heading above it already
|
|
12527
|
+
* says what the box is, and a "PIN" label over a PIN box is furniture. */
|
|
12528
|
+
.fe-ppage__srlabel {
|
|
12529
|
+
position: absolute;
|
|
12530
|
+
width: 1px;
|
|
12531
|
+
height: 1px;
|
|
12532
|
+
padding: 0;
|
|
12533
|
+
margin: -1px;
|
|
12534
|
+
overflow: hidden;
|
|
12535
|
+
clip-path: inset(50%);
|
|
12536
|
+
white-space: nowrap;
|
|
12537
|
+
border: 0;
|
|
12538
|
+
}
|
|
12539
|
+
.fe-ppage__error {
|
|
12540
|
+
margin: 0;
|
|
12541
|
+
padding: 10px 12px;
|
|
12542
|
+
border-radius: 9px;
|
|
12543
|
+
background: color-mix(in srgb, var(--fe-danger) 10%, transparent);
|
|
12544
|
+
color: var(--fe-danger);
|
|
12545
|
+
font-size: 13.5px;
|
|
12546
|
+
}
|
|
12547
|
+
|
|
12548
|
+
/* A card's actions: a full-width row under a rule. ⚠ `width: 100%` is load
|
|
12549
|
+
bearing — inside a body that packs its children to the start
|
|
12550
|
+
(`__file-one`) the row shrink-wrapped and its rule stopped halfway across
|
|
12551
|
+
the card, which is what a folder share shipped as. */
|
|
12552
|
+
.fe-ppage__actions {
|
|
12553
|
+
display: flex;
|
|
12554
|
+
flex-wrap: wrap;
|
|
12555
|
+
justify-content: flex-end;
|
|
12556
|
+
gap: 8px;
|
|
12557
|
+
width: 100%;
|
|
12558
|
+
box-sizing: border-box;
|
|
12559
|
+
padding-top: 12px;
|
|
12560
|
+
border-top: 1px solid var(--fe-border-soft);
|
|
12561
|
+
}
|
|
12562
|
+
.fe-ppage--gate .fe-ppage__file-one {
|
|
12563
|
+
align-items: center;
|
|
12564
|
+
gap: 14px;
|
|
12565
|
+
}
|
|
12566
|
+
.fe-ppage--gate .fe-ppage__actions {
|
|
12567
|
+
justify-content: center;
|
|
12568
|
+
border-top: 0;
|
|
12569
|
+
padding-top: 0;
|
|
12570
|
+
}
|
|
12571
|
+
.fe-ppage__files {
|
|
12572
|
+
list-style: none;
|
|
12573
|
+
margin: 0;
|
|
12574
|
+
padding: 0;
|
|
12575
|
+
display: flex;
|
|
12576
|
+
flex-direction: column;
|
|
12577
|
+
border: 1px solid var(--fe-border);
|
|
12578
|
+
border-radius: 12px;
|
|
12579
|
+
overflow: hidden;
|
|
12580
|
+
}
|
|
12581
|
+
.fe-ppage__file {
|
|
12582
|
+
display: flex;
|
|
12583
|
+
align-items: center;
|
|
12584
|
+
gap: 10px;
|
|
12585
|
+
padding: 10px 14px;
|
|
12586
|
+
font-size: 14px;
|
|
12587
|
+
}
|
|
12588
|
+
.fe-ppage__file + .fe-ppage__file {
|
|
12589
|
+
border-top: 1px solid var(--fe-border);
|
|
12590
|
+
}
|
|
12591
|
+
.fe-ppage__file:hover {
|
|
12592
|
+
background: var(--fe-primary-soft);
|
|
12593
|
+
}
|
|
12594
|
+
.fe-ppage__file a {
|
|
12595
|
+
color: var(--fe-primary-ink);
|
|
12596
|
+
text-decoration: none;
|
|
12597
|
+
overflow: hidden;
|
|
12598
|
+
text-overflow: ellipsis;
|
|
12599
|
+
white-space: nowrap;
|
|
12600
|
+
}
|
|
12601
|
+
.fe-ppage__file a:hover {
|
|
12602
|
+
text-decoration: underline;
|
|
12603
|
+
}
|
|
12604
|
+
.fe-ppage__filesize {
|
|
12605
|
+
color: var(--fe-text-muted);
|
|
12606
|
+
flex: 0 0 auto;
|
|
12607
|
+
font-variant-numeric: tabular-nums;
|
|
12608
|
+
}
|
|
12609
|
+
|
|
12610
|
+
/* The phone. 390px is the measurement that matters: the card gives up its
|
|
12611
|
+
* generous side padding rather than its rhythm, and keeps a 12px gutter each
|
|
12612
|
+
* side. (A body too tall to centre starts at the top by itself — that is
|
|
12613
|
+
* `justify-content: safe center` above, not a rule here.) */
|
|
12614
|
+
@media (max-width: 560px) {
|
|
12615
|
+
.fe.fe-ppage {
|
|
12616
|
+
padding: 24px 12px 32px;
|
|
12617
|
+
}
|
|
12618
|
+
.fe-ppage__card {
|
|
12619
|
+
padding: 24px 18px;
|
|
12620
|
+
}
|
|
12621
|
+
.fe-ppage--gate .fe-ppage__card {
|
|
12622
|
+
padding: 28px 20px;
|
|
12623
|
+
}
|
|
12624
|
+
.fe-ppage__logo {
|
|
12625
|
+
height: 28px;
|
|
12626
|
+
}
|
|
12627
|
+
.fe-ppage__title,
|
|
12628
|
+
.fe-ppage__state-title {
|
|
12629
|
+
font-size: 18px;
|
|
12630
|
+
}
|
|
12631
|
+
.fe-ppage__actions .fe-btn {
|
|
12632
|
+
flex: 1 1 auto;
|
|
12633
|
+
justify-content: center;
|
|
12634
|
+
}
|
|
12635
|
+
}
|
|
12636
|
+
/* === /App plugins M3 === */
|
|
12637
|
+
|
|
12638
|
+
/* === App plugins v3 — the shared choice control and the ONE public
|
|
12639
|
+
* shell (docs/APP-PLUGINS-V3.md §1–§2).
|
|
12640
|
+
*
|
|
12641
|
+
* ⚠⚠ These rules live HERE and not in the components, for a reason the
|
|
12642
|
+
* build makes and not a taste: the web component ships only the styles of
|
|
12643
|
+
* the modules its entry imports, while `packages/core` ships all of them,
|
|
12644
|
+
* so a `<style>` block in a component one distribution does not mount makes
|
|
12645
|
+
* the two published stylesheets differ. `web/tests/deploy/packageLook` is
|
|
12646
|
+
* the gate that says so. === */
|
|
12647
|
+
|
|
12648
|
+
/* ChoiceButtons.vue */
|
|
12649
|
+
.fe-choice {
|
|
12650
|
+
display: flex;
|
|
12651
|
+
flex-wrap: wrap;
|
|
12652
|
+
gap: 8px;
|
|
12653
|
+
}
|
|
12654
|
+
.fe-choice__btn {
|
|
12655
|
+
flex: 0 1 auto;
|
|
12656
|
+
display: flex;
|
|
12657
|
+
flex-direction: column;
|
|
12658
|
+
align-items: flex-start;
|
|
12659
|
+
gap: 2px;
|
|
12660
|
+
min-width: 0;
|
|
12661
|
+
font: inherit;
|
|
12662
|
+
font-size: 13.5px;
|
|
12663
|
+
text-align: start;
|
|
12664
|
+
padding: 8px 12px;
|
|
12665
|
+
border-radius: var(--fe-radius);
|
|
12666
|
+
border: 1px solid var(--fe-border-strong);
|
|
12667
|
+
background: var(--fe-bg);
|
|
12668
|
+
color: var(--fe-text);
|
|
12669
|
+
cursor: pointer;
|
|
12670
|
+
}
|
|
12671
|
+
.fe-choice__btn:hover:not(:disabled) {
|
|
12672
|
+
background: var(--fe-bg-hover);
|
|
12673
|
+
}
|
|
12674
|
+
.fe-choice__btn:focus-visible {
|
|
12675
|
+
outline: 2px solid var(--fe-primary);
|
|
12676
|
+
outline-offset: 1px;
|
|
12677
|
+
}
|
|
12678
|
+
/* ⚠ The chosen one is marked by BORDER and BACKGROUND, not by colour alone:
|
|
12679
|
+
a palette where the primary is close to the surface still shows which is
|
|
12680
|
+
on, and so does a screen nobody has calibrated. */
|
|
12681
|
+
.fe-choice__btn.is-on {
|
|
12682
|
+
border-color: var(--fe-primary);
|
|
12683
|
+
background: var(--fe-bg-selected);
|
|
12684
|
+
color: var(--fe-text);
|
|
12685
|
+
box-shadow: inset 0 0 0 1px var(--fe-primary);
|
|
12686
|
+
}
|
|
12687
|
+
.fe-choice__btn:disabled {
|
|
12688
|
+
opacity: 0.55;
|
|
12689
|
+
cursor: default;
|
|
12690
|
+
}
|
|
12691
|
+
.fe-choice.is-invalid .fe-choice__btn {
|
|
12692
|
+
border-color: var(--fe-danger);
|
|
12693
|
+
}
|
|
12694
|
+
.fe-choice__label {
|
|
12695
|
+
font-weight: 600;
|
|
12696
|
+
}
|
|
12697
|
+
.fe-choice__help {
|
|
12698
|
+
font-size: 12px;
|
|
12699
|
+
color: var(--fe-text-muted);
|
|
12700
|
+
line-height: 1.4;
|
|
12701
|
+
}
|
|
12702
|
+
|
|
12703
|
+
/* SurfaceFooterButtons.vue */
|
|
12704
|
+
/* Back sits at the far end of the row, away from the way forward: a step's
|
|
12705
|
+
two directions must not be two neighbouring buttons. `margin-right: auto`
|
|
12706
|
+
works in every frame that lays the row out as a flex line, and is inert in
|
|
12707
|
+
one that does not. */
|
|
12708
|
+
.fe-surface__back {
|
|
12709
|
+
margin-inline-end: auto;
|
|
12710
|
+
}
|
|
12711
|
+
|
|
12712
|
+
/* PublicShell.vue — the meta line and the foot.
|
|
12713
|
+
The expiry and the visit counter are a quiet line under the heading, and
|
|
12714
|
+
the language picker + attribution sit OUTSIDE the card, centred under it,
|
|
12715
|
+
the way the old page's brand footer did. */
|
|
12716
|
+
.fe-ppage__meta {
|
|
12717
|
+
margin: 0;
|
|
12718
|
+
display: flex;
|
|
12719
|
+
flex-wrap: wrap;
|
|
12720
|
+
gap: 6px;
|
|
12721
|
+
font-size: 13px;
|
|
12722
|
+
color: var(--fe-text-muted);
|
|
12723
|
+
}
|
|
12724
|
+
.fe-ppage--gate .fe-ppage__meta {
|
|
12725
|
+
justify-content: center;
|
|
12726
|
+
}
|
|
12727
|
+
.fe-ppage__foot {
|
|
12728
|
+
display: flex;
|
|
12729
|
+
flex-direction: column;
|
|
12730
|
+
align-items: center;
|
|
12731
|
+
gap: 10px;
|
|
12732
|
+
width: 100%;
|
|
12733
|
+
}
|
|
12734
|
+
.fe-ppage__footmark {
|
|
12735
|
+
display: inline-flex;
|
|
12736
|
+
align-items: center;
|
|
12737
|
+
gap: 7px;
|
|
12738
|
+
font-size: 12.5px;
|
|
12739
|
+
color: var(--fe-text-muted);
|
|
12740
|
+
}
|
|
12741
|
+
.fe-ppage__footmark img,
|
|
12742
|
+
.fe-ppage__footmark svg {
|
|
12743
|
+
width: 16px;
|
|
12744
|
+
height: 16px;
|
|
12745
|
+
flex: none;
|
|
12746
|
+
border-radius: 3px;
|
|
12747
|
+
object-fit: contain;
|
|
12748
|
+
}
|
|
12749
|
+
.fe-ppage__footline {
|
|
12750
|
+
margin: 0;
|
|
12751
|
+
font-size: 12.5px;
|
|
12752
|
+
color: var(--fe-text-muted);
|
|
12753
|
+
text-align: center;
|
|
12754
|
+
max-width: 480px;
|
|
12755
|
+
overflow-wrap: anywhere;
|
|
12756
|
+
}
|
|
12757
|
+
|
|
12758
|
+
/* PublicShareBody.vue */
|
|
12759
|
+
.fe-ppage__crumbs {
|
|
12760
|
+
display: flex;
|
|
12761
|
+
align-items: center;
|
|
12762
|
+
gap: 8px;
|
|
12763
|
+
font-size: 13px;
|
|
12764
|
+
color: var(--fe-text-muted);
|
|
12765
|
+
}
|
|
12766
|
+
.fe-ppage__crumb {
|
|
12767
|
+
overflow: hidden;
|
|
12768
|
+
text-overflow: ellipsis;
|
|
12769
|
+
white-space: nowrap;
|
|
12770
|
+
}
|
|
12771
|
+
.fe-ppage__entry {
|
|
12772
|
+
font: inherit;
|
|
12773
|
+
font-size: 13.5px;
|
|
12774
|
+
color: var(--fe-primary);
|
|
12775
|
+
background: none;
|
|
12776
|
+
border: 0;
|
|
12777
|
+
padding: 0;
|
|
12778
|
+
text-align: start;
|
|
12779
|
+
cursor: pointer;
|
|
12780
|
+
text-decoration: none;
|
|
12781
|
+
}
|
|
12782
|
+
.fe-ppage__entry:hover {
|
|
12783
|
+
text-decoration: underline;
|
|
12784
|
+
}
|
|
12785
|
+
.fe-ppage__file-one {
|
|
12786
|
+
display: flex;
|
|
12787
|
+
flex-direction: column;
|
|
12788
|
+
align-items: flex-start;
|
|
12789
|
+
gap: 10px;
|
|
12790
|
+
}
|
|
12791
|
+
/* An app page's exposed files, drawn as a shared file is, under a rule that
|
|
12792
|
+
separates them from the app's own screen above. */
|
|
12793
|
+
.fe-ppage__appfiles {
|
|
12794
|
+
display: flex;
|
|
12795
|
+
flex-direction: column;
|
|
12796
|
+
gap: 12px;
|
|
12797
|
+
padding-top: 12px;
|
|
12798
|
+
border-top: 1px solid var(--fe-border);
|
|
12799
|
+
}
|
|
12800
|
+
.fe-ppage__shot {
|
|
12801
|
+
max-width: 100%;
|
|
12802
|
+
max-height: 46vh;
|
|
12803
|
+
border-radius: var(--fe-radius);
|
|
12804
|
+
border: 1px solid var(--fe-border);
|
|
12805
|
+
object-fit: contain;
|
|
12806
|
+
}
|
|
12807
|
+
|
|
12808
|
+
/* PublicRequestBody.vue */
|
|
12809
|
+
.fe-pdrop {
|
|
12810
|
+
display: flex;
|
|
12811
|
+
flex-direction: column;
|
|
12812
|
+
gap: 12px;
|
|
12813
|
+
}
|
|
12814
|
+
/* The uploader's name — above the drop area, because dropping sends. */
|
|
12815
|
+
.fe-pdrop__who {
|
|
12816
|
+
display: flex;
|
|
12817
|
+
flex-direction: column;
|
|
12818
|
+
gap: 4px;
|
|
12819
|
+
}
|
|
12820
|
+
.fe-pdrop__wholabel {
|
|
12821
|
+
font-size: var(--fe-text-sm);
|
|
12822
|
+
font-weight: 500;
|
|
12823
|
+
color: var(--fe-text);
|
|
12824
|
+
}
|
|
12825
|
+
.fe-pdrop__whoinput {
|
|
12826
|
+
box-sizing: border-box;
|
|
12827
|
+
width: 100%;
|
|
12828
|
+
height: var(--fe-h-lg);
|
|
12829
|
+
padding: 0 var(--fe-gap-sm);
|
|
12830
|
+
border: 1px solid var(--fe-border);
|
|
12831
|
+
border-radius: var(--fe-radius);
|
|
12832
|
+
background: var(--fe-bg);
|
|
12833
|
+
color: var(--fe-text);
|
|
12834
|
+
font-family: inherit;
|
|
12835
|
+
font-size: var(--fe-text-md);
|
|
12836
|
+
}
|
|
12837
|
+
.fe-pdrop__whoinput:focus {
|
|
12838
|
+
outline: none;
|
|
12839
|
+
border-color: var(--fe-primary);
|
|
12840
|
+
}
|
|
12841
|
+
.fe-pdrop__zone {
|
|
12842
|
+
display: flex;
|
|
12843
|
+
flex-direction: column;
|
|
12844
|
+
align-items: center;
|
|
12845
|
+
justify-content: center;
|
|
12846
|
+
gap: 4px;
|
|
12847
|
+
padding: 28px 16px;
|
|
12848
|
+
border: 2px dashed var(--fe-border-strong);
|
|
12849
|
+
border-radius: var(--fe-radius-lg);
|
|
12850
|
+
background: var(--fe-bg-elev);
|
|
12851
|
+
cursor: pointer;
|
|
12852
|
+
text-align: center;
|
|
12853
|
+
}
|
|
12854
|
+
.fe-pdrop__zone:focus-visible {
|
|
12855
|
+
outline: 2px solid var(--fe-primary);
|
|
12856
|
+
outline-offset: 2px;
|
|
12857
|
+
}
|
|
12858
|
+
.fe-pdrop__zone.is-over {
|
|
12859
|
+
border-color: var(--fe-primary);
|
|
12860
|
+
background: var(--fe-bg-selected);
|
|
12861
|
+
}
|
|
12862
|
+
.fe-pdrop__zone.is-disabled {
|
|
12863
|
+
cursor: default;
|
|
12864
|
+
opacity: 0.6;
|
|
12865
|
+
}
|
|
12866
|
+
.fe-pdrop__icon {
|
|
12867
|
+
width: 38px;
|
|
12868
|
+
height: 38px;
|
|
12869
|
+
margin-block-end: 6px;
|
|
12870
|
+
color: inherit;
|
|
12871
|
+
}
|
|
12872
|
+
.fe-pdrop__lead {
|
|
12873
|
+
margin: 0;
|
|
12874
|
+
font-size: 16px;
|
|
12875
|
+
font-weight: 600;
|
|
12876
|
+
color: var(--fe-text);
|
|
12877
|
+
}
|
|
12878
|
+
/* The zone answers the pointer the way the old one did: the accent's tint,
|
|
12879
|
+
its border and its ink, all three at once. */
|
|
12880
|
+
.fe-pdrop__zone:hover:not(.is-disabled),
|
|
12881
|
+
.fe-pdrop__zone.is-over {
|
|
12882
|
+
border-color: var(--fe-primary);
|
|
12883
|
+
background: var(--fe-primary-soft);
|
|
12884
|
+
color: var(--fe-primary-ink);
|
|
12885
|
+
}
|
|
12886
|
+
.fe-pdrop__zone:hover:not(.is-disabled) .fe-pdrop__lead,
|
|
12887
|
+
.fe-pdrop__zone.is-over .fe-pdrop__lead {
|
|
12888
|
+
color: inherit;
|
|
12889
|
+
}
|
|
12890
|
+
.fe-pdrop__input {
|
|
12891
|
+
display: none;
|
|
12892
|
+
}
|
|
12893
|
+
.fe-pdrop__list {
|
|
12894
|
+
list-style: none;
|
|
12895
|
+
margin: 0;
|
|
12896
|
+
padding: 0;
|
|
12897
|
+
display: flex;
|
|
12898
|
+
flex-direction: column;
|
|
12899
|
+
gap: 6px;
|
|
12900
|
+
}
|
|
12901
|
+
.fe-pdrop__item {
|
|
12902
|
+
display: flex;
|
|
12903
|
+
align-items: center;
|
|
12904
|
+
gap: 8px;
|
|
12905
|
+
font-size: 13px;
|
|
12906
|
+
color: var(--fe-text);
|
|
12907
|
+
}
|
|
12908
|
+
.fe-pdrop__name {
|
|
12909
|
+
flex: 1 1 auto;
|
|
12910
|
+
min-width: 0;
|
|
12911
|
+
overflow: hidden;
|
|
12912
|
+
text-overflow: ellipsis;
|
|
12913
|
+
white-space: nowrap;
|
|
12914
|
+
}
|
|
12915
|
+
.fe-pdrop__bar {
|
|
12916
|
+
flex: 0 0 120px;
|
|
12917
|
+
height: 6px;
|
|
12918
|
+
}
|
|
12919
|
+
.fe-pdrop__ok {
|
|
12920
|
+
color: var(--fe-ok);
|
|
12921
|
+
}
|
|
12922
|
+
|
|
12923
|
+
/* PublicLanguagePicker.vue */
|
|
12924
|
+
.fe-plang {
|
|
12925
|
+
display: flex;
|
|
12926
|
+
flex-wrap: wrap;
|
|
12927
|
+
gap: 6px;
|
|
12928
|
+
}
|
|
12929
|
+
.fe-plang__btn {
|
|
12930
|
+
display: inline-flex;
|
|
12931
|
+
align-items: baseline;
|
|
12932
|
+
gap: 4px;
|
|
12933
|
+
font: inherit;
|
|
12934
|
+
font-size: 12.5px;
|
|
12935
|
+
padding: 4px 10px;
|
|
12936
|
+
border-radius: 999px;
|
|
12937
|
+
border: 1px solid var(--fe-border);
|
|
12938
|
+
background: transparent;
|
|
12939
|
+
color: var(--fe-text-muted);
|
|
12940
|
+
cursor: pointer;
|
|
12941
|
+
}
|
|
12942
|
+
.fe-plang__btn:hover {
|
|
12943
|
+
color: var(--fe-text);
|
|
12944
|
+
background: var(--fe-bg-hover);
|
|
12945
|
+
}
|
|
12946
|
+
.fe-plang__btn.is-on {
|
|
12947
|
+
color: var(--fe-text);
|
|
12948
|
+
border-color: var(--fe-primary);
|
|
12949
|
+
background: var(--fe-bg-selected);
|
|
12950
|
+
}
|
|
12951
|
+
.fe-plang__btn:focus-visible {
|
|
12952
|
+
outline: 2px solid var(--fe-primary);
|
|
12953
|
+
outline-offset: 1px;
|
|
12954
|
+
}
|
|
12955
|
+
.fe-plang__src {
|
|
12956
|
+
font-size: 10.5px;
|
|
12957
|
+
opacity: 0.75;
|
|
12958
|
+
}
|
|
12959
|
+
|
|
12960
|
+
|
|
12961
|
+
/* === App plugins v2 ===================================================
|
|
12962
|
+
* A `page` view (`{base}apps/{plugin}/{view}`), the lock badge an app's
|
|
12963
|
+
* hold puts on a row, and the face picker a typed signature carries. */
|
|
12964
|
+
|
|
12965
|
+
/* The page view is a whole document, not a panel: the `.fe` root's explorer
|
|
12966
|
+
* chrome (border, radius, fixed height, hidden overflow) is undone here for
|
|
12967
|
+
* the same reason `.fe-ppage` undoes it. ⚠ Without this the wizard is a
|
|
12968
|
+
* 420px-tall bordered box floating in an empty tab. */
|
|
12969
|
+
.fe.fe-apppage {
|
|
12970
|
+
min-height: 100vh;
|
|
12971
|
+
height: auto;
|
|
12972
|
+
border: 0;
|
|
12973
|
+
border-radius: 0;
|
|
12974
|
+
overflow: visible;
|
|
12975
|
+
padding: 0 0 40px;
|
|
12976
|
+
gap: 0;
|
|
12977
|
+
}
|
|
12978
|
+
.fe-apppage__bar {
|
|
12979
|
+
display: flex;
|
|
12980
|
+
align-items: baseline;
|
|
12981
|
+
gap: 12px;
|
|
12982
|
+
flex-wrap: wrap;
|
|
12983
|
+
padding: 16px;
|
|
12984
|
+
border-bottom: 1px solid var(--fe-border);
|
|
12985
|
+
background: var(--fe-bg-elev);
|
|
12986
|
+
}
|
|
12987
|
+
.fe-apppage__title {
|
|
12988
|
+
margin: 0;
|
|
12989
|
+
font-size: 18px;
|
|
12990
|
+
font-weight: 600;
|
|
12991
|
+
line-height: 1.25;
|
|
12992
|
+
}
|
|
12993
|
+
.fe-apppage__path {
|
|
12994
|
+
margin: 0;
|
|
12995
|
+
flex: 1 1 200px;
|
|
12996
|
+
min-width: 0;
|
|
12997
|
+
color: var(--fe-text-muted);
|
|
12998
|
+
font-size: var(--fe-text-sm);
|
|
12999
|
+
font-family: var(--fe-font-mono);
|
|
13000
|
+
overflow: hidden;
|
|
13001
|
+
text-overflow: ellipsis;
|
|
13002
|
+
white-space: nowrap;
|
|
13003
|
+
}
|
|
13004
|
+
.fe-apppage__back {
|
|
13005
|
+
flex: 0 0 auto;
|
|
13006
|
+
text-decoration: none;
|
|
13007
|
+
}
|
|
13008
|
+
.fe-apppage__body {
|
|
13009
|
+
width: 100%;
|
|
13010
|
+
max-width: 960px;
|
|
13011
|
+
margin: 0 auto;
|
|
13012
|
+
padding: 20px 16px;
|
|
13013
|
+
display: flex;
|
|
13014
|
+
flex-direction: column;
|
|
13015
|
+
gap: 14px;
|
|
13016
|
+
min-width: 0;
|
|
13017
|
+
}
|
|
13018
|
+
|
|
13019
|
+
/* ⚠⚠ v3 §3.2 — the step that shows a DOCUMENT is shaped by the window,
|
|
13020
|
+
* not by the text column.
|
|
13021
|
+
*
|
|
13022
|
+
* A form step is a readable 960px column that the page scrolls; a step
|
|
13023
|
+
* carrying a `pdf-fields` node is not a form, it is a document. Measured
|
|
13024
|
+
* before this rule, on the request wizard's "place the fields" step at
|
|
13025
|
+
* 1440x900: the page box was 916x1296 inside a 916x618 viewport, i.e. the
|
|
13026
|
+
* document ran off the bottom AND sideways — which is the complaint that
|
|
13027
|
+
* started this round, reproduced exactly.
|
|
13028
|
+
*
|
|
13029
|
+
* `min-height: 0` on the body is not decoration: without it a flex child
|
|
13030
|
+
* refuses to shrink below its content, and the "remainder" the document is
|
|
13031
|
+
* fitted into grows to the document's own height, which is the bug again
|
|
13032
|
+
* wearing a fix's clothes. */
|
|
13033
|
+
.fe.fe-apppage.is-doc {
|
|
13034
|
+
height: 100vh;
|
|
13035
|
+
min-height: 0;
|
|
13036
|
+
overflow: hidden;
|
|
13037
|
+
padding-bottom: 0;
|
|
13038
|
+
}
|
|
13039
|
+
.fe-apppage.is-doc .fe-apppage__body {
|
|
13040
|
+
flex: 1 1 auto;
|
|
13041
|
+
min-height: 0;
|
|
13042
|
+
max-width: none;
|
|
13043
|
+
overflow: hidden;
|
|
13044
|
+
}
|
|
13045
|
+
/* ⚠⚠ ...and one step further down, or none of the above does anything.
|
|
13046
|
+
* `.fe-surface` sits between the body and the document node and grows to its
|
|
13047
|
+
* content by default, so `.fe-spdf--page { height: 100% }` resolved against
|
|
13048
|
+
* an auto-height parent and came back as "as tall as the document" —
|
|
13049
|
+
* measured at 1440x900: a 775px body holding a 1466px document, i.e. the
|
|
13050
|
+
* page running off the bottom exactly as before, with every rule above this
|
|
13051
|
+
* one in place and looking correct. */
|
|
13052
|
+
.fe-apppage.is-doc .fe-surface {
|
|
13053
|
+
flex: 1 1 auto;
|
|
13054
|
+
min-height: 0;
|
|
13055
|
+
}
|
|
13056
|
+
.fe-apppage__state {
|
|
13057
|
+
display: flex;
|
|
13058
|
+
flex-direction: column;
|
|
13059
|
+
gap: 8px;
|
|
13060
|
+
padding: 12px 0;
|
|
13061
|
+
}
|
|
13062
|
+
.fe-apppage__state-title {
|
|
13063
|
+
margin: 0;
|
|
13064
|
+
font-size: 16px;
|
|
13065
|
+
font-weight: 600;
|
|
13066
|
+
}
|
|
13067
|
+
.fe-apppage__state-actions {
|
|
13068
|
+
display: flex;
|
|
13069
|
+
gap: 8px;
|
|
13070
|
+
flex-wrap: wrap;
|
|
13071
|
+
padding-top: 4px;
|
|
13072
|
+
}
|
|
13073
|
+
.fe-apppage__state-actions .fe-btn {
|
|
13074
|
+
text-decoration: none;
|
|
13075
|
+
}
|
|
13076
|
+
.fe-apppage__foot {
|
|
13077
|
+
position: sticky;
|
|
13078
|
+
bottom: 0;
|
|
13079
|
+
width: 100%;
|
|
13080
|
+
max-width: 960px;
|
|
13081
|
+
margin: 0 auto;
|
|
13082
|
+
padding: 12px 16px;
|
|
13083
|
+
display: flex;
|
|
13084
|
+
justify-content: flex-end;
|
|
13085
|
+
gap: 8px;
|
|
13086
|
+
flex-wrap: wrap;
|
|
13087
|
+
border-top: 1px solid var(--fe-border);
|
|
13088
|
+
background: var(--fe-bg);
|
|
13089
|
+
}
|
|
13090
|
+
|
|
13091
|
+
/* The SAME screen inside a HOST's page (`PluginPageView frame="embedded"`) —
|
|
13092
|
+
* the admin panel's Apps section, an embed that already has a header.
|
|
13093
|
+
*
|
|
13094
|
+
* Exactly three things the tab frame provides have to go, and they are the
|
|
13095
|
+
* three the host has already decided: the viewport height (the panel's page
|
|
13096
|
+
* is as tall as its content), the 960px reading column (the host fixed the
|
|
13097
|
+
* width, and an app's home screen is a TABLE, which a text column cramps) and
|
|
13098
|
+
* the tail padding a scrolling tab needs.
|
|
13099
|
+
*
|
|
13100
|
+
* ⚠ The footer stops being sticky too. In a tab it hovers over the document
|
|
13101
|
+
* it belongs to; inside a card `bottom: 0` would pin it to the WINDOW's edge,
|
|
13102
|
+
* a screenful away from the form it submits. */
|
|
13103
|
+
.fe.fe-apppage--embedded {
|
|
13104
|
+
min-height: 0;
|
|
13105
|
+
padding: 0;
|
|
13106
|
+
}
|
|
13107
|
+
.fe-apppage--embedded .fe-apppage__body {
|
|
13108
|
+
max-width: none;
|
|
13109
|
+
padding: var(--fe-gap);
|
|
13110
|
+
}
|
|
13111
|
+
.fe-apppage--embedded .fe-apppage__foot {
|
|
13112
|
+
position: static;
|
|
13113
|
+
max-width: none;
|
|
13114
|
+
padding: var(--fe-gap);
|
|
13115
|
+
background: transparent;
|
|
13116
|
+
}
|
|
13117
|
+
|
|
13118
|
+
/* A home page's section menu (`SurfaceSections`, `surface.sections`). The
|
|
13119
|
+
* product's own underlined tab strip — the look of the Connections and
|
|
13120
|
+
* Plugins screens — and ⚠ one line on a phone, scrolled sideways: a strip
|
|
13121
|
+
* that wrapped moved the table under it every time a count changed. */
|
|
13122
|
+
.fe-sections {
|
|
13123
|
+
display: flex;
|
|
13124
|
+
gap: 2px;
|
|
13125
|
+
border-bottom: 1px solid var(--fe-border);
|
|
13126
|
+
overflow-x: auto;
|
|
13127
|
+
overflow-y: hidden;
|
|
13128
|
+
scrollbar-width: thin;
|
|
13129
|
+
flex: 0 0 auto;
|
|
13130
|
+
min-width: 0;
|
|
13131
|
+
}
|
|
13132
|
+
.fe-sections__tab {
|
|
13133
|
+
font: inherit;
|
|
13134
|
+
font-size: 13.5px;
|
|
13135
|
+
border: 0;
|
|
13136
|
+
background: none;
|
|
13137
|
+
color: var(--fe-text-muted);
|
|
13138
|
+
padding: 8px 12px;
|
|
13139
|
+
cursor: pointer;
|
|
13140
|
+
border-bottom: 2px solid transparent;
|
|
13141
|
+
margin-bottom: -1px;
|
|
13142
|
+
white-space: nowrap;
|
|
13143
|
+
display: inline-flex;
|
|
13144
|
+
align-items: center;
|
|
13145
|
+
gap: 6px;
|
|
13146
|
+
}
|
|
13147
|
+
.fe-sections__tab:hover:not(:disabled) {
|
|
13148
|
+
color: var(--fe-text);
|
|
13149
|
+
}
|
|
13150
|
+
.fe-sections__tab.is-active {
|
|
13151
|
+
color: var(--fe-primary);
|
|
13152
|
+
border-bottom-color: var(--fe-primary);
|
|
13153
|
+
font-weight: 600;
|
|
13154
|
+
}
|
|
13155
|
+
.fe-sections__tab:focus-visible {
|
|
13156
|
+
outline: 2px solid var(--fe-primary);
|
|
13157
|
+
outline-offset: -2px;
|
|
13158
|
+
}
|
|
13159
|
+
.fe-sections__count {
|
|
13160
|
+
min-width: 18px;
|
|
13161
|
+
padding: 0 6px;
|
|
13162
|
+
border-radius: 999px;
|
|
13163
|
+
background: var(--fe-bg-hover);
|
|
13164
|
+
color: var(--fe-text-muted);
|
|
13165
|
+
font-size: 11px;
|
|
13166
|
+
font-weight: 600;
|
|
13167
|
+
line-height: 18px;
|
|
13168
|
+
text-align: center;
|
|
13169
|
+
font-variant-numeric: tabular-nums;
|
|
13170
|
+
}
|
|
13171
|
+
.fe-sections__tab.is-active .fe-sections__count {
|
|
13172
|
+
background: color-mix(in srgb, var(--fe-primary) 14%, transparent);
|
|
13173
|
+
color: var(--fe-primary);
|
|
13174
|
+
}
|
|
13175
|
+
|
|
13176
|
+
/* The lock badge. ⚠ Drawn OUTSIDE `.fe-list__name`: the shot scripts read
|
|
13177
|
+
* that element's textContent as the filename, and a row whose name reads
|
|
13178
|
+
* "nda.pdf 🔒" breaks them silently (lesson #29). */
|
|
13179
|
+
.fe-applock {
|
|
13180
|
+
flex: 0 0 auto;
|
|
13181
|
+
display: inline-flex;
|
|
13182
|
+
align-items: center;
|
|
13183
|
+
gap: 4px;
|
|
13184
|
+
padding: 0 6px;
|
|
13185
|
+
height: 18px;
|
|
13186
|
+
border-radius: 9px;
|
|
13187
|
+
border: 1px solid var(--fe-border);
|
|
13188
|
+
background: var(--fe-bg-elev);
|
|
13189
|
+
color: var(--fe-text-muted);
|
|
13190
|
+
font-size: 11px;
|
|
13191
|
+
line-height: 1;
|
|
13192
|
+
white-space: nowrap;
|
|
13193
|
+
cursor: help;
|
|
13194
|
+
}
|
|
13195
|
+
.fe-applock__glyph {
|
|
13196
|
+
font-size: 11px;
|
|
13197
|
+
}
|
|
13198
|
+
.fe-applock--inline {
|
|
13199
|
+
vertical-align: middle;
|
|
13200
|
+
}
|
|
13201
|
+
|
|
13202
|
+
/* issue #34 — the badge on a symlink the server will not follow. Same chip as
|
|
13203
|
+
* the lock badge above, deliberately: a row that is not ordinary is marked one
|
|
13204
|
+
* way in this product, and a second vocabulary is how two marks end up meaning
|
|
13205
|
+
* the same thing on neighbouring rows.
|
|
13206
|
+
* ⚠ Drawn OUTSIDE `.fe-list__name` for the same reason (lesson #29). */
|
|
13207
|
+
.fe-symlink {
|
|
13208
|
+
flex: 0 0 auto;
|
|
13209
|
+
display: inline-flex;
|
|
13210
|
+
align-items: center;
|
|
13211
|
+
gap: 4px;
|
|
13212
|
+
padding: 0 6px;
|
|
13213
|
+
height: 18px;
|
|
13214
|
+
border-radius: 9px;
|
|
13215
|
+
border: 1px solid var(--fe-border);
|
|
13216
|
+
background: var(--fe-bg-elev);
|
|
13217
|
+
color: var(--fe-text-muted);
|
|
13218
|
+
font-size: 11px;
|
|
13219
|
+
line-height: 1;
|
|
13220
|
+
white-space: nowrap;
|
|
13221
|
+
cursor: help;
|
|
13222
|
+
}
|
|
13223
|
+
.fe-symlink__glyph {
|
|
13224
|
+
font-size: 11px;
|
|
13225
|
+
}
|
|
13226
|
+
/* A broken link is the one state nothing can be configured back into working,
|
|
13227
|
+
* so it is the one state that gets the amber. The other three are boundaries
|
|
13228
|
+
* the operator chose, not faults. */
|
|
13229
|
+
.fe-symlink--broken {
|
|
13230
|
+
border-color: var(--fe-warning);
|
|
13231
|
+
color: var(--fe-warning);
|
|
13232
|
+
}
|
|
13233
|
+
|
|
13234
|
+
/* One notice box, two names: an app's hold on a file and a link that cannot be
|
|
13235
|
+
* opened are the same shape of fact — the thing above the panel's facts that
|
|
13236
|
+
* explains why the facts alone mislead. */
|
|
13237
|
+
.fe-inspector__lock,
|
|
13238
|
+
.fe-inspector__linknote {
|
|
13239
|
+
display: flex;
|
|
13240
|
+
align-items: flex-start;
|
|
13241
|
+
gap: 8px;
|
|
13242
|
+
padding: 8px 10px;
|
|
13243
|
+
border: 1px solid var(--fe-border);
|
|
13244
|
+
border-radius: var(--fe-radius);
|
|
13245
|
+
background: var(--fe-bg-elev);
|
|
13246
|
+
color: var(--fe-text);
|
|
13247
|
+
font-size: var(--fe-text-sm);
|
|
13248
|
+
overflow-wrap: anywhere;
|
|
13249
|
+
}
|
|
13250
|
+
|
|
13251
|
+
/* The face picker a typed signature and a pdf text field share. */
|
|
13252
|
+
.fe-signfonts {
|
|
13253
|
+
display: flex;
|
|
13254
|
+
flex-wrap: wrap;
|
|
13255
|
+
gap: 6px;
|
|
13256
|
+
}
|
|
13257
|
+
.fe-signfonts__btn {
|
|
13258
|
+
padding: 4px 10px;
|
|
13259
|
+
border: 1px solid var(--fe-border);
|
|
13260
|
+
border-radius: var(--fe-radius);
|
|
13261
|
+
background: var(--fe-bg-elev);
|
|
13262
|
+
color: var(--fe-text);
|
|
13263
|
+
font-size: 15px;
|
|
13264
|
+
line-height: 1.4;
|
|
13265
|
+
cursor: pointer;
|
|
13266
|
+
}
|
|
13267
|
+
.fe-signfonts__btn:hover:not(:disabled) {
|
|
13268
|
+
border-color: var(--fe-primary);
|
|
13269
|
+
}
|
|
13270
|
+
.fe-signfonts__btn.is-on {
|
|
13271
|
+
border-color: var(--fe-primary);
|
|
13272
|
+
box-shadow: inset 0 0 0 1px var(--fe-primary);
|
|
13273
|
+
}
|
|
13274
|
+
.fe-signfonts__btn:disabled {
|
|
13275
|
+
opacity: 0.5;
|
|
13276
|
+
cursor: default;
|
|
13277
|
+
}
|
|
13278
|
+
/* === /App plugins v2 === */
|
|
13279
|
+
|
|
13280
|
+
/* ── StorageTags: a storage's driver, "Read-only", "Disabled" ───────────
|
|
13281
|
+
ONE vocabulary for every list of storages (components/StorageTags.vue,
|
|
13282
|
+
QA #34: "RO" on one admin list, "SALT OKUNUR" on the other). Global, like
|
|
13283
|
+
every core rule — scoped styles do not survive the web-component build. */
|
|
13284
|
+
.fe-stags {
|
|
13285
|
+
display: inline-flex;
|
|
13286
|
+
flex-wrap: wrap;
|
|
13287
|
+
align-items: center;
|
|
13288
|
+
gap: 4px;
|
|
13289
|
+
min-width: 0;
|
|
13290
|
+
}
|
|
13291
|
+
.fe-stag {
|
|
13292
|
+
font-size: 11px;
|
|
13293
|
+
line-height: 16px;
|
|
13294
|
+
border: 1px solid var(--fe-border-strong, currentColor);
|
|
13295
|
+
border-radius: 999px;
|
|
13296
|
+
padding: 0 8px;
|
|
13297
|
+
color: var(--fe-text-muted, inherit);
|
|
13298
|
+
white-space: nowrap;
|
|
13299
|
+
}
|
|
13300
|
+
.fe-stag--warn {
|
|
13301
|
+
color: var(--fe-warning, var(--fe-danger));
|
|
13302
|
+
border-color: var(--fe-warning, var(--fe-danger));
|
|
13303
|
+
}
|
|
13304
|
+
|
|
13305
|
+
/* ── PublicLinkPreview: the public page inside the admin's Corporate identity
|
|
13306
|
+
page. The page is a whole document (`min-height: 100vh`); in the admin card
|
|
13307
|
+
it is a panel. Only the height is undone — padding, width, colours and
|
|
13308
|
+
alignment stay the page's own, so what the operator sees is what a visitor
|
|
13309
|
+
gets. It is looked at, not used. */
|
|
13310
|
+
.fe-ppreview {
|
|
13311
|
+
pointer-events: none;
|
|
13312
|
+
user-select: none;
|
|
13313
|
+
border-radius: var(--fe-radius-lg, 12px);
|
|
13314
|
+
overflow: hidden;
|
|
13315
|
+
}
|
|
13316
|
+
.fe-ppreview > .fe.fe-ppage {
|
|
13317
|
+
min-height: 0;
|
|
13318
|
+
}
|