privateboard 0.1.13 → 0.1.15
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/dist/cli.js +921 -25
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/public/app.js +1283 -27
- package/public/index.html +857 -49
package/public/index.html
CHANGED
|
@@ -560,7 +560,7 @@
|
|
|
560
560
|
.agent-row .agent-row-title {
|
|
561
561
|
color: var(--text);
|
|
562
562
|
font-family: var(--font-human);
|
|
563
|
-
font-weight:
|
|
563
|
+
font-weight: 400;
|
|
564
564
|
font-size: 14px;
|
|
565
565
|
letter-spacing: -0.005em;
|
|
566
566
|
/* Truncate long agent names with ellipsis instead of wrapping
|
|
@@ -1219,7 +1219,7 @@
|
|
|
1219
1219
|
}
|
|
1220
1220
|
.row-title {
|
|
1221
1221
|
font-size: 14px;
|
|
1222
|
-
font-weight:
|
|
1222
|
+
font-weight: 400;
|
|
1223
1223
|
color: var(--text);
|
|
1224
1224
|
overflow: hidden;
|
|
1225
1225
|
text-overflow: ellipsis;
|
|
@@ -2664,43 +2664,47 @@
|
|
|
2664
2664
|
border-bottom: 0.5px solid var(--line);
|
|
2665
2665
|
}
|
|
2666
2666
|
.notes-item:last-child { border-bottom: none; }
|
|
2667
|
-
.
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2667
|
+
/* Action row beneath each note · Share + Unfavorite. The row was
|
|
2668
|
+
hover-revealed for a while, but the actions are now always-on so
|
|
2669
|
+
a glance at the note tells the user how to act on it. Buttons
|
|
2670
|
+
use the same flat-pill register as `.bento-director-model` (mono
|
|
2671
|
+
kicker text, 0.5px hairline border, no rounded corners). Clicks
|
|
2672
|
+
funnel through the global click delegator via data-attrs. */
|
|
2673
|
+
/* Bare icon + label, no pill chrome · reads as quiet metadata
|
|
2674
|
+
not as a CTA. The note itself is the primary surface; these
|
|
2675
|
+
actions are secondary affordances revealed on inspection. */
|
|
2676
|
+
.notes-item-actions {
|
|
2677
|
+
display: flex;
|
|
2678
|
+
align-items: center;
|
|
2679
|
+
gap: 16px;
|
|
2680
|
+
padding: 0 4px 14px;
|
|
2681
|
+
margin-top: -4px;
|
|
2682
|
+
}
|
|
2683
|
+
.notes-item-action {
|
|
2684
|
+
display: inline-flex;
|
|
2685
|
+
align-items: center;
|
|
2686
|
+
gap: 5px;
|
|
2687
|
+
padding: 0;
|
|
2688
|
+
background: transparent;
|
|
2689
|
+
border: 0;
|
|
2675
2690
|
color: var(--text-faint);
|
|
2676
2691
|
font-family: var(--mono);
|
|
2677
|
-
font-size:
|
|
2678
|
-
|
|
2692
|
+
font-size: 10px;
|
|
2693
|
+
font-weight: 700;
|
|
2694
|
+
letter-spacing: 0.14em;
|
|
2695
|
+
text-transform: uppercase;
|
|
2696
|
+
line-height: 1.2;
|
|
2679
2697
|
cursor: pointer;
|
|
2680
|
-
|
|
2681
|
-
align-items: center;
|
|
2682
|
-
justify-content: center;
|
|
2683
|
-
padding: 0;
|
|
2684
|
-
transition: color 0.12s, border-color 0.12s, background 0.12s;
|
|
2685
|
-
z-index: 2;
|
|
2698
|
+
transition: color 0.14s;
|
|
2686
2699
|
}
|
|
2687
|
-
.notes-item:hover
|
|
2688
|
-
.notes-item-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2700
|
+
.notes-item-action:hover { color: var(--text); }
|
|
2701
|
+
.notes-item-share:hover { color: var(--lime); }
|
|
2702
|
+
.notes-item-unfav:hover { color: var(--red); }
|
|
2703
|
+
.notes-action-glyph {
|
|
2704
|
+
font-size: 11px;
|
|
2705
|
+
letter-spacing: 0;
|
|
2706
|
+
opacity: 0.9;
|
|
2692
2707
|
}
|
|
2693
|
-
/* Reserve the right-edge gutter ALWAYS (not only on hover) so the
|
|
2694
|
-
passage text doesn't reflow when the delete button appears. An
|
|
2695
|
-
earlier version applied `padding-right: 30px` only on hover —
|
|
2696
|
-
the text visibly jumped each time the user mousemoved across
|
|
2697
|
-
rows. Cost: a fixed 30px of empty space at the right edge of
|
|
2698
|
-
every passage; cheap compared to the jitter. */
|
|
2699
|
-
.notes-item-passage { padding-right: 30px; }
|
|
2700
|
-
/* On hover · hide the trailing time tag so the delete button
|
|
2701
|
-
occupies the right-edge slot cleanly. visibility:hidden keeps
|
|
2702
|
-
the layout box (the meta row doesn't reflow either). */
|
|
2703
|
-
.notes-item:hover .notes-item-time { visibility: hidden; }
|
|
2704
2708
|
.notes-item-link {
|
|
2705
2709
|
display: block;
|
|
2706
2710
|
padding: 18px 4px;
|
|
@@ -2796,6 +2800,542 @@
|
|
|
2796
2800
|
transition: text-decoration-color 0.14s;
|
|
2797
2801
|
}
|
|
2798
2802
|
|
|
2803
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
2804
|
+
SHARE-CARD OVERLAY · the modal mounted when the user clicks the
|
|
2805
|
+
Share button on a note in All Notes. CHROME (overlay + modal
|
|
2806
|
+
+ classification strip + head + foot) is shared with the
|
|
2807
|
+
room-settings overlay via the `.room-settings-overlay /
|
|
2808
|
+
.room-settings-modal / .rs-classification / .rs-head / .rs-body
|
|
2809
|
+
/ .rs-foot` classes (defined in `room-settings.css`). Only the
|
|
2810
|
+
template chips + preview viewport + the cards themselves are
|
|
2811
|
+
local to this feature.
|
|
2812
|
+
|
|
2813
|
+
PNG export uses the same html-to-image CDN loader as
|
|
2814
|
+
`public/magazine.html` (lazy-fetched on first export). Native
|
|
2815
|
+
render 540×675 at pixelRatio: 2 → 1080×1350 PNG, IG/Weibo/
|
|
2816
|
+
WeChat-friendly. Templates carry hard-coded palettes (NOT
|
|
2817
|
+
`var(--bg)` / `var(--lime)`) so the exported image looks the
|
|
2818
|
+
same regardless of the user's active theme.
|
|
2819
|
+
═══════════════════════════════════════════════════════════════ */
|
|
2820
|
+
/* Hoist the share-card overlay z-index above other UI · room-
|
|
2821
|
+
settings reserves 950 but the share-card may need to sit over
|
|
2822
|
+
in-room toasts. Same vertical-scroll behaviour as the rs-modal. */
|
|
2823
|
+
.room-settings-overlay#share-card-overlay { z-index: 9700; }
|
|
2824
|
+
/* The All Notes view's share-card needs a slightly wider modal
|
|
2825
|
+
than room-settings (540px card + 32px gutters fits at 640). */
|
|
2826
|
+
.room-settings-overlay#share-card-overlay .room-settings-modal {
|
|
2827
|
+
max-width: 640px;
|
|
2828
|
+
}
|
|
2829
|
+
/* Template chip row · 4 chips, click to swap the preview's
|
|
2830
|
+
`data-share-template` attribute (the preview re-renders
|
|
2831
|
+
instantly because each template's visual is CSS-keyed off
|
|
2832
|
+
the attr). */
|
|
2833
|
+
.share-card-templates {
|
|
2834
|
+
display: flex;
|
|
2835
|
+
gap: 6px;
|
|
2836
|
+
flex-wrap: wrap;
|
|
2837
|
+
margin-bottom: 14px;
|
|
2838
|
+
}
|
|
2839
|
+
.share-card-template-chip {
|
|
2840
|
+
appearance: none;
|
|
2841
|
+
background: var(--panel-2, #1A1A18);
|
|
2842
|
+
border: 0.5px solid var(--line-bright, #2A2A26);
|
|
2843
|
+
color: var(--text-soft, #8E8B83);
|
|
2844
|
+
font-family: var(--mono);
|
|
2845
|
+
font-size: 9.5px;
|
|
2846
|
+
letter-spacing: 0.14em;
|
|
2847
|
+
text-transform: uppercase;
|
|
2848
|
+
font-weight: 700;
|
|
2849
|
+
padding: 5px 10px;
|
|
2850
|
+
cursor: pointer;
|
|
2851
|
+
transition: color 0.14s, border-color 0.14s, background 0.14s;
|
|
2852
|
+
}
|
|
2853
|
+
.share-card-template-chip:hover {
|
|
2854
|
+
color: var(--text, #C8C5BE);
|
|
2855
|
+
border-color: var(--line-strong, #3A3A35);
|
|
2856
|
+
}
|
|
2857
|
+
.share-card-template-chip.active {
|
|
2858
|
+
color: var(--bg, #0A0A0A);
|
|
2859
|
+
background: var(--lime, #6FB572);
|
|
2860
|
+
border-color: var(--lime, #6FB572);
|
|
2861
|
+
}
|
|
2862
|
+
/* Preview viewport · centers the native 540×675 card and scales
|
|
2863
|
+
it down with `transform: scale()` so it fits inside the modal
|
|
2864
|
+
on smaller viewports. The native size is preserved so the
|
|
2865
|
+
html-to-image export captures crisp text at the full
|
|
2866
|
+
resolution; the visual scale-down is cosmetic. */
|
|
2867
|
+
.share-card-preview {
|
|
2868
|
+
/* Width is the MIN of three caps so the preview always stays
|
|
2869
|
+
a perfect 540:800 rectangle — container width (100%), the
|
|
2870
|
+
absolute 540px ceiling, and a viewport-height-derived cap
|
|
2871
|
+
(height * 540/800). The third cap is what shrinks the
|
|
2872
|
+
preview proportionally on short displays without breaking
|
|
2873
|
+
the aspect ratio — and that's what makes the image stay
|
|
2874
|
+
centered in the modal body. With `aspect-ratio: 540/800`,
|
|
2875
|
+
height is derived and matches the preview perfectly.
|
|
2876
|
+
`margin: 0 auto` then centres the whole block in `.rs-body`. */
|
|
2877
|
+
width: min(100%, 540px, calc((100vh - 260px) * 0.675));
|
|
2878
|
+
aspect-ratio: 540 / 800;
|
|
2879
|
+
position: relative;
|
|
2880
|
+
overflow: hidden;
|
|
2881
|
+
background: #0A0A0A;
|
|
2882
|
+
border: 0.5px solid var(--line, #2A2A26);
|
|
2883
|
+
margin: 0 auto;
|
|
2884
|
+
}
|
|
2885
|
+
.share-card-preview-inner {
|
|
2886
|
+
width: 540px;
|
|
2887
|
+
height: 800px;
|
|
2888
|
+
transform-origin: top left;
|
|
2889
|
+
/* JS sets `--share-card-scale` based on the rendered viewport
|
|
2890
|
+
width so a small viewport sees a 100%-fit preview without
|
|
2891
|
+
sacrificing the native render resolution. */
|
|
2892
|
+
transform: scale(var(--share-card-scale, 1));
|
|
2893
|
+
}
|
|
2894
|
+
/* Tighten room-settings's default rs-foot padding for the share
|
|
2895
|
+
card's single hint + download row. */
|
|
2896
|
+
.room-settings-overlay#share-card-overlay .rs-foot {
|
|
2897
|
+
padding: 10px 16px;
|
|
2898
|
+
}
|
|
2899
|
+
.share-card-hint {
|
|
2900
|
+
font-family: var(--mono);
|
|
2901
|
+
font-size: 9.5px;
|
|
2902
|
+
letter-spacing: 0.18em;
|
|
2903
|
+
text-transform: uppercase;
|
|
2904
|
+
color: var(--text-faint, #5C5A52);
|
|
2905
|
+
font-weight: 700;
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2908
|
+
/* ─── Card template base · everything inside the 540×800 frame ─── */
|
|
2909
|
+
.share-card {
|
|
2910
|
+
position: relative;
|
|
2911
|
+
width: 540px;
|
|
2912
|
+
height: 800px;
|
|
2913
|
+
box-sizing: border-box;
|
|
2914
|
+
overflow: hidden;
|
|
2915
|
+
font-family: var(--font-human, "Inter", "Helvetica Neue", system-ui, sans-serif);
|
|
2916
|
+
}
|
|
2917
|
+
.share-card-watermark {
|
|
2918
|
+
position: absolute;
|
|
2919
|
+
bottom: 22px;
|
|
2920
|
+
left: 32px;
|
|
2921
|
+
font-family: var(--mono, "JetBrains Mono", "Menlo", monospace);
|
|
2922
|
+
font-size: 10px;
|
|
2923
|
+
letter-spacing: 0.22em;
|
|
2924
|
+
text-transform: uppercase;
|
|
2925
|
+
opacity: 0.85;
|
|
2926
|
+
}
|
|
2927
|
+
.share-card-stamp {
|
|
2928
|
+
position: absolute;
|
|
2929
|
+
bottom: 22px;
|
|
2930
|
+
right: 32px;
|
|
2931
|
+
font-family: var(--mono, "JetBrains Mono", "Menlo", monospace);
|
|
2932
|
+
font-size: 9.5px;
|
|
2933
|
+
letter-spacing: 0.18em;
|
|
2934
|
+
text-transform: uppercase;
|
|
2935
|
+
opacity: 0.55;
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
/* ── Template A · BOARDROOM · 8-bit pixel-art (DEFAULT) ───────
|
|
2939
|
+
Dribbble-inspired warm-sunset palette: striped horizontal
|
|
2940
|
+
gradient bands climbing from near-black purple at the top
|
|
2941
|
+
through magenta/coral/orange into warm cream at the horizon,
|
|
2942
|
+
where a tiny 8-bit boardroom (table + chairs + mod chair +
|
|
2943
|
+
plants) sits as the brand anchor. The user's quote lives in
|
|
2944
|
+
the centre in a chunky pixel-art dialog box — cream interior,
|
|
2945
|
+
thick dark outline, theme-accent inner band — that reads as
|
|
2946
|
+
"system message in an 8-bit game".
|
|
2947
|
+
|
|
2948
|
+
Pixel-perfect render: `image-rendering: pixelated` on every
|
|
2949
|
+
SVG + `shape-rendering: crispEdges` on every rect keeps the
|
|
2950
|
+
export reading as authentic 8-bit rather than anti-aliased
|
|
2951
|
+
vector graphics.
|
|
2952
|
+
|
|
2953
|
+
Reference: https://dribbble.com/userupload/13578237 (WorkOS
|
|
2954
|
+
Launch Week 8-bit poster). */
|
|
2955
|
+
.share-card[data-share-template="boardroom"] {
|
|
2956
|
+
/* 8 hard-stop bands · near-black purple → deep purple →
|
|
2957
|
+
mauve → rose → coral → orange → peach → cream. Each band
|
|
2958
|
+
is a fixed-percentage stripe so the transitions are sharp
|
|
2959
|
+
(8-bit "no anti-alias" feel), not a smooth gradient. */
|
|
2960
|
+
background: linear-gradient(180deg,
|
|
2961
|
+
#1B0A35 0%, #1B0A35 5%,
|
|
2962
|
+
#2D1452 5%, #2D1452 11%,
|
|
2963
|
+
#4A2070 11%, #4A2070 18%,
|
|
2964
|
+
#6B2B6E 18%, #6B2B6E 25%,
|
|
2965
|
+
#A03B5E 25%, #A03B5E 33%,
|
|
2966
|
+
#D85F4C 33%, #D85F4C 41%,
|
|
2967
|
+
#ED8E48 41%, #ED8E48 49%,
|
|
2968
|
+
#F4C078 49%, #F4C078 57%,
|
|
2969
|
+
#F8D898 57%, #F8D898 100%);
|
|
2970
|
+
color: #1B0A35;
|
|
2971
|
+
image-rendering: pixelated;
|
|
2972
|
+
image-rendering: crisp-edges;
|
|
2973
|
+
}
|
|
2974
|
+
/* Brand strip · top kicker mirrors the WorkOS-style "◇ BRAND"
|
|
2975
|
+
at the very top of the reference image. Cream-on-purple so
|
|
2976
|
+
it reads against the deepest band. */
|
|
2977
|
+
.share-card[data-share-template="boardroom"] .sc-header {
|
|
2978
|
+
position: absolute;
|
|
2979
|
+
top: 22px;
|
|
2980
|
+
left: 28px;
|
|
2981
|
+
right: 28px;
|
|
2982
|
+
display: flex;
|
|
2983
|
+
justify-content: space-between;
|
|
2984
|
+
align-items: baseline;
|
|
2985
|
+
font-family: var(--mono, monospace);
|
|
2986
|
+
font-size: 10.5px;
|
|
2987
|
+
letter-spacing: 0.24em;
|
|
2988
|
+
text-transform: uppercase;
|
|
2989
|
+
color: #F4D898;
|
|
2990
|
+
font-weight: 700;
|
|
2991
|
+
z-index: 4;
|
|
2992
|
+
}
|
|
2993
|
+
.share-card[data-share-template="boardroom"] .sc-header-right {
|
|
2994
|
+
color: var(--lime, #6FB572);
|
|
2995
|
+
}
|
|
2996
|
+
/* Sky decorations · pixel moon + stars + clouds + floating
|
|
2997
|
+
balloons, painted inline by the renderer as an SVG layer that
|
|
2998
|
+
fills the WHOLE card so the atmosphere wraps the dialog box
|
|
2999
|
+
on every side (not just the top). z-index keeps decorations
|
|
3000
|
+
behind the dialog and the header but in front of the gradient. */
|
|
3001
|
+
.share-card[data-share-template="boardroom"] .sc-sky-deco {
|
|
3002
|
+
position: absolute;
|
|
3003
|
+
inset: 0;
|
|
3004
|
+
z-index: 1;
|
|
3005
|
+
pointer-events: none;
|
|
3006
|
+
image-rendering: pixelated;
|
|
3007
|
+
shape-rendering: crispEdges;
|
|
3008
|
+
}
|
|
3009
|
+
.share-card[data-share-template="boardroom"] .sc-heart {
|
|
3010
|
+
display: inline-block;
|
|
3011
|
+
color: var(--lime, #6FB572);
|
|
3012
|
+
margin-left: 8px;
|
|
3013
|
+
font-size: 11px;
|
|
3014
|
+
transform: translateY(0.5px);
|
|
3015
|
+
}
|
|
3016
|
+
/* Wooden 8-bit signpost · cream parchment interior framed by a
|
|
3017
|
+
chunky 8px wood-tone border, with a 2px pixel bevel inside
|
|
3018
|
+
the wood (sun-side highlight + shadow-side darker tone), a
|
|
3019
|
+
2px dark outline outside the wood ("ink line"), and a hard
|
|
3020
|
+
6px drop shadow on the ground for the 8-bit sticker feel.
|
|
3021
|
+
Four pixel "nails" pin the frame at each corner (added
|
|
3022
|
+
inline by the renderer; styled below).
|
|
3023
|
+
|
|
3024
|
+
The tail is intentionally absent — a wooden sign doesn't
|
|
3025
|
+
speech-bubble. The two pseudo-elements that used to draw the
|
|
3026
|
+
tail are hidden. */
|
|
3027
|
+
.share-card[data-share-template="boardroom"] .sc-bubble {
|
|
3028
|
+
position: absolute;
|
|
3029
|
+
top: 200px;
|
|
3030
|
+
left: 32px;
|
|
3031
|
+
right: 32px;
|
|
3032
|
+
max-height: 260px;
|
|
3033
|
+
min-height: 160px;
|
|
3034
|
+
background: #FFF6D9;
|
|
3035
|
+
/* 8px wood-tone border carries the bevel inset highlights */
|
|
3036
|
+
border: 8px solid #7A5230;
|
|
3037
|
+
box-shadow:
|
|
3038
|
+
inset 2px 2px 0 #C8A877, /* top-left wood highlight */
|
|
3039
|
+
inset -2px -2px 0 #4A2E18, /* bottom-right wood shadow */
|
|
3040
|
+
0 0 0 2px #1B0A35, /* outer ink-line outline */
|
|
3041
|
+
6px 6px 0 0 #1B0A35; /* 8-bit drop shadow */
|
|
3042
|
+
padding: 24px 28px;
|
|
3043
|
+
color: #1B0A35;
|
|
3044
|
+
font-family: "Tiempos Text", "Charter", "Iowan Old Style", "Georgia", serif;
|
|
3045
|
+
font-style: italic;
|
|
3046
|
+
line-height: 1.42;
|
|
3047
|
+
text-align: left;
|
|
3048
|
+
z-index: 3;
|
|
3049
|
+
overflow: hidden;
|
|
3050
|
+
}
|
|
3051
|
+
/* Tail removed for the wooden plank · clean rectangular frame. */
|
|
3052
|
+
.share-card[data-share-template="boardroom"] .sc-bubble::before,
|
|
3053
|
+
.share-card[data-share-template="boardroom"] .sc-bubble::after {
|
|
3054
|
+
display: none;
|
|
3055
|
+
}
|
|
3056
|
+
/* Pixel nails · 4×4 dark squares pinned to the middle of the
|
|
3057
|
+
8px wood border at each corner. Reads as the iron nails
|
|
3058
|
+
holding the wooden plank together. */
|
|
3059
|
+
.share-card[data-share-template="boardroom"] .sc-nail {
|
|
3060
|
+
position: absolute;
|
|
3061
|
+
width: 4px;
|
|
3062
|
+
height: 4px;
|
|
3063
|
+
background: #1B0A35;
|
|
3064
|
+
z-index: 4;
|
|
3065
|
+
}
|
|
3066
|
+
.share-card[data-share-template="boardroom"] .sc-nail.tl { top: 2px; left: 2px; }
|
|
3067
|
+
.share-card[data-share-template="boardroom"] .sc-nail.tr { top: 2px; right: 2px; }
|
|
3068
|
+
.share-card[data-share-template="boardroom"] .sc-nail.bl { bottom: 2px; left: 2px; }
|
|
3069
|
+
.share-card[data-share-template="boardroom"] .sc-nail.br { bottom: 2px; right: 2px; }
|
|
3070
|
+
.share-card[data-share-template="boardroom"] .sc-bubble-text { margin: 0; }
|
|
3071
|
+
/* Topic annotation above the quote · small monospace kicker
|
|
3072
|
+
showing what question the room was convened around (the
|
|
3073
|
+
note's `roomSubject`). Reads as a hand-written marginalia /
|
|
3074
|
+
code-comment on the wooden plank: `// re: <subject>`. A
|
|
3075
|
+
1-px dashed underline separates it from the main quote with
|
|
3076
|
+
comfortable padding on both sides so the line never sits
|
|
3077
|
+
flush against the text. No line-clamp · long subjects wrap
|
|
3078
|
+
naturally, and the bubble's font-size tier-down keeps the
|
|
3079
|
+
quote readable even when the meta block takes a few lines. */
|
|
3080
|
+
.share-card[data-share-template="boardroom"] .sc-bubble-meta {
|
|
3081
|
+
display: block;
|
|
3082
|
+
font-family: var(--mono, "JetBrains Mono", "Menlo", monospace);
|
|
3083
|
+
font-size: 10px;
|
|
3084
|
+
letter-spacing: 0.14em;
|
|
3085
|
+
text-transform: uppercase;
|
|
3086
|
+
color: #6B5A48;
|
|
3087
|
+
font-style: normal;
|
|
3088
|
+
/* Annotation reads as quiet marginalia — regular weight, no
|
|
3089
|
+
bold. The CJK override below keeps Chinese in regular
|
|
3090
|
+
weight too (overriding the default `.cjk { weight: 700 }`). */
|
|
3091
|
+
font-weight: 400;
|
|
3092
|
+
line-height: 1.5;
|
|
3093
|
+
margin: 0 0 16px 0;
|
|
3094
|
+
padding-bottom: 14px;
|
|
3095
|
+
border-bottom: 1px dashed rgba(27, 10, 53, 0.32);
|
|
3096
|
+
word-break: break-word;
|
|
3097
|
+
overflow-wrap: anywhere;
|
|
3098
|
+
}
|
|
3099
|
+
.share-card[data-share-template="boardroom"] .sc-bubble-meta .cjk {
|
|
3100
|
+
font-weight: 400;
|
|
3101
|
+
}
|
|
3102
|
+
/* Mixed-script typography for share cards · Latin / English keeps
|
|
3103
|
+
the serif italic register (Tiempos / Charter / Georgia); CJK
|
|
3104
|
+
runs that the renderer wraps in `<span class="cjk">` switch to
|
|
3105
|
+
PingFang at a heavier weight so Chinese characters print bold
|
|
3106
|
+
and upright (italic-skew on CJK reads as a rendering glitch).
|
|
3107
|
+
Scoped to `.share-card` so other parts of the UI keep their
|
|
3108
|
+
own typography. */
|
|
3109
|
+
.share-card .cjk {
|
|
3110
|
+
/* Prefer the macOS-native Heiti family · STHeiti and Hiragino
|
|
3111
|
+
Sans GB both render Chinese with a slightly warmer, more
|
|
3112
|
+
editorial weight than PingFang. PingFang stays in the stack
|
|
3113
|
+
as a fallback for systems without the Heiti faces. */
|
|
3114
|
+
font-family: "STHeiti", "Heiti SC", "Hiragino Sans GB",
|
|
3115
|
+
"PingFang SC", "PingFang TC", "Microsoft YaHei", sans-serif;
|
|
3116
|
+
font-weight: 700;
|
|
3117
|
+
font-style: normal;
|
|
3118
|
+
letter-spacing: 0;
|
|
3119
|
+
}
|
|
3120
|
+
/* Byline · stone-textured pixel plaque holding the director
|
|
3121
|
+
name. Same three-tone stone palette as the river-bank rocks
|
|
3122
|
+
(mid-grey body / lighter top-left highlight / darker bottom-
|
|
3123
|
+
right rim) plus a 2px dark outline + a 4px hard drop shadow,
|
|
3124
|
+
so the label reads as a chunky 8-bit name-plate carved
|
|
3125
|
+
from the same rock vocabulary. Centred horizontally below
|
|
3126
|
+
the wooden bubble. CJK director names inside it render in
|
|
3127
|
+
PingFang bold via the `.cjk` rule above (italic skew is
|
|
3128
|
+
intentionally not applied to CJK glyphs). */
|
|
3129
|
+
.share-card[data-share-template="boardroom"] .sc-byline {
|
|
3130
|
+
position: absolute;
|
|
3131
|
+
top: 488px;
|
|
3132
|
+
left: 50%;
|
|
3133
|
+
transform: translateX(-50%);
|
|
3134
|
+
display: inline-flex;
|
|
3135
|
+
align-items: center;
|
|
3136
|
+
padding: 8px 22px;
|
|
3137
|
+
background: #7A6F62;
|
|
3138
|
+
border: 2px solid #1B0A35;
|
|
3139
|
+
box-shadow:
|
|
3140
|
+
inset 2px 2px 0 #9F9388,
|
|
3141
|
+
inset -2px -2px 0 #4A4038,
|
|
3142
|
+
4px 4px 0 0 #1B0A35;
|
|
3143
|
+
color: #FFF6D9;
|
|
3144
|
+
font-family: "Tiempos Text", "Charter", "Iowan Old Style", "Georgia", serif;
|
|
3145
|
+
font-style: italic;
|
|
3146
|
+
font-size: 16px;
|
|
3147
|
+
letter-spacing: 0.04em;
|
|
3148
|
+
font-weight: 600;
|
|
3149
|
+
text-align: center;
|
|
3150
|
+
white-space: nowrap;
|
|
3151
|
+
max-width: 380px;
|
|
3152
|
+
z-index: 4;
|
|
3153
|
+
}
|
|
3154
|
+
/* Watermark + stamp · dark purple chrome on the warm-cream
|
|
3155
|
+
bottom band so they read like a stamped postal mark. */
|
|
3156
|
+
.share-card[data-share-template="boardroom"] .share-card-watermark {
|
|
3157
|
+
color: #4A2070;
|
|
3158
|
+
bottom: 16px;
|
|
3159
|
+
left: 28px;
|
|
3160
|
+
font-size: 10.5px;
|
|
3161
|
+
letter-spacing: 0.22em;
|
|
3162
|
+
opacity: 1;
|
|
3163
|
+
}
|
|
3164
|
+
.share-card[data-share-template="boardroom"] .share-card-stamp {
|
|
3165
|
+
color: #4A2070;
|
|
3166
|
+
bottom: 16px;
|
|
3167
|
+
right: 28px;
|
|
3168
|
+
opacity: 0.7;
|
|
3169
|
+
}
|
|
3170
|
+
/* Mod chair · cyan rails / gem follow the user's `--cyan` theme
|
|
3171
|
+
token (matches the live round-table moderator chair). Local
|
|
3172
|
+
to this card so the other templates aren't affected. */
|
|
3173
|
+
.share-card[data-share-template="boardroom"] .mod-rail { fill: var(--cyan, #6A9B97); }
|
|
3174
|
+
.share-card[data-share-template="boardroom"] .mod-rail-hi { fill: color-mix(in srgb, var(--cyan, #6A9B97) 60%, #FFFFFF 40%); }
|
|
3175
|
+
.share-card[data-share-template="boardroom"] .mod-gem { fill: var(--cyan, #6A9B97); }
|
|
3176
|
+
.share-card[data-share-template="boardroom"] .mod-gem-hi { fill: color-mix(in srgb, var(--cyan, #6A9B97) 50%, #FFFFFF 50%); }
|
|
3177
|
+
|
|
3178
|
+
/* ── Template B · EDITORIAL · warm cream, pull-quote, serif ─── */
|
|
3179
|
+
.share-card[data-share-template="editorial"] {
|
|
3180
|
+
background: #F4EFE3;
|
|
3181
|
+
color: #2A2620;
|
|
3182
|
+
padding: 56px 52px;
|
|
3183
|
+
display: flex;
|
|
3184
|
+
flex-direction: column;
|
|
3185
|
+
justify-content: space-between;
|
|
3186
|
+
}
|
|
3187
|
+
.share-card[data-share-template="editorial"] .sc-quotemark {
|
|
3188
|
+
font-family: "Tiempos Headline", "Charter", "Georgia", serif;
|
|
3189
|
+
font-size: 120px;
|
|
3190
|
+
line-height: 0.6;
|
|
3191
|
+
color: #B5704A;
|
|
3192
|
+
margin: 0 0 -28px;
|
|
3193
|
+
user-select: none;
|
|
3194
|
+
}
|
|
3195
|
+
.share-card[data-share-template="editorial"] .sc-quote {
|
|
3196
|
+
font-family: "Tiempos Headline", "Charter", "Iowan Old Style", "Georgia", serif;
|
|
3197
|
+
line-height: 1.32;
|
|
3198
|
+
color: #2A2620;
|
|
3199
|
+
margin: 0;
|
|
3200
|
+
font-weight: 500;
|
|
3201
|
+
/* Font-size set inline by the renderer for length-based step-down. */
|
|
3202
|
+
}
|
|
3203
|
+
.share-card[data-share-template="editorial"] .sc-quote em {
|
|
3204
|
+
font-style: italic;
|
|
3205
|
+
color: #B5704A;
|
|
3206
|
+
}
|
|
3207
|
+
.share-card[data-share-template="editorial"] .sc-byline {
|
|
3208
|
+
margin-top: 24px;
|
|
3209
|
+
padding-top: 18px;
|
|
3210
|
+
border-top: 0.5px solid #B5A893;
|
|
3211
|
+
font-family: var(--mono, monospace);
|
|
3212
|
+
font-size: 10.5px;
|
|
3213
|
+
letter-spacing: 0.18em;
|
|
3214
|
+
text-transform: uppercase;
|
|
3215
|
+
color: #6F6354;
|
|
3216
|
+
}
|
|
3217
|
+
.share-card[data-share-template="editorial"] .sc-byline strong {
|
|
3218
|
+
color: #B5704A;
|
|
3219
|
+
font-weight: 700;
|
|
3220
|
+
}
|
|
3221
|
+
.share-card[data-share-template="editorial"] .share-card-watermark { color: #6F6354; }
|
|
3222
|
+
.share-card[data-share-template="editorial"] .share-card-stamp { color: #8E8270; }
|
|
3223
|
+
|
|
3224
|
+
/* ── Template C · TERMINAL · monospace CRT ──────────────────── */
|
|
3225
|
+
.share-card[data-share-template="terminal"] {
|
|
3226
|
+
background: #0E1414;
|
|
3227
|
+
color: #C9F2C2;
|
|
3228
|
+
padding: 44px 38px;
|
|
3229
|
+
display: flex;
|
|
3230
|
+
flex-direction: column;
|
|
3231
|
+
font-family: var(--mono, "JetBrains Mono", "Menlo", monospace);
|
|
3232
|
+
}
|
|
3233
|
+
.share-card[data-share-template="terminal"] .sc-frame {
|
|
3234
|
+
flex: 1;
|
|
3235
|
+
border: 1px solid var(--lime, #6FB572);
|
|
3236
|
+
padding: 28px 26px;
|
|
3237
|
+
position: relative;
|
|
3238
|
+
display: flex;
|
|
3239
|
+
flex-direction: column;
|
|
3240
|
+
}
|
|
3241
|
+
.share-card[data-share-template="terminal"] .sc-frame::before {
|
|
3242
|
+
content: "// excerpt";
|
|
3243
|
+
position: absolute;
|
|
3244
|
+
top: -7px;
|
|
3245
|
+
left: 24px;
|
|
3246
|
+
background: #0E1414;
|
|
3247
|
+
color: var(--lime, #6FB572);
|
|
3248
|
+
font-family: var(--mono, monospace);
|
|
3249
|
+
font-size: 10px;
|
|
3250
|
+
letter-spacing: 0.28em;
|
|
3251
|
+
text-transform: uppercase;
|
|
3252
|
+
padding: 0 8px;
|
|
3253
|
+
}
|
|
3254
|
+
.share-card[data-share-template="terminal"] .sc-prompt {
|
|
3255
|
+
font-family: var(--mono, monospace);
|
|
3256
|
+
font-size: 10.5px;
|
|
3257
|
+
letter-spacing: 0.18em;
|
|
3258
|
+
text-transform: uppercase;
|
|
3259
|
+
color: var(--lime, #6FB572);
|
|
3260
|
+
margin-bottom: 18px;
|
|
3261
|
+
}
|
|
3262
|
+
.share-card[data-share-template="terminal"] .sc-quote {
|
|
3263
|
+
font-family: var(--mono, "JetBrains Mono", "Menlo", monospace);
|
|
3264
|
+
line-height: 1.55;
|
|
3265
|
+
color: #DDF6D7;
|
|
3266
|
+
margin: 0;
|
|
3267
|
+
flex: 1;
|
|
3268
|
+
/* Font-size set inline by the renderer for length-based step-down. */
|
|
3269
|
+
}
|
|
3270
|
+
.share-card[data-share-template="terminal"] .sc-byline {
|
|
3271
|
+
margin-top: 22px;
|
|
3272
|
+
font-family: var(--mono, monospace);
|
|
3273
|
+
font-size: 10px;
|
|
3274
|
+
letter-spacing: 0.18em;
|
|
3275
|
+
text-transform: uppercase;
|
|
3276
|
+
color: var(--lime, #6FB572);
|
|
3277
|
+
}
|
|
3278
|
+
.share-card[data-share-template="terminal"] .sc-byline-dim { color: #8E9D89; }
|
|
3279
|
+
.share-card[data-share-template="terminal"] .share-card-watermark { color: var(--lime, #6FB572); left: 24px; bottom: 18px; }
|
|
3280
|
+
.share-card[data-share-template="terminal"] .share-card-stamp { color: #8E9D89; right: 24px; bottom: 18px; }
|
|
3281
|
+
|
|
3282
|
+
/* ── Template D · MAGAZINE · mixed serif + sans, pull-quote ─── */
|
|
3283
|
+
.share-card[data-share-template="magazine"] {
|
|
3284
|
+
background: linear-gradient(180deg, #FFFFFF 0%, #F2EFE9 100%);
|
|
3285
|
+
color: #1A1A1A;
|
|
3286
|
+
padding: 56px 52px;
|
|
3287
|
+
display: flex;
|
|
3288
|
+
flex-direction: column;
|
|
3289
|
+
}
|
|
3290
|
+
.share-card[data-share-template="magazine"] .sc-stripe {
|
|
3291
|
+
height: 3px;
|
|
3292
|
+
width: 56px;
|
|
3293
|
+
background: #1A1A1A;
|
|
3294
|
+
margin-bottom: 22px;
|
|
3295
|
+
}
|
|
3296
|
+
.share-card[data-share-template="magazine"] .sc-kicker {
|
|
3297
|
+
font-family: var(--mono, monospace);
|
|
3298
|
+
font-size: 10.5px;
|
|
3299
|
+
letter-spacing: 0.22em;
|
|
3300
|
+
text-transform: uppercase;
|
|
3301
|
+
color: #1A1A1A;
|
|
3302
|
+
margin-bottom: 26px;
|
|
3303
|
+
}
|
|
3304
|
+
.share-card[data-share-template="magazine"] .sc-quote {
|
|
3305
|
+
font-family: "Tiempos Headline", "Charter", "Iowan Old Style", "Georgia", serif;
|
|
3306
|
+
line-height: 1.22;
|
|
3307
|
+
color: #0A0A0A;
|
|
3308
|
+
font-weight: 600;
|
|
3309
|
+
letter-spacing: -0.01em;
|
|
3310
|
+
margin: 0;
|
|
3311
|
+
flex: 1;
|
|
3312
|
+
/* Font-size set inline by the renderer for length-based step-down. */
|
|
3313
|
+
}
|
|
3314
|
+
.share-card[data-share-template="magazine"] .sc-byline {
|
|
3315
|
+
margin-top: 24px;
|
|
3316
|
+
padding-top: 18px;
|
|
3317
|
+
border-top: 1px solid #1A1A1A;
|
|
3318
|
+
font-family: var(--mono, monospace);
|
|
3319
|
+
font-size: 10.5px;
|
|
3320
|
+
letter-spacing: 0.16em;
|
|
3321
|
+
text-transform: uppercase;
|
|
3322
|
+
color: #555050;
|
|
3323
|
+
display: flex;
|
|
3324
|
+
justify-content: space-between;
|
|
3325
|
+
align-items: center;
|
|
3326
|
+
}
|
|
3327
|
+
.share-card[data-share-template="magazine"] .sc-byline strong {
|
|
3328
|
+
color: #1A1A1A;
|
|
3329
|
+
font-weight: 700;
|
|
3330
|
+
}
|
|
3331
|
+
.share-card[data-share-template="magazine"] .share-card-watermark { color: #1A1A1A; }
|
|
3332
|
+
.share-card[data-share-template="magazine"] .share-card-stamp { color: #777070; }
|
|
3333
|
+
|
|
3334
|
+
@media (max-width: 580px) {
|
|
3335
|
+
.share-card-modal { padding: 18px 14px 14px; }
|
|
3336
|
+
.share-card-preview { max-width: 100%; }
|
|
3337
|
+
}
|
|
3338
|
+
|
|
2799
3339
|
/* In-room highlight overlay · injected into director-message
|
|
2800
3340
|
`.msg-bubble` text by app.applyNoteHighlightsForMessage. Same
|
|
2801
3341
|
visual register as `.note-quote` so a saved span reads with the
|
|
@@ -7647,8 +8187,15 @@
|
|
|
7647
8187
|
width: 80px;
|
|
7648
8188
|
height: 18px;
|
|
7649
8189
|
border-radius: 50%;
|
|
8190
|
+
/* Themed glow · matches the speech-bubble border above this
|
|
8191
|
+
seat. Previously hardcoded `rgba(111, 181, 114, 0.55)` (the
|
|
8192
|
+
legacy lime green) which stayed green even when the active
|
|
8193
|
+
theme remapped --lime (e.g. Pinterest red, Apple blue,
|
|
8194
|
+
Nintendo Mario red). color-mix folds the live --lime token
|
|
8195
|
+
to 55% alpha so the floor halo always reads as the same
|
|
8196
|
+
accent as the bubble border. */
|
|
7650
8197
|
background: radial-gradient(ellipse at center,
|
|
7651
|
-
|
|
8198
|
+
color-mix(in srgb, var(--lime) 55%, transparent) 0%,
|
|
7652
8199
|
transparent 70%);
|
|
7653
8200
|
z-index: 0;
|
|
7654
8201
|
animation: rt-glow 0.9s ease-in-out infinite;
|
|
@@ -7656,8 +8203,13 @@
|
|
|
7656
8203
|
transition: background 0.18s;
|
|
7657
8204
|
}
|
|
7658
8205
|
.rt-seat-thinking::before {
|
|
8206
|
+
/* Thinking glow tracks the same primary --lime as the bubble
|
|
8207
|
+
above (see `.rt-bubble.is-thinking`). Dimmer alpha than the
|
|
8208
|
+
speaking glow (35% vs 55%) is the visual "warming up" cue
|
|
8209
|
+
paired with the dashed bubble border + slower dot rhythm —
|
|
8210
|
+
all theme-aware. */
|
|
7659
8211
|
background: radial-gradient(ellipse at center,
|
|
7660
|
-
|
|
8212
|
+
color-mix(in srgb, var(--lime) 35%, transparent) 0%,
|
|
7661
8213
|
transparent 70%);
|
|
7662
8214
|
animation-duration: 1.4s;
|
|
7663
8215
|
}
|
|
@@ -7706,7 +8258,11 @@
|
|
|
7706
8258
|
font-weight: 700;
|
|
7707
8259
|
letter-spacing: 0.06em;
|
|
7708
8260
|
text-transform: uppercase;
|
|
7709
|
-
|
|
8261
|
+
/* Hardcoded light name text · plate background is fixed dark
|
|
8262
|
+
regardless of theme (visibility over the stage floor). On
|
|
8263
|
+
light themes (pinterest / atrium) var(--text-soft) is mid-
|
|
8264
|
+
grey and the name disappears into the plate. */
|
|
8265
|
+
color: #D8D8DC;
|
|
7710
8266
|
white-space: nowrap;
|
|
7711
8267
|
text-align: center;
|
|
7712
8268
|
pointer-events: none;
|
|
@@ -7734,7 +8290,9 @@
|
|
|
7734
8290
|
font-size: 10px;
|
|
7735
8291
|
font-weight: 600;
|
|
7736
8292
|
letter-spacing: 0.04em;
|
|
7737
|
-
|
|
8293
|
+
/* Hardcoded light · same rationale as .rt-name above (dark
|
|
8294
|
+
plate is fixed regardless of theme). */
|
|
8295
|
+
color: rgba(216, 216, 220, 0.78);
|
|
7738
8296
|
margin-top: 3px;
|
|
7739
8297
|
}
|
|
7740
8298
|
/* Chair-seat name colour follows the room's tone via the
|
|
@@ -7797,9 +8355,20 @@
|
|
|
7797
8355
|
transform-origin: 50% 100%;
|
|
7798
8356
|
transition: border-color 0.18s, color 0.18s;
|
|
7799
8357
|
}
|
|
8358
|
+
/* Thinking variant · same theme primary as speaking
|
|
8359
|
+
(`var(--lime)`), differentiated by softer opacity + slower
|
|
8360
|
+
dot rhythm (set further down). Previously used `var(--amber)`
|
|
8361
|
+
for border/text — but amber is a separate accent (Pinterest =
|
|
8362
|
+
orange, Nintendo = coin gold, etc.) that doesn't match the
|
|
8363
|
+
primary theme colour, so thinking bubbles looked "off-brand"
|
|
8364
|
+
in light themes. Tying both states to --lime keeps the seat
|
|
8365
|
+
indicators on-theme; the visual state read still works
|
|
8366
|
+
because the dimmer opacity + slower dots + status word
|
|
8367
|
+
"thinking" carry the "warming up" cue. */
|
|
7800
8368
|
.rt-bubble.is-thinking {
|
|
7801
|
-
border-color: var(--
|
|
7802
|
-
color: var(--
|
|
8369
|
+
border-color: var(--lime);
|
|
8370
|
+
color: var(--lime);
|
|
8371
|
+
opacity: 0.78;
|
|
7803
8372
|
}
|
|
7804
8373
|
.rt-bubble::after {
|
|
7805
8374
|
content: "";
|
|
@@ -7815,7 +8384,10 @@
|
|
|
7815
8384
|
transition: border-top-color 0.18s;
|
|
7816
8385
|
}
|
|
7817
8386
|
.rt-bubble.is-thinking::after {
|
|
7818
|
-
|
|
8387
|
+
/* Tail tracks the bubble's themed primary too · see the
|
|
8388
|
+
.rt-bubble.is-thinking rule above for why thinking switched
|
|
8389
|
+
from --amber to --lime. */
|
|
8390
|
+
border-top-color: var(--lime);
|
|
7819
8391
|
}
|
|
7820
8392
|
/* Speaker name (primary) + status (secondary) inside the bubble.
|
|
7821
8393
|
Both lines centred · monospace sticks to the kicker register
|
|
@@ -7854,7 +8426,10 @@
|
|
|
7854
8426
|
transition: background 0.18s;
|
|
7855
8427
|
}
|
|
7856
8428
|
.rt-bubble.is-thinking .rt-bubble-dots i {
|
|
7857
|
-
|
|
8429
|
+
/* Dots track the bubble's themed primary too. The slower
|
|
8430
|
+
animation (1.4s vs the speaking 1s) is the kinetic state
|
|
8431
|
+
cue alongside the dashed border + dimmed opacity. */
|
|
8432
|
+
background: var(--lime);
|
|
7858
8433
|
animation-duration: 1.4s;
|
|
7859
8434
|
}
|
|
7860
8435
|
.rt-bubble-dots i:nth-child(2) { animation-delay: 0.15s; }
|
|
@@ -8000,6 +8575,94 @@
|
|
|
8000
8575
|
}
|
|
8001
8576
|
.rt-bubble-user-close:hover { color: var(--lime); }
|
|
8002
8577
|
|
|
8578
|
+
/* ─── Chair clarify bubble · prose question pinned above the chair
|
|
8579
|
+
avatar in voice-mode round-1 ───────────────────────────────────
|
|
8580
|
+
When the chair asks a clarifying question (meta.kind === "clarify")
|
|
8581
|
+
the user sees the question text in a speech bubble over the chair
|
|
8582
|
+
seat with a 10s border countdown — same conic-gradient mechanic
|
|
8583
|
+
as the user's bubble (see `.rt-bubble-user`). On timeout (or `×`
|
|
8584
|
+
click) the bubble auto-dismisses. The user-bubble's lime palette
|
|
8585
|
+
is reused intentionally: same countdown grammar, same speech-
|
|
8586
|
+
bubble register, only the anchor seat differs.
|
|
8587
|
+
|
|
8588
|
+
The chair seat sits at the BOTTOM of the stage, so the bubble
|
|
8589
|
+
grows upward over the table — which is fine visually because the
|
|
8590
|
+
bubble has its own `panel-3` interior and z-index: 5 keeps it
|
|
8591
|
+
above table props. Multi-line questions stay legible at any
|
|
8592
|
+
reasonable length. */
|
|
8593
|
+
.rt-bubble-chair-clarify {
|
|
8594
|
+
display: flex;
|
|
8595
|
+
align-items: flex-start;
|
|
8596
|
+
gap: 6px;
|
|
8597
|
+
width: max-content;
|
|
8598
|
+
max-width: 240px;
|
|
8599
|
+
pointer-events: auto;
|
|
8600
|
+
white-space: normal;
|
|
8601
|
+
padding: 5px 9px;
|
|
8602
|
+
text-transform: none;
|
|
8603
|
+
letter-spacing: 0;
|
|
8604
|
+
font-size: 11px;
|
|
8605
|
+
font-weight: 500;
|
|
8606
|
+
color: var(--text);
|
|
8607
|
+
animation: none;
|
|
8608
|
+
transform: translateX(-50%);
|
|
8609
|
+
top: auto;
|
|
8610
|
+
bottom: calc(100% + 4px);
|
|
8611
|
+
border-width: 2px;
|
|
8612
|
+
border-color: transparent;
|
|
8613
|
+
--rt-bubble-chair-progress: 0;
|
|
8614
|
+
background:
|
|
8615
|
+
linear-gradient(var(--panel-3), var(--panel-3)) padding-box,
|
|
8616
|
+
conic-gradient(
|
|
8617
|
+
from -90deg,
|
|
8618
|
+
var(--lime) 0,
|
|
8619
|
+
var(--lime) calc(var(--rt-bubble-chair-progress) * 360deg),
|
|
8620
|
+
var(--lime-dim, #2D5532) 0
|
|
8621
|
+
) border-box;
|
|
8622
|
+
}
|
|
8623
|
+
.rt-bubble-chair-clarify-text {
|
|
8624
|
+
min-width: 0;
|
|
8625
|
+
color: var(--text);
|
|
8626
|
+
line-height: 1.4;
|
|
8627
|
+
word-break: break-word;
|
|
8628
|
+
overflow-wrap: anywhere;
|
|
8629
|
+
}
|
|
8630
|
+
/* Same heftier downward tail as the user bubble · keeps the speech
|
|
8631
|
+
bubble visually anchored to the seat below at the stage's scale. */
|
|
8632
|
+
.rt-bubble-chair-clarify::after {
|
|
8633
|
+
border-left-width: 7px;
|
|
8634
|
+
border-right-width: 7px;
|
|
8635
|
+
border-top-width: 7px;
|
|
8636
|
+
border-top-color: var(--lime);
|
|
8637
|
+
bottom: -7px;
|
|
8638
|
+
}
|
|
8639
|
+
.rt-bubble-chair-clarify::before {
|
|
8640
|
+
content: "";
|
|
8641
|
+
position: absolute;
|
|
8642
|
+
bottom: -8px;
|
|
8643
|
+
left: 50%;
|
|
8644
|
+
transform: translateX(-50%);
|
|
8645
|
+
width: 0;
|
|
8646
|
+
height: 0;
|
|
8647
|
+
border-left: 8px solid transparent;
|
|
8648
|
+
border-right: 8px solid transparent;
|
|
8649
|
+
border-top: 8px solid var(--lime-dim, #2D5532);
|
|
8650
|
+
pointer-events: none;
|
|
8651
|
+
}
|
|
8652
|
+
.rt-bubble-chair-clarify-close {
|
|
8653
|
+
appearance: none;
|
|
8654
|
+
background: none;
|
|
8655
|
+
border: 0;
|
|
8656
|
+
color: var(--text-faint);
|
|
8657
|
+
cursor: pointer;
|
|
8658
|
+
font-size: 11px;
|
|
8659
|
+
line-height: 1;
|
|
8660
|
+
padding: 2px 4px;
|
|
8661
|
+
margin-top: -1px;
|
|
8662
|
+
transition: color 0.12s;
|
|
8663
|
+
}
|
|
8664
|
+
.rt-bubble-chair-clarify-close:hover { color: var(--lime); }
|
|
8665
|
+
|
|
8003
8666
|
/* Wait-marker · small flat pixel pill on the user seat shown
|
|
8004
8667
|
ONLY when the user has picked "wait — flush after current
|
|
8005
8668
|
speaker finishes" in the interrupt-or-queue modal. Slow
|
|
@@ -8020,10 +8683,16 @@
|
|
|
8020
8683
|
font-weight: 700;
|
|
8021
8684
|
letter-spacing: 0.18em;
|
|
8022
8685
|
text-transform: uppercase;
|
|
8023
|
-
|
|
8686
|
+
/* Themed primary · matches the speech bubble border family
|
|
8687
|
+
(speaking/thinking/wait all read off the same --lime so the
|
|
8688
|
+
seat indicators stay on-brand across themes). Dashed border
|
|
8689
|
+
+ blink animation differentiates "queued, holding" from the
|
|
8690
|
+
solid speaking border. Was --amber (Pinterest = orange,
|
|
8691
|
+
Nintendo = coin gold) which clashed with the primary theme. */
|
|
8692
|
+
color: var(--lime);
|
|
8024
8693
|
padding: 3px 6px;
|
|
8025
8694
|
background: var(--panel-3);
|
|
8026
|
-
border: 1px
|
|
8695
|
+
border: 1px dashed var(--lime);
|
|
8027
8696
|
white-space: nowrap;
|
|
8028
8697
|
animation: rt-seat-wait-blink 1.6s steps(1) infinite;
|
|
8029
8698
|
}
|
|
@@ -8242,7 +8911,13 @@
|
|
|
8242
8911
|
font-family: var(--font-human);
|
|
8243
8912
|
font-size: 14px;
|
|
8244
8913
|
line-height: 1.5;
|
|
8245
|
-
|
|
8914
|
+
/* Hardcoded light caption text · the subtitle panel uses a
|
|
8915
|
+
fixed near-black background regardless of theme (cinema-
|
|
8916
|
+
caption aesthetic for legibility over a busy stage), so the
|
|
8917
|
+
body text can't follow var(--text). On light themes
|
|
8918
|
+
(pinterest / atrium / etc.) var(--text) is near-black and
|
|
8919
|
+
collides with the panel — black-on-black caption. */
|
|
8920
|
+
color: #F4F4F6;
|
|
8246
8921
|
word-break: break-word;
|
|
8247
8922
|
/* The renderer slices `text` to a ~140-char window ending at
|
|
8248
8923
|
the current TTS cursor (`audio.currentTime / duration`), so
|
|
@@ -8440,7 +9115,9 @@
|
|
|
8440
9115
|
font-weight: 700;
|
|
8441
9116
|
letter-spacing: 0.18em;
|
|
8442
9117
|
text-transform: uppercase;
|
|
8443
|
-
|
|
9118
|
+
/* Hardcoded light · rate-btn label over the fixed dark HUD
|
|
9119
|
+
glass; var(--text-soft) is mid-grey in light themes. */
|
|
9120
|
+
color: rgba(216, 216, 220, 0.85);
|
|
8444
9121
|
cursor: pointer;
|
|
8445
9122
|
pointer-events: auto;
|
|
8446
9123
|
transition: background 0.08s, color 0.08s;
|
|
@@ -8487,7 +9164,10 @@
|
|
|
8487
9164
|
padding: 5px 10px;
|
|
8488
9165
|
font-size: 9px;
|
|
8489
9166
|
letter-spacing: 0.04em;
|
|
8490
|
-
|
|
9167
|
+
/* Hardcoded light · the HUD body sits on a fixed dark frosted-
|
|
9168
|
+
glass background, so log entries can't follow var(--text-soft)
|
|
9169
|
+
which is dark grey in light themes (pinterest / atrium). */
|
|
9170
|
+
color: rgba(216, 216, 220, 0.78);
|
|
8491
9171
|
border-top: 1px solid var(--line);
|
|
8492
9172
|
/* `steps(4)` so the entry materialises in 4 discrete frames —
|
|
8493
9173
|
reads as a pixel-game tile flip, not a smooth fade. */
|
|
@@ -8512,7 +9192,9 @@
|
|
|
8512
9192
|
}
|
|
8513
9193
|
.rt-hud-log-text em {
|
|
8514
9194
|
font-style: italic;
|
|
8515
|
-
|
|
9195
|
+
/* Hardcoded light · emphasis word (speaker name) over the
|
|
9196
|
+
fixed dark HUD glass; var(--text) is dark in light themes. */
|
|
9197
|
+
color: #F4F4F6;
|
|
8516
9198
|
font-weight: 700;
|
|
8517
9199
|
}
|
|
8518
9200
|
.rt-hud-log-entry.rt-hud-log-add .rt-hud-log-glyph { color: var(--lime, #6FB572); }
|
|
@@ -9991,7 +10673,13 @@
|
|
|
9991
10673
|
overflow-y: auto;
|
|
9992
10674
|
}
|
|
9993
10675
|
.chat.chat--composer.chat--composer-overflow .cmp {
|
|
9994
|
-
|
|
10676
|
+
/* Overflow mode · the starters tray (now augmented with
|
|
10677
|
+
topic recommendations + the "+ N more" button) can push
|
|
10678
|
+
total content past one viewport, at which point the
|
|
10679
|
+
composer can't stay centred. Pin the hero a fixed 120px
|
|
10680
|
+
from the top so it sits comfortably above the fold and
|
|
10681
|
+
the tray scrolls underneath. */
|
|
10682
|
+
padding-top: 120px;
|
|
9995
10683
|
}
|
|
9996
10684
|
.cmp-hero {
|
|
9997
10685
|
text-align: center;
|
|
@@ -10570,6 +11258,126 @@
|
|
|
10570
11258
|
transform: translateX(3px);
|
|
10571
11259
|
}
|
|
10572
11260
|
|
|
11261
|
+
/* ─── Topic recommendations · home composer "or try a starter"
|
|
11262
|
+
tray.
|
|
11263
|
+
· `.cmp-recs-trigger-card` · disguised as the FIRST row
|
|
11264
|
+
in the starters grid. Click → SSE-driven loading +
|
|
11265
|
+
animated dots happen INSIDE the same card (no separate
|
|
11266
|
+
progress strip). Dashed lime-dim bottom rule + ✦ glyph
|
|
11267
|
+
distinguish it from regular starters at a glance.
|
|
11268
|
+
· `.cmp-rec` · each AI-generated topic. Tag is the
|
|
11269
|
+
synthesiser's category (e.g. "strategy", "product").
|
|
11270
|
+
Tray shows exactly 6 cards — every generation wipes
|
|
11271
|
+
the previous batch, no pagination surface.
|
|
11272
|
+
Theme-token only · no hardcoded colors. ─── */
|
|
11273
|
+
.cmp-recs-trigger-card {
|
|
11274
|
+
position: relative;
|
|
11275
|
+
/* Dashed lime-dim bottom rule reads as "this row is the
|
|
11276
|
+
generator" before any click. Override .cmp-starter's
|
|
11277
|
+
solid var(--line) baseline; the progress bar lives on
|
|
11278
|
+
this same edge during the busy state. */
|
|
11279
|
+
border-bottom-style: dashed !important;
|
|
11280
|
+
border-bottom-color: var(--lime-dim) !important;
|
|
11281
|
+
}
|
|
11282
|
+
.cmp-recs-trigger-card .cmp-starter-tag {
|
|
11283
|
+
color: var(--lime);
|
|
11284
|
+
}
|
|
11285
|
+
.cmp-recs-trigger-card .cmp-starter-arrow {
|
|
11286
|
+
color: var(--lime);
|
|
11287
|
+
font-weight: 700;
|
|
11288
|
+
transition: transform 0.18s ease;
|
|
11289
|
+
}
|
|
11290
|
+
.cmp-recs-trigger-card:hover:not(.is-busy) .cmp-starter-arrow {
|
|
11291
|
+
transform: rotate(90deg);
|
|
11292
|
+
}
|
|
11293
|
+
.cmp-recs-trigger-card.is-busy {
|
|
11294
|
+
cursor: progress;
|
|
11295
|
+
}
|
|
11296
|
+
.cmp-recs-trigger-card.is-busy .cmp-starter-text {
|
|
11297
|
+
color: var(--text-soft);
|
|
11298
|
+
}
|
|
11299
|
+
/* Progress bar · sits flush along the card's dashed bottom
|
|
11300
|
+
edge. Lime fill grows left-to-right as the pipeline ticks. */
|
|
11301
|
+
.cmp-recs-trigger-bar {
|
|
11302
|
+
position: absolute;
|
|
11303
|
+
left: 0;
|
|
11304
|
+
right: 0;
|
|
11305
|
+
bottom: -1px;
|
|
11306
|
+
height: 2px;
|
|
11307
|
+
background: transparent;
|
|
11308
|
+
pointer-events: none;
|
|
11309
|
+
overflow: hidden;
|
|
11310
|
+
}
|
|
11311
|
+
.cmp-recs-trigger-fill {
|
|
11312
|
+
height: 100%;
|
|
11313
|
+
background: var(--lime);
|
|
11314
|
+
width: 0;
|
|
11315
|
+
transition: width 0.4s ease-out;
|
|
11316
|
+
}
|
|
11317
|
+
/* Three-dot loading glyph · matches the round-table
|
|
11318
|
+
speech-bubble dots' rhythm; lime accent, compact, sits
|
|
11319
|
+
inline next to the phase-detail text inside the busy
|
|
11320
|
+
card so the user reads "<dots> scanning 3/10 keywords". */
|
|
11321
|
+
.cmp-recs-trigger-dots {
|
|
11322
|
+
display: inline-flex;
|
|
11323
|
+
align-items: center;
|
|
11324
|
+
gap: 3px;
|
|
11325
|
+
margin-right: 6px;
|
|
11326
|
+
vertical-align: middle;
|
|
11327
|
+
}
|
|
11328
|
+
.cmp-recs-trigger-dots i {
|
|
11329
|
+
width: 4px;
|
|
11330
|
+
height: 4px;
|
|
11331
|
+
background: var(--lime);
|
|
11332
|
+
border-radius: 50%;
|
|
11333
|
+
display: inline-block;
|
|
11334
|
+
animation: cmp-trec-dot 1s ease-in-out infinite;
|
|
11335
|
+
}
|
|
11336
|
+
.cmp-recs-trigger-dots i:nth-child(2) { animation-delay: 0.15s; }
|
|
11337
|
+
.cmp-recs-trigger-dots i:nth-child(3) { animation-delay: 0.30s; }
|
|
11338
|
+
@keyframes cmp-trec-dot {
|
|
11339
|
+
0%, 80%, 100% { opacity: 0.25; transform: scale(0.7); }
|
|
11340
|
+
40% { opacity: 1; transform: scale(1); }
|
|
11341
|
+
}
|
|
11342
|
+
/* Topic-rec card · extends .cmp-starter. The tag is the
|
|
11343
|
+
synthesiser-produced category; the data-source attribute
|
|
11344
|
+
drives a subtle colour cue (lime for web-grounded recs,
|
|
11345
|
+
text-faint for memory-only) without taking real estate
|
|
11346
|
+
away from the actual tag text. */
|
|
11347
|
+
.cmp-rec {
|
|
11348
|
+
/* `.cmp-starter` base is `auto 1fr auto`. The rec card adds
|
|
11349
|
+
a hint row spanning the middle column so the middle column
|
|
11350
|
+
stacks subject / hint. `align-items: start` so tag + arrow
|
|
11351
|
+
anchor to the subject line, not the centre of the taller
|
|
11352
|
+
block. */
|
|
11353
|
+
align-items: start;
|
|
11354
|
+
padding-top: 12px;
|
|
11355
|
+
padding-bottom: 12px;
|
|
11356
|
+
}
|
|
11357
|
+
.cmp-rec[data-source="web"] .cmp-starter-tag {
|
|
11358
|
+
color: var(--lime);
|
|
11359
|
+
}
|
|
11360
|
+
.cmp-rec[data-source="memory"] .cmp-starter-tag {
|
|
11361
|
+
color: var(--text-faint);
|
|
11362
|
+
}
|
|
11363
|
+
/* Subtitle · synthesiser's "why this fits you" rationale.
|
|
11364
|
+
Sits under the subject in the middle column, italic +
|
|
11365
|
+
text-faint so it reads as caption-tier without competing
|
|
11366
|
+
with the subject line above. ALSO travels into the room
|
|
11367
|
+
as hidden seed context (see `applyTopicRec`). */
|
|
11368
|
+
.cmp-rec-hint {
|
|
11369
|
+
grid-column: 2;
|
|
11370
|
+
margin-top: 4px;
|
|
11371
|
+
font-family: var(--font-human);
|
|
11372
|
+
font-size: 11.5px;
|
|
11373
|
+
line-height: 1.4;
|
|
11374
|
+
color: var(--text-faint);
|
|
11375
|
+
display: -webkit-box;
|
|
11376
|
+
-webkit-line-clamp: 2;
|
|
11377
|
+
-webkit-box-orient: vertical;
|
|
11378
|
+
overflow: hidden;
|
|
11379
|
+
font-style: italic;
|
|
11380
|
+
}
|
|
10573
11381
|
/* ─── New-agent composer · variant of the new-room composer.
|
|
10574
11382
|
Reuses .cmp / .cmp-* classes for the hero + input frame; adds
|
|
10575
11383
|
ag-cmp-* for agent-specific bits and ag-prev-* for the editable
|