@jant/core 0.6.15 → 0.6.16
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/bin/commands/import-site.js +7 -0
- package/dist/app-C75Zc8dD.js +6 -0
- package/dist/{app-C-oi_t8W.js → app-C7_4oab9.js} +480 -196
- package/dist/client/.vite/manifest.json +8 -8
- package/dist/client/_assets/chunks/{url-pLre2DM_.js → url-CU9pEbk5.js} +1 -1
- package/dist/client/_assets/{client-DxY5BFe8.js → client-Bq0vre8Y.js} +3 -3
- package/dist/client/_assets/client-D3VZyG4L.css +2 -0
- package/dist/client/_assets/{client-auth-CakPESv9.js → client-auth-F2rb9WfF.js} +1015 -977
- package/dist/{env-OHRKGcMj.js → env-BPYViDJJ.js} +1 -1
- package/dist/{export-CsFx6F_M.js → export-Dl5KCiEs.js} +93 -7
- package/dist/{github-api-BgSiE71w.js → github-api-BNF35Lkx.js} +1 -1
- package/dist/{github-app-BbklkFmU.js → github-app-DdiD-bC4.js} +1 -1
- package/dist/{github-sync-ppWXN3jb.js → github-sync-Bqg62IvV.js} +3 -3
- package/dist/{github-sync-Cq1pzzOI.js → github-sync-HdK2EgvJ.js} +3 -3
- package/dist/index.js +5 -5
- package/dist/node.js +6 -6
- package/dist/{url-BMYO-Zlt.js → url-CbLAtlZe.js} +517 -12
- package/package.json +1 -1
- package/src/__tests__/mise-config.test.ts +22 -0
- package/src/client/__tests__/compose-bridge.test.ts +252 -2
- package/src/client/__tests__/compose-shortcuts.test.ts +20 -0
- package/src/client/__tests__/toast.test.ts +65 -1
- package/src/client/components/__tests__/compose-format-convert.test.ts +0 -19
- package/src/client/components/__tests__/jant-command-palette.test.ts +51 -0
- package/src/client/components/__tests__/jant-compose-dialog.test.ts +2015 -318
- package/src/client/components/__tests__/jant-compose-editor.test.ts +53 -62
- package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +35 -89
- package/src/client/components/compose-format-convert.ts +5 -1
- package/src/client/components/compose-types.ts +47 -3
- package/src/client/components/jant-command-palette.ts +12 -6
- package/src/client/components/jant-compose-dialog.ts +1464 -680
- package/src/client/components/jant-compose-editor.ts +225 -93
- package/src/client/components/jant-compose-fullscreen.ts +3 -5
- package/src/client/components/jant-post-menu.ts +91 -21
- package/src/client/compose-bridge.ts +143 -122
- package/src/client/compose-launch.ts +13 -0
- package/src/client/compose-shortcuts.ts +5 -1
- package/src/client/post-refresh.ts +135 -0
- package/src/client/tiptap/__tests__/link-input-rules.test.ts +121 -0
- package/src/client/tiptap/link-input-rules.ts +4 -4
- package/src/client/toast.ts +130 -38
- package/src/db/__tests__/backfill-thread-activity.test.ts +234 -0
- package/src/db/__tests__/thread-activity.test.ts +113 -0
- package/src/db/backfills/0005_split_thread_activity_from_quiet_replies.sql +68 -0
- package/src/db/migrations/0031_many_ego.sql +3 -0
- package/src/db/migrations/meta/0031_snapshot.json +2562 -0
- package/src/db/migrations/meta/_journal.json +7 -0
- package/src/db/migrations/pg/0029_rare_hairball.sql +3 -0
- package/src/db/migrations/pg/meta/0029_snapshot.json +3289 -0
- package/src/db/migrations/pg/meta/_journal.json +7 -0
- package/src/db/pg/schema.ts +18 -0
- package/src/db/schema.ts +20 -0
- package/src/db/thread-activity.ts +101 -0
- package/src/i18n/locales/public/en.po +89 -21
- package/src/i18n/locales/public/en.ts +1 -1
- package/src/i18n/locales/public/zh-Hans.po +88 -20
- package/src/i18n/locales/public/zh-Hans.ts +1 -1
- package/src/i18n/locales/public/zh-Hant.po +88 -20
- package/src/i18n/locales/public/zh-Hant.ts +1 -1
- package/src/lib/__tests__/feed.test.ts +168 -0
- package/src/lib/__tests__/markdown.test.ts +16 -0
- package/src/lib/__tests__/slug.test.ts +18 -0
- package/src/lib/__tests__/translit.test.ts +87 -0
- package/src/lib/__tests__/url.test.ts +53 -0
- package/src/lib/feed.ts +113 -11
- package/src/lib/hugo-markdown.ts +5 -0
- package/src/lib/link-preview.ts +25 -0
- package/src/lib/markdown-manager.ts +6 -1
- package/src/lib/post-display.ts +42 -9
- package/src/lib/timeline.ts +39 -9
- package/src/lib/tiptap-render.ts +4 -2
- package/src/lib/translit.ts +288 -0
- package/src/lib/url.ts +123 -12
- package/src/lib/view.ts +28 -0
- package/src/routes/api/__tests__/palette.test.ts +44 -0
- package/src/routes/api/posts.ts +13 -9
- package/src/routes/api/public/__tests__/posts.test.ts +38 -0
- package/src/routes/api/public/posts.ts +7 -0
- package/src/routes/compose.tsx +6 -2
- package/src/routes/feed/__tests__/sitemap.test.ts +68 -1
- package/src/routes/pages/__tests__/archive-params.test.ts +292 -0
- package/src/routes/pages/__tests__/featured.test.ts +6 -2
- package/src/routes/pages/__tests__/preview.test.ts +3 -1
- package/src/routes/pages/archive.tsx +65 -17
- package/src/routes/pages/page.tsx +5 -2
- package/src/services/__tests__/collection.test.ts +32 -1
- package/src/services/__tests__/post-timeline.test.ts +142 -11
- package/src/services/__tests__/post.test.ts +277 -0
- package/src/services/collection.ts +8 -10
- package/src/services/export-theme/assets/client-site.css +1 -1
- package/src/services/export.ts +3 -5
- package/src/services/path.ts +4 -1
- package/src/services/post.ts +297 -100
- package/src/services/search.ts +9 -0
- package/src/styles/components.css +0 -14
- package/src/styles/site-media.css +4 -4
- package/src/styles/tokens.css +62 -1
- package/src/styles/ui.css +1363 -1283
- package/src/types/entities.ts +5 -0
- package/src/types/props.ts +12 -0
- package/src/types/views.ts +6 -0
- package/src/ui/compose/ComposeDialog.tsx +17 -17
- package/src/ui/feed/LinkPreview.tsx +2 -7
- package/src/ui/feed/PostStatusBadges.tsx +42 -3
- package/src/ui/pages/ArchivePage.tsx +131 -24
- package/src/ui/pages/__tests__/ArchivePage.test.tsx +63 -0
- package/src/ui/shared/DraftPreviewBar.tsx +25 -9
- package/src/ui/shared/PostFooter.tsx +35 -12
- package/src/ui/shared/custom-icons.ts +5 -0
- package/src/ui/shared/post-article-attributes.ts +6 -0
- package/dist/app-BxCOR3Uc.js +0 -6
- package/dist/client/_assets/client-B_eGKN5p.css +0 -2
package/src/styles/ui.css
CHANGED
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
.draft-preview-bar-inner {
|
|
56
56
|
display: flex;
|
|
57
57
|
align-items: center;
|
|
58
|
-
justify-content:
|
|
58
|
+
justify-content: space-between;
|
|
59
59
|
gap: 0.7rem;
|
|
60
60
|
min-height: 2.5rem;
|
|
61
61
|
max-width: var(--layout-body-max-width);
|
|
@@ -66,6 +66,13 @@
|
|
|
66
66
|
text-align: center;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
.draft-preview-bar-copy {
|
|
70
|
+
display: inline-flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
gap: 0.7rem;
|
|
73
|
+
min-width: 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
69
76
|
.draft-preview-bar-label {
|
|
70
77
|
display: inline-flex;
|
|
71
78
|
align-items: center;
|
|
@@ -90,10 +97,64 @@
|
|
|
90
97
|
color: var(--site-text-secondary);
|
|
91
98
|
}
|
|
92
99
|
|
|
100
|
+
.draft-preview-bar-action {
|
|
101
|
+
display: inline-flex;
|
|
102
|
+
flex: none;
|
|
103
|
+
align-items: center;
|
|
104
|
+
justify-content: center;
|
|
105
|
+
min-height: 1.9rem;
|
|
106
|
+
padding: 0.28rem 0.72rem;
|
|
107
|
+
border: 1px solid
|
|
108
|
+
color-mix(in srgb, var(--site-text-primary) 18%, transparent);
|
|
109
|
+
border-radius: 999px;
|
|
110
|
+
background: color-mix(
|
|
111
|
+
in srgb,
|
|
112
|
+
var(--site-elevated-bg) 78%,
|
|
113
|
+
var(--site-nav-hover-bg)
|
|
114
|
+
);
|
|
115
|
+
color: var(--site-text-primary);
|
|
116
|
+
font-size: var(--type-ui-caption);
|
|
117
|
+
font-weight: var(--fw-medium);
|
|
118
|
+
line-height: 1;
|
|
119
|
+
text-decoration: none;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
transition:
|
|
122
|
+
border-color 150ms ease,
|
|
123
|
+
background-color 150ms ease,
|
|
124
|
+
color 150ms ease,
|
|
125
|
+
transform 150ms ease;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.draft-preview-bar-action:hover {
|
|
129
|
+
border-color: color-mix(
|
|
130
|
+
in srgb,
|
|
131
|
+
var(--site-accent) 48%,
|
|
132
|
+
var(--site-divider)
|
|
133
|
+
);
|
|
134
|
+
background: var(--site-nav-hover-bg);
|
|
135
|
+
color: var(--site-accent);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.draft-preview-bar-action:active {
|
|
139
|
+
transform: translateY(1px);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.draft-preview-bar-action:focus-visible {
|
|
143
|
+
outline: 2px solid var(--site-accent);
|
|
144
|
+
outline-offset: 2px;
|
|
145
|
+
}
|
|
146
|
+
|
|
93
147
|
@media (max-width: 480px) {
|
|
94
148
|
.draft-preview-bar-inner {
|
|
149
|
+
align-items: center;
|
|
150
|
+
gap: 0.65rem;
|
|
151
|
+
text-align: left;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.draft-preview-bar-copy {
|
|
95
155
|
flex-direction: column;
|
|
96
|
-
|
|
156
|
+
align-items: flex-start;
|
|
157
|
+
gap: 0.12rem;
|
|
97
158
|
}
|
|
98
159
|
}
|
|
99
160
|
|
|
@@ -2878,21 +2939,52 @@
|
|
|
2878
2939
|
flex-shrink: 0;
|
|
2879
2940
|
}
|
|
2880
2941
|
|
|
2942
|
+
/* One dot on both rails: a flat fill with a surface-coloured gap punched
|
|
2943
|
+
around it, so it reads as a bead threaded on the rail rather than a bulge in
|
|
2944
|
+
it. Same size, same colours, same punch — reading then rings it (below) and
|
|
2945
|
+
compose stops at the fill. What a post *is* comes from its card; the dot
|
|
2946
|
+
only says where it sits on the chain, and an accent fill says which one the
|
|
2947
|
+
view is about. */
|
|
2881
2948
|
.thread-group,
|
|
2882
2949
|
.compose-thread-layout {
|
|
2883
|
-
--site-thread-marker-size:
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
--site-thread-
|
|
2950
|
+
--site-thread-marker-size: 7px;
|
|
2951
|
+
/* Kept at 7:1.5 with the marker. A 7px dot on a 1px hairline reads as a bead
|
|
2952
|
+
dropped onto a thread rather than the same stroke thickening; the timeline
|
|
2953
|
+
components this pattern comes from (Ant, CodyHouse) all run a 2px rail. */
|
|
2954
|
+
--site-thread-rail-line-width: 1.5px;
|
|
2955
|
+
/* The gap's ceiling is set by whichever dot has the rail on one side only —
|
|
2956
|
+
in compose that's the last post, where the rail is trimmed. One line end
|
|
2957
|
+
holds it instead of two, and around 12px it reads as floating loose. */
|
|
2958
|
+
--site-thread-marker-gap: 9px;
|
|
2888
2959
|
--site-thread-marker-surface: var(--site-page-bg);
|
|
2960
|
+
/* "This is the post the view is about." Tinted toward the rail rather than
|
|
2961
|
+
the raw accent: every other accent-derived token in the system sits
|
|
2962
|
+
between 6% and 24% (see tokens.css), and a 7px shape at full accent was
|
|
2963
|
+
the single highest-contrast thing in an otherwise near-empty column. */
|
|
2964
|
+
--site-thread-marker-current: color-mix(
|
|
2965
|
+
in srgb,
|
|
2966
|
+
var(--site-accent) 90%,
|
|
2967
|
+
var(--site-threadline)
|
|
2968
|
+
);
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
.compose-thread-layout {
|
|
2972
|
+
--site-thread-marker-surface: var(--compose-paper-bg);
|
|
2889
2973
|
}
|
|
2890
2974
|
|
|
2891
|
-
/* Thread group: timeline layout — vertical line with dot markers
|
|
2975
|
+
/* Thread group: timeline layout — vertical line with dot markers.
|
|
2976
|
+
Reading rings its dots; compose doesn't. A compose dot sits beside a card
|
|
2977
|
+
edge, a format switcher and a "1/3", so a joint in the line is all it has to
|
|
2978
|
+
be. Reading's rail runs down an otherwise empty column, where a bare fill
|
|
2979
|
+
reads as a speck of stray threadline — the ring gives it a silhouette
|
|
2980
|
+
without making it any louder, since the tint is the same 16% accent every
|
|
2981
|
+
other halo in the system uses. Held off the fill by a band of surface so
|
|
2982
|
+
the two stay separate marks rather than one fuzzy dot. */
|
|
2892
2983
|
.thread-group {
|
|
2893
2984
|
--site-thread-rail-indent: 24px;
|
|
2894
2985
|
--site-thread-rail-line-left: 5px;
|
|
2895
|
-
--site-thread-
|
|
2986
|
+
--site-thread-marker-ring-inset: 2px;
|
|
2987
|
+
--site-thread-marker-ring-width: 2px;
|
|
2896
2988
|
position: relative;
|
|
2897
2989
|
padding-left: var(--site-thread-rail-indent);
|
|
2898
2990
|
}
|
|
@@ -2926,28 +3018,55 @@
|
|
|
2926
3018
|
|
|
2927
3019
|
/* Dot marker at each post position — auto-centered on the rail line.
|
|
2928
3020
|
Line ::before is relative to .thread-group, but dot ::before is relative
|
|
2929
|
-
to .thread-item which sits inside the padding (indent), so we subtract it.
|
|
3021
|
+
to .thread-item which sits inside the padding (indent), so we subtract it.
|
|
3022
|
+
Every length here is derived: a hardcoded half-marker is what once left the
|
|
3023
|
+
compose rail running down the edge of its own dots instead of through them. */
|
|
2930
3024
|
.thread-item::before {
|
|
2931
3025
|
content: "";
|
|
2932
3026
|
position: absolute;
|
|
2933
3027
|
left: calc(
|
|
2934
3028
|
var(--site-thread-rail-line-left) + var(--site-thread-rail-line-width) /
|
|
2935
|
-
2 -
|
|
3029
|
+
2 - var(--site-thread-marker-size) / 2 - var(--site-thread-rail-indent)
|
|
2936
3030
|
);
|
|
2937
3031
|
top: 50%;
|
|
2938
3032
|
transform: translateY(-50%);
|
|
2939
|
-
width:
|
|
2940
|
-
height:
|
|
3033
|
+
width: var(--site-thread-marker-size);
|
|
3034
|
+
height: var(--site-thread-marker-size);
|
|
2941
3035
|
border-radius: 50%;
|
|
2942
3036
|
background-color: var(--site-threadline);
|
|
3037
|
+
/* Three concentric layers off one border box, painted first-on-top: a band
|
|
3038
|
+
of surface, the accent ring, then the rest of the punch-out. The punch's
|
|
3039
|
+
radius is unchanged, so the ring sits inside the gap the rail line was
|
|
3040
|
+
already broken for and nothing downstream (`.thread-context-shell`'s
|
|
3041
|
+
inset, the compose switcher's overhang) has to move for it. */
|
|
3042
|
+
box-shadow:
|
|
3043
|
+
0 0 0 var(--site-thread-marker-ring-inset)
|
|
3044
|
+
var(--site-thread-marker-surface),
|
|
3045
|
+
0 0 0
|
|
3046
|
+
calc(
|
|
3047
|
+
var(--site-thread-marker-ring-inset) +
|
|
3048
|
+
var(--site-thread-marker-ring-width)
|
|
3049
|
+
)
|
|
3050
|
+
var(--site-thread-dot-ring),
|
|
3051
|
+
0 0 0 var(--site-thread-marker-gap) var(--site-thread-marker-surface);
|
|
2943
3052
|
z-index: 1;
|
|
2944
3053
|
}
|
|
2945
3054
|
|
|
3055
|
+
/* "This is the post the view is about": the feed preview's latest reply, a
|
|
3056
|
+
curated preview's highlighted segment, and the post you opened on a detail
|
|
3057
|
+
page. One signal for all three — accent fill on the same dot. Hero and
|
|
3058
|
+
curated also ran 4px larger; the full card beside them already says it, so
|
|
3059
|
+
size was a second signal doing the first one's job. */
|
|
3060
|
+
.thread-item-hero::before,
|
|
3061
|
+
.thread-item-curated::before,
|
|
3062
|
+
.thread-item-current::before {
|
|
3063
|
+
background-color: var(--site-thread-marker-current);
|
|
3064
|
+
}
|
|
3065
|
+
|
|
2946
3066
|
.thread-group-preview,
|
|
2947
3067
|
.thread-group-detail {
|
|
2948
3068
|
--site-thread-rail-indent: 0px;
|
|
2949
3069
|
--site-thread-rail-line-left: -27px;
|
|
2950
|
-
--site-thread-rail-line-width: 1px;
|
|
2951
3070
|
}
|
|
2952
3071
|
|
|
2953
3072
|
@media (max-width: 760px) {
|
|
@@ -2958,6 +3077,12 @@
|
|
|
2958
3077
|
}
|
|
2959
3078
|
}
|
|
2960
3079
|
|
|
3080
|
+
/* The rail fades in at the top, where collapsed ancestor context begins: the
|
|
3081
|
+
thread continues above what this view shows, so the line shouldn't start on
|
|
3082
|
+
a hard edge. The bottom needs no matching fade — the line is cut at the last
|
|
3083
|
+
dot instead. Compose doesn't share the gradient: its rail is drawn per row
|
|
3084
|
+
so both ends can be trimmed, and a per-row gradient would fade once per
|
|
3085
|
+
post rather than once per thread. */
|
|
2961
3086
|
.thread-group-preview::before,
|
|
2962
3087
|
.thread-group-detail::before {
|
|
2963
3088
|
background: linear-gradient(
|
|
@@ -2968,39 +3093,44 @@
|
|
|
2968
3093
|
);
|
|
2969
3094
|
}
|
|
2970
3095
|
|
|
3096
|
+
/* The rail ends at the last dot. Below it the line pointed at posts that
|
|
3097
|
+
aren't there — the thread is over, and compose already trims its own rail
|
|
3098
|
+
the same way. Painted over rather than shortened: the line is one box on the
|
|
3099
|
+
group so it can carry a single gradient, and only the last post knows where
|
|
3100
|
+
its own dot sits (its own 50%). `> ` scopes this to the group's own children
|
|
3101
|
+
— the ancestors inside `.thread-context-shell` have a last child too, and
|
|
3102
|
+
the rail must run straight through it. */
|
|
3103
|
+
.thread-group > .thread-item:last-child::after {
|
|
3104
|
+
content: "";
|
|
3105
|
+
position: absolute;
|
|
3106
|
+
left: calc(
|
|
3107
|
+
var(--site-thread-rail-line-left) - var(--site-thread-rail-indent)
|
|
3108
|
+
);
|
|
3109
|
+
top: 50%;
|
|
3110
|
+
bottom: 0;
|
|
3111
|
+
width: var(--site-thread-rail-line-width);
|
|
3112
|
+
background-color: var(--site-thread-marker-surface);
|
|
3113
|
+
}
|
|
3114
|
+
|
|
2971
3115
|
.thread-group-preview .thread-item,
|
|
2972
3116
|
.thread-group-detail .thread-item {
|
|
2973
3117
|
padding: var(--site-thread-item-spacing) 0;
|
|
2974
3118
|
}
|
|
2975
3119
|
|
|
2976
|
-
.thread-group-preview .thread-item::before,
|
|
2977
|
-
.thread-group-detail .thread-item::before {
|
|
2978
|
-
left: calc(
|
|
2979
|
-
var(--site-thread-rail-line-left) + var(--site-thread-rail-line-width) /
|
|
2980
|
-
2 - var(--site-thread-marker-size) / 2 - var(--site-thread-rail-indent)
|
|
2981
|
-
);
|
|
2982
|
-
width: var(--site-thread-marker-size);
|
|
2983
|
-
height: var(--site-thread-marker-size);
|
|
2984
|
-
border: var(--site-thread-marker-border-width) solid
|
|
2985
|
-
var(--site-thread-marker-surface);
|
|
2986
|
-
background-color: var(--site-threadline);
|
|
2987
|
-
box-shadow: 0 0 0 var(--site-thread-marker-ring-width)
|
|
2988
|
-
var(--site-thread-dot-ring);
|
|
2989
|
-
}
|
|
2990
|
-
|
|
2991
3120
|
/* Collapsible ancestor context wrapper.
|
|
2992
3121
|
Server-rendered with `data-collapsed`. Crop and fade are always active
|
|
2993
3122
|
while data-collapsed is set; JS only toggles the Show more/less button
|
|
2994
3123
|
visibility based on real overflow. Negative left margin + matching
|
|
2995
3124
|
padding extends the shell's box past the content edge so the dot
|
|
2996
|
-
markers
|
|
2997
|
-
|
|
2998
|
-
|
|
3125
|
+
markers survive `overflow: hidden`. `box-sizing: content-box` keeps the
|
|
3126
|
+
inner content width identical to before. The inset has to clear the dot's
|
|
3127
|
+
punched gap, not just its fill: on desktop the fill starts at -30px but the
|
|
3128
|
+
gap reaches -39px, so the old 40px cleared it by a single pixel. */
|
|
2999
3129
|
.thread-context-shell {
|
|
3000
3130
|
position: relative;
|
|
3001
3131
|
box-sizing: content-box;
|
|
3002
|
-
margin-left: -
|
|
3003
|
-
padding-left:
|
|
3132
|
+
margin-left: -48px;
|
|
3133
|
+
padding-left: 48px;
|
|
3004
3134
|
transition: max-height 0.32s cubic-bezier(0.4, 0, 0.2, 1);
|
|
3005
3135
|
}
|
|
3006
3136
|
|
|
@@ -3191,37 +3321,6 @@
|
|
|
3191
3321
|
padding-top: 0.95rem;
|
|
3192
3322
|
}
|
|
3193
3323
|
|
|
3194
|
-
.thread-group-preview .thread-item-hero::before,
|
|
3195
|
-
.compose-editor-row .compose-thread-dot {
|
|
3196
|
-
left: calc(
|
|
3197
|
-
var(--site-thread-rail-line-left) + var(--site-thread-rail-line-width) /
|
|
3198
|
-
2 - var(--site-thread-marker-hero-size) / 2 -
|
|
3199
|
-
var(--site-thread-rail-indent)
|
|
3200
|
-
);
|
|
3201
|
-
width: var(--site-thread-marker-hero-size);
|
|
3202
|
-
height: var(--site-thread-marker-hero-size);
|
|
3203
|
-
border: var(--site-thread-marker-hero-border-width) solid
|
|
3204
|
-
var(--site-thread-marker-surface);
|
|
3205
|
-
background-color: var(--site-accent);
|
|
3206
|
-
box-shadow: 0 0 0 var(--site-thread-marker-ring-width)
|
|
3207
|
-
var(--site-thread-dot-ring);
|
|
3208
|
-
}
|
|
3209
|
-
|
|
3210
|
-
.thread-group-curated .thread-item-curated::before {
|
|
3211
|
-
left: calc(
|
|
3212
|
-
var(--site-thread-rail-line-left) + var(--site-thread-rail-line-width) /
|
|
3213
|
-
2 - var(--site-thread-marker-hero-size) / 2 -
|
|
3214
|
-
var(--site-thread-rail-indent)
|
|
3215
|
-
);
|
|
3216
|
-
width: var(--site-thread-marker-hero-size);
|
|
3217
|
-
height: var(--site-thread-marker-hero-size);
|
|
3218
|
-
border: var(--site-thread-marker-hero-border-width) solid
|
|
3219
|
-
var(--site-thread-marker-surface);
|
|
3220
|
-
background-color: var(--site-accent);
|
|
3221
|
-
box-shadow: 0 0 0 var(--site-thread-marker-ring-width)
|
|
3222
|
-
var(--site-thread-dot-ring);
|
|
3223
|
-
}
|
|
3224
|
-
|
|
3225
3324
|
/* Compact text for thread replies */
|
|
3226
3325
|
.feed-compact {
|
|
3227
3326
|
@apply text-sm;
|
|
@@ -3232,6 +3331,28 @@
|
|
|
3232
3331
|
scroll-margin-top: 80px;
|
|
3233
3332
|
}
|
|
3234
3333
|
|
|
3334
|
+
/* --- Trailing draft in a thread (author-only) ---------------------------
|
|
3335
|
+
Rendered so the author sees the same thread end the server does. Reads as
|
|
3336
|
+
provisional — present enough to act on, quiet enough not to pass for
|
|
3337
|
+
published writing. */
|
|
3338
|
+
|
|
3339
|
+
.thread-detail-item article[data-post-draft] {
|
|
3340
|
+
opacity: 0.72;
|
|
3341
|
+
transition: opacity 0.18s ease;
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
.thread-detail-item article[data-post-draft]:hover,
|
|
3345
|
+
.thread-detail-item article[data-post-draft]:focus-within {
|
|
3346
|
+
opacity: 1;
|
|
3347
|
+
}
|
|
3348
|
+
|
|
3349
|
+
/* A draft is not part of the published spine, so its marker is hollow: the
|
|
3350
|
+
rail reaches it, but the dot reads as an empty slot rather than another
|
|
3351
|
+
published stop. */
|
|
3352
|
+
.thread-item:has(article[data-post-draft])::before {
|
|
3353
|
+
background-color: var(--site-thread-marker-surface);
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3235
3356
|
/* When a child post has an ancestor shell above it (toggle button sits
|
|
3236
3357
|
directly before the current post), leave enough room above the scroll
|
|
3237
3358
|
landing so the user can see the Show more button + a peek of the
|
|
@@ -3242,23 +3363,6 @@
|
|
|
3242
3363
|
scroll-margin-top: 120px;
|
|
3243
3364
|
}
|
|
3244
3365
|
|
|
3245
|
-
.thread-group-detail .thread-item-current::before {
|
|
3246
|
-
background-color: var(--site-accent);
|
|
3247
|
-
box-shadow:
|
|
3248
|
-
0 0 0 var(--site-thread-marker-border-width)
|
|
3249
|
-
var(--site-thread-marker-surface),
|
|
3250
|
-
0 0 0
|
|
3251
|
-
calc(
|
|
3252
|
-
var(--site-thread-marker-border-width) +
|
|
3253
|
-
var(--site-thread-marker-ring-width)
|
|
3254
|
-
)
|
|
3255
|
-
color-mix(
|
|
3256
|
-
in srgb,
|
|
3257
|
-
var(--site-accent) 18%,
|
|
3258
|
-
var(--site-thread-marker-surface)
|
|
3259
|
-
);
|
|
3260
|
-
}
|
|
3261
|
-
|
|
3262
3366
|
/* Quote block styling */
|
|
3263
3367
|
.feed-quote {
|
|
3264
3368
|
margin: 0;
|
|
@@ -3477,6 +3581,7 @@
|
|
|
3477
3581
|
/* Show the container when at least one status is active */
|
|
3478
3582
|
article[data-post-pinned] .post-status-badges,
|
|
3479
3583
|
article[data-post-pinned-in-collection] .post-status-badges,
|
|
3584
|
+
article[data-post-draft] .post-status-badges,
|
|
3480
3585
|
article[data-post-visibility="private"] .post-status-badges {
|
|
3481
3586
|
display: flex;
|
|
3482
3587
|
}
|
|
@@ -3507,6 +3612,38 @@
|
|
|
3507
3612
|
display: inline-flex;
|
|
3508
3613
|
}
|
|
3509
3614
|
|
|
3615
|
+
article[data-post-draft] .post-status-draft {
|
|
3616
|
+
display: inline-flex;
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
/* The draft badge is a button — the shortest path from "I see an unfinished
|
|
3620
|
+
post" to "I'm finishing it". */
|
|
3621
|
+
.post-status-draft {
|
|
3622
|
+
padding: 0;
|
|
3623
|
+
border: 0;
|
|
3624
|
+
background: transparent;
|
|
3625
|
+
font: inherit;
|
|
3626
|
+
letter-spacing: inherit;
|
|
3627
|
+
cursor: pointer;
|
|
3628
|
+
transition: color 0.18s ease;
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3631
|
+
.post-status-draft:hover,
|
|
3632
|
+
.post-status-draft:focus-visible {
|
|
3633
|
+
color: var(--site-text-primary);
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3636
|
+
.post-status-draft:hover svg,
|
|
3637
|
+
.post-status-draft:focus-visible svg {
|
|
3638
|
+
opacity: 1;
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
.post-status-draft:focus-visible {
|
|
3642
|
+
outline: 2px solid var(--site-accent);
|
|
3643
|
+
outline-offset: 3px;
|
|
3644
|
+
border-radius: 3px;
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3510
3647
|
.post-status-badge svg {
|
|
3511
3648
|
width: 11px;
|
|
3512
3649
|
height: 11px;
|
|
@@ -3954,6 +4091,14 @@
|
|
|
3954
4091
|
padding: 0 0.22rem;
|
|
3955
4092
|
}
|
|
3956
4093
|
|
|
4094
|
+
/* Every item in a group is conditional, so a group can end up with none —
|
|
4095
|
+
a draft reply hides both Featured and Pin. Match on element children so
|
|
4096
|
+
Lit's binding comments and the template's whitespace don't count as
|
|
4097
|
+
content, otherwise the empty group still draws its divider and padding. */
|
|
4098
|
+
.post-menu-section:not(:has(> *)) {
|
|
4099
|
+
display: none;
|
|
4100
|
+
}
|
|
4101
|
+
|
|
3957
4102
|
.post-menu-section + .post-menu-section {
|
|
3958
4103
|
margin-top: 0.08rem;
|
|
3959
4104
|
padding-top: 0.3rem;
|
|
@@ -4704,7 +4849,12 @@
|
|
|
4704
4849
|
}
|
|
4705
4850
|
}
|
|
4706
4851
|
|
|
4852
|
+
/* The one composer that is not a floating sheet: it fills the viewport, so
|
|
4853
|
+
its paper is the page's, not the elevated surface's. Nothing sits behind
|
|
4854
|
+
it to be lifted away from. */
|
|
4707
4855
|
.compose-page {
|
|
4856
|
+
--compose-paper-bg: var(--site-page-bg);
|
|
4857
|
+
|
|
4708
4858
|
position: fixed;
|
|
4709
4859
|
inset: 0;
|
|
4710
4860
|
z-index: 50;
|
|
@@ -4773,19 +4923,18 @@
|
|
|
4773
4923
|
.compose-page-shell .compose-dialog-inner {
|
|
4774
4924
|
min-height: 0;
|
|
4775
4925
|
max-height: none;
|
|
4926
|
+
padding-top: 0;
|
|
4776
4927
|
border-radius: inherit;
|
|
4777
4928
|
}
|
|
4778
4929
|
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
.compose-page-shell .compose-
|
|
4782
|
-
.compose-page-shell .compose-editor-row > jant-compose-editor {
|
|
4930
|
+
/* The page itself is the scroller here, so the composer's region gives up
|
|
4931
|
+
its own and grows to whatever it holds. */
|
|
4932
|
+
.compose-page-shell .compose-scroll {
|
|
4783
4933
|
flex: 0 1 auto;
|
|
4784
|
-
|
|
4934
|
+
overflow: visible;
|
|
4785
4935
|
}
|
|
4786
4936
|
|
|
4787
4937
|
.compose-page-shell .compose-body {
|
|
4788
|
-
flex: 0 1 auto;
|
|
4789
4938
|
min-height: clamp(8rem, 22vh, 12rem);
|
|
4790
4939
|
}
|
|
4791
4940
|
|
|
@@ -4812,6 +4961,10 @@
|
|
|
4812
4961
|
}
|
|
4813
4962
|
|
|
4814
4963
|
.compose-page-shell .compose-dialog-inner-page {
|
|
4964
|
+
/* The card's own padding is the text column here, so nothing inside it
|
|
4965
|
+
adds a gutter of its own. */
|
|
4966
|
+
--compose-gutter: 0px;
|
|
4967
|
+
|
|
4815
4968
|
padding: 20px 24px 16px;
|
|
4816
4969
|
background-color: var(--compose-floating-bg);
|
|
4817
4970
|
border: 1px solid var(--compose-control-border);
|
|
@@ -4822,40 +4975,25 @@
|
|
|
4822
4975
|
overflow: visible;
|
|
4823
4976
|
}
|
|
4824
4977
|
|
|
4825
|
-
.compose-page-shell .compose-dialog-inner-page .compose-dialog-header {
|
|
4826
|
-
display: grid;
|
|
4827
|
-
grid-template-columns: 1fr auto;
|
|
4828
|
-
align-items: center;
|
|
4829
|
-
gap: 12px;
|
|
4830
|
-
padding: 0 0 16px;
|
|
4831
|
-
}
|
|
4832
|
-
|
|
4833
|
-
.compose-page-shell
|
|
4834
|
-
.compose-dialog-inner-page
|
|
4835
|
-
.compose-dialog-header-center {
|
|
4836
|
-
position: static;
|
|
4837
|
-
transform: none;
|
|
4838
|
-
justify-self: start;
|
|
4839
|
-
min-width: 0;
|
|
4840
|
-
}
|
|
4841
|
-
|
|
4842
|
-
.compose-page-shell .compose-dialog-inner-page .compose-dialog-cancel {
|
|
4843
|
-
display: none;
|
|
4844
|
-
}
|
|
4845
|
-
|
|
4846
4978
|
.compose-page-shell .compose-dialog-inner-page .compose-body {
|
|
4847
|
-
padding: 22px 0 12px;
|
|
4979
|
+
padding: 22px 0 12px var(--compose-gutter);
|
|
4848
4980
|
min-height: clamp(16rem, 36vh, 24rem);
|
|
4849
4981
|
}
|
|
4850
4982
|
|
|
4983
|
+
/* Only the right is restated: the left comes from the card's own gutter,
|
|
4984
|
+
which is what every one of these rows already reads. */
|
|
4851
4985
|
.compose-page-shell .compose-dialog-inner-page .compose-tools-row,
|
|
4852
4986
|
.compose-page-shell .compose-dialog-inner-page .compose-add-thread-trigger {
|
|
4853
|
-
padding-inline: 0;
|
|
4987
|
+
padding-inline-end: 0;
|
|
4854
4988
|
background: transparent;
|
|
4855
4989
|
}
|
|
4856
4990
|
|
|
4991
|
+
.compose-page-shell .compose-dialog-inner-page .compose-thread-post-header {
|
|
4992
|
+
padding-inline-end: 0;
|
|
4993
|
+
}
|
|
4994
|
+
|
|
4857
4995
|
.compose-page-shell .compose-dialog-inner-page .compose-attachments-dock {
|
|
4858
|
-
padding-inline: 0;
|
|
4996
|
+
padding-inline-end: 0;
|
|
4859
4997
|
background: transparent;
|
|
4860
4998
|
}
|
|
4861
4999
|
|
|
@@ -4864,7 +5002,15 @@
|
|
|
4864
5002
|
bottom: 0;
|
|
4865
5003
|
z-index: 5;
|
|
4866
5004
|
margin-inline: 0;
|
|
4867
|
-
padding: 14px 0 0;
|
|
5005
|
+
padding: 14px 0 0 var(--compose-gutter);
|
|
5006
|
+
background-color: inherit;
|
|
5007
|
+
}
|
|
5008
|
+
|
|
5009
|
+
/* Takes the page's gutter rather than the dialog's, so the toggles line up
|
|
5010
|
+
under Publish instead of sitting 12px inside it. */
|
|
5011
|
+
.compose-page-shell .compose-dialog-inner-page .compose-quick-actions-row {
|
|
5012
|
+
padding-inline: 0;
|
|
5013
|
+
padding-bottom: 2px;
|
|
4868
5014
|
background-color: inherit;
|
|
4869
5015
|
}
|
|
4870
5016
|
|
|
@@ -4889,8 +5035,8 @@
|
|
|
4889
5035
|
|
|
4890
5036
|
.compose-dialog,
|
|
4891
5037
|
.compose-page-shell > jant-compose-dialog {
|
|
4892
|
-
--compose-title-input-size: var(--type-content-
|
|
4893
|
-
--compose-title-input-leading:
|
|
5038
|
+
--compose-title-input-size: calc(var(--type-content-body) * 1.2);
|
|
5039
|
+
--compose-title-input-leading: 1.35;
|
|
4894
5040
|
--compose-quote-input-size: var(--type-content-subtitle);
|
|
4895
5041
|
--compose-quote-input-leading: 1.32;
|
|
4896
5042
|
--compose-inline-input-size: var(--type-ui-input);
|
|
@@ -4899,12 +5045,40 @@
|
|
|
4899
5045
|
--compose-panel-control-size: var(--type-ui-control);
|
|
4900
5046
|
--compose-summary-size: var(--type-ui-meta);
|
|
4901
5047
|
--compose-primary-button-size: var(--type-ui-meta);
|
|
5048
|
+
|
|
5049
|
+
/* How far the format switcher is pulled left of the text column. Declared
|
|
5050
|
+
up here with the other compose tunables so one value covers the dialog,
|
|
5051
|
+
the /new page and every thread row at once. See `.compose-segmented` for
|
|
5052
|
+
what the endpoints look like and why 12px is the ceiling. */
|
|
5053
|
+
--compose-switcher-hang: 8px;
|
|
5054
|
+
|
|
5055
|
+
/* The composer's text column, measured from each row's own container.
|
|
5056
|
+
Every row starts its padding here and the control inside it hangs its
|
|
5057
|
+
box back out by its own optical inset, so what lands on the column is
|
|
5058
|
+
the glyph or the label rather than the box around it — the switcher's
|
|
5059
|
+
hang above is the same idea, named per control because each one is
|
|
5060
|
+
inset by a different amount.
|
|
5061
|
+
|
|
5062
|
+
It drops to 0 wherever something outside the editor already supplies the
|
|
5063
|
+
indent: a thread row's rail, or the /new card's own padding. Only the
|
|
5064
|
+
left is expressed this way; the right paddings stay per-row, because a
|
|
5065
|
+
thread row is indented on one side only. */
|
|
5066
|
+
--compose-gutter: 20px;
|
|
5067
|
+
}
|
|
5068
|
+
|
|
5069
|
+
/* The fullscreen sheet renders none of these rows today, but it does share
|
|
5070
|
+
`.compose-editor-row`. Give it the column too rather than leave the value
|
|
5071
|
+
undefined there: an undefined custom property drops the whole padding
|
|
5072
|
+
declaration that reads it instead of falling back to a sane number. */
|
|
5073
|
+
.compose-fullscreen-dialog {
|
|
5074
|
+
--compose-gutter: 20px;
|
|
4902
5075
|
}
|
|
4903
5076
|
|
|
4904
5077
|
@media (min-width: 700px) {
|
|
4905
5078
|
.compose-dialog,
|
|
5079
|
+
.compose-fullscreen-dialog,
|
|
4906
5080
|
.compose-page-shell > jant-compose-dialog {
|
|
4907
|
-
--compose-
|
|
5081
|
+
--compose-gutter: 24px;
|
|
4908
5082
|
}
|
|
4909
5083
|
}
|
|
4910
5084
|
|
|
@@ -4924,7 +5098,7 @@
|
|
|
4924
5098
|
box-shadow:
|
|
4925
5099
|
0 8px 40px rgba(0, 0, 0, 0.08),
|
|
4926
5100
|
0 1px 3px rgba(0, 0, 0, 0.04);
|
|
4927
|
-
border: 1px solid var(--
|
|
5101
|
+
border: 1px solid var(--site-raised-border);
|
|
4928
5102
|
overflow: visible;
|
|
4929
5103
|
}
|
|
4930
5104
|
|
|
@@ -4932,8 +5106,15 @@
|
|
|
4932
5106
|
animation: compose-modal-in 0.32s cubic-bezier(0.22, 1, 0.36, 1) both;
|
|
4933
5107
|
}
|
|
4934
5108
|
|
|
5109
|
+
/* The dim is only half of it. On a dark page there is no luminance left to
|
|
5110
|
+
take away — 0.3 → 0.7 alpha moves the dialog's contrast against its own
|
|
5111
|
+
backdrop by 0.05 — so the blur carries the separation instead. It reads as
|
|
5112
|
+
depth rather than darkness, which is the one cue that still works when the
|
|
5113
|
+
page and the sheet are three percent apart. */
|
|
4935
5114
|
.compose-dialog::backdrop {
|
|
4936
5115
|
background-color: rgba(0, 0, 0, 0.3);
|
|
5116
|
+
backdrop-filter: blur(3px);
|
|
5117
|
+
-webkit-backdrop-filter: blur(3px);
|
|
4937
5118
|
}
|
|
4938
5119
|
|
|
4939
5120
|
.compose-dialog jant-compose-dialog {
|
|
@@ -4953,10 +5134,15 @@
|
|
|
4953
5134
|
background: transparent;
|
|
4954
5135
|
}
|
|
4955
5136
|
|
|
5137
|
+
/* The composer opens straight onto the first post's header row now that the
|
|
5138
|
+
title bar is gone, so the top gutter it used to provide lives here. It
|
|
5139
|
+
cannot go on the row itself: single-post mode's wrapper is
|
|
5140
|
+
`display: contents` and generates no box to pad. */
|
|
4956
5141
|
.compose-dialog-inner {
|
|
4957
5142
|
display: flex;
|
|
4958
5143
|
flex-direction: column;
|
|
4959
5144
|
max-height: calc(100dvh - var(--compose-margin-top) - 20px);
|
|
5145
|
+
padding-top: 10px;
|
|
4960
5146
|
position: relative;
|
|
4961
5147
|
background-color: var(--compose-paper-bg);
|
|
4962
5148
|
border-radius: inherit;
|
|
@@ -4976,12 +5162,31 @@
|
|
|
4976
5162
|
pointer-events: none;
|
|
4977
5163
|
}
|
|
4978
5164
|
|
|
4979
|
-
.
|
|
5165
|
+
/* The composer's one scroll region. Every block inside it — editor body,
|
|
5166
|
+
attachments, per-post toolbar — flows at its natural height and scrolls
|
|
5167
|
+
together, so there is a single answer to "what scrolls?" in every mode.
|
|
5168
|
+
Only the action row below it stays pinned. Nesting a second scroller in
|
|
5169
|
+
here (a fixed-height body, a capped attachment dock) is what forced the
|
|
5170
|
+
old previews to be small; don't reintroduce one. */
|
|
5171
|
+
.compose-scroll {
|
|
4980
5172
|
flex: 1;
|
|
4981
5173
|
min-height: 0;
|
|
5174
|
+
overflow-y: auto;
|
|
5175
|
+
overflow-x: hidden;
|
|
5176
|
+
}
|
|
5177
|
+
|
|
5178
|
+
.compose-scroll::-webkit-scrollbar {
|
|
5179
|
+
width: 3px;
|
|
5180
|
+
}
|
|
5181
|
+
|
|
5182
|
+
.compose-scroll::-webkit-scrollbar-thumb {
|
|
5183
|
+
background-color: var(--site-divider);
|
|
5184
|
+
border-radius: 4px;
|
|
5185
|
+
}
|
|
5186
|
+
|
|
5187
|
+
.compose-scroll > jant-compose-editor {
|
|
4982
5188
|
display: flex;
|
|
4983
5189
|
flex-direction: column;
|
|
4984
|
-
overflow: hidden;
|
|
4985
5190
|
position: relative;
|
|
4986
5191
|
}
|
|
4987
5192
|
|
|
@@ -5059,144 +5264,63 @@
|
|
|
5059
5264
|
|
|
5060
5265
|
/* --- Header ------------------------------------------------------------- */
|
|
5061
5266
|
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
min-height: 3.6rem;
|
|
5067
|
-
padding: 12px 14px;
|
|
5068
|
-
background-color: var(--compose-paper-bg);
|
|
5069
|
-
border-top-left-radius: inherit;
|
|
5070
|
-
border-top-right-radius: inherit;
|
|
5071
|
-
position: relative;
|
|
5072
|
-
z-index: 4;
|
|
5073
|
-
}
|
|
5074
|
-
|
|
5075
|
-
@media (min-width: 700px) {
|
|
5076
|
-
.compose-dialog-header {
|
|
5077
|
-
padding: 14px 18px;
|
|
5078
|
-
}
|
|
5079
|
-
}
|
|
5267
|
+
/* Leaves the composer, so unlike the per-post × it never hides until hover:
|
|
5268
|
+
on a phone this and the options sheet are the only ways out. */
|
|
5269
|
+
.compose-close-btn {
|
|
5270
|
+
--compose-dialog-icon-paper-fill: var(--compose-paper-bg);
|
|
5080
5271
|
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5272
|
+
display: inline-flex;
|
|
5273
|
+
align-items: center;
|
|
5274
|
+
justify-content: center;
|
|
5275
|
+
margin-left: auto;
|
|
5276
|
+
width: 28px;
|
|
5277
|
+
height: 28px;
|
|
5278
|
+
border-radius: 8px;
|
|
5085
5279
|
border: none;
|
|
5086
|
-
background:
|
|
5087
|
-
border-radius: 10px;
|
|
5280
|
+
background: transparent;
|
|
5088
5281
|
color: var(--site-text-secondary);
|
|
5089
|
-
font-size: var(--type-ui-control);
|
|
5090
|
-
font-weight: var(--fw-medium);
|
|
5091
5282
|
cursor: pointer;
|
|
5092
|
-
transition: color 0.15s ease-out;
|
|
5093
5283
|
flex-shrink: 0;
|
|
5094
|
-
|
|
5284
|
+
opacity: 0.6;
|
|
5285
|
+
transition:
|
|
5286
|
+
opacity 0.15s ease,
|
|
5287
|
+
background-color 0.13s ease,
|
|
5288
|
+
color 0.13s ease;
|
|
5095
5289
|
}
|
|
5096
5290
|
|
|
5097
|
-
.compose-
|
|
5291
|
+
.compose-close-btn:hover {
|
|
5292
|
+
opacity: 1;
|
|
5293
|
+
background-color: var(--compose-control-bg);
|
|
5098
5294
|
color: var(--site-text-primary);
|
|
5099
5295
|
}
|
|
5100
5296
|
|
|
5101
|
-
.compose-
|
|
5102
|
-
position: absolute;
|
|
5103
|
-
left: 50%;
|
|
5104
|
-
transform: translateX(-50%);
|
|
5105
|
-
width: max-content;
|
|
5106
|
-
max-width: calc(100% - 9.5rem);
|
|
5107
|
-
}
|
|
5108
|
-
|
|
5109
|
-
.compose-dialog-header-actions {
|
|
5297
|
+
.compose-edit-loading-close {
|
|
5110
5298
|
display: flex;
|
|
5111
|
-
align-items: center;
|
|
5112
|
-
gap: 0;
|
|
5113
|
-
flex-shrink: 0;
|
|
5114
|
-
min-width: 44px;
|
|
5115
5299
|
justify-content: flex-end;
|
|
5116
5300
|
}
|
|
5117
5301
|
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5302
|
+
/* Treat touch-first browsers as mobile here too. iOS Safari can expose a
|
|
5303
|
+
* desktop-sized layout viewport for dialogs while still behaving like phone UI. */
|
|
5304
|
+
@media (max-width: 700px),
|
|
5305
|
+
(max-height: 760px),
|
|
5306
|
+
(hover: none) and (pointer: coarse) {
|
|
5307
|
+
.compose-dialog {
|
|
5308
|
+
--compose-margin-top: 0px;
|
|
5123
5309
|
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
background-color 0.15s ease-out,
|
|
5139
|
-
color 0.15s ease-out;
|
|
5140
|
-
}
|
|
5141
|
-
|
|
5142
|
-
.compose-dialog-header-btn:hover {
|
|
5143
|
-
--compose-dialog-icon-paper-fill: var(--compose-control-bg);
|
|
5144
|
-
color: var(--site-text-primary);
|
|
5145
|
-
background-color: var(--compose-control-bg);
|
|
5146
|
-
}
|
|
5147
|
-
|
|
5148
|
-
.compose-dialog-draft-btn {
|
|
5149
|
-
color: color-mix(
|
|
5150
|
-
in srgb,
|
|
5151
|
-
var(--site-text-primary) 48%,
|
|
5152
|
-
var(--site-text-secondary)
|
|
5153
|
-
);
|
|
5154
|
-
}
|
|
5155
|
-
|
|
5156
|
-
.compose-dialog-header-icon {
|
|
5157
|
-
display: block;
|
|
5158
|
-
width: 26px;
|
|
5159
|
-
height: 26px;
|
|
5160
|
-
--icon-stroke: 1.32;
|
|
5161
|
-
flex-shrink: 0;
|
|
5162
|
-
overflow: visible;
|
|
5163
|
-
}
|
|
5164
|
-
|
|
5165
|
-
.compose-dialog-draft-btn .compose-dialog-header-icon {
|
|
5166
|
-
--icon-stroke: 1.24;
|
|
5167
|
-
}
|
|
5168
|
-
|
|
5169
|
-
.compose-dialog-draft-btn:hover {
|
|
5170
|
-
color: var(--site-text-primary);
|
|
5171
|
-
}
|
|
5172
|
-
|
|
5173
|
-
.compose-dialog-header-btn:disabled {
|
|
5174
|
-
opacity: 0.3;
|
|
5175
|
-
cursor: not-allowed;
|
|
5176
|
-
}
|
|
5177
|
-
|
|
5178
|
-
/* Treat touch-first browsers as mobile here too. iOS Safari can expose a
|
|
5179
|
-
* desktop-sized layout viewport for dialogs while still behaving like phone UI. */
|
|
5180
|
-
@media (max-width: 700px),
|
|
5181
|
-
(max-height: 760px),
|
|
5182
|
-
(hover: none) and (pointer: coarse) {
|
|
5183
|
-
.compose-dialog {
|
|
5184
|
-
--compose-margin-top: 0px;
|
|
5185
|
-
|
|
5186
|
-
position: fixed;
|
|
5187
|
-
inset: 0;
|
|
5188
|
-
box-sizing: border-box;
|
|
5189
|
-
width: 100vw;
|
|
5190
|
-
min-width: 100vw;
|
|
5191
|
-
max-width: 100vw;
|
|
5192
|
-
height: 100dvh;
|
|
5193
|
-
min-height: 100dvh;
|
|
5194
|
-
max-height: 100dvh;
|
|
5195
|
-
margin: 0;
|
|
5196
|
-
border: none;
|
|
5197
|
-
border-radius: 0;
|
|
5198
|
-
box-shadow: none;
|
|
5199
|
-
}
|
|
5310
|
+
position: fixed;
|
|
5311
|
+
inset: 0;
|
|
5312
|
+
box-sizing: border-box;
|
|
5313
|
+
width: 100vw;
|
|
5314
|
+
min-width: 100vw;
|
|
5315
|
+
max-width: 100vw;
|
|
5316
|
+
height: 100dvh;
|
|
5317
|
+
min-height: 100dvh;
|
|
5318
|
+
max-height: 100dvh;
|
|
5319
|
+
margin: 0;
|
|
5320
|
+
border: none;
|
|
5321
|
+
border-radius: 0;
|
|
5322
|
+
box-shadow: none;
|
|
5323
|
+
}
|
|
5200
5324
|
|
|
5201
5325
|
.compose-dialog-inner {
|
|
5202
5326
|
height: 100dvh;
|
|
@@ -5212,29 +5336,13 @@
|
|
|
5212
5336
|
padding-left: calc(20px + env(safe-area-inset-left));
|
|
5213
5337
|
}
|
|
5214
5338
|
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
.compose-
|
|
5218
|
-
|
|
5219
|
-
flex: 0 1 auto;
|
|
5220
|
-
}
|
|
5221
|
-
|
|
5222
|
-
.compose-dialog-inner > jant-compose-editor,
|
|
5223
|
-
.compose-editor-row > jant-compose-editor {
|
|
5224
|
-
max-height: calc(
|
|
5225
|
-
100dvh - 13rem - env(safe-area-inset-top) - env(safe-area-inset-bottom)
|
|
5226
|
-
);
|
|
5227
|
-
}
|
|
5228
|
-
|
|
5229
|
-
.compose-dialog-header {
|
|
5230
|
-
padding-top: calc(12px + env(safe-area-inset-top));
|
|
5231
|
-
padding-right: calc(14px + env(safe-area-inset-right));
|
|
5232
|
-
padding-left: calc(14px + env(safe-area-inset-left));
|
|
5233
|
-
border-bottom: 1px solid var(--compose-control-border);
|
|
5339
|
+
/* Fullscreen on a phone, so the composer's own first row sits under the
|
|
5340
|
+
notch — it takes the inset the title bar used to. */
|
|
5341
|
+
.compose-dialog-inner {
|
|
5342
|
+
padding-top: calc(10px + env(safe-area-inset-top));
|
|
5234
5343
|
}
|
|
5235
5344
|
|
|
5236
5345
|
.compose-body {
|
|
5237
|
-
flex: 0 1 auto;
|
|
5238
5346
|
min-height: clamp(8rem, 22vh, 12rem);
|
|
5239
5347
|
padding-right: calc(20px + env(safe-area-inset-right));
|
|
5240
5348
|
padding-left: calc(20px + env(safe-area-inset-left));
|
|
@@ -5261,92 +5369,100 @@
|
|
|
5261
5369
|
}
|
|
5262
5370
|
}
|
|
5263
5371
|
|
|
5264
|
-
/* --- Format switcher
|
|
5372
|
+
/* --- Format switcher ----------------------------------------------------- */
|
|
5373
|
+
|
|
5374
|
+
/* One grouped control — a tinted track with a pill on the active format.
|
|
5375
|
+
The strip's own inset (track padding + item padding) is 16px, so its box
|
|
5376
|
+
and its first label can never both sit on the text column: whatever the
|
|
5377
|
+
strip is pulled left by, the other edge is 16px away from the text. There
|
|
5378
|
+
is no value that aligns both, only a choice of which one to favour, so the
|
|
5379
|
+
amount is a knob rather than a derived number:
|
|
5265
5380
|
|
|
5381
|
+
0px strip's tinted box on the text edge, "Note" 16px inside it
|
|
5382
|
+
8px neither edge exact; the tint is light enough that the perceived
|
|
5383
|
+
edge sits between them, which is why this is the default
|
|
5384
|
+
16px "Note" on the text edge, the tint hanging a full inset out
|
|
5385
|
+
|
|
5386
|
+
12px is the hard ceiling: in a thread row the rail dot ends 12px short of
|
|
5387
|
+
the content edge, and past that the tint runs over the dot. */
|
|
5266
5388
|
.compose-segmented {
|
|
5389
|
+
--compose-switcher-track-pad: 3px;
|
|
5390
|
+
--compose-switcher-item-pad: 13px;
|
|
5391
|
+
|
|
5267
5392
|
display: inline-flex;
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
padding:
|
|
5393
|
+
flex: none;
|
|
5394
|
+
gap: 1px;
|
|
5395
|
+
padding: var(--compose-switcher-track-pad);
|
|
5396
|
+
margin-inline-start: calc(-1 * var(--compose-switcher-hang));
|
|
5397
|
+
/* Paints over the thread rail dot, not under it. The dot carries a
|
|
5398
|
+
surface-coloured ring (`--site-thread-marker-gap`) to break the rail line
|
|
5399
|
+
around itself, and that ring reaches further right than the dot does —
|
|
5400
|
+
far enough to clip the strip's left edge once it hangs. Both sit at
|
|
5401
|
+
z-index 1, so the strip wins on document order. Covering ring pixels is
|
|
5402
|
+
harmless here: the line it protects runs down the dot's centre, well left
|
|
5403
|
+
of anywhere the strip reaches. */
|
|
5271
5404
|
position: relative;
|
|
5272
|
-
|
|
5405
|
+
z-index: 1;
|
|
5406
|
+
border-radius: calc(var(--compose-switcher-track-pad) + 8px);
|
|
5407
|
+
background-color: var(--compose-control-bg);
|
|
5273
5408
|
font-family: var(--font-ui);
|
|
5274
5409
|
}
|
|
5275
5410
|
|
|
5276
|
-
.compose-format-pill {
|
|
5277
|
-
position: absolute;
|
|
5278
|
-
top: 3px;
|
|
5279
|
-
left: 3px;
|
|
5280
|
-
width: calc((100% - 6px) / 3);
|
|
5281
|
-
height: calc(100% - 6px);
|
|
5282
|
-
background-color: var(--compose-paper-bg);
|
|
5283
|
-
border-radius: 7px;
|
|
5284
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
|
|
5285
|
-
transition: left 0.28s cubic-bezier(0.22, 1, 0.36, 1);
|
|
5286
|
-
z-index: 0;
|
|
5287
|
-
}
|
|
5288
|
-
|
|
5289
|
-
.compose-format-pill-link {
|
|
5290
|
-
left: calc(3px + (100% - 6px) / 3);
|
|
5291
|
-
}
|
|
5292
|
-
|
|
5293
|
-
.compose-format-pill-quote {
|
|
5294
|
-
left: calc(3px + (100% - 6px) * 2 / 3);
|
|
5295
|
-
}
|
|
5296
|
-
|
|
5297
5411
|
.compose-segmented-item {
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
flex: 1;
|
|
5301
|
-
padding: 5px 0.95rem;
|
|
5302
|
-
border-radius: 8px;
|
|
5412
|
+
flex: none;
|
|
5413
|
+
padding: 5px var(--compose-switcher-item-pad);
|
|
5303
5414
|
border: none;
|
|
5415
|
+
border-radius: 8px;
|
|
5304
5416
|
background: transparent;
|
|
5305
5417
|
color: var(--site-text-secondary);
|
|
5306
5418
|
font-size: var(--type-ui-hint);
|
|
5307
5419
|
font-weight: var(--fw-medium);
|
|
5308
5420
|
line-height: 1.2;
|
|
5309
|
-
cursor: pointer;
|
|
5310
|
-
transition: color 0.2s ease;
|
|
5311
5421
|
letter-spacing: 0.01em;
|
|
5422
|
+
cursor: pointer;
|
|
5423
|
+
transition:
|
|
5424
|
+
color 0.15s ease,
|
|
5425
|
+
background-color 0.15s ease,
|
|
5426
|
+
box-shadow 0.15s ease;
|
|
5312
5427
|
}
|
|
5313
5428
|
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
padding: 0.4rem 1.15rem;
|
|
5317
|
-
font-size: var(--type-ui-control);
|
|
5318
|
-
}
|
|
5429
|
+
.compose-segmented-item:hover:not(.compose-segmented-item-active) {
|
|
5430
|
+
color: var(--site-text-primary);
|
|
5319
5431
|
}
|
|
5320
5432
|
|
|
5321
5433
|
.compose-segmented-item-active {
|
|
5322
5434
|
color: var(--site-text-primary);
|
|
5323
|
-
|
|
5435
|
+
background-color: var(--compose-paper-bg);
|
|
5436
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
5324
5437
|
}
|
|
5325
5438
|
|
|
5326
5439
|
/* --- Body --------------------------------------------------------------- */
|
|
5327
5440
|
|
|
5441
|
+
/* Grows with its content — `.compose-scroll` does the scrolling. The floor is
|
|
5442
|
+
a target to click into on an empty post, so it yields once the post has an
|
|
5443
|
+
attachment: below a full-size preview the same space reads as a gap between
|
|
5444
|
+
the text and the picture. */
|
|
5328
5445
|
.compose-body {
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
overflow-y: auto;
|
|
5332
|
-
padding: 16px 20px 12px;
|
|
5446
|
+
min-height: 72px;
|
|
5447
|
+
padding: 16px 20px 12px var(--compose-gutter);
|
|
5333
5448
|
display: flex;
|
|
5334
5449
|
flex-direction: column;
|
|
5335
5450
|
}
|
|
5336
5451
|
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
padding: 18px 24px 12px;
|
|
5340
|
-
}
|
|
5452
|
+
jant-compose-editor:has(.compose-attachments-dock) .compose-body {
|
|
5453
|
+
min-height: 0;
|
|
5341
5454
|
}
|
|
5342
5455
|
|
|
5343
|
-
.compose-
|
|
5344
|
-
|
|
5456
|
+
jant-compose-editor:has(.compose-attachments-dock)
|
|
5457
|
+
.compose-tiptap-body
|
|
5458
|
+
.tiptap {
|
|
5459
|
+
min-height: 0;
|
|
5345
5460
|
}
|
|
5346
5461
|
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5462
|
+
@media (min-width: 700px) {
|
|
5463
|
+
.compose-body {
|
|
5464
|
+
padding: 18px 24px 12px var(--compose-gutter);
|
|
5465
|
+
}
|
|
5350
5466
|
}
|
|
5351
5467
|
|
|
5352
5468
|
.compose-field-enter {
|
|
@@ -5372,22 +5488,25 @@
|
|
|
5372
5488
|
color: var(--site-text-secondary);
|
|
5373
5489
|
}
|
|
5374
5490
|
|
|
5491
|
+
/* An optional field sitting directly above the one people came to type in:
|
|
5492
|
+
the empty state should recede, not announce itself. */
|
|
5493
|
+
.compose-note-title::placeholder,
|
|
5494
|
+
.compose-link-title::placeholder {
|
|
5495
|
+
color: color-mix(in srgb, var(--site-text-secondary) 55%, transparent);
|
|
5496
|
+
font-weight: 400;
|
|
5497
|
+
}
|
|
5498
|
+
|
|
5375
5499
|
.compose-input:focus::placeholder {
|
|
5376
5500
|
opacity: 0.6;
|
|
5377
5501
|
}
|
|
5378
5502
|
|
|
5379
5503
|
/* --- Note mode ---------------------------------------------------------- */
|
|
5380
5504
|
|
|
5381
|
-
.compose-note-title-row {
|
|
5382
|
-
display: flex;
|
|
5383
|
-
align-items: center;
|
|
5384
|
-
gap: 10px;
|
|
5385
|
-
margin-bottom: 14px;
|
|
5386
|
-
animation: compose-fade-up 0.28s cubic-bezier(0.22, 1, 0.36, 1) both;
|
|
5387
|
-
}
|
|
5388
|
-
|
|
5389
5505
|
.compose-note-title {
|
|
5390
|
-
|
|
5506
|
+
width: 100%;
|
|
5507
|
+
/* Sole owner of the title-to-body gap now that the first block's lead-in
|
|
5508
|
+
margin is gone — one place to tune instead of two that stack. */
|
|
5509
|
+
margin-bottom: 12px;
|
|
5391
5510
|
font-family: var(--font-heading);
|
|
5392
5511
|
font-size: var(--compose-title-input-size);
|
|
5393
5512
|
font-weight: var(--type-heading-weight);
|
|
@@ -5396,30 +5515,6 @@
|
|
|
5396
5515
|
text-wrap: pretty;
|
|
5397
5516
|
}
|
|
5398
5517
|
|
|
5399
|
-
@media (min-width: 700px) {
|
|
5400
|
-
.compose-note-title {
|
|
5401
|
-
font-size: var(--compose-title-input-size);
|
|
5402
|
-
}
|
|
5403
|
-
}
|
|
5404
|
-
|
|
5405
|
-
.compose-note-title-dismiss {
|
|
5406
|
-
border: none;
|
|
5407
|
-
background: transparent;
|
|
5408
|
-
color: var(--site-text-secondary);
|
|
5409
|
-
cursor: pointer;
|
|
5410
|
-
font-size: var(--type-ui-hint);
|
|
5411
|
-
padding: 6px 8px;
|
|
5412
|
-
border-radius: 8px;
|
|
5413
|
-
flex-shrink: 0;
|
|
5414
|
-
line-height: 1;
|
|
5415
|
-
opacity: 0.6;
|
|
5416
|
-
transition: opacity 0.15s ease;
|
|
5417
|
-
}
|
|
5418
|
-
|
|
5419
|
-
.compose-note-title-dismiss:hover {
|
|
5420
|
-
opacity: 1;
|
|
5421
|
-
}
|
|
5422
|
-
|
|
5423
5518
|
.compose-body-input {
|
|
5424
5519
|
width: 100%;
|
|
5425
5520
|
padding: 0;
|
|
@@ -5480,17 +5575,11 @@
|
|
|
5480
5575
|
font-weight: var(--type-heading-weight);
|
|
5481
5576
|
letter-spacing: var(--type-heading-tracking);
|
|
5482
5577
|
line-height: var(--compose-title-input-leading);
|
|
5483
|
-
margin-bottom:
|
|
5578
|
+
margin-bottom: 10px;
|
|
5484
5579
|
padding-left: 2px;
|
|
5485
5580
|
text-wrap: pretty;
|
|
5486
5581
|
}
|
|
5487
5582
|
|
|
5488
|
-
@media (min-width: 700px) {
|
|
5489
|
-
.compose-link-title {
|
|
5490
|
-
font-size: var(--compose-title-input-size);
|
|
5491
|
-
}
|
|
5492
|
-
}
|
|
5493
|
-
|
|
5494
5583
|
/* --- Quote mode --------------------------------------------------------- */
|
|
5495
5584
|
|
|
5496
5585
|
.compose-quote-wrap {
|
|
@@ -5561,15 +5650,17 @@
|
|
|
5561
5650
|
font-weight: var(--fw-regular);
|
|
5562
5651
|
line-height: var(--compose-quote-input-leading);
|
|
5563
5652
|
letter-spacing: -0.02em;
|
|
5564
|
-
|
|
5653
|
+
/* Four lines of the quote's own type — enough to hold most pulled passages
|
|
5654
|
+
without opening a well. Stated in lines so it tracks the two leadings
|
|
5655
|
+
this input takes (1.32 in compose, 1.42 in a reply) instead of needing a
|
|
5656
|
+
pixel value per breakpoint. The `rows` attribute is set to match. */
|
|
5657
|
+
min-height: calc(var(--compose-quote-input-leading) * 4em);
|
|
5565
5658
|
padding-top: 0.5rem;
|
|
5566
5659
|
text-wrap: pretty;
|
|
5567
5660
|
}
|
|
5568
5661
|
|
|
5569
5662
|
@media (min-width: 700px) {
|
|
5570
5663
|
.compose-quote-text {
|
|
5571
|
-
font-size: var(--compose-quote-input-size);
|
|
5572
|
-
min-height: 9.5rem;
|
|
5573
5664
|
padding-top: 0.55rem;
|
|
5574
5665
|
}
|
|
5575
5666
|
}
|
|
@@ -5638,7 +5729,9 @@
|
|
|
5638
5729
|
|
|
5639
5730
|
.compose-url-input {
|
|
5640
5731
|
border-bottom: 1px solid transparent;
|
|
5732
|
+
font-family: var(--font-mono);
|
|
5641
5733
|
font-size: var(--compose-inline-input-size);
|
|
5734
|
+
color: var(--site-accent);
|
|
5642
5735
|
line-height: 1.4;
|
|
5643
5736
|
padding-block: 0.1rem;
|
|
5644
5737
|
transition:
|
|
@@ -5735,16 +5828,11 @@
|
|
|
5735
5828
|
margin-left: 4px;
|
|
5736
5829
|
}
|
|
5737
5830
|
|
|
5831
|
+
/* Plain background, no top fade: nothing scrolls underneath it any more —
|
|
5832
|
+
the dock travels with its post inside `.compose-scroll`. */
|
|
5738
5833
|
.compose-attachments-dock {
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
background:
|
|
5742
|
-
linear-gradient(
|
|
5743
|
-
180deg,
|
|
5744
|
-
color-mix(in srgb, var(--compose-paper-bg) 0%, transparent) 0%,
|
|
5745
|
-
var(--compose-paper-bg) 18px
|
|
5746
|
-
),
|
|
5747
|
-
var(--compose-paper-bg);
|
|
5834
|
+
padding: 8px 20px 4px var(--compose-gutter);
|
|
5835
|
+
background-color: var(--compose-paper-bg);
|
|
5748
5836
|
}
|
|
5749
5837
|
|
|
5750
5838
|
@media (min-width: 700px) {
|
|
@@ -5832,26 +5920,31 @@
|
|
|
5832
5920
|
|
|
5833
5921
|
/* --- Tools row ---------------------------------------------------------- */
|
|
5834
5922
|
|
|
5923
|
+
/* Belongs to its post, not to the dialog: it sits under that post's content
|
|
5924
|
+
and scrolls away with it, so a thread shows one toolbar per block. */
|
|
5835
5925
|
.compose-tools-row {
|
|
5836
|
-
|
|
5926
|
+
/* Half the difference between the 44px button and the 20px glyph inside
|
|
5927
|
+
it. The row starts on the text column and its first control hangs back
|
|
5928
|
+
out by this much, so the icon lands on the column while the button keeps
|
|
5929
|
+
its full touch target. 12px is also the ceiling for anything hanging out
|
|
5930
|
+
of a thread row — see `.compose-segmented`, whose knob has the same job
|
|
5931
|
+
for a control with a different inset. */
|
|
5932
|
+
--compose-tool-hang: 12px;
|
|
5933
|
+
|
|
5934
|
+
padding: 6px 10px 6px var(--compose-gutter);
|
|
5837
5935
|
display: flex;
|
|
5838
5936
|
align-items: center;
|
|
5839
|
-
flex-shrink: 0;
|
|
5840
5937
|
gap: 4px;
|
|
5841
5938
|
background-color: var(--compose-paper-bg);
|
|
5842
5939
|
}
|
|
5843
5940
|
|
|
5844
|
-
.compose-
|
|
5845
|
-
|
|
5846
|
-
}
|
|
5847
|
-
|
|
5848
|
-
.compose-thread-layout .compose-tools-row .compose-tool-btn:first-child {
|
|
5849
|
-
margin-inline-start: -10px;
|
|
5941
|
+
.compose-tools-row > :first-child {
|
|
5942
|
+
margin-inline-start: calc(-1 * var(--compose-tool-hang));
|
|
5850
5943
|
}
|
|
5851
5944
|
|
|
5852
5945
|
@media (min-width: 700px) {
|
|
5853
5946
|
.compose-tools-row {
|
|
5854
|
-
padding: 6px 16px;
|
|
5947
|
+
padding: 6px 16px 6px var(--compose-gutter);
|
|
5855
5948
|
gap: 4px;
|
|
5856
5949
|
}
|
|
5857
5950
|
}
|
|
@@ -5863,37 +5956,64 @@
|
|
|
5863
5956
|
justify-content: center;
|
|
5864
5957
|
width: 44px;
|
|
5865
5958
|
height: 44px;
|
|
5959
|
+
/* The button keeps its 44px touch target; only the paint is inset, so the
|
|
5960
|
+
chip a hovered or switched-on tool wears is 36px and sits closer to the
|
|
5961
|
+
glyph than to its neighbours. `background-clip` shrinks the corner radii
|
|
5962
|
+
with the box, which is why 12px here reads as 8px on the chip. */
|
|
5963
|
+
padding: 4px;
|
|
5964
|
+
background-clip: content-box;
|
|
5866
5965
|
border-radius: 12px;
|
|
5867
5966
|
border: none;
|
|
5868
|
-
background: transparent;
|
|
5967
|
+
background-color: transparent;
|
|
5869
5968
|
cursor: pointer;
|
|
5870
5969
|
transition: all 0.18s ease;
|
|
5871
5970
|
flex-shrink: 0;
|
|
5872
|
-
color: var(--
|
|
5971
|
+
color: var(--compose-tool-ink);
|
|
5873
5972
|
}
|
|
5874
5973
|
|
|
5974
|
+
/* One weight for the whole row, stated here rather than per icon, so the
|
|
5975
|
+
stroked glyphs and the star's outline read as one set. */
|
|
5875
5976
|
.compose-tool-icon {
|
|
5876
|
-
--icon-stroke: 1.46;
|
|
5877
5977
|
display: block;
|
|
5878
5978
|
width: 20px;
|
|
5879
5979
|
height: 20px;
|
|
5880
5980
|
flex-shrink: 0;
|
|
5881
5981
|
overflow: visible;
|
|
5982
|
+
stroke-width: 1.42;
|
|
5882
5983
|
}
|
|
5883
5984
|
|
|
5884
5985
|
.compose-tool-btn:hover {
|
|
5885
5986
|
background-color: var(--compose-control-bg);
|
|
5886
5987
|
}
|
|
5887
5988
|
|
|
5989
|
+
/* On is a real chip — the shape people already read as "this control is
|
|
5990
|
+
switched on" — just quieter than the one that was tried first. That one
|
|
5991
|
+
paired the chip with full-strength ink, so the whole button lit up at
|
|
5992
|
+
once; here the glyph is left in the row's faded ink and the chip does the
|
|
5993
|
+
talking on its own, a little under the row's hover tint. It is the only
|
|
5994
|
+
edge in the row, so it needs no help to be found. */
|
|
5888
5995
|
.compose-tool-btn-active {
|
|
5889
|
-
color:
|
|
5996
|
+
background-color: color-mix(
|
|
5997
|
+
in srgb,
|
|
5998
|
+
var(--compose-control-bg) 85%,
|
|
5999
|
+
var(--compose-paper-bg)
|
|
6000
|
+
);
|
|
6001
|
+
}
|
|
6002
|
+
|
|
6003
|
+
/* Hover has to stay a step above a button that already carries a chip. */
|
|
6004
|
+
.compose-tool-btn-active:hover {
|
|
5890
6005
|
background-color: var(--compose-control-bg-strong);
|
|
5891
6006
|
}
|
|
5892
6007
|
|
|
6008
|
+
/* A tool that has grown a label is reading matter now, so it carries text's
|
|
6009
|
+
weight — the row's faded ink would put "Add more" under the 4.5:1 floor. */
|
|
5893
6010
|
.compose-tool-btn-add {
|
|
5894
6011
|
width: auto;
|
|
5895
6012
|
gap: 4px;
|
|
5896
|
-
|
|
6013
|
+
/* Same 4px of inset paint as the icon-only buttons; only the sides open up
|
|
6014
|
+
to make room for the label. */
|
|
6015
|
+
padding: 4px 10px 4px 8px;
|
|
6016
|
+
color: var(--site-text-secondary);
|
|
5897
6017
|
}
|
|
5898
6018
|
|
|
5899
6019
|
.compose-tool-label {
|
|
@@ -5902,12 +6022,11 @@
|
|
|
5902
6022
|
white-space: nowrap;
|
|
5903
6023
|
}
|
|
5904
6024
|
|
|
5905
|
-
.
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
border-radius: 1px;
|
|
6025
|
+
/* Was a hairline. The two groups (insert something / mark something up) are
|
|
6026
|
+
still worth telling apart, but air does it without drawing another edge
|
|
6027
|
+
into the paper. */
|
|
6028
|
+
.compose-tool-gap {
|
|
6029
|
+
width: 8px;
|
|
5911
6030
|
flex-shrink: 0;
|
|
5912
6031
|
}
|
|
5913
6032
|
|
|
@@ -5921,7 +6040,6 @@
|
|
|
5921
6040
|
width: 44px;
|
|
5922
6041
|
height: 44px;
|
|
5923
6042
|
border-radius: 12px;
|
|
5924
|
-
color: var(--site-text-secondary);
|
|
5925
6043
|
}
|
|
5926
6044
|
|
|
5927
6045
|
.compose-tool-btn-view:hover,
|
|
@@ -5950,7 +6068,7 @@
|
|
|
5950
6068
|
/* --- Action row --------------------------------------------------------- */
|
|
5951
6069
|
|
|
5952
6070
|
.compose-action-row {
|
|
5953
|
-
padding: 10px 12px 14px;
|
|
6071
|
+
padding: 10px 12px 14px var(--compose-gutter);
|
|
5954
6072
|
display: flex;
|
|
5955
6073
|
align-items: center;
|
|
5956
6074
|
gap: 10px;
|
|
@@ -5961,7 +6079,10 @@
|
|
|
5961
6079
|
border-bottom-right-radius: inherit;
|
|
5962
6080
|
}
|
|
5963
6081
|
|
|
6082
|
+
/* The quick toggles take over the action row's bottom edge when present, so
|
|
6083
|
+
the two read as one block rather than a strip stuck underneath. */
|
|
5964
6084
|
.compose-action-row:has(+ .compose-quick-actions-row) {
|
|
6085
|
+
padding-bottom: 4px;
|
|
5965
6086
|
border-bottom-left-radius: 0;
|
|
5966
6087
|
border-bottom-right-radius: 0;
|
|
5967
6088
|
}
|
|
@@ -5974,17 +6095,50 @@
|
|
|
5974
6095
|
justify-content: flex-end;
|
|
5975
6096
|
}
|
|
5976
6097
|
|
|
6098
|
+
.compose-quick-actions-row {
|
|
6099
|
+
display: flex;
|
|
6100
|
+
justify-content: flex-end;
|
|
6101
|
+
gap: 0.5rem;
|
|
6102
|
+
padding: 2px 12px 12px;
|
|
6103
|
+
background-color: var(--compose-paper-bg);
|
|
6104
|
+
border-bottom-left-radius: inherit;
|
|
6105
|
+
border-bottom-right-radius: inherit;
|
|
6106
|
+
}
|
|
6107
|
+
|
|
5977
6108
|
@media (min-width: 700px) {
|
|
5978
6109
|
.compose-action-row {
|
|
5979
|
-
padding: 12px 18px 16px;
|
|
6110
|
+
padding: 12px 18px 16px var(--compose-gutter);
|
|
6111
|
+
}
|
|
6112
|
+
|
|
6113
|
+
.compose-action-row:has(+ .compose-quick-actions-row) {
|
|
6114
|
+
padding-bottom: 4px;
|
|
6115
|
+
}
|
|
6116
|
+
|
|
6117
|
+
.compose-quick-actions-row {
|
|
6118
|
+
padding: 2px 18px 14px;
|
|
5980
6119
|
}
|
|
5981
6120
|
}
|
|
5982
6121
|
|
|
5983
6122
|
.compose-collection-select {
|
|
6123
|
+
/* Optically, not geometrically, centered: the glyph meets the left padding
|
|
6124
|
+
at a vertex and sits inset in its own box, so equal padding leaves the
|
|
6125
|
+
icon side looking open and the label side pinched against the edge.
|
|
6126
|
+
Tune the pill's side padding here and in the touch block below — both
|
|
6127
|
+
set these two values rather than re-declaring `padding`, so neither
|
|
6128
|
+
silently shadows the other. They live on the wrapper because the hang
|
|
6129
|
+
below is measured from them and has to apply to the flex item the action
|
|
6130
|
+
row lays out, not to the trigger inside it. */
|
|
6131
|
+
--compose-collection-pad-icon: 0.56rem;
|
|
6132
|
+
--compose-collection-pad-label: 0.85rem;
|
|
6133
|
+
|
|
5984
6134
|
display: inline-flex;
|
|
5985
6135
|
position: relative;
|
|
5986
6136
|
min-width: 0;
|
|
5987
6137
|
max-width: 100%;
|
|
6138
|
+
/* Hangs back by the trigger's icon-side inset plus its 1px transparent
|
|
6139
|
+
border, so it is the layers glyph that lands on the text column rather
|
|
6140
|
+
than the pill's edge. */
|
|
6141
|
+
margin-inline-start: calc(-1 * (var(--compose-collection-pad-icon) + 1px));
|
|
5988
6142
|
}
|
|
5989
6143
|
|
|
5990
6144
|
.compose-collection-select[data-open] {
|
|
@@ -5994,14 +6148,18 @@
|
|
|
5994
6148
|
.compose-collection-trigger {
|
|
5995
6149
|
display: flex;
|
|
5996
6150
|
align-items: center;
|
|
5997
|
-
gap: 0.
|
|
6151
|
+
gap: 0.38rem;
|
|
5998
6152
|
min-width: 0;
|
|
5999
6153
|
max-width: 100%;
|
|
6000
|
-
min-height:
|
|
6001
|
-
|
|
6002
|
-
|
|
6154
|
+
min-height: 1.95rem;
|
|
6155
|
+
/* No fill and no edge at rest — it was the one bordered pill left in the
|
|
6156
|
+
composer, which made picking a collection look like the thing to do. It
|
|
6157
|
+
keeps a transparent border so the box does not resize on hover. */
|
|
6158
|
+
border: 1px solid transparent;
|
|
6159
|
+
background: transparent;
|
|
6003
6160
|
border-radius: 999px;
|
|
6004
|
-
padding: 0.
|
|
6161
|
+
padding: 0.2rem var(--compose-collection-pad-label) 0.2rem
|
|
6162
|
+
var(--compose-collection-pad-icon);
|
|
6005
6163
|
cursor: pointer;
|
|
6006
6164
|
transition:
|
|
6007
6165
|
background-color 0.18s ease,
|
|
@@ -6012,12 +6170,12 @@
|
|
|
6012
6170
|
font-size: var(--type-ui-control);
|
|
6013
6171
|
}
|
|
6014
6172
|
|
|
6173
|
+
/* The same flat wash the tools row uses on hover — no lift, no edge. A chip
|
|
6174
|
+
that rises off the paper is what made this read as the loud control. */
|
|
6015
6175
|
.compose-collection-trigger:hover,
|
|
6016
6176
|
.compose-collection-trigger[data-open="true"] {
|
|
6017
6177
|
color: var(--site-text-primary);
|
|
6018
|
-
background: var(--compose-control-bg
|
|
6019
|
-
border-color: color-mix(in srgb, var(--site-text-primary) 10%, transparent);
|
|
6020
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
|
|
6178
|
+
background: var(--compose-control-bg);
|
|
6021
6179
|
}
|
|
6022
6180
|
|
|
6023
6181
|
.compose-collection-trigger[data-selected="true"] {
|
|
@@ -6028,39 +6186,16 @@
|
|
|
6028
6186
|
);
|
|
6029
6187
|
}
|
|
6030
6188
|
|
|
6031
|
-
.compose-collection-trigger-icon {
|
|
6032
|
-
display: inline-flex;
|
|
6033
|
-
align-items: center;
|
|
6034
|
-
justify-content: center;
|
|
6035
|
-
width: 1.65rem;
|
|
6036
|
-
height: 1.65rem;
|
|
6037
|
-
border-radius: 999px;
|
|
6038
|
-
background: color-mix(
|
|
6039
|
-
in srgb,
|
|
6040
|
-
var(--compose-paper-bg) 72%,
|
|
6041
|
-
var(--compose-control-bg)
|
|
6042
|
-
);
|
|
6043
|
-
color: color-mix(
|
|
6044
|
-
in srgb,
|
|
6045
|
-
var(--site-text-primary) 58%,
|
|
6046
|
-
var(--site-text-secondary)
|
|
6047
|
-
);
|
|
6048
|
-
flex-shrink: 0;
|
|
6049
|
-
}
|
|
6050
|
-
|
|
6051
|
-
.compose-collection-trigger-svg,
|
|
6052
6189
|
.compose-collection-search-icon,
|
|
6053
6190
|
.compose-collection-add-svg,
|
|
6054
6191
|
.compose-collection-option-check-circle,
|
|
6055
6192
|
.compose-collection-option-plus-circle,
|
|
6056
6193
|
.compose-collection-option-svg,
|
|
6057
|
-
.compose-collection-chevron,
|
|
6058
6194
|
.compose-collection-option-check {
|
|
6059
6195
|
display: block;
|
|
6060
6196
|
overflow: visible;
|
|
6061
6197
|
}
|
|
6062
6198
|
|
|
6063
|
-
.compose-collection-trigger-svg,
|
|
6064
6199
|
.compose-collection-option-svg {
|
|
6065
6200
|
width: 0.92rem;
|
|
6066
6201
|
height: 0.92rem;
|
|
@@ -6068,6 +6203,26 @@
|
|
|
6068
6203
|
stroke-width: var(--icon-stroke);
|
|
6069
6204
|
}
|
|
6070
6205
|
|
|
6206
|
+
/* Bare on the pill rather than in its own tinted circle: the pill is already
|
|
6207
|
+
a container, and a chip inside it read as a button inside a button. */
|
|
6208
|
+
.compose-collection-trigger-svg {
|
|
6209
|
+
display: block;
|
|
6210
|
+
overflow: visible;
|
|
6211
|
+
width: 0.86rem;
|
|
6212
|
+
height: 0.86rem;
|
|
6213
|
+
flex-shrink: 0;
|
|
6214
|
+
opacity: 0.75;
|
|
6215
|
+
--icon-stroke: 1.4;
|
|
6216
|
+
stroke-width: var(--icon-stroke);
|
|
6217
|
+
}
|
|
6218
|
+
|
|
6219
|
+
.compose-collection-trigger:hover .compose-collection-trigger-svg,
|
|
6220
|
+
.compose-collection-trigger[data-open="true"] .compose-collection-trigger-svg,
|
|
6221
|
+
.compose-collection-trigger[data-selected="true"]
|
|
6222
|
+
.compose-collection-trigger-svg {
|
|
6223
|
+
opacity: 1;
|
|
6224
|
+
}
|
|
6225
|
+
|
|
6071
6226
|
.compose-collection-label {
|
|
6072
6227
|
display: block;
|
|
6073
6228
|
flex: 1 1 auto;
|
|
@@ -6079,32 +6234,18 @@
|
|
|
6079
6234
|
font-weight: var(--fw-medium);
|
|
6080
6235
|
}
|
|
6081
6236
|
|
|
6082
|
-
.
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
flex-shrink: 0;
|
|
6086
|
-
opacity: 0.46;
|
|
6087
|
-
--icon-stroke: 1.38;
|
|
6088
|
-
stroke-width: var(--icon-stroke);
|
|
6089
|
-
transition:
|
|
6090
|
-
transform 0.18s ease,
|
|
6091
|
-
opacity 0.18s ease;
|
|
6092
|
-
}
|
|
6093
|
-
|
|
6094
|
-
.compose-collection-trigger[data-open="true"] .compose-collection-chevron {
|
|
6095
|
-
transform: rotate(180deg);
|
|
6096
|
-
opacity: 0.74;
|
|
6097
|
-
}
|
|
6098
|
-
|
|
6237
|
+
/* Desktop sizing. Every dimension here has a roomier counterpart in the
|
|
6238
|
+
touch block near the end of the file — a picker aimed with a cursor can be
|
|
6239
|
+
tighter than one aimed with a thumb. */
|
|
6099
6240
|
.compose-collection-select [data-popover] {
|
|
6100
6241
|
z-index: 100;
|
|
6101
|
-
min-width:
|
|
6102
|
-
max-width:
|
|
6242
|
+
min-width: 13.5rem;
|
|
6243
|
+
max-width: 17rem;
|
|
6103
6244
|
}
|
|
6104
6245
|
|
|
6105
6246
|
.compose-collection-popover {
|
|
6106
|
-
padding: 0.
|
|
6107
|
-
border-radius:
|
|
6247
|
+
padding: 0.44rem 0.48rem 0.4rem;
|
|
6248
|
+
border-radius: 0.95rem;
|
|
6108
6249
|
border: 1px solid var(--compose-control-border);
|
|
6109
6250
|
background: var(--compose-floating-bg);
|
|
6110
6251
|
box-shadow:
|
|
@@ -6114,16 +6255,16 @@
|
|
|
6114
6255
|
}
|
|
6115
6256
|
|
|
6116
6257
|
.compose-collection-popover-header {
|
|
6117
|
-
padding: 0.
|
|
6258
|
+
padding: 0.18rem 0 0.44rem;
|
|
6118
6259
|
}
|
|
6119
6260
|
|
|
6120
6261
|
.compose-collection-search-shell {
|
|
6121
6262
|
display: flex;
|
|
6122
6263
|
align-items: center;
|
|
6123
|
-
gap: 0.
|
|
6124
|
-
min-height: 2.
|
|
6125
|
-
padding: 0 0.
|
|
6126
|
-
border-radius: 0.
|
|
6264
|
+
gap: 0.45rem;
|
|
6265
|
+
min-height: 2.25rem;
|
|
6266
|
+
padding: 0 0.75rem;
|
|
6267
|
+
border-radius: 0.75rem;
|
|
6127
6268
|
border: 1px solid var(--compose-control-border);
|
|
6128
6269
|
background: var(--compose-control-bg);
|
|
6129
6270
|
color: var(--site-text-secondary);
|
|
@@ -6146,8 +6287,8 @@
|
|
|
6146
6287
|
}
|
|
6147
6288
|
|
|
6148
6289
|
.compose-collection-search-icon {
|
|
6149
|
-
width:
|
|
6150
|
-
height:
|
|
6290
|
+
width: 0.98rem;
|
|
6291
|
+
height: 0.98rem;
|
|
6151
6292
|
flex-shrink: 0;
|
|
6152
6293
|
--icon-stroke: 1.3;
|
|
6153
6294
|
stroke-width: var(--icon-stroke);
|
|
@@ -6174,7 +6315,7 @@
|
|
|
6174
6315
|
display: flex;
|
|
6175
6316
|
flex-direction: column;
|
|
6176
6317
|
gap: 0.06rem;
|
|
6177
|
-
max-height:
|
|
6318
|
+
max-height: 12.5rem;
|
|
6178
6319
|
overflow-y: auto;
|
|
6179
6320
|
padding: 0.08rem;
|
|
6180
6321
|
}
|
|
@@ -6183,15 +6324,15 @@
|
|
|
6183
6324
|
width: 100%;
|
|
6184
6325
|
display: flex;
|
|
6185
6326
|
align-items: center;
|
|
6186
|
-
gap: 0.
|
|
6327
|
+
gap: 0.6rem;
|
|
6187
6328
|
min-width: 0;
|
|
6188
|
-
min-height:
|
|
6329
|
+
min-height: 2.35rem;
|
|
6189
6330
|
padding-top: 0;
|
|
6190
6331
|
padding-bottom: 0;
|
|
6191
|
-
padding-left: 0.
|
|
6192
|
-
padding-right: 0.
|
|
6332
|
+
padding-left: 0.62rem !important;
|
|
6333
|
+
padding-right: 0.4rem !important;
|
|
6193
6334
|
border: none;
|
|
6194
|
-
border-radius: 0.
|
|
6335
|
+
border-radius: 0.7rem;
|
|
6195
6336
|
background: transparent;
|
|
6196
6337
|
background-image: none !important;
|
|
6197
6338
|
cursor: pointer !important;
|
|
@@ -6231,8 +6372,8 @@
|
|
|
6231
6372
|
display: inline-flex;
|
|
6232
6373
|
align-items: center;
|
|
6233
6374
|
justify-content: center;
|
|
6234
|
-
width: 1.
|
|
6235
|
-
height: 1.
|
|
6375
|
+
width: 1.12rem;
|
|
6376
|
+
height: 1.12rem;
|
|
6236
6377
|
flex-shrink: 0;
|
|
6237
6378
|
}
|
|
6238
6379
|
|
|
@@ -6283,7 +6424,7 @@
|
|
|
6283
6424
|
}
|
|
6284
6425
|
|
|
6285
6426
|
.compose-collection-empty {
|
|
6286
|
-
padding: 0.
|
|
6427
|
+
padding: 0.75rem 0.6rem 0.85rem;
|
|
6287
6428
|
color: var(--site-text-secondary);
|
|
6288
6429
|
font-size: var(--type-ui-caption);
|
|
6289
6430
|
line-height: 1.5;
|
|
@@ -6291,8 +6432,8 @@
|
|
|
6291
6432
|
}
|
|
6292
6433
|
|
|
6293
6434
|
.compose-collection-footer {
|
|
6294
|
-
margin-top: 0.
|
|
6295
|
-
padding: 0.
|
|
6435
|
+
margin-top: 0.28rem;
|
|
6436
|
+
padding: 0.28rem 0.18rem 0.1rem;
|
|
6296
6437
|
border-top: 1px solid
|
|
6297
6438
|
color-mix(in srgb, var(--site-divider) 50%, transparent);
|
|
6298
6439
|
}
|
|
@@ -6300,12 +6441,12 @@
|
|
|
6300
6441
|
.compose-collection-add-action {
|
|
6301
6442
|
display: flex;
|
|
6302
6443
|
align-items: center;
|
|
6303
|
-
gap: 0.
|
|
6444
|
+
gap: 0.6rem;
|
|
6304
6445
|
width: 100%;
|
|
6305
|
-
min-height:
|
|
6306
|
-
padding: 0 0.
|
|
6446
|
+
min-height: 2.35rem;
|
|
6447
|
+
padding: 0 0.62rem;
|
|
6307
6448
|
border: none;
|
|
6308
|
-
border-radius:
|
|
6449
|
+
border-radius: 0.7rem;
|
|
6309
6450
|
background: transparent;
|
|
6310
6451
|
cursor: pointer;
|
|
6311
6452
|
text-align: left;
|
|
@@ -6386,28 +6527,7 @@
|
|
|
6386
6527
|
min-width: 0;
|
|
6387
6528
|
}
|
|
6388
6529
|
|
|
6389
|
-
.compose-quick-actions-row {
|
|
6390
|
-
display: flex;
|
|
6391
|
-
justify-content: flex-end;
|
|
6392
|
-
gap: 0.5rem;
|
|
6393
|
-
padding: 2px 12px 12px;
|
|
6394
|
-
background-color: var(--compose-paper-bg);
|
|
6395
|
-
border-bottom-left-radius: inherit;
|
|
6396
|
-
border-bottom-right-radius: inherit;
|
|
6397
|
-
}
|
|
6398
|
-
|
|
6399
|
-
.compose-action-row:has(+ .compose-quick-actions-row) {
|
|
6400
|
-
padding-bottom: 4px;
|
|
6401
|
-
}
|
|
6402
|
-
|
|
6403
6530
|
@media (min-width: 700px) {
|
|
6404
|
-
.compose-quick-actions-row {
|
|
6405
|
-
padding: 2px 18px 14px;
|
|
6406
|
-
}
|
|
6407
|
-
|
|
6408
|
-
.compose-action-row:has(+ .compose-quick-actions-row) {
|
|
6409
|
-
padding-bottom: 4px;
|
|
6410
|
-
}
|
|
6411
6531
|
}
|
|
6412
6532
|
|
|
6413
6533
|
.compose-publish-quick-toggle {
|
|
@@ -6470,83 +6590,6 @@
|
|
|
6470
6590
|
cursor: not-allowed;
|
|
6471
6591
|
}
|
|
6472
6592
|
|
|
6473
|
-
.compose-publish-summaries {
|
|
6474
|
-
display: flex;
|
|
6475
|
-
flex-wrap: wrap;
|
|
6476
|
-
justify-content: flex-end;
|
|
6477
|
-
gap: 0.5rem;
|
|
6478
|
-
width: 100%;
|
|
6479
|
-
}
|
|
6480
|
-
|
|
6481
|
-
.compose-publish-summary {
|
|
6482
|
-
display: inline-flex;
|
|
6483
|
-
align-items: center;
|
|
6484
|
-
gap: 0.48rem;
|
|
6485
|
-
min-height: 2.15rem;
|
|
6486
|
-
max-width: min(100%, 17rem);
|
|
6487
|
-
padding: 0.38rem 0.74rem;
|
|
6488
|
-
border: 1px solid var(--compose-control-border);
|
|
6489
|
-
border-radius: 999px;
|
|
6490
|
-
background-color: color-mix(
|
|
6491
|
-
in srgb,
|
|
6492
|
-
var(--compose-control-bg) 82%,
|
|
6493
|
-
var(--compose-paper-bg)
|
|
6494
|
-
);
|
|
6495
|
-
color: color-mix(
|
|
6496
|
-
in srgb,
|
|
6497
|
-
var(--site-text-primary) 70%,
|
|
6498
|
-
var(--site-text-secondary)
|
|
6499
|
-
);
|
|
6500
|
-
font-size: var(--compose-summary-size);
|
|
6501
|
-
font-weight: var(--fw-medium);
|
|
6502
|
-
line-height: 1.1;
|
|
6503
|
-
cursor: pointer;
|
|
6504
|
-
white-space: nowrap;
|
|
6505
|
-
transition:
|
|
6506
|
-
background-color 0.18s ease,
|
|
6507
|
-
border-color 0.18s ease,
|
|
6508
|
-
color 0.18s ease,
|
|
6509
|
-
transform 0.18s ease;
|
|
6510
|
-
}
|
|
6511
|
-
|
|
6512
|
-
.compose-publish-summary:hover:not(:disabled) {
|
|
6513
|
-
border-color: color-mix(in srgb, var(--site-text-primary) 12%, transparent);
|
|
6514
|
-
background-color: color-mix(
|
|
6515
|
-
in srgb,
|
|
6516
|
-
var(--compose-control-bg-strong) 84%,
|
|
6517
|
-
var(--compose-paper-bg)
|
|
6518
|
-
);
|
|
6519
|
-
color: var(--site-text-primary);
|
|
6520
|
-
transform: translateY(-1px);
|
|
6521
|
-
}
|
|
6522
|
-
|
|
6523
|
-
.compose-publish-summary:disabled {
|
|
6524
|
-
opacity: 0.6;
|
|
6525
|
-
cursor: progress;
|
|
6526
|
-
}
|
|
6527
|
-
|
|
6528
|
-
.compose-publish-summary-icon {
|
|
6529
|
-
display: inline-flex;
|
|
6530
|
-
align-items: center;
|
|
6531
|
-
justify-content: center;
|
|
6532
|
-
width: 1rem;
|
|
6533
|
-
height: 1rem;
|
|
6534
|
-
flex-shrink: 0;
|
|
6535
|
-
}
|
|
6536
|
-
|
|
6537
|
-
.compose-publish-summary-icon svg {
|
|
6538
|
-
display: block;
|
|
6539
|
-
width: 100%;
|
|
6540
|
-
height: 100%;
|
|
6541
|
-
overflow: visible;
|
|
6542
|
-
}
|
|
6543
|
-
|
|
6544
|
-
.compose-publish-summary-text {
|
|
6545
|
-
min-width: 0;
|
|
6546
|
-
overflow: hidden;
|
|
6547
|
-
text-overflow: ellipsis;
|
|
6548
|
-
}
|
|
6549
|
-
|
|
6550
6593
|
.compose-publish-group {
|
|
6551
6594
|
position: relative;
|
|
6552
6595
|
display: inline-flex;
|
|
@@ -6559,10 +6602,17 @@
|
|
|
6559
6602
|
z-index: 100;
|
|
6560
6603
|
}
|
|
6561
6604
|
|
|
6562
|
-
.
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6605
|
+
/* Sized against the row it leads, not in isolation. Measured: Publish 33px,
|
|
6606
|
+
the options trigger 33px, the collection pill 30.5px — Publish and the
|
|
6607
|
+
options circle share a height so they read as one pair at the end of the
|
|
6608
|
+
row, and the collection pill sits just under them. Touch gets the roomier
|
|
6609
|
+
set back further down: 33px is a fine mouse target and a poor thumb one. */
|
|
6610
|
+
.compose-publish-main {
|
|
6611
|
+
/* `em`, not `rem`: the box is a multiple of its own label, so the ratio
|
|
6612
|
+
holds if the button's type ever scales. The reference is 2.4em (36px
|
|
6613
|
+
around a 15px label); ours sits a step under, which is the only place we
|
|
6614
|
+
leave it — every other number in this button is traced. */
|
|
6615
|
+
min-height: 2.2em;
|
|
6566
6616
|
border: none;
|
|
6567
6617
|
background: transparent;
|
|
6568
6618
|
cursor: pointer;
|
|
@@ -6572,28 +6622,36 @@
|
|
|
6572
6622
|
box-shadow 0.18s ease;
|
|
6573
6623
|
}
|
|
6574
6624
|
|
|
6575
|
-
.
|
|
6625
|
+
/* Shape traced from threads.com's Post button, measured off the reference at
|
|
6626
|
+
2x: 1px border, 8px radius, 18px side padding, ~15px bold label, content
|
|
6627
|
+
width with no `min-width` — the reference sizes to its word. Height is the
|
|
6628
|
+
one number we take a step under; see above.
|
|
6629
|
+
|
|
6630
|
+
Where we part from it: threads outlines Post in *both* states, and we only
|
|
6631
|
+
borrow that for disabled (below). Once there is something to post the
|
|
6632
|
+
button fills with ink rather than firming up an outline — a composer this
|
|
6633
|
+
flat can carry one solid object, and it should be the send. Weight and
|
|
6634
|
+
tracking hold across both states so the box does not resize the moment the
|
|
6635
|
+
post becomes postable. */
|
|
6576
6636
|
.compose-publish-main {
|
|
6577
6637
|
display: inline-flex;
|
|
6578
6638
|
align-items: center;
|
|
6579
6639
|
justify-content: center;
|
|
6580
6640
|
gap: 0.3rem;
|
|
6581
6641
|
white-space: nowrap;
|
|
6582
|
-
min-width: 6rem;
|
|
6583
6642
|
padding: 0 18px;
|
|
6584
6643
|
background-color: var(--site-text-primary);
|
|
6585
6644
|
color: var(--site-elevated-bg);
|
|
6586
6645
|
font-size: var(--compose-primary-button-size);
|
|
6587
|
-
font-weight: var(--fw-
|
|
6588
|
-
letter-spacing: 0
|
|
6646
|
+
font-weight: var(--fw-bold);
|
|
6647
|
+
letter-spacing: 0;
|
|
6589
6648
|
box-shadow: none;
|
|
6590
6649
|
}
|
|
6591
6650
|
|
|
6592
|
-
.compose-publish-single:hover:not(:disabled),
|
|
6593
6651
|
.compose-publish-main:hover:not(:disabled) {
|
|
6594
6652
|
background-color: color-mix(
|
|
6595
6653
|
in srgb,
|
|
6596
|
-
var(--site-text-primary)
|
|
6654
|
+
var(--site-text-primary) 92%,
|
|
6597
6655
|
var(--site-elevated-bg)
|
|
6598
6656
|
);
|
|
6599
6657
|
}
|
|
@@ -6602,138 +6660,32 @@
|
|
|
6602
6660
|
display: inline-flex;
|
|
6603
6661
|
align-items: stretch;
|
|
6604
6662
|
overflow: hidden;
|
|
6605
|
-
border-radius:
|
|
6606
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
6663
|
+
border-radius: 8px;
|
|
6607
6664
|
}
|
|
6608
6665
|
|
|
6609
6666
|
.compose-publish-buttons .compose-publish-main {
|
|
6610
|
-
border-radius:
|
|
6611
|
-
}
|
|
6612
|
-
|
|
6613
|
-
.compose-publish-buttons-inactive .compose-publish-toggle:not(:disabled) {
|
|
6614
|
-
color: color-mix(
|
|
6615
|
-
in srgb,
|
|
6616
|
-
var(--site-text-secondary) 92%,
|
|
6617
|
-
var(--site-elevated-bg)
|
|
6618
|
-
);
|
|
6619
|
-
background-color: color-mix(
|
|
6620
|
-
in srgb,
|
|
6621
|
-
var(--compose-control-bg) 88%,
|
|
6622
|
-
var(--compose-paper-bg)
|
|
6623
|
-
);
|
|
6624
|
-
--compose-publish-divider-color: color-mix(
|
|
6625
|
-
in srgb,
|
|
6626
|
-
var(--site-divider) 72%,
|
|
6627
|
-
transparent
|
|
6628
|
-
);
|
|
6629
|
-
}
|
|
6630
|
-
|
|
6631
|
-
.compose-publish-buttons-inactive
|
|
6632
|
-
.compose-publish-toggle:not(:disabled):hover,
|
|
6633
|
-
.compose-publish-buttons-inactive
|
|
6634
|
-
.compose-publish-toggle[aria-expanded="true"]:not(:disabled) {
|
|
6635
|
-
color: color-mix(
|
|
6636
|
-
in srgb,
|
|
6637
|
-
var(--site-text-primary) 68%,
|
|
6638
|
-
var(--site-text-secondary)
|
|
6639
|
-
);
|
|
6640
|
-
background-color: color-mix(
|
|
6641
|
-
in srgb,
|
|
6642
|
-
var(--compose-control-bg-strong) 88%,
|
|
6643
|
-
var(--compose-paper-bg)
|
|
6644
|
-
);
|
|
6645
|
-
}
|
|
6646
|
-
|
|
6647
|
-
.compose-publish-buttons-inactive .compose-publish-toggle-chevron {
|
|
6648
|
-
opacity: 0.62;
|
|
6649
|
-
}
|
|
6650
|
-
|
|
6651
|
-
.compose-publish-toggle {
|
|
6652
|
-
display: inline-flex;
|
|
6653
|
-
align-items: center;
|
|
6654
|
-
justify-content: center;
|
|
6655
|
-
position: relative;
|
|
6656
|
-
width: 2.75rem;
|
|
6657
|
-
color: var(--site-elevated-bg);
|
|
6658
|
-
background-color: var(--site-text-primary);
|
|
6659
|
-
border-radius: 0 999px 999px 0;
|
|
6660
|
-
flex-shrink: 0;
|
|
6661
|
-
--compose-publish-divider-color: color-mix(
|
|
6662
|
-
in srgb,
|
|
6663
|
-
var(--site-elevated-bg) 14%,
|
|
6664
|
-
transparent
|
|
6665
|
-
);
|
|
6666
|
-
}
|
|
6667
|
-
|
|
6668
|
-
.compose-publish-toggle::before {
|
|
6669
|
-
content: "";
|
|
6670
|
-
position: absolute;
|
|
6671
|
-
left: 0;
|
|
6672
|
-
top: 50%;
|
|
6673
|
-
width: 1px;
|
|
6674
|
-
height: 1rem;
|
|
6675
|
-
transform: translateY(-50%);
|
|
6676
|
-
background-color: var(--compose-publish-divider-color);
|
|
6677
|
-
opacity: 0.7;
|
|
6678
|
-
}
|
|
6679
|
-
|
|
6680
|
-
.compose-publish-toggle:hover:not(:disabled),
|
|
6681
|
-
.compose-publish-toggle[aria-expanded="true"]:not(:disabled) {
|
|
6682
|
-
background-color: color-mix(
|
|
6683
|
-
in srgb,
|
|
6684
|
-
var(--site-text-primary) 94%,
|
|
6685
|
-
var(--site-elevated-bg)
|
|
6686
|
-
);
|
|
6687
|
-
}
|
|
6688
|
-
|
|
6689
|
-
.compose-publish-toggle-chevron {
|
|
6690
|
-
opacity: 0.78;
|
|
6691
|
-
display: block;
|
|
6692
|
-
width: 0.92rem;
|
|
6693
|
-
height: 0.92rem;
|
|
6694
|
-
overflow: visible;
|
|
6695
|
-
--icon-stroke: 1.46;
|
|
6696
|
-
stroke-width: var(--icon-stroke);
|
|
6697
|
-
}
|
|
6698
|
-
|
|
6699
|
-
.compose-publish-single:focus-visible,
|
|
6700
|
-
.compose-publish-main:focus-visible,
|
|
6701
|
-
.compose-publish-toggle:focus-visible,
|
|
6702
|
-
.compose-publish-summary:focus-visible,
|
|
6703
|
-
.compose-publish-chip:focus-visible {
|
|
6704
|
-
outline: 2px solid
|
|
6705
|
-
color-mix(in srgb, var(--site-text-primary) 22%, transparent);
|
|
6706
|
-
outline-offset: 2px;
|
|
6667
|
+
border-radius: 8px;
|
|
6707
6668
|
}
|
|
6708
6669
|
|
|
6709
|
-
.
|
|
6670
|
+
/* Nothing postable yet. Both channels step back together: the frame to
|
|
6671
|
+
7% (1.10:1, the reference's #f4f4f4 on white) and the label to 46%
|
|
6672
|
+
(2.12:1, its #b2b2b2). Inactive controls are exempt from the contrast
|
|
6673
|
+
floors, which is the only reason a label may sit this far under 4.5:1. */
|
|
6710
6674
|
.compose-publish-main:disabled:not(.compose-publish-main-loading) {
|
|
6711
6675
|
opacity: 1;
|
|
6712
|
-
color: var(--site-text-secondary);
|
|
6713
|
-
background-color:
|
|
6714
|
-
|
|
6715
|
-
var(--
|
|
6716
|
-
|
|
6717
|
-
);
|
|
6718
|
-
box-shadow: none;
|
|
6719
|
-
}
|
|
6720
|
-
|
|
6721
|
-
.compose-publish-toggle:disabled:not(.compose-publish-toggle-loading) {
|
|
6722
|
-
opacity: 1;
|
|
6723
|
-
color: var(--site-text-secondary);
|
|
6724
|
-
background-color: color-mix(
|
|
6725
|
-
in srgb,
|
|
6726
|
-
var(--compose-control-bg) 88%,
|
|
6727
|
-
var(--compose-paper-bg)
|
|
6728
|
-
);
|
|
6729
|
-
border-left-color: color-mix(in srgb, var(--site-divider) 80%, transparent);
|
|
6676
|
+
color: color-mix(in srgb, var(--site-text-secondary) 46%, transparent);
|
|
6677
|
+
background-color: transparent;
|
|
6678
|
+
box-shadow: inset 0 0 0 1px
|
|
6679
|
+
color-mix(in srgb, var(--site-text-secondary) 7%, transparent);
|
|
6680
|
+
cursor: not-allowed;
|
|
6730
6681
|
}
|
|
6731
6682
|
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6683
|
+
/* Pointing at it says so rather than doing nothing: the frame comes up a
|
|
6684
|
+
step, but the label stays faded and the cursor stays barred, so the hover
|
|
6685
|
+
never promises a press it will not accept. */
|
|
6686
|
+
.compose-publish-main:disabled:not(.compose-publish-main-loading):hover {
|
|
6687
|
+
box-shadow: inset 0 0 0 1px
|
|
6688
|
+
color-mix(in srgb, var(--site-text-secondary) 18%, transparent);
|
|
6737
6689
|
}
|
|
6738
6690
|
|
|
6739
6691
|
.compose-publish-panel {
|
|
@@ -6810,163 +6762,398 @@
|
|
|
6810
6762
|
padding-left: calc(1rem + env(safe-area-inset-left));
|
|
6811
6763
|
}
|
|
6812
6764
|
|
|
6813
|
-
|
|
6765
|
+
/* ── Options sheet ──────────────────────────────────────────────────
|
|
6766
|
+
A vertical list read top to bottom, not a toolbar of chips: muted
|
|
6767
|
+
group label, one full-width row per setting, value or control on the
|
|
6768
|
+
right. Every choice carries its own hint so they can be compared
|
|
6769
|
+
before picking one. */
|
|
6770
|
+
|
|
6771
|
+
.compose-sheet {
|
|
6814
6772
|
display: flex;
|
|
6815
6773
|
flex-direction: column;
|
|
6816
|
-
gap: 0.625rem;
|
|
6817
6774
|
}
|
|
6818
6775
|
|
|
6819
|
-
.compose-
|
|
6776
|
+
.compose-sheet-label {
|
|
6777
|
+
margin: 0;
|
|
6778
|
+
padding: 0.35rem 0.35rem 0.3rem;
|
|
6779
|
+
color: var(--site-text-secondary);
|
|
6780
|
+
font-size: 0.79rem;
|
|
6781
|
+
font-weight: var(--fw-semibold);
|
|
6782
|
+
}
|
|
6783
|
+
|
|
6784
|
+
.compose-sheet-row {
|
|
6785
|
+
--compose-icon-paper-fill: var(--compose-paper-bg);
|
|
6786
|
+
|
|
6820
6787
|
display: flex;
|
|
6821
|
-
align-items:
|
|
6822
|
-
|
|
6823
|
-
|
|
6788
|
+
align-items: center;
|
|
6789
|
+
gap: 0.7rem;
|
|
6790
|
+
width: 100%;
|
|
6791
|
+
padding: 0.5rem 0.45rem;
|
|
6792
|
+
border: none;
|
|
6793
|
+
border-radius: 10px;
|
|
6794
|
+
background: transparent;
|
|
6795
|
+
color: var(--site-text-primary);
|
|
6796
|
+
text-align: left;
|
|
6797
|
+
cursor: pointer;
|
|
6798
|
+
transition: background-color 0.15s ease;
|
|
6799
|
+
}
|
|
6800
|
+
|
|
6801
|
+
.compose-sheet-row:hover:not(:disabled) {
|
|
6802
|
+
--compose-icon-paper-fill: var(--compose-control-bg);
|
|
6803
|
+
background-color: var(--compose-control-bg);
|
|
6804
|
+
}
|
|
6805
|
+
|
|
6806
|
+
/* Sized to the visibility glyphs it sits in a list with, so the session rows
|
|
6807
|
+
at the foot of the panel read as the same kind of row. */
|
|
6808
|
+
.compose-sheet-row-icon {
|
|
6809
|
+
display: block;
|
|
6810
|
+
width: 0.98rem;
|
|
6811
|
+
height: 0.98rem;
|
|
6812
|
+
--icon-stroke: 1.3;
|
|
6813
|
+
stroke-width: var(--icon-stroke);
|
|
6814
|
+
flex-shrink: 0;
|
|
6815
|
+
overflow: visible;
|
|
6816
|
+
color: var(--site-text-secondary);
|
|
6817
|
+
}
|
|
6818
|
+
|
|
6819
|
+
.compose-sheet-row:disabled {
|
|
6820
|
+
cursor: not-allowed;
|
|
6821
|
+
opacity: 0.55;
|
|
6822
|
+
}
|
|
6823
|
+
|
|
6824
|
+
.compose-sheet-row:focus-visible {
|
|
6825
|
+
outline: 2px solid
|
|
6826
|
+
color-mix(in srgb, var(--site-text-primary) 22%, transparent);
|
|
6827
|
+
outline-offset: 1px;
|
|
6824
6828
|
}
|
|
6825
6829
|
|
|
6826
|
-
.compose-
|
|
6830
|
+
.compose-sheet-main {
|
|
6831
|
+
display: flex;
|
|
6832
|
+
flex-direction: column;
|
|
6833
|
+
gap: 0.08rem;
|
|
6834
|
+
flex: 1;
|
|
6827
6835
|
min-width: 0;
|
|
6828
6836
|
}
|
|
6829
6837
|
|
|
6830
|
-
.compose-
|
|
6831
|
-
|
|
6832
|
-
in srgb,
|
|
6833
|
-
var(--site-text-primary) 84%,
|
|
6834
|
-
var(--site-text-secondary)
|
|
6835
|
-
);
|
|
6836
|
-
font-size: var(--compose-panel-label-size);
|
|
6838
|
+
.compose-sheet-title {
|
|
6839
|
+
font-size: 0.9rem;
|
|
6837
6840
|
font-weight: var(--fw-medium);
|
|
6838
|
-
letter-spacing: 0.01em;
|
|
6839
|
-
line-height: 1.24;
|
|
6840
6841
|
}
|
|
6841
6842
|
|
|
6842
|
-
.compose-
|
|
6843
|
-
margin-top: 0.25rem;
|
|
6843
|
+
.compose-sheet-sub {
|
|
6844
6844
|
color: var(--site-text-secondary);
|
|
6845
|
-
font-size:
|
|
6845
|
+
font-size: 0.75rem;
|
|
6846
|
+
line-height: 1.4;
|
|
6847
|
+
}
|
|
6848
|
+
|
|
6849
|
+
.compose-sheet-check,
|
|
6850
|
+
.compose-sheet-caret {
|
|
6851
|
+
display: inline-flex;
|
|
6852
|
+
flex-shrink: 0;
|
|
6853
|
+
align-items: center;
|
|
6854
|
+
}
|
|
6855
|
+
|
|
6856
|
+
.compose-sheet-caret {
|
|
6857
|
+
color: var(--site-text-secondary);
|
|
6858
|
+
opacity: 0.75;
|
|
6859
|
+
}
|
|
6860
|
+
|
|
6861
|
+
.compose-sheet-hint {
|
|
6862
|
+
margin: 0;
|
|
6863
|
+
color: var(--site-text-secondary);
|
|
6864
|
+
font-size: 0.75rem;
|
|
6846
6865
|
line-height: 1.45;
|
|
6847
|
-
text-wrap: pretty;
|
|
6848
6866
|
}
|
|
6849
6867
|
|
|
6850
|
-
.compose-
|
|
6868
|
+
.compose-sheet-divider {
|
|
6869
|
+
height: 1px;
|
|
6870
|
+
margin: 0.45rem 0.1rem;
|
|
6871
|
+
background-color: var(--site-divider);
|
|
6872
|
+
}
|
|
6873
|
+
|
|
6874
|
+
.compose-sheet-row-switch {
|
|
6875
|
+
cursor: default;
|
|
6876
|
+
}
|
|
6877
|
+
|
|
6878
|
+
.compose-sheet-row-switch > .input[role="switch"] {
|
|
6851
6879
|
flex-shrink: 0;
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6880
|
+
}
|
|
6881
|
+
|
|
6882
|
+
/* ── Per-post date / permalink ──────────────────────────────────────
|
|
6883
|
+
Sits on the post it describes, not in the publish panel. Quiet until the
|
|
6884
|
+
post is hovered or focused, or the values are non-default. Uses
|
|
6885
|
+
margin-left:auto so appearing and disappearing never shifts the × next
|
|
6886
|
+
to it. */
|
|
6887
|
+
|
|
6888
|
+
.compose-post-meta {
|
|
6889
|
+
position: relative;
|
|
6890
|
+
margin-left: auto;
|
|
6891
|
+
/* Without this the flex item cannot shrink past its content's min-content
|
|
6892
|
+
width, so the header row overflows on narrow screens instead of
|
|
6893
|
+
ellipsising the permalink. */
|
|
6894
|
+
min-width: 0;
|
|
6895
|
+
opacity: 0;
|
|
6896
|
+
transition: opacity 0.18s ease;
|
|
6897
|
+
}
|
|
6898
|
+
|
|
6899
|
+
/* Narrow screens show the pill outright instead of revealing it. "Quiet until
|
|
6900
|
+
approached" needs a pointer to approach with, and this width is mostly
|
|
6901
|
+
touch, where there is none — an invisible-until-focused control is just a
|
|
6902
|
+
missing one.
|
|
6903
|
+
|
|
6904
|
+
It must also stay in the layout. Gating `display` on
|
|
6905
|
+
`jant-compose-editor:focus-within` made pressing the pill destroy it:
|
|
6906
|
+
pointerdown moves focus off the editor, the pill unmounts before mouseup,
|
|
6907
|
+
and a press that starts and ends on different elements never becomes a
|
|
6908
|
+
click. The pill was unclickable at this width — only `.click()` from script
|
|
6909
|
+
could open the panel. */
|
|
6910
|
+
@media (max-width: 760px) {
|
|
6911
|
+
.compose-post-meta {
|
|
6912
|
+
opacity: 1;
|
|
6913
|
+
}
|
|
6914
|
+
}
|
|
6915
|
+
|
|
6916
|
+
/* Only the first trailing control claims the free space. Two `auto` margins
|
|
6917
|
+
would split it and strand the pill mid-row. */
|
|
6918
|
+
.compose-post-meta ~ .compose-thread-post-remove,
|
|
6919
|
+
.compose-post-meta ~ .compose-close-btn {
|
|
6920
|
+
margin-left: 0;
|
|
6921
|
+
}
|
|
6922
|
+
|
|
6923
|
+
/* Scoped to the editor element rather than a layout row: single-post mode
|
|
6924
|
+
has no `.compose-editor-row` wrapper to hang this off. */
|
|
6925
|
+
jant-compose-editor:hover .compose-post-meta,
|
|
6926
|
+
jant-compose-editor:focus-within .compose-post-meta,
|
|
6927
|
+
.compose-post-meta-set,
|
|
6928
|
+
.compose-post-meta-open,
|
|
6929
|
+
.compose-post-meta:hover,
|
|
6930
|
+
.compose-post-meta:focus-within {
|
|
6931
|
+
opacity: 1;
|
|
6932
|
+
}
|
|
6933
|
+
|
|
6934
|
+
/* A lone post shows its pill outright. "Quiet until approached" only pays
|
|
6935
|
+
off when several rows would each carry one — with a single pill there is
|
|
6936
|
+
no noise to save, and hiding it made the date/permalink fade out exactly
|
|
6937
|
+
when focus moved to the publish controls, where that metadata matters
|
|
6938
|
+
most. The child combinator is the single-post detector: only that mode
|
|
6939
|
+
renders the editor as a direct child of `.compose-scroll`; reply and
|
|
6940
|
+
thread rows sit inside `.compose-editor-row` and stay quiet. */
|
|
6941
|
+
.compose-scroll > jant-compose-editor .compose-post-meta {
|
|
6942
|
+
opacity: 1;
|
|
6943
|
+
}
|
|
6944
|
+
|
|
6945
|
+
/* Defaults are the common case, so at rest this is a caption rather than a
|
|
6946
|
+
control: no chrome, and dimmer than the format selector it shares the row
|
|
6947
|
+
with. The outline arrives on hover, once it is being aimed at. */
|
|
6948
|
+
.compose-post-meta-pill {
|
|
6949
|
+
display: inline-flex;
|
|
6950
|
+
align-items: center;
|
|
6951
|
+
gap: 5px;
|
|
6952
|
+
max-width: min(17rem, 52vw);
|
|
6953
|
+
min-width: 0;
|
|
6954
|
+
padding: 3px 10px 3px 8px;
|
|
6955
|
+
border: 1px solid transparent;
|
|
6855
6956
|
border-radius: 999px;
|
|
6856
|
-
background-color:
|
|
6857
|
-
color: color-mix(
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
);
|
|
6862
|
-
font-size: var(--compose-panel-control-size);
|
|
6863
|
-
font-weight: var(--fw-medium);
|
|
6864
|
-
line-height: 1;
|
|
6957
|
+
background-color: transparent;
|
|
6958
|
+
color: color-mix(in srgb, var(--site-text-secondary) 62%, transparent);
|
|
6959
|
+
font-family: var(--font-ui);
|
|
6960
|
+
font-size: var(--type-ui-caption);
|
|
6961
|
+
white-space: nowrap;
|
|
6865
6962
|
cursor: pointer;
|
|
6866
6963
|
transition:
|
|
6867
|
-
color 0.
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
transform 0.16s ease;
|
|
6964
|
+
background-color 0.15s ease,
|
|
6965
|
+
border-color 0.15s ease,
|
|
6966
|
+
color 0.15s ease;
|
|
6871
6967
|
}
|
|
6872
6968
|
|
|
6873
|
-
.compose-
|
|
6969
|
+
.compose-post-meta-pill:hover,
|
|
6970
|
+
.compose-post-meta-pill[aria-expanded="true"] {
|
|
6971
|
+
border-color: var(--compose-control-border);
|
|
6972
|
+
background-color: var(--compose-control-bg);
|
|
6874
6973
|
color: var(--site-text-primary);
|
|
6875
|
-
border-color: color-mix(in srgb, var(--site-text-primary) 14%, transparent);
|
|
6876
|
-
background-color: var(--compose-control-bg-strong);
|
|
6877
|
-
transform: translateY(-1px);
|
|
6878
6974
|
}
|
|
6879
6975
|
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6976
|
+
/* A date or permalink the author chose is real information, not a default —
|
|
6977
|
+
it gets the chrome back and full contrast. */
|
|
6978
|
+
.compose-post-meta-set .compose-post-meta-pill {
|
|
6979
|
+
border-color: color-mix(in srgb, var(--site-text-primary) 32%, transparent);
|
|
6980
|
+
background-color: var(--compose-paper-bg);
|
|
6981
|
+
color: var(--site-text-primary);
|
|
6982
|
+
font-weight: var(--fw-medium);
|
|
6884
6983
|
}
|
|
6885
6984
|
|
|
6886
|
-
.compose-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
justify-content: space-between;
|
|
6890
|
-
gap: 0.75rem;
|
|
6891
|
-
cursor: pointer;
|
|
6985
|
+
.compose-post-meta-icon {
|
|
6986
|
+
flex-shrink: 0;
|
|
6987
|
+
opacity: 0.85;
|
|
6892
6988
|
}
|
|
6893
6989
|
|
|
6894
|
-
.compose-
|
|
6895
|
-
|
|
6896
|
-
margin-top: 0.1rem;
|
|
6990
|
+
.compose-post-meta-sep {
|
|
6991
|
+
color: color-mix(in srgb, currentcolor 45%, transparent);
|
|
6897
6992
|
}
|
|
6898
6993
|
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
);
|
|
6994
|
+
/* Only the permalink gives ground when space runs out — the date is short and
|
|
6995
|
+
already as terse as it gets. Without `overflow: hidden` a shrunk flex item
|
|
6996
|
+
still paints its full text, so a long slug used to run under the date. */
|
|
6997
|
+
.compose-post-meta-value {
|
|
6998
|
+
flex-shrink: 0;
|
|
6999
|
+
min-width: 0;
|
|
7000
|
+
overflow: hidden;
|
|
6907
7001
|
}
|
|
6908
7002
|
|
|
6909
|
-
|
|
7003
|
+
.compose-post-meta-value-slug {
|
|
7004
|
+
flex-shrink: 1;
|
|
7005
|
+
text-overflow: ellipsis;
|
|
7006
|
+
}
|
|
6910
7007
|
|
|
6911
|
-
.compose-
|
|
7008
|
+
/* Fixed, not absolute. The pill it hangs from lives inside `.compose-scroll`,
|
|
7009
|
+
and an absolute panel is clipped by that box — an empty post makes the box
|
|
7010
|
+
shorter than the panel every time, so the footer went missing and focusing
|
|
7011
|
+
the panel scrolled the format switcher off the top to compensate. Fixed
|
|
7012
|
+
leaves the scroller behind; `_updatePostMetaPanelLayout` supplies top/left
|
|
7013
|
+
and the max-height, since only script can know where the pill ended up. */
|
|
7014
|
+
.compose-post-meta-panel {
|
|
7015
|
+
position: fixed;
|
|
7016
|
+
z-index: 100;
|
|
7017
|
+
top: 0;
|
|
7018
|
+
left: 0;
|
|
6912
7019
|
display: flex;
|
|
7020
|
+
flex-direction: column;
|
|
7021
|
+
gap: 0.85rem;
|
|
7022
|
+
width: min(20rem, calc(100vw - 3rem));
|
|
7023
|
+
/* A window too short for the whole panel scrolls the panel, never crops it.
|
|
7024
|
+
Unset until script measures, so the panel is never briefly 1px tall. */
|
|
7025
|
+
max-height: var(--compose-post-meta-panel-max-height, none);
|
|
7026
|
+
overflow-y: auto;
|
|
7027
|
+
overscroll-behavior: contain;
|
|
7028
|
+
padding: 0.8rem 0.85rem 0.85rem;
|
|
7029
|
+
border: 1px solid var(--compose-control-border);
|
|
6913
7030
|
border-radius: 12px;
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
7031
|
+
/* Same surface treatment as .compose-publish-panel — it is the same kind
|
|
7032
|
+
of floating panel, and --compose-floating-bg is what adapts to dark. */
|
|
7033
|
+
background-color: var(--compose-floating-bg);
|
|
7034
|
+
box-shadow:
|
|
7035
|
+
0 10px 28px rgba(0, 0, 0, 0.08),
|
|
7036
|
+
0 1px 3px rgba(0, 0, 0, 0.05);
|
|
6917
7037
|
}
|
|
6918
7038
|
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
7039
|
+
/* It takes focus when it opens so the dialog is announced and Tab lands in
|
|
7040
|
+
the fields, but it is a container, not a control — no focus ring. */
|
|
7041
|
+
.compose-post-meta-panel:focus {
|
|
7042
|
+
outline: none;
|
|
7043
|
+
}
|
|
7044
|
+
|
|
7045
|
+
/* ── Date / permalink form ──────────────────────────────────────────
|
|
7046
|
+
Two settings, so they are both just open: a drill row per field meant
|
|
7047
|
+
the panel restated each value directly above the input showing it, and
|
|
7048
|
+
changed height every time one was opened. */
|
|
7049
|
+
|
|
7050
|
+
.compose-meta-field {
|
|
7051
|
+
display: flex;
|
|
7052
|
+
flex-direction: column;
|
|
7053
|
+
gap: 0.4rem;
|
|
7054
|
+
}
|
|
7055
|
+
|
|
7056
|
+
.compose-meta-field-head {
|
|
7057
|
+
display: flex;
|
|
7058
|
+
align-items: baseline;
|
|
7059
|
+
justify-content: space-between;
|
|
7060
|
+
gap: 0.6rem;
|
|
7061
|
+
min-height: 1.15rem;
|
|
7062
|
+
}
|
|
7063
|
+
|
|
7064
|
+
.compose-meta-label {
|
|
7065
|
+
color: var(--site-text-primary);
|
|
7066
|
+
font-size: 0.82rem;
|
|
7067
|
+
font-weight: var(--fw-medium);
|
|
7068
|
+
}
|
|
7069
|
+
|
|
7070
|
+
/* The panel's own way out. Escape and a click outside both close it, but
|
|
7071
|
+
neither announces itself, and on touch there is no Escape key at all. It
|
|
7072
|
+
spans the panel's padding so the divider reads as the foot of the panel
|
|
7073
|
+
rather than a line drawn inside it. */
|
|
7074
|
+
.compose-post-meta-footer {
|
|
7075
|
+
display: flex;
|
|
7076
|
+
justify-content: flex-end;
|
|
7077
|
+
margin: -0.1rem -0.85rem -0.85rem;
|
|
7078
|
+
padding: 0.4rem 0.6rem 0.5rem;
|
|
7079
|
+
border-top: 1px solid
|
|
7080
|
+
color-mix(in srgb, var(--site-divider) 60%, transparent);
|
|
7081
|
+
}
|
|
7082
|
+
|
|
7083
|
+
.compose-post-meta-open {
|
|
7084
|
+
z-index: 100;
|
|
7085
|
+
}
|
|
7086
|
+
|
|
7087
|
+
/* Options trigger: its own button past Publish, never a chevron welded to
|
|
7088
|
+
it. A split button reads as one button. */
|
|
7089
|
+
.compose-options-trigger {
|
|
7090
|
+
display: inline-grid;
|
|
7091
|
+
flex-shrink: 0;
|
|
7092
|
+
place-items: center;
|
|
7093
|
+
width: 2.2rem;
|
|
7094
|
+
height: 2.2rem;
|
|
6928
7095
|
border: none;
|
|
7096
|
+
border-radius: 999px;
|
|
6929
7097
|
background: transparent;
|
|
6930
|
-
cursor: pointer;
|
|
6931
|
-
white-space: nowrap;
|
|
6932
7098
|
color: var(--site-text-secondary);
|
|
7099
|
+
cursor: pointer;
|
|
6933
7100
|
transition:
|
|
6934
7101
|
background-color 0.18s ease,
|
|
6935
|
-
box-shadow 0.18s ease,
|
|
6936
7102
|
color 0.18s ease;
|
|
6937
7103
|
}
|
|
6938
7104
|
|
|
6939
|
-
.compose-
|
|
6940
|
-
|
|
6941
|
-
)
|
|
7105
|
+
.compose-options-trigger:hover:not(:disabled),
|
|
7106
|
+
.compose-options-trigger-open {
|
|
7107
|
+
background-color: var(--compose-control-bg);
|
|
6942
7108
|
color: var(--site-text-primary);
|
|
6943
7109
|
}
|
|
6944
7110
|
|
|
6945
|
-
.compose-
|
|
6946
|
-
cursor:
|
|
6947
|
-
opacity: 0.
|
|
7111
|
+
.compose-options-trigger:disabled {
|
|
7112
|
+
cursor: not-allowed;
|
|
7113
|
+
opacity: 0.5;
|
|
6948
7114
|
}
|
|
6949
7115
|
|
|
6950
|
-
.compose-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
7116
|
+
.compose-options-trigger:focus-visible {
|
|
7117
|
+
outline: 2px solid
|
|
7118
|
+
color-mix(in srgb, var(--site-text-primary) 22%, transparent);
|
|
7119
|
+
outline-offset: 2px;
|
|
6954
7120
|
}
|
|
6955
7121
|
|
|
6956
|
-
.compose-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
letter-spacing: 0.005em;
|
|
6960
|
-
line-height: 1.28;
|
|
7122
|
+
.compose-options-trigger-icon {
|
|
7123
|
+
width: 1.35rem;
|
|
7124
|
+
height: 1.35rem;
|
|
6961
7125
|
}
|
|
6962
7126
|
|
|
6963
|
-
|
|
7127
|
+
/* Sits on the field's label row, so it reads as an aside to that label rather
|
|
7128
|
+
than a second thing to do. It only appears once there is a value to undo,
|
|
7129
|
+
which is why it can afford to be this quiet. */
|
|
7130
|
+
.compose-publish-section-action {
|
|
7131
|
+
flex-shrink: 0;
|
|
7132
|
+
padding: 0;
|
|
7133
|
+
border: none;
|
|
7134
|
+
background: none;
|
|
6964
7135
|
color: var(--site-text-secondary);
|
|
6965
|
-
font-size:
|
|
6966
|
-
line-height: 1.
|
|
6967
|
-
text-
|
|
7136
|
+
font-size: 0.75rem;
|
|
7137
|
+
line-height: 1.2;
|
|
7138
|
+
text-underline-offset: 2px;
|
|
7139
|
+
cursor: pointer;
|
|
7140
|
+
transition: color 0.16s ease;
|
|
7141
|
+
}
|
|
7142
|
+
|
|
7143
|
+
.compose-publish-section-action:hover {
|
|
7144
|
+
color: var(--site-text-primary);
|
|
7145
|
+
text-decoration: underline;
|
|
7146
|
+
}
|
|
7147
|
+
|
|
7148
|
+
.compose-publish-section-action:focus-visible {
|
|
7149
|
+
outline: 2px solid
|
|
7150
|
+
color-mix(in srgb, var(--site-text-primary) 18%, transparent);
|
|
7151
|
+
outline-offset: 3px;
|
|
7152
|
+
border-radius: 4px;
|
|
6968
7153
|
}
|
|
6969
7154
|
|
|
7155
|
+
/* --- Visibility segmented control --------------------------------------- */
|
|
7156
|
+
|
|
6970
7157
|
.compose-publish-visibility-icon {
|
|
6971
7158
|
display: inline-flex;
|
|
6972
7159
|
align-items: center;
|
|
@@ -7079,90 +7266,46 @@
|
|
|
7079
7266
|
background-color: var(--compose-control-border);
|
|
7080
7267
|
}
|
|
7081
7268
|
|
|
7269
|
+
/* One line, no card: a card holding a chip holding the slug was three nested
|
|
7270
|
+
frames for what is a single tap-to-accept. */
|
|
7082
7271
|
.compose-slug-suggestion {
|
|
7083
|
-
display:
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
gap: 0.65rem;
|
|
7272
|
+
display: flex;
|
|
7273
|
+
align-items: baseline;
|
|
7274
|
+
gap: 0.4rem;
|
|
7087
7275
|
width: 100%;
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
border
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
var(--compose-control-bg) 72%,
|
|
7094
|
-
var(--compose-paper-bg)
|
|
7095
|
-
);
|
|
7096
|
-
box-shadow:
|
|
7097
|
-
inset 0 1px 0 color-mix(in srgb, var(--compose-paper-bg) 88%, transparent),
|
|
7098
|
-
0 1px 2px rgba(0, 0, 0, 0.03);
|
|
7276
|
+
margin: -0.05rem -0.35rem;
|
|
7277
|
+
padding: 0.3rem 0.35rem;
|
|
7278
|
+
border: none;
|
|
7279
|
+
border-radius: 7px;
|
|
7280
|
+
background: none;
|
|
7099
7281
|
cursor: pointer;
|
|
7100
7282
|
text-align: left;
|
|
7101
|
-
transition:
|
|
7102
|
-
background-color 0.16s ease,
|
|
7103
|
-
border-color 0.16s ease,
|
|
7104
|
-
transform 0.16s ease,
|
|
7105
|
-
box-shadow 0.16s ease;
|
|
7283
|
+
transition: background-color 0.16s ease;
|
|
7106
7284
|
}
|
|
7107
7285
|
|
|
7108
7286
|
.compose-slug-suggestion:hover {
|
|
7109
|
-
|
|
7110
|
-
background-color: color-mix(
|
|
7111
|
-
in srgb,
|
|
7112
|
-
var(--compose-control-bg-strong) 78%,
|
|
7113
|
-
var(--compose-paper-bg)
|
|
7114
|
-
);
|
|
7115
|
-
transform: translateY(-1px);
|
|
7116
|
-
box-shadow:
|
|
7117
|
-
inset 0 1px 0 color-mix(in srgb, var(--compose-paper-bg) 88%, transparent),
|
|
7118
|
-
0 4px 14px rgba(0, 0, 0, 0.045);
|
|
7287
|
+
background-color: var(--compose-control-bg);
|
|
7119
7288
|
}
|
|
7120
7289
|
|
|
7121
7290
|
.compose-slug-suggestion:focus-visible {
|
|
7122
7291
|
outline: 2px solid
|
|
7123
7292
|
color-mix(in srgb, var(--site-text-primary) 18%, transparent);
|
|
7124
|
-
outline-offset:
|
|
7125
|
-
}
|
|
7126
|
-
|
|
7127
|
-
.compose-slug-suggestion-copy {
|
|
7128
|
-
min-width: 0;
|
|
7129
|
-
display: flex;
|
|
7130
|
-
align-items: center;
|
|
7131
|
-
flex-wrap: wrap;
|
|
7132
|
-
gap: 0.45rem;
|
|
7293
|
+
outline-offset: 1px;
|
|
7133
7294
|
}
|
|
7134
7295
|
|
|
7135
7296
|
.compose-slug-suggestion-label {
|
|
7297
|
+
flex-shrink: 0;
|
|
7136
7298
|
color: var(--site-text-secondary);
|
|
7137
|
-
font-size:
|
|
7138
|
-
|
|
7139
|
-
letter-spacing: 0.01em;
|
|
7140
|
-
line-height: 1.2;
|
|
7141
|
-
}
|
|
7142
|
-
|
|
7143
|
-
.compose-slug-suggestion-chip {
|
|
7144
|
-
display: inline-flex;
|
|
7145
|
-
align-items: center;
|
|
7146
|
-
min-width: 0;
|
|
7147
|
-
max-width: 100%;
|
|
7148
|
-
padding: 0.25rem 0.48rem;
|
|
7149
|
-
border-radius: 999px;
|
|
7150
|
-
border: 1px solid var(--compose-control-border);
|
|
7151
|
-
background-color: color-mix(
|
|
7152
|
-
in srgb,
|
|
7153
|
-
var(--compose-paper-bg) 92%,
|
|
7154
|
-
var(--compose-control-bg)
|
|
7155
|
-
);
|
|
7156
|
-
box-shadow: inset 0 1px 0
|
|
7157
|
-
color-mix(in srgb, var(--compose-paper-bg) 88%, transparent);
|
|
7299
|
+
font-size: 0.75rem;
|
|
7300
|
+
line-height: 1.3;
|
|
7158
7301
|
}
|
|
7159
7302
|
|
|
7160
7303
|
.compose-slug-suggestion-value {
|
|
7161
|
-
|
|
7304
|
+
min-width: 0;
|
|
7162
7305
|
color: var(--site-text-primary);
|
|
7163
7306
|
font-size: var(--type-ui-caption);
|
|
7164
7307
|
font-weight: var(--fw-medium);
|
|
7165
|
-
line-height: 1.
|
|
7308
|
+
line-height: 1.3;
|
|
7166
7309
|
font-family:
|
|
7167
7310
|
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
7168
7311
|
"Courier New", monospace;
|
|
@@ -7173,101 +7316,61 @@
|
|
|
7173
7316
|
|
|
7174
7317
|
.compose-slug-suggestion-icon {
|
|
7175
7318
|
display: inline-flex;
|
|
7319
|
+
flex-shrink: 0;
|
|
7176
7320
|
align-items: center;
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
border-radius: 999px;
|
|
7181
|
-
background-color: color-mix(
|
|
7182
|
-
in srgb,
|
|
7183
|
-
var(--compose-paper-bg) 88%,
|
|
7184
|
-
var(--compose-control-bg)
|
|
7185
|
-
);
|
|
7186
|
-
color: color-mix(
|
|
7187
|
-
in srgb,
|
|
7188
|
-
var(--site-text-primary) 72%,
|
|
7189
|
-
var(--site-text-secondary)
|
|
7190
|
-
);
|
|
7321
|
+
margin-left: auto;
|
|
7322
|
+
color: var(--site-text-secondary);
|
|
7323
|
+
transform: translateY(0.1em);
|
|
7191
7324
|
transition:
|
|
7192
7325
|
transform 0.16s ease,
|
|
7193
|
-
background-color 0.16s ease,
|
|
7194
7326
|
color 0.16s ease;
|
|
7195
7327
|
}
|
|
7196
7328
|
|
|
7197
7329
|
.compose-slug-suggestion:hover .compose-slug-suggestion-icon {
|
|
7198
|
-
transform:
|
|
7199
|
-
background-color: color-mix(
|
|
7200
|
-
in srgb,
|
|
7201
|
-
var(--compose-paper-bg) 66%,
|
|
7202
|
-
var(--compose-control-bg-strong)
|
|
7203
|
-
);
|
|
7330
|
+
transform: translate(2px, 0.1em);
|
|
7204
7331
|
color: var(--site-text-primary);
|
|
7205
7332
|
}
|
|
7206
7333
|
|
|
7207
|
-
.
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
flex-direction: column;
|
|
7211
|
-
gap: 0.55rem;
|
|
7212
|
-
}
|
|
7213
|
-
|
|
7334
|
+
/* Scaled to the panel it sits in. The old field was 3rem tall with a 14px
|
|
7335
|
+
radius, a gradient, an inset highlight and a drop shadow — more chrome than
|
|
7336
|
+
the dialog's own controls carry. */
|
|
7214
7337
|
.compose-publish-slug-input-wrap,
|
|
7215
7338
|
.compose-publish-date-input-wrap {
|
|
7216
7339
|
display: flex;
|
|
7217
7340
|
align-items: center;
|
|
7218
|
-
gap: 0.
|
|
7219
|
-
min-height: 3rem;
|
|
7220
|
-
padding: 0 0.
|
|
7341
|
+
gap: 0.5rem;
|
|
7342
|
+
min-height: 2.3rem;
|
|
7343
|
+
padding: 0 0.6rem;
|
|
7221
7344
|
border: 1px solid var(--compose-control-border);
|
|
7222
|
-
border-radius:
|
|
7223
|
-
background:
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
),
|
|
7229
|
-
color-mix(in srgb, var(--compose-paper-bg) 97%, var(--compose-control-bg));
|
|
7230
|
-
box-shadow:
|
|
7231
|
-
inset 0 1px 0 color-mix(in srgb, var(--compose-paper-bg) 92%, transparent),
|
|
7232
|
-
0 1px 2px rgba(0, 0, 0, 0.02);
|
|
7345
|
+
border-radius: 9px;
|
|
7346
|
+
background-color: color-mix(
|
|
7347
|
+
in srgb,
|
|
7348
|
+
var(--compose-control-bg) 55%,
|
|
7349
|
+
var(--compose-paper-bg)
|
|
7350
|
+
);
|
|
7233
7351
|
transition:
|
|
7234
7352
|
border-color 0.16s ease,
|
|
7235
|
-
background-color 0.16s ease,
|
|
7236
7353
|
box-shadow 0.16s ease;
|
|
7237
7354
|
}
|
|
7238
7355
|
|
|
7239
7356
|
.compose-publish-slug-input-wrap:focus-within,
|
|
7240
7357
|
.compose-publish-date-input-wrap:focus-within {
|
|
7241
|
-
border-color: color-mix(in srgb, var(--site-text-primary)
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
var(--compose-control-bg-strong)
|
|
7252
|
-
);
|
|
7253
|
-
box-shadow:
|
|
7254
|
-
inset 0 1px 0 color-mix(in srgb, var(--compose-paper-bg) 94%, transparent),
|
|
7255
|
-
0 0 0 3px color-mix(in srgb, var(--site-text-primary) 6%, transparent);
|
|
7358
|
+
border-color: color-mix(in srgb, var(--site-text-primary) 22%, transparent);
|
|
7359
|
+
box-shadow: 0 0 0 3px
|
|
7360
|
+
color-mix(in srgb, var(--site-text-primary) 7%, transparent);
|
|
7361
|
+
}
|
|
7362
|
+
|
|
7363
|
+
/* The message under the field is red; the field it belongs to should say so
|
|
7364
|
+
too, rather than leaving the reader to pair them up. */
|
|
7365
|
+
.compose-publish-slug-input-wrap:has([aria-invalid="true"]),
|
|
7366
|
+
.compose-publish-date-input-wrap:has([aria-invalid="true"]) {
|
|
7367
|
+
border-color: color-mix(in srgb, var(--destructive) 42%, transparent);
|
|
7256
7368
|
}
|
|
7257
7369
|
|
|
7258
7370
|
.compose-publish-slug-prefix {
|
|
7259
7371
|
flex-shrink: 0;
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
border-right: 1px solid
|
|
7263
|
-
color-mix(in srgb, var(--site-text-primary) 8%, transparent);
|
|
7264
|
-
color: color-mix(
|
|
7265
|
-
in srgb,
|
|
7266
|
-
var(--site-text-primary) 52%,
|
|
7267
|
-
var(--site-text-secondary)
|
|
7268
|
-
);
|
|
7269
|
-
font-size: var(--compose-panel-control-size);
|
|
7270
|
-
font-weight: var(--fw-medium);
|
|
7372
|
+
color: var(--site-text-secondary);
|
|
7373
|
+
font-size: var(--type-ui-caption);
|
|
7271
7374
|
line-height: 1;
|
|
7272
7375
|
font-family:
|
|
7273
7376
|
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
@@ -7283,9 +7386,8 @@
|
|
|
7283
7386
|
padding: 0;
|
|
7284
7387
|
box-shadow: none;
|
|
7285
7388
|
color: var(--site-text-primary);
|
|
7286
|
-
font-size: var(--
|
|
7287
|
-
|
|
7288
|
-
line-height: 1.35;
|
|
7389
|
+
font-size: var(--type-ui-caption);
|
|
7390
|
+
line-height: 1.4;
|
|
7289
7391
|
font-family:
|
|
7290
7392
|
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
7291
7393
|
"Courier New", monospace;
|
|
@@ -7295,13 +7397,56 @@
|
|
|
7295
7397
|
font-family: inherit;
|
|
7296
7398
|
}
|
|
7297
7399
|
|
|
7400
|
+
/* The browser paints `yyyy-mm-dd` in the value's own colour, so an untouched
|
|
7401
|
+
field reads as a date that was chosen. Only the empty state is dimmed. */
|
|
7402
|
+
.compose-publish-date-input-empty::-webkit-datetime-edit {
|
|
7403
|
+
color: var(--site-text-secondary);
|
|
7404
|
+
opacity: 0.75;
|
|
7405
|
+
}
|
|
7406
|
+
|
|
7407
|
+
/* Replaced by .compose-publish-date-picker, which drives the same picker from
|
|
7408
|
+
a target the height of the field instead of a ~13px UA glyph. */
|
|
7409
|
+
.compose-publish-date-input::-webkit-calendar-picker-indicator {
|
|
7410
|
+
display: none;
|
|
7411
|
+
}
|
|
7412
|
+
|
|
7413
|
+
.compose-publish-date-picker {
|
|
7414
|
+
display: inline-grid;
|
|
7415
|
+
flex-shrink: 0;
|
|
7416
|
+
place-items: center;
|
|
7417
|
+
width: 1.7rem;
|
|
7418
|
+
height: 1.7rem;
|
|
7419
|
+
margin-right: -0.35rem;
|
|
7420
|
+
border: none;
|
|
7421
|
+
border-radius: 7px;
|
|
7422
|
+
background: transparent;
|
|
7423
|
+
color: var(--site-text-secondary);
|
|
7424
|
+
cursor: pointer;
|
|
7425
|
+
transition:
|
|
7426
|
+
background-color 0.16s ease,
|
|
7427
|
+
color 0.16s ease;
|
|
7428
|
+
}
|
|
7429
|
+
|
|
7430
|
+
.compose-publish-date-picker:hover {
|
|
7431
|
+
background-color: var(--compose-control-bg-strong);
|
|
7432
|
+
color: var(--site-text-primary);
|
|
7433
|
+
}
|
|
7434
|
+
|
|
7435
|
+
.compose-publish-date-picker:focus-visible {
|
|
7436
|
+
outline: 2px solid
|
|
7437
|
+
color-mix(in srgb, var(--site-text-primary) 22%, transparent);
|
|
7438
|
+
outline-offset: 1px;
|
|
7439
|
+
}
|
|
7440
|
+
|
|
7441
|
+
.compose-publish-date-picker-icon {
|
|
7442
|
+
width: 0.95rem;
|
|
7443
|
+
height: 0.95rem;
|
|
7444
|
+
}
|
|
7445
|
+
|
|
7298
7446
|
.compose-publish-slug-input::placeholder,
|
|
7299
7447
|
.compose-publish-date-input::placeholder {
|
|
7300
|
-
color:
|
|
7301
|
-
|
|
7302
|
-
var(--site-text-secondary) 82%,
|
|
7303
|
-
var(--compose-paper-bg)
|
|
7304
|
-
);
|
|
7448
|
+
color: var(--site-text-secondary);
|
|
7449
|
+
opacity: 0.75;
|
|
7305
7450
|
}
|
|
7306
7451
|
|
|
7307
7452
|
.compose-publish-slug-input:focus,
|
|
@@ -7322,21 +7467,13 @@
|
|
|
7322
7467
|
color: var(--destructive);
|
|
7323
7468
|
}
|
|
7324
7469
|
|
|
7470
|
+
/* The URL a slug resolves to is a confirmation, not a control — a bordered
|
|
7471
|
+
box for it made a third framed thing in a panel with two fields. */
|
|
7325
7472
|
.compose-publish-slug-preview {
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
padding: 0.48rem 0.62rem;
|
|
7331
|
-
border-radius: 9px;
|
|
7332
|
-
border: 1px solid var(--compose-control-border);
|
|
7333
|
-
background-color: color-mix(
|
|
7334
|
-
in srgb,
|
|
7335
|
-
var(--compose-control-bg) 58%,
|
|
7336
|
-
var(--compose-paper-bg)
|
|
7337
|
-
);
|
|
7338
|
-
font-size: var(--type-ui-caption);
|
|
7339
|
-
line-height: 1.35;
|
|
7473
|
+
margin: 0;
|
|
7474
|
+
color: var(--site-text-secondary);
|
|
7475
|
+
font-size: var(--type-ui-micro);
|
|
7476
|
+
line-height: 1.4;
|
|
7340
7477
|
word-break: break-word;
|
|
7341
7478
|
font-family:
|
|
7342
7479
|
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
@@ -7344,19 +7481,11 @@
|
|
|
7344
7481
|
}
|
|
7345
7482
|
|
|
7346
7483
|
.compose-publish-slug-preview-origin {
|
|
7347
|
-
|
|
7348
|
-
in srgb,
|
|
7349
|
-
var(--site-text-secondary) 92%,
|
|
7350
|
-
var(--compose-paper-bg)
|
|
7351
|
-
);
|
|
7352
|
-
font-size: var(--type-ui-micro);
|
|
7353
|
-
font-weight: var(--fw-normal);
|
|
7484
|
+
opacity: 0.75;
|
|
7354
7485
|
}
|
|
7355
7486
|
|
|
7356
7487
|
.compose-publish-slug-preview-path {
|
|
7357
7488
|
color: var(--site-text-primary);
|
|
7358
|
-
font-size: var(--type-ui-caption);
|
|
7359
|
-
font-weight: var(--fw-medium);
|
|
7360
7489
|
overflow-wrap: anywhere;
|
|
7361
7490
|
}
|
|
7362
7491
|
|
|
@@ -7455,10 +7584,13 @@
|
|
|
7455
7584
|
transform: scale(1.02);
|
|
7456
7585
|
}
|
|
7457
7586
|
|
|
7587
|
+
/* Sized to be looked at, not to leave room for a pinned toolbar. Nothing
|
|
7588
|
+
clips the dock any more, so a tall preview just makes `.compose-scroll`
|
|
7589
|
+
longer. The dvh half keeps it from filling a short window on its own. */
|
|
7458
7590
|
.compose-attachment-img {
|
|
7459
7591
|
display: block;
|
|
7460
7592
|
border-radius: var(--media-radius, 0.5rem);
|
|
7461
|
-
max-height: min(
|
|
7593
|
+
max-height: min(420px, 46dvh);
|
|
7462
7594
|
object-fit: contain;
|
|
7463
7595
|
}
|
|
7464
7596
|
|
|
@@ -7515,7 +7647,7 @@
|
|
|
7515
7647
|
cropped from the top (object-fit: cover) instead of shrinking to a sliver. */
|
|
7516
7648
|
.compose-attachment:only-child .compose-attachment-img {
|
|
7517
7649
|
max-width: 100%;
|
|
7518
|
-
max-height: min(
|
|
7650
|
+
max-height: min(460px, 52dvh);
|
|
7519
7651
|
min-width: 48px;
|
|
7520
7652
|
object-fit: cover;
|
|
7521
7653
|
object-position: center top;
|
|
@@ -7526,9 +7658,9 @@
|
|
|
7526
7658
|
aspect-ratio: 4 / 3;
|
|
7527
7659
|
}
|
|
7528
7660
|
|
|
7529
|
-
/* Multiple images:
|
|
7661
|
+
/* Multiple images: one shared height so the row reads as a strip, cover */
|
|
7530
7662
|
.compose-attachment:not(:only-child) .compose-attachment-img {
|
|
7531
|
-
height:
|
|
7663
|
+
height: min(340px, 40dvh);
|
|
7532
7664
|
width: auto;
|
|
7533
7665
|
min-width: 120px;
|
|
7534
7666
|
object-fit: cover;
|
|
@@ -7867,18 +7999,21 @@
|
|
|
7867
7999
|
--compose-thread-padding-left: 16px;
|
|
7868
8000
|
--compose-thread-padding-right: 16px;
|
|
7869
8001
|
--compose-thread-gap: 12px;
|
|
7870
|
-
|
|
7871
|
-
|
|
8002
|
+
/* Fixed track every rail child sits in and centres its circle inside, so the
|
|
8003
|
+
line's x depends on the track alone and no dot size can pull it off centre.
|
|
8004
|
+
The constant this replaced was half the *feed's* 10px marker and stayed
|
|
8005
|
+
behind when compose dropped to 7px, leaving the line down the dot's edge. */
|
|
8006
|
+
--compose-thread-rail-width: 10px;
|
|
8007
|
+
--compose-thread-rail-left: calc(
|
|
8008
|
+
var(--compose-thread-padding-left) + var(--compose-thread-rail-width) / 2
|
|
8009
|
+
);
|
|
7872
8010
|
display: flex;
|
|
7873
8011
|
flex-direction: column;
|
|
7874
|
-
flex: 1;
|
|
7875
|
-
min-height: 0;
|
|
7876
|
-
overflow: hidden;
|
|
7877
8012
|
position: relative;
|
|
7878
8013
|
}
|
|
7879
8014
|
|
|
7880
8015
|
.compose-reply-compose-layout {
|
|
7881
|
-
--compose-title-input-size: var(--type-content-
|
|
8016
|
+
--compose-title-input-size: calc(var(--type-content-body) * 1.2);
|
|
7882
8017
|
--compose-title-input-leading: 1.35;
|
|
7883
8018
|
--compose-quote-input-size: calc(var(--type-content-body) * 1.06);
|
|
7884
8019
|
--compose-quote-input-leading: 1.42;
|
|
@@ -7901,8 +8036,9 @@
|
|
|
7901
8036
|
width: 1.55rem;
|
|
7902
8037
|
}
|
|
7903
8038
|
|
|
8039
|
+
/* Height comes from the shared four-line floor, which already reads this
|
|
8040
|
+
layout's own leading and type size — only the lead-in changes here. */
|
|
7904
8041
|
.compose-reply-compose-layout .compose-quote-text {
|
|
7905
|
-
min-height: 6.5rem;
|
|
7906
8042
|
padding-top: 0.35rem;
|
|
7907
8043
|
}
|
|
7908
8044
|
|
|
@@ -7917,28 +8053,68 @@
|
|
|
7917
8053
|
left: 1rem;
|
|
7918
8054
|
width: 1.6rem;
|
|
7919
8055
|
}
|
|
8056
|
+
}
|
|
7920
8057
|
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
8058
|
+
/* The rail is drawn one row at a time rather than as a single strip down the
|
|
8059
|
+
layout, so the two ends can be trimmed: it starts at the first dot and
|
|
8060
|
+
stops at the last post's. Under the last post it used to keep going —
|
|
8061
|
+
that's the tallest row in the layout, so it was a long line pointing at
|
|
8062
|
+
nothing. */
|
|
8063
|
+
/* Distance from a row's top edge to the centre of its dot: where the rail
|
|
8064
|
+
has to start or stop, and where the dot itself has to land. The dot derives
|
|
8065
|
+
its own margin from this pair (see `.compose-thread-dot`) rather than
|
|
8066
|
+
restating it, so resizing the marker cannot drift the line off the dot. */
|
|
8067
|
+
.compose-thread-layout > * {
|
|
8068
|
+
position: relative;
|
|
8069
|
+
--compose-thread-row-padding-top: 0px;
|
|
8070
|
+
--compose-thread-dot-center: calc(0.65rem + 5px);
|
|
8071
|
+
}
|
|
8072
|
+
|
|
8073
|
+
.compose-thread-layout > .compose-editor-row {
|
|
8074
|
+
--compose-thread-row-padding-top: 14px;
|
|
8075
|
+
--compose-thread-dot-center: calc(14px + 1rem + 7px);
|
|
8076
|
+
}
|
|
8077
|
+
|
|
8078
|
+
.compose-thread-compose-layout > .compose-editor-row {
|
|
8079
|
+
--compose-thread-row-padding-top: 4px;
|
|
8080
|
+
--compose-thread-dot-center: calc(4px + 1.05rem + 7px);
|
|
7925
8081
|
}
|
|
7926
8082
|
|
|
7927
|
-
|
|
7928
|
-
.compose-thread-layout::before {
|
|
8083
|
+
.compose-thread-layout > *::before {
|
|
7929
8084
|
content: "";
|
|
7930
8085
|
position: absolute;
|
|
7931
8086
|
left: var(--compose-thread-rail-left);
|
|
7932
8087
|
top: 0;
|
|
7933
8088
|
bottom: 0;
|
|
7934
|
-
width:
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
8089
|
+
width: var(--site-thread-rail-line-width);
|
|
8090
|
+
margin-left: calc(var(--site-thread-rail-line-width) / -2);
|
|
8091
|
+
border-radius: 1px;
|
|
8092
|
+
/* Matched to the weight of the reading rail's gradient rather than its
|
|
8093
|
+
implementation. That one runs 85% → 55% down its length, so ~70% flat
|
|
8094
|
+
reads at the same strength here. It can't literally share the gradient:
|
|
8095
|
+
this rail is drawn per row so both ends can be trimmed, and a per-row
|
|
8096
|
+
gradient would fade in once per post instead of once per thread. */
|
|
8097
|
+
background-color: color-mix(
|
|
8098
|
+
in srgb,
|
|
8099
|
+
var(--site-threadline) 70%,
|
|
8100
|
+
transparent
|
|
7940
8101
|
);
|
|
7941
|
-
|
|
8102
|
+
}
|
|
8103
|
+
|
|
8104
|
+
.compose-thread-layout > :first-child::before {
|
|
8105
|
+
top: var(--compose-thread-dot-center);
|
|
8106
|
+
}
|
|
8107
|
+
|
|
8108
|
+
/* The last post ends the rail. `.compose-thread-add-row` sits below it and is
|
|
8109
|
+
a placeholder, not a post, so its dashed dot is left unconnected. */
|
|
8110
|
+
.compose-thread-layout
|
|
8111
|
+
> .compose-editor-row:not(:has(~ .compose-editor-row))::before {
|
|
8112
|
+
bottom: auto;
|
|
8113
|
+
height: var(--compose-thread-dot-center);
|
|
8114
|
+
}
|
|
8115
|
+
|
|
8116
|
+
.compose-thread-layout > .compose-thread-add-row::before {
|
|
8117
|
+
display: none;
|
|
7942
8118
|
}
|
|
7943
8119
|
|
|
7944
8120
|
/* Row containing dot + reply context */
|
|
@@ -7952,152 +8128,72 @@
|
|
|
7952
8128
|
|
|
7953
8129
|
/* Row containing dot + editor */
|
|
7954
8130
|
.compose-editor-row {
|
|
8131
|
+
/* The rail already indents this row from outside the editor, so nothing
|
|
8132
|
+
inside it adds a gutter of its own. */
|
|
8133
|
+
--compose-gutter: 0px;
|
|
8134
|
+
|
|
7955
8135
|
display: flex;
|
|
7956
8136
|
align-items: flex-start;
|
|
7957
8137
|
gap: var(--compose-thread-gap);
|
|
7958
8138
|
padding-right: var(--compose-thread-padding-right);
|
|
7959
8139
|
padding-left: var(--compose-thread-padding-left);
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
overflow: hidden;
|
|
8140
|
+
padding-top: 4px;
|
|
8141
|
+
padding-bottom: 4px;
|
|
7963
8142
|
}
|
|
7964
8143
|
|
|
8144
|
+
/* `flex: 1` here is horizontal — it claims the width left by the rail dot.
|
|
8145
|
+
The row's height comes from the editor's own content; nothing in this
|
|
8146
|
+
chain clips or scrolls, that is `.compose-scroll`'s job. */
|
|
7965
8147
|
.compose-editor-row > jant-compose-editor {
|
|
7966
8148
|
flex: 1;
|
|
7967
|
-
min-
|
|
8149
|
+
min-width: 0;
|
|
7968
8150
|
display: flex;
|
|
7969
8151
|
flex-direction: column;
|
|
7970
|
-
align-self: stretch;
|
|
7971
|
-
overflow: hidden;
|
|
7972
8152
|
position: relative;
|
|
7973
8153
|
}
|
|
7974
8154
|
|
|
7975
|
-
/* Reduce editor body left padding — the thread rail already provides indent */
|
|
7976
|
-
.compose-editor-row .compose-body {
|
|
7977
|
-
padding-left: 0;
|
|
7978
|
-
}
|
|
7979
|
-
|
|
7980
8155
|
.compose-editor-row .compose-attachments-dock {
|
|
7981
|
-
|
|
7982
|
-
min-height: 0;
|
|
7983
|
-
max-height: min(240px, 34dvh);
|
|
7984
|
-
overflow-y: auto;
|
|
7985
|
-
padding-inline: 0;
|
|
8156
|
+
padding-inline-end: 0;
|
|
7986
8157
|
background: transparent;
|
|
7987
8158
|
}
|
|
7988
8159
|
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
padding-block: 4px 2px;
|
|
7995
|
-
}
|
|
7996
|
-
|
|
7997
|
-
.compose-reply-compose-layout .compose-editor-row .compose-attachments {
|
|
7998
|
-
gap: 6px;
|
|
7999
|
-
padding-block: 0;
|
|
8000
|
-
}
|
|
8001
|
-
|
|
8002
|
-
.compose-reply-compose-layout .compose-editor-row .compose-attachment {
|
|
8003
|
-
gap: 2px;
|
|
8004
|
-
max-width: none;
|
|
8005
|
-
}
|
|
8006
|
-
|
|
8007
|
-
.compose-reply-compose-layout
|
|
8008
|
-
.compose-editor-row
|
|
8009
|
-
.compose-attachment:has(.compose-attachment-preview-fallback) {
|
|
8010
|
-
width: var(--compose-reply-attachment-width);
|
|
8011
|
-
}
|
|
8012
|
-
|
|
8013
|
-
.compose-reply-compose-layout
|
|
8014
|
-
.compose-editor-row
|
|
8015
|
-
.compose-attachment:only-child
|
|
8016
|
-
.compose-attachment-img,
|
|
8017
|
-
.compose-reply-compose-layout
|
|
8018
|
-
.compose-editor-row
|
|
8019
|
-
.compose-attachment:not(:only-child)
|
|
8020
|
-
.compose-attachment-img {
|
|
8021
|
-
width: var(--compose-reply-attachment-width);
|
|
8022
|
-
height: var(--compose-reply-attachment-height);
|
|
8023
|
-
min-width: 0;
|
|
8024
|
-
max-width: var(--compose-reply-attachment-width);
|
|
8025
|
-
max-height: var(--compose-reply-attachment-height);
|
|
8026
|
-
object-fit: cover;
|
|
8027
|
-
object-position: center;
|
|
8028
|
-
}
|
|
8029
|
-
|
|
8030
|
-
.compose-reply-compose-layout
|
|
8031
|
-
.compose-editor-row
|
|
8032
|
-
.compose-attachment-preview-fallback,
|
|
8033
|
-
.compose-reply-compose-layout
|
|
8034
|
-
.compose-editor-row
|
|
8035
|
-
.compose-attachment-processing {
|
|
8036
|
-
width: var(--compose-reply-attachment-width);
|
|
8037
|
-
height: var(--compose-reply-attachment-height);
|
|
8038
|
-
aspect-ratio: auto;
|
|
8039
|
-
}
|
|
8040
|
-
|
|
8041
|
-
.compose-reply-compose-layout
|
|
8042
|
-
.compose-editor-row
|
|
8043
|
-
.compose-attachment-preview-fallback
|
|
8044
|
-
svg {
|
|
8045
|
-
width: 28px;
|
|
8046
|
-
height: 28px;
|
|
8047
|
-
}
|
|
8048
|
-
|
|
8049
|
-
.compose-reply-compose-layout
|
|
8050
|
-
.compose-editor-row
|
|
8051
|
-
.compose-attachment-file-card,
|
|
8052
|
-
.compose-reply-compose-layout
|
|
8053
|
-
.compose-editor-row
|
|
8054
|
-
.compose-attachment:not(:only-child)
|
|
8055
|
-
.compose-attachment-file-card {
|
|
8056
|
-
width: 112px;
|
|
8057
|
-
height: var(--compose-reply-attachment-height);
|
|
8058
|
-
gap: 4px;
|
|
8059
|
-
padding: 8px 10px;
|
|
8060
|
-
}
|
|
8061
|
-
|
|
8062
|
-
.compose-reply-compose-layout .compose-editor-row .compose-attachment-alt {
|
|
8063
|
-
padding: 1px 3px;
|
|
8064
|
-
font-size: var(--type-ui-micro);
|
|
8065
|
-
line-height: 1.2;
|
|
8066
|
-
}
|
|
8067
|
-
|
|
8068
|
-
.compose-reply-compose-layout .compose-editor-row .compose-attachment-remove {
|
|
8069
|
-
top: 4px;
|
|
8070
|
-
right: 4px;
|
|
8071
|
-
width: 20px;
|
|
8072
|
-
height: 20px;
|
|
8073
|
-
}
|
|
8074
|
-
|
|
8075
|
-
/* Dot marker for thread positions */
|
|
8160
|
+
/* Dot marker for thread positions. Sits above the rail so it reads as a joint
|
|
8161
|
+
in the line, and takes its offset from the row's declared dot centre so the
|
|
8162
|
+
two ends of the rail always meet it. The element is the full rail track and
|
|
8163
|
+
only centres the circle inside it, which is what keeps the line through the
|
|
8164
|
+
dot's middle no matter how the marker is resized. */
|
|
8076
8165
|
.compose-thread-dot {
|
|
8077
|
-
|
|
8166
|
+
position: relative;
|
|
8167
|
+
z-index: 1;
|
|
8168
|
+
display: flex;
|
|
8169
|
+
justify-content: center;
|
|
8170
|
+
width: var(--compose-thread-rail-width);
|
|
8078
8171
|
height: var(--site-thread-marker-size);
|
|
8079
|
-
margin-top:
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
background-color: var(--site-threadline);
|
|
8172
|
+
margin-top: calc(
|
|
8173
|
+
var(--compose-thread-dot-center) - var(--compose-thread-row-padding-top) -
|
|
8174
|
+
var(--site-thread-marker-size) / 2
|
|
8175
|
+
);
|
|
8084
8176
|
flex-shrink: 0;
|
|
8085
8177
|
align-self: flex-start;
|
|
8086
|
-
box-shadow: 0 0 0 var(--site-thread-marker-ring-width)
|
|
8087
|
-
var(--site-thread-dot-ring);
|
|
8088
|
-
z-index: 1;
|
|
8089
8178
|
}
|
|
8090
8179
|
|
|
8091
|
-
.compose-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8180
|
+
.compose-thread-dot::before {
|
|
8181
|
+
content: "";
|
|
8182
|
+
width: var(--site-thread-marker-size);
|
|
8183
|
+
height: var(--site-thread-marker-size);
|
|
8184
|
+
border-radius: 50%;
|
|
8185
|
+
background-color: var(--site-threadline);
|
|
8186
|
+
box-shadow: 0 0 0 var(--site-thread-marker-gap)
|
|
8187
|
+
var(--site-thread-marker-surface);
|
|
8188
|
+
transition: background-color 0.15s ease;
|
|
8096
8189
|
}
|
|
8097
8190
|
|
|
8098
|
-
/*
|
|
8099
|
-
|
|
8100
|
-
|
|
8191
|
+
/* Every post in a thread is equally new, so accenting all of them says nothing
|
|
8192
|
+
— it just makes the rail loud. The accent marks where you are on the chain
|
|
8193
|
+
instead: the one post holding the cursor. The reply context above stays on
|
|
8194
|
+
the line's own colour. */
|
|
8195
|
+
.compose-editor-row.is-current .compose-thread-dot::before {
|
|
8196
|
+
background-color: var(--site-thread-marker-current);
|
|
8101
8197
|
}
|
|
8102
8198
|
|
|
8103
8199
|
.compose-reply-context {
|
|
@@ -8107,12 +8203,15 @@
|
|
|
8107
8203
|
overflow: hidden;
|
|
8108
8204
|
position: relative;
|
|
8109
8205
|
padding: 0.08rem 0 0.18rem;
|
|
8110
|
-
transition: max-height 0.3s ease;
|
|
8111
8206
|
}
|
|
8112
8207
|
|
|
8208
|
+
/* "Show more" means show it: expanding hands the post its full height rather
|
|
8209
|
+
than a taller box with a second scrollbar in it. That inner scrollbar is
|
|
8210
|
+
what made the parent's pictures thumbnails — there was never room for one
|
|
8211
|
+
at full size. Length is the toggle's job now, not the preview's. */
|
|
8113
8212
|
.compose-reply-context.expanded {
|
|
8114
|
-
max-height:
|
|
8115
|
-
overflow
|
|
8213
|
+
max-height: none;
|
|
8214
|
+
overflow: visible;
|
|
8116
8215
|
}
|
|
8117
8216
|
|
|
8118
8217
|
.compose-reply-context-body {
|
|
@@ -8167,21 +8266,26 @@
|
|
|
8167
8266
|
background-color: transparent;
|
|
8168
8267
|
}
|
|
8169
8268
|
|
|
8269
|
+
/* The parent reads at the same scale as the reply being written — the same
|
|
8270
|
+
ceiling as `.compose-attachment-img`, the same radius token — so the two
|
|
8271
|
+
halves of the exchange look like the same material. This is the only size
|
|
8272
|
+
rule for pictures in the context: it covers both the ones inside the post's
|
|
8273
|
+
own HTML and the media strip below it, which sits in here too. */
|
|
8170
8274
|
.compose-reply-context-body img,
|
|
8171
8275
|
.compose-reply-context-body video {
|
|
8172
8276
|
width: auto !important;
|
|
8173
8277
|
height: auto !important;
|
|
8174
|
-
max-height:
|
|
8175
|
-
border-radius:
|
|
8278
|
+
max-height: min(420px, 46dvh);
|
|
8279
|
+
border-radius: var(--media-radius, 0.5rem);
|
|
8176
8280
|
object-fit: contain;
|
|
8177
8281
|
background-image: none !important;
|
|
8178
8282
|
}
|
|
8179
8283
|
|
|
8180
8284
|
.compose-reply-context-media {
|
|
8181
8285
|
display: flex;
|
|
8182
|
-
gap:
|
|
8286
|
+
gap: 8px;
|
|
8183
8287
|
flex-wrap: wrap;
|
|
8184
|
-
margin-top:
|
|
8288
|
+
margin-top: 8px;
|
|
8185
8289
|
}
|
|
8186
8290
|
|
|
8187
8291
|
.compose-reply-context-media-link {
|
|
@@ -8189,12 +8293,6 @@
|
|
|
8189
8293
|
cursor: pointer;
|
|
8190
8294
|
}
|
|
8191
8295
|
|
|
8192
|
-
.compose-reply-context-media-img {
|
|
8193
|
-
max-height: 80px;
|
|
8194
|
-
border-radius: 6px;
|
|
8195
|
-
object-fit: contain;
|
|
8196
|
-
}
|
|
8197
|
-
|
|
8198
8296
|
.compose-reply-fade {
|
|
8199
8297
|
position: absolute;
|
|
8200
8298
|
bottom: 0;
|
|
@@ -8212,7 +8310,8 @@
|
|
|
8212
8310
|
padding-top: 4px;
|
|
8213
8311
|
padding-right: var(--compose-thread-padding-right);
|
|
8214
8312
|
padding-left: calc(
|
|
8215
|
-
var(--compose-thread-padding-left) + var(--compose-thread-gap) +
|
|
8313
|
+
var(--compose-thread-padding-left) + var(--compose-thread-gap) +
|
|
8314
|
+
var(--compose-thread-rail-width)
|
|
8216
8315
|
);
|
|
8217
8316
|
font-size: var(--type-thread-context-meta);
|
|
8218
8317
|
color: var(--site-text-secondary);
|
|
@@ -8312,14 +8411,26 @@
|
|
|
8312
8411
|
padding: 0.78rem 0.9rem;
|
|
8313
8412
|
}
|
|
8314
8413
|
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8414
|
+
/* Touch keeps the roomier set: the reference's 36px box is tuned for a
|
|
8415
|
+
cursor, and a thumb needs the millimetres back. Width still comes from
|
|
8416
|
+
the word — only the box around it grows. */
|
|
8417
|
+
.compose-publish-main {
|
|
8418
|
+
min-height: 2.8em;
|
|
8419
|
+
padding-inline: 22px;
|
|
8318
8420
|
}
|
|
8319
8421
|
|
|
8320
|
-
.compose-
|
|
8321
|
-
width:
|
|
8322
|
-
height:
|
|
8422
|
+
.compose-options-trigger {
|
|
8423
|
+
width: 2.5rem;
|
|
8424
|
+
height: 2.5rem;
|
|
8425
|
+
}
|
|
8426
|
+
|
|
8427
|
+
.compose-collection-select {
|
|
8428
|
+
--compose-collection-pad-icon: 0.68rem;
|
|
8429
|
+
--compose-collection-pad-label: 0.85rem;
|
|
8430
|
+
}
|
|
8431
|
+
|
|
8432
|
+
.compose-collection-trigger {
|
|
8433
|
+
min-height: 2.5rem;
|
|
8323
8434
|
}
|
|
8324
8435
|
|
|
8325
8436
|
.compose-collection-select [data-popover] {
|
|
@@ -8327,13 +8438,24 @@
|
|
|
8327
8438
|
max-width: min(20rem, calc(100vw - 1rem));
|
|
8328
8439
|
}
|
|
8329
8440
|
|
|
8441
|
+
.compose-collection-search-icon {
|
|
8442
|
+
width: 1.15rem;
|
|
8443
|
+
height: 1.15rem;
|
|
8444
|
+
}
|
|
8445
|
+
|
|
8446
|
+
.compose-collection-options {
|
|
8447
|
+
max-height: 15rem;
|
|
8448
|
+
}
|
|
8449
|
+
|
|
8330
8450
|
.compose-collection-popover {
|
|
8331
8451
|
padding: 0.62rem 0.68rem 0.58rem;
|
|
8332
8452
|
}
|
|
8333
8453
|
|
|
8334
8454
|
.compose-collection-search-shell {
|
|
8455
|
+
gap: 0.52rem;
|
|
8335
8456
|
min-height: 3rem;
|
|
8336
8457
|
padding: 0 1rem;
|
|
8458
|
+
border-radius: 0.92rem;
|
|
8337
8459
|
}
|
|
8338
8460
|
|
|
8339
8461
|
.compose-collection-options {
|
|
@@ -8352,12 +8474,20 @@
|
|
|
8352
8474
|
height: 1.5rem;
|
|
8353
8475
|
}
|
|
8354
8476
|
|
|
8355
|
-
.compose-
|
|
8356
|
-
|
|
8477
|
+
.compose-collection-add-action {
|
|
8478
|
+
gap: 0.82rem;
|
|
8479
|
+
min-height: 3rem;
|
|
8480
|
+
padding: 0 0.92rem;
|
|
8481
|
+
border-radius: 1rem;
|
|
8482
|
+
}
|
|
8483
|
+
|
|
8484
|
+
.compose-collection-footer {
|
|
8485
|
+
margin-top: 0.35rem;
|
|
8486
|
+
padding: 0.35rem 0.22rem 0.12rem;
|
|
8357
8487
|
}
|
|
8358
8488
|
|
|
8359
|
-
.compose-thread-layout
|
|
8360
|
-
top: 0.75rem;
|
|
8489
|
+
.compose-thread-layout {
|
|
8490
|
+
padding-top: 0.75rem;
|
|
8361
8491
|
}
|
|
8362
8492
|
|
|
8363
8493
|
.compose-reply-context {
|
|
@@ -8380,35 +8510,14 @@
|
|
|
8380
8510
|
}
|
|
8381
8511
|
}
|
|
8382
8512
|
|
|
8383
|
-
/* --- Thread compose layout (multi-post
|
|
8384
|
-
|
|
8385
|
-
/* Scrollable variant for composing a new thread (vs reply thread which is
|
|
8386
|
-
fixed-height). Each editor item grows naturally; the whole layout scrolls. */
|
|
8387
|
-
.compose-thread-compose-layout {
|
|
8388
|
-
overflow-y: auto;
|
|
8389
|
-
overflow-x: hidden;
|
|
8390
|
-
}
|
|
8391
|
-
|
|
8392
|
-
.compose-thread-compose-layout .compose-editor-row {
|
|
8393
|
-
flex: none;
|
|
8394
|
-
overflow: visible;
|
|
8395
|
-
align-items: flex-start;
|
|
8396
|
-
padding-top: 4px;
|
|
8397
|
-
padding-bottom: 4px;
|
|
8398
|
-
}
|
|
8399
|
-
|
|
8400
|
-
.compose-thread-compose-layout .compose-editor-row > jant-compose-editor {
|
|
8401
|
-
overflow: visible;
|
|
8402
|
-
min-width: 0;
|
|
8403
|
-
}
|
|
8513
|
+
/* --- Thread compose layout (multi-post) --------------------------------- */
|
|
8404
8514
|
|
|
8405
|
-
|
|
8406
|
-
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
}
|
|
8515
|
+
/* `.compose-thread-compose-layout` carries no layout rules of its own: the
|
|
8516
|
+
grow-naturally-and-scroll-as-one behaviour it used to opt into is now what
|
|
8517
|
+
every mode does, under `.compose-scroll`. It survives as a hook for the
|
|
8518
|
+
rail geometry above.
|
|
8410
8519
|
|
|
8411
|
-
|
|
8520
|
+
Focused thread post gets a subtle left accent. Use an inset box-shadow, not
|
|
8412
8521
|
a border: a border adds 2px of layout width only while focused, so switching
|
|
8413
8522
|
focus between thread posts shifted each one sideways ("jitter"). box-shadow
|
|
8414
8523
|
paints in the same spot without affecting layout. */
|
|
@@ -8416,7 +8525,8 @@
|
|
|
8416
8525
|
box-shadow: inset 2px 0 0 transparent;
|
|
8417
8526
|
}
|
|
8418
8527
|
|
|
8419
|
-
/* "Add to thread"
|
|
8528
|
+
/* "Add to thread" on the rail — thread compose, and a reply before it has
|
|
8529
|
+
grown a second post. */
|
|
8420
8530
|
.compose-thread-add-row {
|
|
8421
8531
|
display: flex;
|
|
8422
8532
|
align-items: center;
|
|
@@ -8427,92 +8537,63 @@
|
|
|
8427
8537
|
padding-bottom: 10px;
|
|
8428
8538
|
}
|
|
8429
8539
|
|
|
8540
|
+
/* Fills the rail track exactly, so it lands on the same centre line as the
|
|
8541
|
+
post dots without any offset of its own. */
|
|
8430
8542
|
.compose-thread-add-dot {
|
|
8431
|
-
width:
|
|
8432
|
-
height:
|
|
8543
|
+
width: var(--compose-thread-rail-width);
|
|
8544
|
+
height: var(--compose-thread-rail-width);
|
|
8433
8545
|
border-radius: 50%;
|
|
8434
8546
|
border: 1.5px dashed
|
|
8435
8547
|
color-mix(in srgb, var(--site-threadline) 60%, transparent);
|
|
8436
8548
|
flex-shrink: 0;
|
|
8437
8549
|
margin-top: 1px;
|
|
8438
|
-
margin-left: calc(
|
|
8439
|
-
(var(--site-thread-marker-hero-size) - var(--site-thread-marker-size)) / 2
|
|
8440
|
-
);
|
|
8441
|
-
}
|
|
8442
|
-
|
|
8443
|
-
.compose-thread-add-btn {
|
|
8444
|
-
display: inline-flex;
|
|
8445
|
-
align-items: center;
|
|
8446
|
-
gap: 6px;
|
|
8447
|
-
font-size: var(--type-ui-caption);
|
|
8448
|
-
font-family: var(--font-ui);
|
|
8449
|
-
color: var(--site-text-secondary);
|
|
8450
|
-
padding: 4px 12px 4px 9px;
|
|
8451
|
-
border-radius: 20px;
|
|
8452
|
-
border: 1.5px dashed
|
|
8453
|
-
color-mix(in srgb, var(--site-threadline) 70%, transparent);
|
|
8454
|
-
background: transparent;
|
|
8455
|
-
cursor: pointer;
|
|
8456
|
-
transition:
|
|
8457
|
-
color 0.15s ease,
|
|
8458
|
-
background-color 0.15s ease,
|
|
8459
|
-
border-color 0.15s ease;
|
|
8460
|
-
}
|
|
8461
|
-
|
|
8462
|
-
.compose-thread-compose-layout .compose-thread-add-btn {
|
|
8463
|
-
margin-inline-start: -8px;
|
|
8464
|
-
}
|
|
8465
|
-
|
|
8466
|
-
.compose-thread-add-btn:hover:not(:disabled) {
|
|
8467
|
-
color: var(--site-text-primary);
|
|
8468
|
-
background-color: var(--compose-control-bg);
|
|
8469
|
-
border-color: var(--site-threadline);
|
|
8470
|
-
border-style: solid;
|
|
8471
8550
|
}
|
|
8472
8551
|
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
opacity: 0.4;
|
|
8476
|
-
cursor: default;
|
|
8477
|
-
}
|
|
8478
|
-
|
|
8479
|
-
/* "Add to thread" trigger below single-post editor */
|
|
8552
|
+
/* "Add to thread" trigger with no rail under it — a single post, which has
|
|
8553
|
+
no next slot to point at yet. */
|
|
8480
8554
|
.compose-add-thread-trigger {
|
|
8481
|
-
padding: 1px 10px 4px;
|
|
8555
|
+
padding: 1px 10px 4px var(--compose-gutter);
|
|
8482
8556
|
display: flex;
|
|
8483
8557
|
align-items: center;
|
|
8484
8558
|
}
|
|
8485
8559
|
|
|
8486
8560
|
@media (min-width: 700px) {
|
|
8487
8561
|
.compose-add-thread-trigger {
|
|
8488
|
-
padding-inline: 16px;
|
|
8562
|
+
padding-inline: var(--compose-gutter) 16px;
|
|
8489
8563
|
}
|
|
8490
8564
|
}
|
|
8491
8565
|
|
|
8492
|
-
|
|
8566
|
+
/* No glyph of its own: on the rail the dashed dot already says "next slot",
|
|
8567
|
+
and on a single post the row's position says it. The label is all that is
|
|
8568
|
+
left, so it sits at the row's own quiet weight — and hangs back by its own
|
|
8569
|
+
side padding so the label, not the hover chip, starts on the text column. */
|
|
8570
|
+
.compose-thread-add-btn {
|
|
8571
|
+
--compose-add-hang: 8px;
|
|
8572
|
+
|
|
8493
8573
|
display: inline-flex;
|
|
8494
8574
|
align-items: center;
|
|
8495
|
-
gap: 6px;
|
|
8496
8575
|
font-size: var(--type-ui-caption);
|
|
8497
8576
|
font-family: var(--font-ui);
|
|
8498
8577
|
color: var(--site-text-secondary);
|
|
8499
|
-
padding:
|
|
8500
|
-
|
|
8501
|
-
border:
|
|
8502
|
-
|
|
8578
|
+
padding: 5px var(--compose-add-hang);
|
|
8579
|
+
margin-inline-start: calc(-1 * var(--compose-add-hang));
|
|
8580
|
+
border-radius: 9px;
|
|
8581
|
+
border: none;
|
|
8503
8582
|
background: transparent;
|
|
8504
8583
|
cursor: pointer;
|
|
8505
8584
|
transition:
|
|
8506
8585
|
color 0.15s ease,
|
|
8507
|
-
background-color 0.15s ease
|
|
8508
|
-
border-color 0.15s ease;
|
|
8586
|
+
background-color 0.15s ease;
|
|
8509
8587
|
}
|
|
8510
8588
|
|
|
8511
|
-
.compose-add-
|
|
8589
|
+
.compose-thread-add-btn:hover:not(:disabled) {
|
|
8512
8590
|
color: var(--site-text-primary);
|
|
8513
8591
|
background-color: var(--compose-control-bg);
|
|
8514
|
-
|
|
8515
|
-
|
|
8592
|
+
}
|
|
8593
|
+
|
|
8594
|
+
.compose-thread-add-btn:disabled {
|
|
8595
|
+
opacity: 0.4;
|
|
8596
|
+
cursor: default;
|
|
8516
8597
|
}
|
|
8517
8598
|
|
|
8518
8599
|
/* --- Thread post header: format tag switcher + × on right --------------- */
|
|
@@ -8520,8 +8601,45 @@
|
|
|
8520
8601
|
.compose-thread-post-header {
|
|
8521
8602
|
display: flex;
|
|
8522
8603
|
align-items: center;
|
|
8523
|
-
|
|
8524
|
-
|
|
8604
|
+
/* The format selector will not shrink, so on a narrow screen let the
|
|
8605
|
+
date/permalink pill drop to its own line rather than clip. */
|
|
8606
|
+
flex-wrap: wrap;
|
|
8607
|
+
row-gap: 4px;
|
|
8608
|
+
gap: 8px;
|
|
8609
|
+
/* Left is the shared text column: the switcher hangs back out of it by its
|
|
8610
|
+
own item padding, so it is the label that starts on the edge. Right keeps
|
|
8611
|
+
the tools row's 16px so × and the date pill stay over the tool buttons
|
|
8612
|
+
bracketing the editor from below. */
|
|
8613
|
+
padding: 10px 16px 2px var(--compose-gutter);
|
|
8614
|
+
}
|
|
8615
|
+
|
|
8616
|
+
.compose-editor-row .compose-thread-post-header {
|
|
8617
|
+
padding-block: 6px 4px;
|
|
8618
|
+
}
|
|
8619
|
+
|
|
8620
|
+
/* "1/3" position marker. Identity comes before attribute, so it leads the
|
|
8621
|
+
row; it pairs visually with the thread rail dot to its left. */
|
|
8622
|
+
.compose-post-position {
|
|
8623
|
+
flex-shrink: 0;
|
|
8624
|
+
padding: 1px 7px;
|
|
8625
|
+
border-radius: 999px;
|
|
8626
|
+
background: var(--compose-control-bg);
|
|
8627
|
+
color: var(--site-text-secondary);
|
|
8628
|
+
font-size: 0.68rem;
|
|
8629
|
+
font-variant-numeric: tabular-nums;
|
|
8630
|
+
letter-spacing: 0.01em;
|
|
8631
|
+
}
|
|
8632
|
+
|
|
8633
|
+
/* "Editing" — the one thing a compose title ever said that you could not read
|
|
8634
|
+
off the composer itself: this post is already live. New / reply / thread
|
|
8635
|
+
all announce themselves through the parent post, the 2/3 markers and the
|
|
8636
|
+
submit label, so only this case earns a word.
|
|
8637
|
+
It takes the position marker's weight rather than an accent tint: it sits
|
|
8638
|
+
in that marker's slot, and everything else in this row that is not the
|
|
8639
|
+
format selector is deliberately quiet. Only the numerals are reset. */
|
|
8640
|
+
.compose-post-badge {
|
|
8641
|
+
font-variant-numeric: normal;
|
|
8642
|
+
letter-spacing: 0.02em;
|
|
8525
8643
|
}
|
|
8526
8644
|
|
|
8527
8645
|
/* Reply / edit-reply compose (a .compose-editor-row directly under
|
|
@@ -8536,7 +8654,8 @@
|
|
|
8536
8654
|
padding-top: 14px;
|
|
8537
8655
|
}
|
|
8538
8656
|
|
|
8539
|
-
|
|
8657
|
+
/* The header now sits above every post, so it owns the gap to the body. */
|
|
8658
|
+
.compose-editor-row .compose-thread-post-header + .compose-body {
|
|
8540
8659
|
padding-top: 8px;
|
|
8541
8660
|
}
|
|
8542
8661
|
|
|
@@ -8544,55 +8663,12 @@
|
|
|
8544
8663
|
padding-top: 12px;
|
|
8545
8664
|
}
|
|
8546
8665
|
|
|
8547
|
-
/* Thread format selector: pill-tag style (lighter than the main segmented) */
|
|
8548
|
-
.compose-thread-segmented {
|
|
8549
|
-
background: transparent;
|
|
8550
|
-
box-shadow: none;
|
|
8551
|
-
padding: 0;
|
|
8552
|
-
gap: 4px;
|
|
8553
|
-
}
|
|
8554
|
-
|
|
8555
|
-
.compose-thread-segmented .compose-format-pill {
|
|
8556
|
-
display: none;
|
|
8557
|
-
}
|
|
8558
|
-
|
|
8559
|
-
.compose-thread-segmented .compose-segmented-item {
|
|
8560
|
-
flex: none;
|
|
8561
|
-
font-size: var(--type-ui-caption);
|
|
8562
|
-
padding: 3px 10px;
|
|
8563
|
-
border-radius: 20px;
|
|
8564
|
-
border: 1.5px solid
|
|
8565
|
-
color-mix(in srgb, var(--site-text-secondary) 22%, transparent);
|
|
8566
|
-
letter-spacing: 0.01em;
|
|
8567
|
-
transition:
|
|
8568
|
-
border-color 0.15s ease,
|
|
8569
|
-
color 0.15s ease,
|
|
8570
|
-
background-color 0.15s ease;
|
|
8571
|
-
}
|
|
8572
|
-
|
|
8573
|
-
.compose-thread-segmented
|
|
8574
|
-
.compose-segmented-item:hover:not(.compose-segmented-item-active) {
|
|
8575
|
-
border-color: color-mix(
|
|
8576
|
-
in srgb,
|
|
8577
|
-
var(--site-text-secondary) 50%,
|
|
8578
|
-
transparent
|
|
8579
|
-
);
|
|
8580
|
-
color: var(--site-text-primary);
|
|
8581
|
-
background: transparent;
|
|
8582
|
-
}
|
|
8583
|
-
|
|
8584
|
-
.compose-thread-segmented .compose-segmented-item-active {
|
|
8585
|
-
color: var(--site-text-primary);
|
|
8586
|
-
font-weight: var(--fw-medium);
|
|
8587
|
-
border-color: color-mix(in srgb, var(--site-text-primary) 55%, transparent);
|
|
8588
|
-
background: color-mix(in srgb, var(--site-text-primary) 7%, transparent);
|
|
8589
|
-
}
|
|
8590
|
-
|
|
8591
8666
|
/* Remove button (×) — hidden by default, revealed on thread post hover/focus */
|
|
8592
8667
|
.compose-thread-post-remove {
|
|
8593
8668
|
display: inline-flex;
|
|
8594
8669
|
align-items: center;
|
|
8595
8670
|
justify-content: center;
|
|
8671
|
+
margin-left: auto;
|
|
8596
8672
|
width: 28px;
|
|
8597
8673
|
height: 28px;
|
|
8598
8674
|
border-radius: 8px;
|
|
@@ -8622,11 +8698,6 @@
|
|
|
8622
8698
|
color: var(--site-text-primary);
|
|
8623
8699
|
}
|
|
8624
8700
|
|
|
8625
|
-
/* In thread compose, toolbar padding matches thread indent */
|
|
8626
|
-
.compose-thread-compose-layout .compose-tools-row {
|
|
8627
|
-
padding-inline-start: 0;
|
|
8628
|
-
}
|
|
8629
|
-
|
|
8630
8701
|
/* --- Alt text overlay panel (Threads-style, covers entire dialog) ------- */
|
|
8631
8702
|
|
|
8632
8703
|
.compose-alt-panel {
|
|
@@ -8798,11 +8869,18 @@
|
|
|
8798
8869
|
}
|
|
8799
8870
|
|
|
8800
8871
|
.compose-draft-meta {
|
|
8872
|
+
display: flex;
|
|
8873
|
+
align-items: center;
|
|
8874
|
+
gap: 0.35rem;
|
|
8801
8875
|
font-size: var(--type-ui-caption);
|
|
8802
8876
|
color: var(--site-text-secondary);
|
|
8803
8877
|
margin-top: 4px;
|
|
8804
8878
|
}
|
|
8805
8879
|
|
|
8880
|
+
.compose-draft-format {
|
|
8881
|
+
font-weight: 500;
|
|
8882
|
+
}
|
|
8883
|
+
|
|
8806
8884
|
.compose-draft-more {
|
|
8807
8885
|
width: 40px;
|
|
8808
8886
|
height: 40px;
|
|
@@ -9293,9 +9371,14 @@
|
|
|
9293
9371
|
min-height: 0;
|
|
9294
9372
|
}
|
|
9295
9373
|
|
|
9374
|
+
/* The floor is two lines, written as two lines. It is a target to click into
|
|
9375
|
+
on an empty post, not a reserved shape, so it should follow the type
|
|
9376
|
+
instead of a pixel count that goes stale when the leading moves. Every
|
|
9377
|
+
compose text surface shares it: a note's body and the "thoughts" under a
|
|
9378
|
+
link or a quote all open the same way and grow from there. */
|
|
9296
9379
|
.compose-tiptap-body .tiptap {
|
|
9297
9380
|
outline: none;
|
|
9298
|
-
min-height:
|
|
9381
|
+
min-height: calc(var(--type-body-leading) * 2em);
|
|
9299
9382
|
min-width: 0;
|
|
9300
9383
|
max-width: 100%;
|
|
9301
9384
|
overflow-x: auto;
|
|
@@ -9311,14 +9394,6 @@
|
|
|
9311
9394
|
line-height: var(--type-body-leading);
|
|
9312
9395
|
}
|
|
9313
9396
|
|
|
9314
|
-
.compose-tiptap-thoughts .tiptap {
|
|
9315
|
-
min-height: 72px;
|
|
9316
|
-
}
|
|
9317
|
-
|
|
9318
|
-
.compose-tiptap-thoughts-quote .tiptap {
|
|
9319
|
-
min-height: 56px;
|
|
9320
|
-
}
|
|
9321
|
-
|
|
9322
9397
|
.compose-tiptap-link .tiptap {
|
|
9323
9398
|
color: var(--site-text-primary);
|
|
9324
9399
|
}
|
|
@@ -9379,12 +9454,12 @@
|
|
|
9379
9454
|
margin-bottom: 1rem;
|
|
9380
9455
|
}
|
|
9381
9456
|
|
|
9382
|
-
/*
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
editors
|
|
9387
|
-
.compose-
|
|
9457
|
+
/* The first block's 1.4rem top margin is a lead-in that only made sense when
|
|
9458
|
+
the body was the first thing in the editor. Every editor now renders a
|
|
9459
|
+
format header above it — and notes a title field too — so it reads as a gap
|
|
9460
|
+
instead. (This used to be scoped to .compose-editor-row, back when
|
|
9461
|
+
standalone new/edit editors did start with the body.) */
|
|
9462
|
+
.compose-tiptap-body .tiptap > :first-child {
|
|
9388
9463
|
margin-top: 0;
|
|
9389
9464
|
}
|
|
9390
9465
|
|
|
@@ -11215,12 +11290,16 @@
|
|
|
11215
11290
|
var(--site-page-bg) 88%,
|
|
11216
11291
|
var(--site-elevated-bg) 12%
|
|
11217
11292
|
);
|
|
11293
|
+
}
|
|
11218
11294
|
|
|
11219
|
-
|
|
11295
|
+
/* Scoped to the collapsed state. Unscoped it also outranked
|
|
11296
|
+
`.compose-reply-context.expanded` — same specificity, declared later — so
|
|
11297
|
+
fullscreen's "Show more" expanded a box that was still pinned at 140px. */
|
|
11298
|
+
.compose-fullscreen-thread-layout .compose-reply-context:not(.expanded) {
|
|
11299
|
+
max-height: 140px;
|
|
11220
11300
|
}
|
|
11221
11301
|
|
|
11222
11302
|
.compose-fullscreen-thread-layout .compose-reply-context {
|
|
11223
|
-
max-height: 140px;
|
|
11224
11303
|
padding: 0.08rem 0 0.08rem;
|
|
11225
11304
|
}
|
|
11226
11305
|
|
|
@@ -11234,12 +11313,7 @@
|
|
|
11234
11313
|
color: var(--site-text-secondary);
|
|
11235
11314
|
}
|
|
11236
11315
|
|
|
11237
|
-
.compose-fullscreen-thread-layout .compose-thread-dot {
|
|
11238
|
-
margin-top: 0.6rem;
|
|
11239
|
-
}
|
|
11240
|
-
|
|
11241
11316
|
.compose-fullscreen-editor-row {
|
|
11242
|
-
overflow: visible;
|
|
11243
11317
|
padding-top: 1.5rem;
|
|
11244
11318
|
}
|
|
11245
11319
|
|
|
@@ -11255,10 +11329,9 @@
|
|
|
11255
11329
|
gap: 0.7rem;
|
|
11256
11330
|
}
|
|
11257
11331
|
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11332
|
+
/* Stand-in for a hidden title: reads as the field's own placeholder, and
|
|
11333
|
+
clicking it swaps in the real input. Fullscreen has no toolbar to put the
|
|
11334
|
+
`T` toggle on, so this is the way back to a title from here. */
|
|
11262
11335
|
.compose-fullscreen-title-placeholder {
|
|
11263
11336
|
display: block;
|
|
11264
11337
|
width: 100%;
|
|
@@ -11490,6 +11563,13 @@
|
|
|
11490
11563
|
|
|
11491
11564
|
/* --- View toggle -------------------------------------------------------- */
|
|
11492
11565
|
|
|
11566
|
+
.archive-toolbar-toggles {
|
|
11567
|
+
display: flex;
|
|
11568
|
+
align-items: center;
|
|
11569
|
+
gap: 6px;
|
|
11570
|
+
flex-shrink: 0;
|
|
11571
|
+
}
|
|
11572
|
+
|
|
11493
11573
|
.archive-view-toggle {
|
|
11494
11574
|
display: flex;
|
|
11495
11575
|
align-items: center;
|