fraim-hub 2.0.338 → 2.0.340
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/registry/scripts/learning/completion-state.js +153 -0
- package/dist/src/ai-hub/desktop-main.js +46 -0
- package/dist/src/ai-hub/hosts.js +18 -0
- package/dist/src/ai-hub/server.js +67 -69
- package/dist/src/core/handoff-contracts.js +617 -0
- package/dist/src/local-mcp-server/artifact-retention-cleanup.js +36 -9
- package/dist/src/local-mcp-server/learning-context-builder.js +145 -27
- package/dist/src/local-mcp-server/learning-usage-events.js +267 -0
- package/dist/src/local-mcp-server/learning-usage-projection.js +25 -21
- package/dist/src/local-mcp-server/learning-usage-store.js +626 -88
- package/package.json +5 -2
- package/public/ai-hub/review.css +378 -0
- package/public/ai-hub/script.js +763 -33
- package/public/ai-hub/styles.css +53 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fraim-hub",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.340",
|
|
4
4
|
"description": "FRAIM Hub local companion package.",
|
|
5
5
|
"author": "Sid Mathur <sid.mathur@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/mathursrus/FRAIM#readme",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"dist/registry/scripts/learning/learning-domains.json",
|
|
20
20
|
"dist/registry/scripts/learning/entry-format.js",
|
|
21
|
+
"dist/registry/scripts/learning/completion-state.js",
|
|
21
22
|
"dist/src/ai-hub/",
|
|
22
23
|
"dist/src/api/admin/payments.js",
|
|
23
24
|
"dist/src/api/admin/sales-leads.js",
|
|
@@ -72,6 +73,7 @@
|
|
|
72
73
|
"dist/src/config/stripe.js",
|
|
73
74
|
"dist/src/core/brand-store.js",
|
|
74
75
|
"dist/src/core/capability-pack.js",
|
|
76
|
+
"dist/src/core/handoff-contracts.js",
|
|
75
77
|
"dist/src/core/quality-evidence.js",
|
|
76
78
|
"dist/src/core/job-visualization.js",
|
|
77
79
|
"dist/src/core/resolve-phase-edge.js",
|
|
@@ -93,6 +95,7 @@
|
|
|
93
95
|
"dist/src/local-mcp-server/agent-token-prices.js",
|
|
94
96
|
"dist/src/local-mcp-server/artifact-retention-cleanup.js",
|
|
95
97
|
"dist/src/local-mcp-server/learning-context-builder.js",
|
|
98
|
+
"dist/src/local-mcp-server/learning-usage-events.js",
|
|
96
99
|
"dist/src/local-mcp-server/learning-usage-projection.js",
|
|
97
100
|
"dist/src/local-mcp-server/learning-usage-store.js",
|
|
98
101
|
"dist/src/middleware/rate-limit.js",
|
|
@@ -225,7 +228,7 @@
|
|
|
225
228
|
"electron-updater": "^6.8.9",
|
|
226
229
|
"express": "^5.2.1",
|
|
227
230
|
"extract-zip": "^2.0.1",
|
|
228
|
-
"fraim": "2.0.
|
|
231
|
+
"fraim": "2.0.340",
|
|
229
232
|
"mongodb": "^7.0.0",
|
|
230
233
|
"node-cron": "4.2.1",
|
|
231
234
|
"node-edge-tts": "^1.2.10",
|
package/public/ai-hub/review.css
CHANGED
|
@@ -634,3 +634,381 @@
|
|
|
634
634
|
|
|
635
635
|
.review-turn .review-actions { border: 0; margin: 0; padding: 0; }
|
|
636
636
|
.review-turn .rb-handoff { flex-basis: 100%; }
|
|
637
|
+
|
|
638
|
+
/* ===========================================================================
|
|
639
|
+
Issue #1755 - the learnings library.
|
|
640
|
+
The corpus was a flat list of full-text cards with no summary, no filter and
|
|
641
|
+
no sign of whether an entry has ever worked. These rules add the stats row,
|
|
642
|
+
the filter toolbar, the domain grouping, and the per-card strength + usage
|
|
643
|
+
footer. Every colour comes from the existing token set.
|
|
644
|
+
=========================================================================== */
|
|
645
|
+
|
|
646
|
+
/* Stats row */
|
|
647
|
+
.ll-stats {
|
|
648
|
+
display: flex;
|
|
649
|
+
align-items: center;
|
|
650
|
+
flex-wrap: wrap;
|
|
651
|
+
gap: 6px 14px;
|
|
652
|
+
padding: 2px 2px 12px;
|
|
653
|
+
}
|
|
654
|
+
.ll-stats .ll-stat {
|
|
655
|
+
display: inline-flex;
|
|
656
|
+
align-items: baseline;
|
|
657
|
+
gap: 5px;
|
|
658
|
+
font-size: 11.5px;
|
|
659
|
+
color: var(--muted);
|
|
660
|
+
white-space: nowrap;
|
|
661
|
+
}
|
|
662
|
+
.ll-stats .ll-stat b { font-size: 14px; font-weight: 700; color: var(--text); }
|
|
663
|
+
.ll-stats .ll-total b { font-size: 16px; }
|
|
664
|
+
.ll-stats .ll-stat::before {
|
|
665
|
+
content: '';
|
|
666
|
+
width: 7px; height: 7px; border-radius: 50%;
|
|
667
|
+
background: var(--muted);
|
|
668
|
+
align-self: center;
|
|
669
|
+
}
|
|
670
|
+
.ll-stats .ll-total::before { display: none; }
|
|
671
|
+
.ll-stats .s-strong::before { background: var(--done); }
|
|
672
|
+
.ll-stats .s-wouldfire::before { background: var(--warn); }
|
|
673
|
+
.ll-stats .s-unresolved::before { background: var(--strength-unresolved); }
|
|
674
|
+
.ll-stats .s-weak::before { background: var(--line); box-shadow: inset 0 0 0 1px var(--muted); }
|
|
675
|
+
.ll-stats .s-dead::before { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
|
|
676
|
+
|
|
677
|
+
/* Filter + sort toolbar */
|
|
678
|
+
.ll-tools {
|
|
679
|
+
display: flex;
|
|
680
|
+
align-items: center;
|
|
681
|
+
justify-content: space-between;
|
|
682
|
+
flex-wrap: wrap;
|
|
683
|
+
gap: 8px;
|
|
684
|
+
padding-bottom: 12px;
|
|
685
|
+
}
|
|
686
|
+
.ll-tools .ll-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
687
|
+
.ll-tools .ll-tab {
|
|
688
|
+
font: inherit;
|
|
689
|
+
font-size: 11.5px;
|
|
690
|
+
font-weight: 600;
|
|
691
|
+
color: var(--muted);
|
|
692
|
+
background: var(--surface);
|
|
693
|
+
border: 1px solid var(--line);
|
|
694
|
+
border-radius: 999px;
|
|
695
|
+
padding: 4px 11px;
|
|
696
|
+
cursor: pointer;
|
|
697
|
+
transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
|
|
698
|
+
}
|
|
699
|
+
.ll-tools .ll-tab:hover { color: var(--text); border-color: var(--muted); }
|
|
700
|
+
.ll-tools .ll-tab.active {
|
|
701
|
+
color: var(--accent-strong);
|
|
702
|
+
background: var(--accent-soft);
|
|
703
|
+
border-color: var(--accent);
|
|
704
|
+
}
|
|
705
|
+
.ll-tools .ll-selects { display: flex; gap: 8px; }
|
|
706
|
+
.ll-tools .ll-sel {
|
|
707
|
+
font: inherit;
|
|
708
|
+
font-size: 11.5px;
|
|
709
|
+
color: var(--text);
|
|
710
|
+
background: var(--surface);
|
|
711
|
+
border: 1px solid var(--line);
|
|
712
|
+
border-radius: 8px;
|
|
713
|
+
padding: 4px 8px;
|
|
714
|
+
cursor: pointer;
|
|
715
|
+
max-width: 190px;
|
|
716
|
+
}
|
|
717
|
+
.ll-tools .ll-sel:focus { outline: none; border-color: var(--accent); }
|
|
718
|
+
|
|
719
|
+
/* Domain group header */
|
|
720
|
+
.ll-group-head {
|
|
721
|
+
display: flex;
|
|
722
|
+
align-items: baseline;
|
|
723
|
+
gap: 8px;
|
|
724
|
+
margin-top: 8px;
|
|
725
|
+
padding-bottom: 5px;
|
|
726
|
+
border-bottom: 1px solid var(--line);
|
|
727
|
+
}
|
|
728
|
+
.learn-list > .ll-group-head:first-child { margin-top: 0; }
|
|
729
|
+
.ll-group-head .llg-name {
|
|
730
|
+
font-size: 10.5px;
|
|
731
|
+
font-weight: 700;
|
|
732
|
+
letter-spacing: 0.06em;
|
|
733
|
+
text-transform: uppercase;
|
|
734
|
+
color: var(--text);
|
|
735
|
+
}
|
|
736
|
+
.ll-group-head .llg-reach { font-size: 11px; color: var(--muted); }
|
|
737
|
+
.ll-group-head .llg-count {
|
|
738
|
+
margin-left: auto;
|
|
739
|
+
font-size: 11px;
|
|
740
|
+
font-weight: 600;
|
|
741
|
+
color: var(--muted);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/* No-match state */
|
|
745
|
+
.ll-nomatch { font-size: 13px; color: var(--muted); padding: 18px 2px 4px; }
|
|
746
|
+
|
|
747
|
+
/* Card: domain, strength and score badges */
|
|
748
|
+
.learn-prop .lp-domain {
|
|
749
|
+
font-size: 10px;
|
|
750
|
+
font-weight: 700;
|
|
751
|
+
padding: 2px 8px;
|
|
752
|
+
border-radius: 6px;
|
|
753
|
+
letter-spacing: 0.03em;
|
|
754
|
+
flex-shrink: 0;
|
|
755
|
+
background: var(--bg);
|
|
756
|
+
color: var(--muted);
|
|
757
|
+
box-shadow: inset 0 0 0 1px var(--line);
|
|
758
|
+
}
|
|
759
|
+
.learn-prop .lp-domain.dom-global { color: var(--muted); }
|
|
760
|
+
.learn-prop .lp-domain.dom-c0 { color: var(--domain-slot-0); box-shadow: inset 0 0 0 1px var(--domain-slot-0-ring); }
|
|
761
|
+
.learn-prop .lp-domain.dom-c1 { color: var(--domain-slot-1); box-shadow: inset 0 0 0 1px var(--domain-slot-1-ring); }
|
|
762
|
+
.learn-prop .lp-domain.dom-c2 { color: var(--domain-slot-2); box-shadow: inset 0 0 0 1px var(--domain-slot-2-ring); }
|
|
763
|
+
.learn-prop .lp-domain.dom-c3 { color: var(--domain-slot-3); box-shadow: inset 0 0 0 1px var(--domain-slot-3-ring); }
|
|
764
|
+
.learn-prop .lp-domain.dom-c4 { color: var(--domain-slot-4); box-shadow: inset 0 0 0 1px var(--domain-slot-4-ring); }
|
|
765
|
+
.learn-prop .lp-domain.dom-c5 { color: var(--domain-slot-5); box-shadow: inset 0 0 0 1px var(--domain-slot-5-ring); }
|
|
766
|
+
|
|
767
|
+
.learn-prop .lp-strength {
|
|
768
|
+
display: inline-flex;
|
|
769
|
+
align-items: center;
|
|
770
|
+
gap: 5px;
|
|
771
|
+
font-size: 10.5px;
|
|
772
|
+
font-weight: 700;
|
|
773
|
+
padding: 2px 8px 2px 6px;
|
|
774
|
+
border-radius: 6px;
|
|
775
|
+
flex-shrink: 0;
|
|
776
|
+
background: var(--bg);
|
|
777
|
+
color: var(--muted);
|
|
778
|
+
}
|
|
779
|
+
.learn-prop .lp-strength .lp-dot {
|
|
780
|
+
width: 6px; height: 6px; border-radius: 50%; background: currentColor;
|
|
781
|
+
flex-shrink: 0;
|
|
782
|
+
}
|
|
783
|
+
.learn-prop .lp-strength.s-strong { color: var(--done); }
|
|
784
|
+
.learn-prop .lp-strength.s-wouldfire { color: var(--warn); }
|
|
785
|
+
.learn-prop .lp-strength.s-unresolved { color: var(--strength-unresolved); }
|
|
786
|
+
.learn-prop .lp-strength.s-weak { color: var(--muted); }
|
|
787
|
+
.learn-prop .lp-strength.s-dead { color: var(--muted); opacity: 0.65; }
|
|
788
|
+
.learn-prop .lp-strength.s-dead .lp-dot { background: transparent; box-shadow: inset 0 0 0 1px currentColor; }
|
|
789
|
+
|
|
790
|
+
.learn-prop .lp-score {
|
|
791
|
+
font-size: 11px;
|
|
792
|
+
font-weight: 700;
|
|
793
|
+
font-variant-numeric: tabular-nums;
|
|
794
|
+
color: var(--muted);
|
|
795
|
+
background: var(--bg);
|
|
796
|
+
border-radius: 6px;
|
|
797
|
+
padding: 2px 7px;
|
|
798
|
+
flex-shrink: 0;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/* Card body clamp */
|
|
802
|
+
.learn-prop .lp-body.lp-clamped {
|
|
803
|
+
display: -webkit-box;
|
|
804
|
+
-webkit-line-clamp: 3;
|
|
805
|
+
line-clamp: 3;
|
|
806
|
+
-webkit-box-orient: vertical;
|
|
807
|
+
overflow: hidden;
|
|
808
|
+
}
|
|
809
|
+
.learn-prop .lp-more {
|
|
810
|
+
align-self: flex-start;
|
|
811
|
+
font: inherit;
|
|
812
|
+
font-size: 11.5px;
|
|
813
|
+
font-weight: 600;
|
|
814
|
+
color: var(--accent);
|
|
815
|
+
background: none;
|
|
816
|
+
border: none;
|
|
817
|
+
padding: 0;
|
|
818
|
+
margin-top: -2px;
|
|
819
|
+
cursor: pointer;
|
|
820
|
+
}
|
|
821
|
+
.learn-prop .lp-more:hover { color: var(--accent-strong); text-decoration: underline; }
|
|
822
|
+
|
|
823
|
+
/* Card usage footer */
|
|
824
|
+
.learn-prop .lp-stats {
|
|
825
|
+
display: flex;
|
|
826
|
+
align-items: center;
|
|
827
|
+
flex-wrap: wrap;
|
|
828
|
+
gap: 6px 12px;
|
|
829
|
+
margin-top: 2px;
|
|
830
|
+
padding-top: 9px;
|
|
831
|
+
border-top: 1px solid var(--line);
|
|
832
|
+
font-size: 11px;
|
|
833
|
+
color: var(--muted);
|
|
834
|
+
}
|
|
835
|
+
.learn-prop .lp-stats .lps-none { font-style: italic; }
|
|
836
|
+
.learn-prop .lp-bar {
|
|
837
|
+
display: flex;
|
|
838
|
+
width: 68px;
|
|
839
|
+
height: 4px;
|
|
840
|
+
border-radius: 999px;
|
|
841
|
+
overflow: hidden;
|
|
842
|
+
background: var(--line);
|
|
843
|
+
flex-shrink: 0;
|
|
844
|
+
}
|
|
845
|
+
.learn-prop .lp-bar i { display: block; height: 100%; }
|
|
846
|
+
.learn-prop .lp-bar .lb-applied { background: var(--done); }
|
|
847
|
+
.learn-prop .lp-bar .lb-prevented { background: var(--accent); }
|
|
848
|
+
.learn-prop .lp-bar .lb-ignored { background: var(--warn); }
|
|
849
|
+
.learn-prop .lp-stats .lps-counts { display: flex; flex-wrap: wrap; gap: 10px; }
|
|
850
|
+
.learn-prop .lp-stats .lps-c { display: inline-flex; align-items: baseline; gap: 4px; }
|
|
851
|
+
.learn-prop .lp-stats .lps-c b { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
|
|
852
|
+
.learn-prop .lp-stats .lps-last { margin-left: auto; white-space: nowrap; }
|
|
853
|
+
|
|
854
|
+
/* Domain select in the inline editor */
|
|
855
|
+
.learn-prop .lp-edit-domain {
|
|
856
|
+
font: inherit; font-size: 12px; padding: 6px 8px; border: 1px solid var(--line);
|
|
857
|
+
border-radius: 8px; background: var(--surface); color: var(--text);
|
|
858
|
+
}
|
|
859
|
+
.learn-prop .lp-edit-domain:focus { outline: none; border-color: var(--accent); }
|
|
860
|
+
|
|
861
|
+
/* Collapsed sections (below-threshold + archived). These had no rules at all,
|
|
862
|
+
so they rendered as an unstyled details block in the middle of a card list. */
|
|
863
|
+
.learn-dormant-section {
|
|
864
|
+
border: 1px dashed var(--line);
|
|
865
|
+
border-radius: 14px;
|
|
866
|
+
padding: 4px 12px;
|
|
867
|
+
background: transparent;
|
|
868
|
+
}
|
|
869
|
+
.learn-dormant-section > .learn-dormant-header {
|
|
870
|
+
font-size: 11.5px;
|
|
871
|
+
font-weight: 600;
|
|
872
|
+
color: var(--muted);
|
|
873
|
+
padding: 8px 2px;
|
|
874
|
+
cursor: pointer;
|
|
875
|
+
list-style: none;
|
|
876
|
+
}
|
|
877
|
+
.learn-dormant-section > .learn-dormant-header::-webkit-details-marker { display: none; }
|
|
878
|
+
.learn-dormant-section > .learn-dormant-header::before {
|
|
879
|
+
content: '\25B8';
|
|
880
|
+
display: inline-block;
|
|
881
|
+
width: 12px;
|
|
882
|
+
transition: transform 140ms ease;
|
|
883
|
+
}
|
|
884
|
+
.learn-dormant-section[open] > .learn-dormant-header::before { transform: rotate(90deg); }
|
|
885
|
+
.learn-dormant-section > .learn-prop {
|
|
886
|
+
margin-bottom: 10px;
|
|
887
|
+
background: var(--bg);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
/* Issue #1755: entries are authored as short labelled lines (Takeaway / Why this
|
|
892
|
+
matters / Example / What to do next). Collapsing them into one paragraph is
|
|
893
|
+
what made the readable ones read like the dense ones. */
|
|
894
|
+
.learn-prop .lp-body { white-space: pre-line; }
|
|
895
|
+
|
|
896
|
+
/* The provenance tail, revealed with the rest of the entry. */
|
|
897
|
+
.learn-prop .lp-prov {
|
|
898
|
+
white-space: pre-line;
|
|
899
|
+
font-size: 11.5px;
|
|
900
|
+
line-height: 1.55;
|
|
901
|
+
color: var(--muted);
|
|
902
|
+
border-left: 2px solid var(--line);
|
|
903
|
+
padding-left: 10px;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/* Issue #1755: the accordion body is a capped scroll region (.ctx-acc-body), so
|
|
907
|
+
the library's summary and controls pin to its top rather than scrolling out of
|
|
908
|
+
reach behind a hundred cards. */
|
|
909
|
+
.ll-head {
|
|
910
|
+
position: sticky;
|
|
911
|
+
top: -4px;
|
|
912
|
+
z-index: 2;
|
|
913
|
+
background: var(--ll-head-bg);
|
|
914
|
+
margin: -4px -2px 0;
|
|
915
|
+
padding: 6px 2px 0;
|
|
916
|
+
box-shadow: var(--ll-head-shadow);
|
|
917
|
+
}
|
|
918
|
+
.ll-head .ll-tools { padding-bottom: 10px; }
|
|
919
|
+
|
|
920
|
+
/* Issue #1755 R6: the proposal card's two zones. Configuration sits in a recessed
|
|
921
|
+
block so the controls that change what gets written read as settings, and the
|
|
922
|
+
decision sits below a hairline so it reads as the commit. */
|
|
923
|
+
.learn-prop .lp-config {
|
|
924
|
+
display: flex;
|
|
925
|
+
flex-direction: column;
|
|
926
|
+
gap: 8px;
|
|
927
|
+
background: var(--lp-recessed);
|
|
928
|
+
border-radius: 10px;
|
|
929
|
+
padding: 9px 11px 11px;
|
|
930
|
+
margin-top: 2px;
|
|
931
|
+
}
|
|
932
|
+
.learn-prop .lp-config .lp-config-head {
|
|
933
|
+
font-size: 10px;
|
|
934
|
+
font-weight: 700;
|
|
935
|
+
letter-spacing: 0.06em;
|
|
936
|
+
text-transform: uppercase;
|
|
937
|
+
color: var(--muted);
|
|
938
|
+
}
|
|
939
|
+
.learn-prop .lp-config .lp-actions { margin-top: 0; }
|
|
940
|
+
.learn-prop .lp-decide {
|
|
941
|
+
display: flex;
|
|
942
|
+
align-items: center;
|
|
943
|
+
flex-wrap: wrap;
|
|
944
|
+
gap: 10px;
|
|
945
|
+
margin-top: 2px;
|
|
946
|
+
padding-top: 10px;
|
|
947
|
+
border-top: 1px solid var(--line);
|
|
948
|
+
}
|
|
949
|
+
.learn-prop .lp-decide .lp-scope-note { margin-left: auto; text-align: right; }
|
|
950
|
+
.learn-prop .lp-decided-badge {
|
|
951
|
+
font-size: 10.5px;
|
|
952
|
+
font-weight: 700;
|
|
953
|
+
padding: 2px 9px;
|
|
954
|
+
border-radius: 999px;
|
|
955
|
+
letter-spacing: 0.02em;
|
|
956
|
+
}
|
|
957
|
+
/* Tinted with its own outcome colour rather than --accent-soft: an org brand
|
|
958
|
+
overrides --accent, and a purple-tinted pill around green text reads as two
|
|
959
|
+
unrelated signals. */
|
|
960
|
+
.learn-prop .lp-decided-badge.is-saved { background: var(--bg); color: var(--done); box-shadow: inset 0 0 0 1px currentColor; }
|
|
961
|
+
.learn-prop .lp-decided-badge.is-skipped { background: var(--bg); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line); }
|
|
962
|
+
|
|
963
|
+
/* Issue #1755: at a narrow panel width the head row's badges (domain, category,
|
|
964
|
+
priority, strength) plus the score chip outrun the row, and an unbreakable
|
|
965
|
+
title word pushes the card into horizontal overflow. Let the row wrap and let
|
|
966
|
+
a long title break, rather than letting the card scroll sideways. */
|
|
967
|
+
.learn-prop .lp-head { flex-wrap: wrap; row-gap: 6px; }
|
|
968
|
+
/* A 220px basis is the hinge: while that much room is left after the badges the
|
|
969
|
+
title stays on their line, and below it the title takes a full row of its own
|
|
970
|
+
instead of being squeezed into a four-word-wide column. */
|
|
971
|
+
.learn-prop .lp-head .lp-title { flex: 1 1 220px; overflow-wrap: break-word; }
|
|
972
|
+
|
|
973
|
+
/* Issue #1755: the row actions were display:none until hover, which takes them out
|
|
974
|
+
of the tab order entirely: a keyboard or screen-reader manager could not reach
|
|
975
|
+
Edit or Delete at all, and Edit is now also where an entry is re-scoped. Hide
|
|
976
|
+
them visually instead of structurally, and reveal on focus as well as hover.
|
|
977
|
+
Reserving their space also stops the title reflowing every time the pointer
|
|
978
|
+
crosses a card. */
|
|
979
|
+
.learn-prop .lp-act {
|
|
980
|
+
display: inline-flex;
|
|
981
|
+
opacity: 0;
|
|
982
|
+
transition: opacity 120ms ease;
|
|
983
|
+
}
|
|
984
|
+
.learn-prop:hover .lp-act,
|
|
985
|
+
.learn-prop:focus-within .lp-act,
|
|
986
|
+
.learn-prop .lp-act:focus-visible { opacity: 1; }
|
|
987
|
+
.learn-prop .lp-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
988
|
+
.ll-tools .ll-tab:focus-visible,
|
|
989
|
+
.ll-tools .ll-sel:focus-visible,
|
|
990
|
+
.learn-prop .lp-more:focus-visible {
|
|
991
|
+
outline: 2px solid var(--accent);
|
|
992
|
+
outline-offset: 2px;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
/* Issue #1755 R5: the sleep-on-learnings proposal set, rendered in the
|
|
996
|
+
conversation where the job wrote it. Full conversation width, because a
|
|
997
|
+
proposal carries a lesson body, a configuration zone and a decision. */
|
|
998
|
+
.learn-proposal-turn .bubble {
|
|
999
|
+
display: flex;
|
|
1000
|
+
flex-direction: column;
|
|
1001
|
+
gap: 10px;
|
|
1002
|
+
width: 100%;
|
|
1003
|
+
max-width: 100%;
|
|
1004
|
+
box-sizing: border-box;
|
|
1005
|
+
}
|
|
1006
|
+
.learn-proposal-turn .review-turn-label { margin-bottom: 0; }
|
|
1007
|
+
.learn-proposal-turn .learn-batch {
|
|
1008
|
+
background: var(--lp-raised);
|
|
1009
|
+
border: 1px solid var(--lp-raised-line);
|
|
1010
|
+
border-radius: 12px;
|
|
1011
|
+
padding: 9px 12px;
|
|
1012
|
+
}
|
|
1013
|
+
.learn-proposal-turn .learn-list { gap: 10px; }
|
|
1014
|
+
.learn-proposal-turn .learn-prop { background: var(--surface); }
|