clearotron 0.3.2-beta.1 → 0.3.2-beta.3
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/.env.example +29 -0
- package/INSTALL.md +2 -0
- package/README.md +15 -10
- package/bin/onboard.mjs +4 -4
- package/build-info.json +2 -2
- package/docs/CLIENT-MCP.md +54 -54
- package/docs/DELIVERY.md +16 -15
- package/docs/E2E.md +8 -8
- package/docs/GLOSSARY.md +2 -2
- package/docs/INTAKE.md +11 -11
- package/docs/ONBOARDING.md +17 -16
- package/docs/PORTAL.md +18 -16
- package/docs/README.md +10 -10
- package/docs/SECURITY.md +20 -20
- package/docs/architecture/01-product-overview.md +17 -16
- package/docs/architecture/02-architecture.md +6 -6
- package/docs/architecture/03-run-lifecycle.md +7 -7
- package/docs/architecture/04-configuration-reference.md +15 -13
- package/docs/architecture/05-config-governance.md +39 -30
- package/docs/architecture/05-customer-profiles.md +35 -35
- package/docs/architecture/06-operations-runbook.md +20 -20
- package/docs/architecture/07-quality-and-audit.md +17 -17
- package/docs/architecture/08-development-guide.md +3 -3
- package/docs/architecture/09-security-and-data.md +27 -27
- package/docs/architecture/README.md +1 -1
- package/docs/branding.md +8 -3
- package/docs/configuration.md +18 -18
- package/docs/writing-standard.md +3 -3
- package/driver/CHANGELOG.md +33 -0
- package/driver/driver.config.mjs +19 -3
- package/driver/package.json +1 -1
- package/driver/portal-service.mjs +34 -4
- package/driver/suite-census.json +118 -46
- package/mcp-server/CHANGELOG.md +8 -0
- package/mcp-server/package.json +1 -1
- package/mcp-server/packs/client/CONNECT.md +6 -6
- package/package.json +1 -1
- package/portal-ui/dist/assets/{index-BsbasHjM.js → index-Bki5jT_N.js} +3376 -2971
- package/portal-ui/dist/assets/{index-DNQpLYZF.css → index-De2RFLbT.css} +972 -205
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +8 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/signa/src/core.js +29 -1
- package/scripts/ask-ai-render-check.mjs +287 -105
- package/scripts/release-note-required.mjs +16 -2
- package/scripts/release-pre-gate.mjs +111 -0
- package/scripts/settings-render-check.mjs +575 -0
- package/shared/brand.mjs +29 -0
- package/shared/connect-clients.mjs +99 -47
- package/shared/names-in-force.mjs +1 -0
- package/shared/stdio-connect.mjs +16 -2
- package/shared/writing-standard-classes.mjs +34 -3
|
@@ -254,6 +254,36 @@ html.anon-on [data-anon='mark']:not(.anon-clear) {
|
|
|
254
254
|
border-bottom: 1px solid var(--border-hairline);
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
+
/* The breadcrumb above it: one step back as a quiet button, then where the reader is. Compound selectors
|
|
258
|
+
throughout this block, because the button and row rules they adjust are declared later in the file. */
|
|
259
|
+
.report-crumbs { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
|
|
260
|
+
.btn-ghost.report-back { padding: 4px 9px; border-color: var(--border-hairline); }
|
|
261
|
+
.report-crumb { font-size: 12.5px; color: var(--text-muted); }
|
|
262
|
+
|
|
263
|
+
/* THE HEADER'S TWO ACTIONS, Ask AI then Export, as secondary buttons with a hairline edge. */
|
|
264
|
+
.btn-ghost.report-action,
|
|
265
|
+
.btn-ghost.ask-ai-btn { border-color: var(--border-hairline); }
|
|
266
|
+
|
|
267
|
+
/* ── ASK AI ──────────────────────────────────────────────────────────────────────────────────────────
|
|
268
|
+
The panel hangs under its button with the right edges aligned, wherever the button sits — the report's
|
|
269
|
+
header, or a row where a bordered primary action beside it wants the quieter button. */
|
|
270
|
+
.ask-ai { position: relative; }
|
|
271
|
+
.btn-ghost.ask-ai-btn.is-quiet { border-color: transparent; color: var(--text-muted); }
|
|
272
|
+
.btn-ghost.ask-ai-btn.is-quiet:hover { border-color: var(--border-hairline); color: var(--text-strong); }
|
|
273
|
+
.ask-ai-float { position: absolute; right: 0; top: calc(100% + 6px); z-index: 50; }
|
|
274
|
+
.ask-ai-panel { width: 360px; max-width: calc(100vw - 32px); padding: 12px; display: grid; gap: 10px; text-align: left; }
|
|
275
|
+
.ask-ai-head { font-size: 12.5px; line-height: 1.45; color: var(--text-muted); }
|
|
276
|
+
.ask-ai-when { white-space: nowrap; }
|
|
277
|
+
.ask-ai-choices { display: grid; gap: 1px; }
|
|
278
|
+
.nav-item.ask-ai-choice {
|
|
279
|
+
gap: 10px; align-items: flex-start; margin: 0; padding: 7px 9px;
|
|
280
|
+
font-size: 13px; line-height: 1.45; white-space: normal; color: var(--text-body);
|
|
281
|
+
}
|
|
282
|
+
.nav-item.ask-ai-choice[aria-checked='true'] { background: var(--accent-wash); color: var(--text-strong); font-weight: 700; }
|
|
283
|
+
.ask-ai-choice .radio { margin-top: 2px; }
|
|
284
|
+
.btn-primary.ask-ai-go { justify-self: start; padding: 8px 14px; font-size: 13px; }
|
|
285
|
+
.ask-ai-note { margin: 0; font-size: 12px; line-height: 1.5; color: var(--text-muted); }
|
|
286
|
+
|
|
257
287
|
/* ── sidebar ─────────────────────────────────────────────────────────────────────────────────────── */
|
|
258
288
|
|
|
259
289
|
.sidebar {
|
|
@@ -402,6 +432,23 @@ html.anon-on [data-anon='mark']:not(.anon-clear) {
|
|
|
402
432
|
color: var(--text-strong);
|
|
403
433
|
}
|
|
404
434
|
|
|
435
|
+
/* The avatar: the signed-in person's initials, and the door to the screens that belong to them. Drawn
|
|
436
|
+
active on those screens, because the rail cannot highlight a screen it does not carry. After the hover
|
|
437
|
+
rule and one class stronger, so hovering the round button does not repaint it as a square one's. */
|
|
438
|
+
.icon-btn.avatar {
|
|
439
|
+
border-radius: 50%;
|
|
440
|
+
background: var(--surface-float);
|
|
441
|
+
border: 1px solid var(--border-hairline);
|
|
442
|
+
font-size: 11px;
|
|
443
|
+
font-weight: 700;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.icon-btn.avatar[aria-current='true'] {
|
|
447
|
+
background: var(--accent-wash);
|
|
448
|
+
border-color: var(--accent);
|
|
449
|
+
color: var(--text-accent);
|
|
450
|
+
}
|
|
451
|
+
|
|
405
452
|
.float {
|
|
406
453
|
background: var(--surface-float);
|
|
407
454
|
border: 1px solid var(--border-strong);
|
|
@@ -521,42 +568,19 @@ table.data.fixed td {
|
|
|
521
568
|
/* An expanded read: quiet enough to read as subordinate to the row it belongs to. The indent is on the
|
|
522
569
|
cells, not here, because it is structural — see ReadRow. */
|
|
523
570
|
table.data tr.read-row > td {
|
|
524
|
-
background: var(--surface-sunken);
|
|
571
|
+
background-color: var(--surface-sunken);
|
|
525
572
|
}
|
|
526
573
|
|
|
527
|
-
/*
|
|
528
|
-
The
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
target is worse than no target. */
|
|
574
|
+
/* A search with a report can still be opened with a click anywhere on its row — the mouse's convenience.
|
|
575
|
+
The named, focusable control is its Open button in the actions column; the row takes no focus of its
|
|
576
|
+
own, so a keyboard meets one target per search rather than two.
|
|
577
|
+
A search with no report gets none of this — not the pointer, not the hover. A dead target is worse
|
|
578
|
+
than no target. */
|
|
533
579
|
table.data tr.read-row.openable > td {
|
|
534
580
|
cursor: pointer;
|
|
535
581
|
}
|
|
536
582
|
table.data tr.read-row.openable:hover > td {
|
|
537
|
-
background: var(--surface-raised);
|
|
538
|
-
}
|
|
539
|
-
/* focus-visible, not focus: a keyboard user must see where they are, a mouse user must not get a ring
|
|
540
|
-
they did not ask for. The outline is on the ROW, so it reads as one target rather than six cells. */
|
|
541
|
-
table.data tr.read-row.openable:focus {
|
|
542
|
-
outline: none;
|
|
543
|
-
}
|
|
544
|
-
table.data tr.read-row.openable:focus-visible {
|
|
545
|
-
outline: 2px solid var(--accent);
|
|
546
|
-
outline-offset: -2px;
|
|
547
|
-
}
|
|
548
|
-
/* The cue that the row leads somewhere. It brightens with the row rather than being a control of its
|
|
549
|
-
own — clicking it is clicking the row, because it is not clickable separately. */
|
|
550
|
-
.read-go {
|
|
551
|
-
display: inline-flex;
|
|
552
|
-
align-items: center;
|
|
553
|
-
gap: 4px;
|
|
554
|
-
font-size: 12.5px;
|
|
555
|
-
color: var(--text-faint);
|
|
556
|
-
}
|
|
557
|
-
table.data tr.read-row.openable:hover .read-go,
|
|
558
|
-
table.data tr.read-row.openable:focus-visible .read-go {
|
|
559
|
-
color: var(--accent);
|
|
583
|
+
background-color: var(--surface-raised);
|
|
560
584
|
}
|
|
561
585
|
|
|
562
586
|
table.data tr.row {
|
|
@@ -606,8 +630,14 @@ button.twisty:focus-visible {
|
|
|
606
630
|
white-space: nowrap;
|
|
607
631
|
}
|
|
608
632
|
|
|
609
|
-
table.data tr.row:hover td {
|
|
610
|
-
background: var(--surface-sunken);
|
|
633
|
+
table.data tr.row:not(.inert):hover td {
|
|
634
|
+
background-color: var(--surface-sunken);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/* A name with one search and no report — running for the first time — has nothing to open and nothing to
|
|
638
|
+
expand, so its row does not pretend to be a control. */
|
|
639
|
+
table.data tr.row.inert {
|
|
640
|
+
cursor: default;
|
|
611
641
|
}
|
|
612
642
|
|
|
613
643
|
/* A SECTION HEADER, not a decorative divider.
|
|
@@ -617,7 +647,9 @@ table.data tr.row:hover td {
|
|
|
617
647
|
Body-text size, medium weight, full-strength ink, sentence case rather than letterspaced caps — and a
|
|
618
648
|
hairline rule spanning the table beneath it, so containment is visible without reading anything. */
|
|
619
649
|
table.data tr.group-head td {
|
|
620
|
-
padding:
|
|
650
|
+
padding: 10px 12px;
|
|
651
|
+
background: var(--surface-sunken);
|
|
652
|
+
border-top: 1px solid var(--border-strong);
|
|
621
653
|
border-bottom: 1px solid var(--border-strong);
|
|
622
654
|
}
|
|
623
655
|
|
|
@@ -635,10 +667,177 @@ table.data tr.group-head .owner-count {
|
|
|
635
667
|
color: var(--text-muted);
|
|
636
668
|
}
|
|
637
669
|
|
|
638
|
-
/*
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
670
|
+
/* NESTING IS DRAWN, not only indented. The company heading is a filled band; a name inside a group carries
|
|
671
|
+
one vertical rule in its first cell, and a search under a name one rule per level above it. Drawn as
|
|
672
|
+
background images so a rule costs no width and cannot move a column, and so it survives the row's own
|
|
673
|
+
background colour. */
|
|
674
|
+
table.data td.nest-1,
|
|
675
|
+
table.data td.nest-2 {
|
|
676
|
+
background-repeat: no-repeat;
|
|
677
|
+
}
|
|
678
|
+
table.data td.nest-1 {
|
|
679
|
+
background-image: linear-gradient(var(--border-strong), var(--border-strong));
|
|
680
|
+
background-size: 1px 100%;
|
|
681
|
+
background-position: 7px 0;
|
|
682
|
+
}
|
|
683
|
+
table.data td.nest-2 {
|
|
684
|
+
background-image: linear-gradient(var(--border-strong), var(--border-strong)), linear-gradient(var(--border-strong), var(--border-strong));
|
|
685
|
+
background-size: 1px 100%, 1px 100%;
|
|
686
|
+
background-position: 7px 0, 17px 0;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/* "Group ·" before a group's name: what kind of row this is, quieter than the name it introduces. */
|
|
690
|
+
.row-kind {
|
|
691
|
+
margin-right: 6px;
|
|
692
|
+
font-size: 13px;
|
|
693
|
+
color: var(--text-muted);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/* ── the Clearances actions column ──────────────────────────────────────────────────────────────────
|
|
697
|
+
Open, Ask AI and the row menu in fixed tracks, so every Open on the page shares one x and one width.
|
|
698
|
+
Narrow, Ask AI sits under Open; with room, beside it — the table's wrapper is the container measured,
|
|
699
|
+
so a collapsed rail widens it exactly as a wider window does. */
|
|
700
|
+
.names-wrap {
|
|
701
|
+
container-type: inline-size;
|
|
702
|
+
/* VISIBLE, not the wrapper's usual `auto`. This table cannot overflow — its columns are shares of its
|
|
703
|
+
own width — so the scroll container bought nothing here, and it clipped on both axes: an Ask AI
|
|
704
|
+
panel opened from a row near the bottom of the list was cut off at the table's edge. */
|
|
705
|
+
overflow: visible;
|
|
706
|
+
}
|
|
707
|
+
/* Eight pixels either side instead of twelve, on every column but the two narrow ones at the left: the
|
|
708
|
+
actions column takes a quarter of the table, and the text columns keep their words on one line by
|
|
709
|
+
giving up padding rather than width. The date and the actions give up a little more. */
|
|
710
|
+
.names-wrap table.data.fixed th:nth-child(n + 3),
|
|
711
|
+
.names-wrap table.data.fixed td:nth-child(n + 3) {
|
|
712
|
+
padding-left: 8px;
|
|
713
|
+
padding-right: 8px;
|
|
714
|
+
}
|
|
715
|
+
.names-wrap table.data.fixed td.col-date,
|
|
716
|
+
.names-wrap table.data.fixed td.col-actions {
|
|
717
|
+
padding-left: 6px;
|
|
718
|
+
padding-right: 6px;
|
|
719
|
+
}
|
|
720
|
+
/* A status that does not fit wraps between its halves — "Queued ·" over "1 search" — rather than running
|
|
721
|
+
under the Risk column: `.status` is nowrap everywhere else, which is right for a word and wrong for a
|
|
722
|
+
phrase in a column of fixed width. The dot stays level with the first line. */
|
|
723
|
+
.names-wrap table.data.fixed td .status {
|
|
724
|
+
white-space: normal;
|
|
725
|
+
align-items: flex-start;
|
|
726
|
+
}
|
|
727
|
+
.names-wrap table.data.fixed td .status .dot {
|
|
728
|
+
margin-top: 0.42em;
|
|
729
|
+
}
|
|
730
|
+
.status-count {
|
|
731
|
+
white-space: nowrap;
|
|
732
|
+
}
|
|
733
|
+
/* A date is one word to a reader. A line may break before it, never at its hyphens: "2026-09-" over "02"
|
|
734
|
+
read as a different date on the line below. */
|
|
735
|
+
.names-wrap table.data.fixed td .sub.report-line {
|
|
736
|
+
overflow-wrap: normal;
|
|
737
|
+
}
|
|
738
|
+
.names-wrap .nowrap-date {
|
|
739
|
+
white-space: nowrap;
|
|
740
|
+
}
|
|
741
|
+
.row-actions {
|
|
742
|
+
/* WIDE ENOUGH FOR THE LONGEST LABEL ON A FONT THIS BOX DOES NOT HAVE. The track is fixed so every
|
|
743
|
+
Open shares one width — "the track decides, not the text" — which means the number has to clear
|
|
744
|
+
the longest label, "Open latest report", everywhere. At 11em it cleared it on a developer machine
|
|
745
|
+
and clipped on the CI runner, whose default font is wider: the browser check went green locally
|
|
746
|
+
and red in CI on the same commit. 13.5em is the local measurement plus about a fifth, which is
|
|
747
|
+
more than the spread between the font stacks the two see. */
|
|
748
|
+
--row-open-w: 13.5em;
|
|
749
|
+
--row-ask-w: 6.5em;
|
|
750
|
+
display: grid;
|
|
751
|
+
grid-template-columns: var(--row-open-w) auto;
|
|
752
|
+
grid-template-areas: 'open more' 'ask more';
|
|
753
|
+
justify-content: start;
|
|
754
|
+
align-items: start;
|
|
755
|
+
gap: 6px;
|
|
756
|
+
font-size: 12.5px;
|
|
757
|
+
}
|
|
758
|
+
.row-actions-open { grid-area: open; }
|
|
759
|
+
/* Ask AI in a row: the header's button, compacted to the height of Open beside it and kept on one line —
|
|
760
|
+
in its own track it wrapped to "Ask" over "AI" with its icon stranded beside them. */
|
|
761
|
+
.row-actions .btn-ghost.ask-ai-btn {
|
|
762
|
+
padding: 5px 8px;
|
|
763
|
+
gap: 5px;
|
|
764
|
+
white-space: nowrap;
|
|
765
|
+
}
|
|
766
|
+
.row-actions-ask { grid-area: ask; }
|
|
767
|
+
.row-actions-more { grid-area: more; }
|
|
768
|
+
.row-actions-open:empty,
|
|
769
|
+
.row-actions-ask:empty {
|
|
770
|
+
display: none;
|
|
771
|
+
}
|
|
772
|
+
@container (min-width: 1000px) {
|
|
773
|
+
.row-actions {
|
|
774
|
+
grid-template-columns: var(--row-open-w) var(--row-ask-w) auto;
|
|
775
|
+
grid-template-areas: 'open ask more';
|
|
776
|
+
}
|
|
777
|
+
.row-actions-open:empty,
|
|
778
|
+
.row-actions-ask:empty {
|
|
779
|
+
display: block;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
/* The bordered Open. One width, whatever its label says: the track decides, not the text. */
|
|
783
|
+
button.row-open {
|
|
784
|
+
width: 100%;
|
|
785
|
+
padding: 5px 8px;
|
|
786
|
+
border: 1px solid var(--border-strong);
|
|
787
|
+
border-radius: 7px;
|
|
788
|
+
background: var(--surface-raised);
|
|
789
|
+
color: var(--text-strong);
|
|
790
|
+
font: inherit;
|
|
791
|
+
font-weight: 600;
|
|
792
|
+
white-space: nowrap;
|
|
793
|
+
cursor: pointer;
|
|
794
|
+
}
|
|
795
|
+
button.row-open:hover {
|
|
796
|
+
border-color: var(--text-muted);
|
|
797
|
+
}
|
|
798
|
+
button.row-open:focus-visible,
|
|
799
|
+
button.row-menu-btn:focus-visible {
|
|
800
|
+
outline: 2px solid var(--accent);
|
|
801
|
+
outline-offset: 1px;
|
|
802
|
+
}
|
|
803
|
+
.row-menu {
|
|
804
|
+
position: relative;
|
|
805
|
+
}
|
|
806
|
+
button.row-menu-btn {
|
|
807
|
+
width: 28px;
|
|
808
|
+
height: 28px;
|
|
809
|
+
padding: 0;
|
|
810
|
+
border: 0;
|
|
811
|
+
border-radius: 6px;
|
|
812
|
+
background: none;
|
|
813
|
+
color: var(--text-muted);
|
|
814
|
+
font: inherit;
|
|
815
|
+
font-size: 15px;
|
|
816
|
+
line-height: 1;
|
|
817
|
+
cursor: pointer;
|
|
818
|
+
}
|
|
819
|
+
button.row-menu-btn:hover,
|
|
820
|
+
button.row-menu-btn[aria-expanded='true'] {
|
|
821
|
+
background: var(--surface-sunken);
|
|
822
|
+
color: var(--text-strong);
|
|
823
|
+
}
|
|
824
|
+
/* To the LEFT of the button, level with it. Every row menu holds one act, and a list of one fits beside
|
|
825
|
+
its button inside its own row — so opening it covers the row it acts on, never the rows beneath, and
|
|
826
|
+
it cannot be the thing that runs off the bottom of the page. */
|
|
827
|
+
.row-menu-list {
|
|
828
|
+
position: absolute;
|
|
829
|
+
right: 100%;
|
|
830
|
+
top: -4px;
|
|
831
|
+
margin-right: 4px;
|
|
832
|
+
min-width: 132px;
|
|
833
|
+
padding: 4px;
|
|
834
|
+
z-index: 50;
|
|
835
|
+
}
|
|
836
|
+
button.row-menu-item {
|
|
837
|
+
font-size: 13px;
|
|
838
|
+
padding: 6px 10px;
|
|
839
|
+
margin: 0;
|
|
840
|
+
white-space: nowrap;
|
|
642
841
|
}
|
|
643
842
|
|
|
644
843
|
.pager {
|
|
@@ -691,6 +890,21 @@ table.data tr.group-head ~ tr.row > td:first-child {
|
|
|
691
890
|
color: var(--text-muted);
|
|
692
891
|
}
|
|
693
892
|
|
|
893
|
+
/* The larger pill, for a control that is a card's closing action rather than a label — and an anchor
|
|
894
|
+
drawn as one, which is what opening a document in a new tab is. */
|
|
895
|
+
.pill-lg {
|
|
896
|
+
padding: 5px 13px;
|
|
897
|
+
font-size: 12px;
|
|
898
|
+
}
|
|
899
|
+
a.pill {
|
|
900
|
+
text-decoration: none;
|
|
901
|
+
cursor: pointer;
|
|
902
|
+
}
|
|
903
|
+
a.pill:hover {
|
|
904
|
+
color: var(--text-strong);
|
|
905
|
+
border-color: var(--border-strong);
|
|
906
|
+
}
|
|
907
|
+
|
|
694
908
|
/* ── status + risk ───────────────────────────────────────────────────────────────────────────────── */
|
|
695
909
|
|
|
696
910
|
.dot {
|
|
@@ -707,7 +921,7 @@ table.data tr.group-head ~ tr.row > td:first-child {
|
|
|
707
921
|
}
|
|
708
922
|
|
|
709
923
|
.dot.running {
|
|
710
|
-
background: var(--
|
|
924
|
+
background: var(--text-muted);
|
|
711
925
|
animation: cordPulse 1.4s ease-in-out infinite;
|
|
712
926
|
}
|
|
713
927
|
|
|
@@ -862,6 +1076,270 @@ input.filter {
|
|
|
862
1076
|
background: var(--surface-raised);
|
|
863
1077
|
}
|
|
864
1078
|
|
|
1079
|
+
/* ── Preferences, Installation settings and About ─────────────────────────────────────────────────
|
|
1080
|
+
The three pages the avatar menu leads to. Each is a stack of raised cards or rows on the page ground,
|
|
1081
|
+
drawn from these few rules so the three read as one family. */
|
|
1082
|
+
|
|
1083
|
+
.pref-cards {
|
|
1084
|
+
display: flex;
|
|
1085
|
+
flex-direction: column;
|
|
1086
|
+
gap: 14px;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
.pref-card,
|
|
1090
|
+
.about-card {
|
|
1091
|
+
padding: 18px 20px;
|
|
1092
|
+
border-radius: 12px;
|
|
1093
|
+
border: 1px solid var(--border-hairline);
|
|
1094
|
+
background: var(--surface-raised);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
.pref-title {
|
|
1098
|
+
font-size: 15px;
|
|
1099
|
+
font-weight: 700;
|
|
1100
|
+
color: var(--text-strong);
|
|
1101
|
+
margin: 0 0 14px;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
.pref-dl {
|
|
1105
|
+
margin: 0;
|
|
1106
|
+
display: grid;
|
|
1107
|
+
grid-template-columns: auto 1fr;
|
|
1108
|
+
gap: 8px 18px;
|
|
1109
|
+
font-size: 14px;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
.pref-dl dt {
|
|
1113
|
+
color: var(--text-muted);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
.pref-dl dd {
|
|
1117
|
+
margin: 0;
|
|
1118
|
+
min-width: 0;
|
|
1119
|
+
color: var(--text-strong);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
.pref-address {
|
|
1123
|
+
word-break: break-all;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
.pref-none {
|
|
1127
|
+
color: var(--text-muted);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
.pref-line {
|
|
1131
|
+
margin: 14px 0 0;
|
|
1132
|
+
font-size: 13px;
|
|
1133
|
+
color: var(--text-muted);
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/* A link inside a sentence: accent ink and a quiet rule under it, so it reads as a link without shouting. */
|
|
1137
|
+
.pref-link,
|
|
1138
|
+
.about-link {
|
|
1139
|
+
color: var(--text-accent);
|
|
1140
|
+
text-decoration: none;
|
|
1141
|
+
border-bottom: 1px solid var(--accent-quiet);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
.pref-foot {
|
|
1145
|
+
margin-top: 12px;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
/* A pill that is the card's own action is a size up from a pill that labels a row. */
|
|
1149
|
+
.pref-foot .pill,
|
|
1150
|
+
.about-docs .pill {
|
|
1151
|
+
padding: 5px 13px;
|
|
1152
|
+
font-size: 12px;
|
|
1153
|
+
text-decoration: none;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
.pref-themes {
|
|
1157
|
+
display: flex;
|
|
1158
|
+
gap: 10px;
|
|
1159
|
+
flex-wrap: wrap;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
.pref-blur {
|
|
1163
|
+
display: flex;
|
|
1164
|
+
align-items: center;
|
|
1165
|
+
gap: 12px;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
/* THE TOP BAR'S EYE, GIVEN AN EDGE. On the top bar it sits in a row of buttons like it; alone in a card, a
|
|
1169
|
+
borderless glyph beside a sentence reads as a bullet. So here it carries the hairline edge the design
|
|
1170
|
+
draws round this control, and keeps the top bar's pressed state. */
|
|
1171
|
+
.pref-blur .icon-btn {
|
|
1172
|
+
flex: none;
|
|
1173
|
+
border-color: var(--border-hairline);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
.pref-blur-line {
|
|
1177
|
+
font-size: 13.5px;
|
|
1178
|
+
color: var(--text-muted);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/* About: the source offer as one list of facts, the label column fixed so the values line up. */
|
|
1182
|
+
.about-dl {
|
|
1183
|
+
margin: 0;
|
|
1184
|
+
display: grid;
|
|
1185
|
+
grid-template-columns: 132px 1fr;
|
|
1186
|
+
gap: 10px 18px;
|
|
1187
|
+
align-items: baseline;
|
|
1188
|
+
font-size: 14px;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
.about-dl dt {
|
|
1192
|
+
color: var(--text-muted);
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
.about-dl dd {
|
|
1196
|
+
margin: 0;
|
|
1197
|
+
min-width: 0;
|
|
1198
|
+
color: var(--text-strong);
|
|
1199
|
+
overflow-wrap: anywhere;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
.about-row {
|
|
1203
|
+
display: flex;
|
|
1204
|
+
align-items: center;
|
|
1205
|
+
gap: 10px;
|
|
1206
|
+
flex-wrap: wrap;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
.about-row .pill {
|
|
1210
|
+
text-decoration: none;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
.about-docs {
|
|
1214
|
+
display: flex;
|
|
1215
|
+
gap: 7px;
|
|
1216
|
+
flex-wrap: wrap;
|
|
1217
|
+
margin-top: 18px;
|
|
1218
|
+
padding-top: 14px;
|
|
1219
|
+
border-top: 1px solid var(--border-hairline);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/* Installation settings: a section label, then rows. A provider category is a sub-heading with its sources
|
|
1223
|
+
beneath it, so the category is said once and never repeated on a row. The state column has a floor so
|
|
1224
|
+
every row's state lines up, whatever the name and coverage beside it. */
|
|
1225
|
+
.cfg-group {
|
|
1226
|
+
margin-top: 24px;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
.page-header + .cfg-group {
|
|
1230
|
+
margin-top: 4px;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
.cfg-rows {
|
|
1234
|
+
display: grid;
|
|
1235
|
+
gap: 6px;
|
|
1236
|
+
margin-top: 8px;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
.cfg-cat {
|
|
1240
|
+
margin-top: 16px;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
.cfg-sub {
|
|
1244
|
+
font-size: 13px;
|
|
1245
|
+
font-weight: 700;
|
|
1246
|
+
color: var(--text-muted);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
.cfg-cat-note {
|
|
1250
|
+
max-width: var(--prose-measure);
|
|
1251
|
+
margin: 3px 0 0;
|
|
1252
|
+
font-size: 12.5px;
|
|
1253
|
+
color: var(--text-muted);
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
.cfg-row {
|
|
1257
|
+
padding: 10px 13px;
|
|
1258
|
+
border-radius: 9px;
|
|
1259
|
+
border: 1px solid var(--border-hairline);
|
|
1260
|
+
background: var(--surface-raised);
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
.cfg-line {
|
|
1264
|
+
display: flex;
|
|
1265
|
+
align-items: center;
|
|
1266
|
+
gap: 12px;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
.cfg-name {
|
|
1270
|
+
flex: 1;
|
|
1271
|
+
min-width: 0;
|
|
1272
|
+
font-size: 13px;
|
|
1273
|
+
color: var(--text-strong);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
.cfg-val {
|
|
1277
|
+
font-size: 12.5px;
|
|
1278
|
+
color: var(--text-muted);
|
|
1279
|
+
text-align: right;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
.cfg-state {
|
|
1283
|
+
min-width: 92px;
|
|
1284
|
+
font-size: 12.5px;
|
|
1285
|
+
color: var(--text-muted);
|
|
1286
|
+
text-align: right;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
.cfg-state.bad,
|
|
1290
|
+
.cfg-note.bad {
|
|
1291
|
+
color: var(--tone-high);
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
.cfg-state.off {
|
|
1295
|
+
color: var(--text-faint);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
/* Indented under the name, past the dot, so a row's second line reads as the row's own. */
|
|
1299
|
+
.cfg-note {
|
|
1300
|
+
margin: 6px 0 0 21px;
|
|
1301
|
+
font-size: 12.5px;
|
|
1302
|
+
color: var(--text-muted);
|
|
1303
|
+
overflow-wrap: anywhere;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
.cfg-act {
|
|
1307
|
+
display: flex;
|
|
1308
|
+
align-items: center;
|
|
1309
|
+
gap: 10px;
|
|
1310
|
+
flex-wrap: wrap;
|
|
1311
|
+
margin: 6px 0 0 21px;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
.cfg-act .cfg-note {
|
|
1315
|
+
margin: 0;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
.cfg-act .pill {
|
|
1319
|
+
text-decoration: none;
|
|
1320
|
+
cursor: pointer;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
.cfg-act .pill:disabled {
|
|
1324
|
+
cursor: default;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
.cfg-dot {
|
|
1328
|
+
flex: none;
|
|
1329
|
+
width: 9px;
|
|
1330
|
+
height: 9px;
|
|
1331
|
+
border-radius: 50%;
|
|
1332
|
+
background: var(--tone-minimal);
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
.cfg-dot.bad {
|
|
1336
|
+
background: var(--tone-high);
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
.cfg-dot.off {
|
|
1340
|
+
background: var(--text-faint);
|
|
1341
|
+
}
|
|
1342
|
+
|
|
865
1343
|
/* ── mobile ──────────────────────────────────────────────────────────────────────────────────────── */
|
|
866
1344
|
|
|
867
1345
|
@media (max-width: 899px) {
|
|
@@ -948,15 +1426,6 @@ input.filter {
|
|
|
948
1426
|
margin: 6px 0 4px;
|
|
949
1427
|
}
|
|
950
1428
|
|
|
951
|
-
.fw-bmh {
|
|
952
|
-
font-size: 10.5px;
|
|
953
|
-
letter-spacing: 0.12em;
|
|
954
|
-
text-transform: uppercase;
|
|
955
|
-
color: var(--text-accent);
|
|
956
|
-
font-weight: 700;
|
|
957
|
-
margin: 16px 0 6px;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
1429
|
/* THE rule that makes this read as a rated ladder instead of a bullet list: a fixed pill column and a
|
|
961
1430
|
text column, so every meaning starts at the same left edge no matter how wide its band label is.
|
|
962
1431
|
A flex row here lets each pill size itself and leaves the prose ragged — that is what the first
|
|
@@ -1000,69 +1469,306 @@ input.filter {
|
|
|
1000
1469
|
.fw-bmrung {
|
|
1001
1470
|
display: contents;
|
|
1002
1471
|
}
|
|
1003
|
-
.fw-bmrunglbl {
|
|
1004
|
-
color: var(--text-body);
|
|
1005
|
-
font-weight: 600;
|
|
1472
|
+
.fw-bmrunglbl {
|
|
1473
|
+
color: var(--text-body);
|
|
1474
|
+
font-weight: 600;
|
|
1475
|
+
}
|
|
1476
|
+
@media (max-width: 640px) {
|
|
1477
|
+
/* Stacked: one column, and the display:contents rows flow label-above-text in source order. */
|
|
1478
|
+
.fw-bmrungs {
|
|
1479
|
+
grid-template-columns: 1fr;
|
|
1480
|
+
row-gap: 1px;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
.footer-demo-note {
|
|
1485
|
+
max-width: 420px; /* the note's width is the note's own, not its call site's */
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
/* The line beside the primary action: what happens next when it is available, and why it is not when
|
|
1489
|
+
it is not. Capped here rather than at the call site for the same reason the note above is — width is
|
|
1490
|
+
a decision this file makes. Narrower than the note because it sits IN the action row, beside a
|
|
1491
|
+
button, rather than replacing it. */
|
|
1492
|
+
.footer-hint {
|
|
1493
|
+
max-width: 260px;
|
|
1494
|
+
font-size: 12px;
|
|
1495
|
+
line-height: 1.4;
|
|
1496
|
+
color: var(--text-muted);
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
/* The acknowledgement a save leaves beside the button that was pressed.
|
|
1500
|
+
Quiet on purpose: it is a receipt, not an alert, and it sits in the same row as the primary action
|
|
1501
|
+
without competing with it. No new colour — `--tone-minimal` (the palette's clear-green) and the hairline are what the rest of
|
|
1502
|
+
this file already uses for a settled, good state. */
|
|
1503
|
+
.save-done {
|
|
1504
|
+
display: inline-flex;
|
|
1505
|
+
align-items: center;
|
|
1506
|
+
gap: 7px;
|
|
1507
|
+
font-size: 12.5px;
|
|
1508
|
+
color: var(--text-body);
|
|
1509
|
+
background: var(--surface-sunken);
|
|
1510
|
+
border: 1px solid var(--border-hairline);
|
|
1511
|
+
border-radius: 7px;
|
|
1512
|
+
padding: 7px 11px;
|
|
1513
|
+
}
|
|
1514
|
+
.save-done svg {
|
|
1515
|
+
color: var(--tone-minimal);
|
|
1516
|
+
flex: none;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
.fw-meta {
|
|
1520
|
+
font-size: 12px;
|
|
1521
|
+
color: var(--text-muted);
|
|
1522
|
+
margin-top: 4px;
|
|
1523
|
+
}
|
|
1524
|
+
.fw-meta b {
|
|
1525
|
+
color: var(--text-strong);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
/* Narrow viewports: the fixed pill column would squeeze the prose to a sliver, so the row stacks. */
|
|
1529
|
+
@media (max-width: 560px) {
|
|
1530
|
+
.fw-bmrow {
|
|
1531
|
+
grid-template-columns: 1fr;
|
|
1532
|
+
gap: 2px;
|
|
1533
|
+
padding: 6px 0;
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
/* ── Company settings: Profile, Projects, Search templates, New company ─────────────────────────────
|
|
1538
|
+
Each page is a stack of cards. The framework card leads Profile; Identity, Search defaults, the law
|
|
1539
|
+
firm fold and the background follow it, and New company draws the same cards in the same order. */
|
|
1540
|
+
|
|
1541
|
+
.card-stack {
|
|
1542
|
+
display: flex;
|
|
1543
|
+
flex-direction: column;
|
|
1544
|
+
gap: 14px;
|
|
1545
|
+
}
|
|
1546
|
+
.card-stack > .notice {
|
|
1547
|
+
margin: 0;
|
|
1548
|
+
}
|
|
1549
|
+
/* The fieldset that decides whether Profile can be changed is a stack in its own right, and a
|
|
1550
|
+
fieldset's own border, padding and minimum width are browser furniture nobody asked for. */
|
|
1551
|
+
fieldset.profile-cards {
|
|
1552
|
+
border: 0;
|
|
1553
|
+
padding: 0;
|
|
1554
|
+
margin: 0;
|
|
1555
|
+
min-width: 0;
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
/* THE FOLD. A closed row whose chevron sits at its right edge and turns down when open — the shape every
|
|
1559
|
+
openable row on these pages takes, centre-aligned so the title, its note and the chevron share a line. */
|
|
1560
|
+
.fold-summary {
|
|
1561
|
+
display: flex;
|
|
1562
|
+
align-items: center;
|
|
1563
|
+
gap: 10px;
|
|
1564
|
+
list-style: none;
|
|
1565
|
+
cursor: pointer;
|
|
1566
|
+
font-weight: 700;
|
|
1567
|
+
font-size: 13.5px;
|
|
1568
|
+
color: var(--text-strong);
|
|
1569
|
+
}
|
|
1570
|
+
.fold-summary::-webkit-details-marker {
|
|
1571
|
+
display: none;
|
|
1572
|
+
}
|
|
1573
|
+
.fold-note {
|
|
1574
|
+
font-weight: 400;
|
|
1575
|
+
font-size: 12.5px;
|
|
1576
|
+
color: var(--text-muted);
|
|
1577
|
+
}
|
|
1578
|
+
.fold-chev {
|
|
1579
|
+
margin-left: auto;
|
|
1580
|
+
color: var(--text-faint);
|
|
1581
|
+
transition: transform 0.15s var(--ease-out);
|
|
1582
|
+
}
|
|
1583
|
+
details[open] > .fold-summary .fold-chev {
|
|
1584
|
+
transform: rotate(90deg);
|
|
1585
|
+
}
|
|
1586
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1587
|
+
.fold-chev {
|
|
1588
|
+
transition: none;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
.fold-body {
|
|
1592
|
+
margin-top: 10px;
|
|
1593
|
+
}
|
|
1594
|
+
/* A fold inside a card: a hairline above it, so it reads as a row of the card rather than as a field. */
|
|
1595
|
+
.fw-fold {
|
|
1596
|
+
margin-top: 16px;
|
|
1597
|
+
border-top: 1px solid var(--border-hairline);
|
|
1598
|
+
padding-top: 12px;
|
|
1599
|
+
}
|
|
1600
|
+
/* A fold that IS a card: the whole card is the row until it opens. */
|
|
1601
|
+
.fold-card > .fold-summary {
|
|
1602
|
+
font-size: 14px;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
/* The configuration rows under the framework, in view whether the band detail is open or not. */
|
|
1606
|
+
.fw-rows {
|
|
1607
|
+
margin-top: 16px;
|
|
1608
|
+
border-top: 1px solid var(--border-hairline);
|
|
1609
|
+
padding-top: 12px;
|
|
1610
|
+
}
|
|
1611
|
+
.fw-row {
|
|
1612
|
+
display: flex;
|
|
1613
|
+
gap: 14px;
|
|
1614
|
+
padding: 5px 0;
|
|
1615
|
+
font-size: 13px;
|
|
1616
|
+
align-items: baseline;
|
|
1617
|
+
}
|
|
1618
|
+
.fw-row-label {
|
|
1619
|
+
color: var(--text-muted);
|
|
1620
|
+
min-width: 150px;
|
|
1621
|
+
}
|
|
1622
|
+
.fw-row-value {
|
|
1623
|
+
color: var(--text-strong);
|
|
1624
|
+
word-break: break-word;
|
|
1625
|
+
}
|
|
1626
|
+
.fw-foot {
|
|
1627
|
+
margin-top: 14px;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
/* One profile field: its label, its tag, its hint line, then the control. */
|
|
1631
|
+
.profile-field {
|
|
1632
|
+
display: block;
|
|
1633
|
+
margin-top: 18px;
|
|
1634
|
+
}
|
|
1635
|
+
.eyebrow + .profile-field,
|
|
1636
|
+
.eyebrow + div > .profile-field:first-child {
|
|
1637
|
+
margin-top: 12px;
|
|
1638
|
+
}
|
|
1639
|
+
.profile-field-label {
|
|
1640
|
+
display: block;
|
|
1641
|
+
font-weight: 700;
|
|
1642
|
+
color: var(--text-strong);
|
|
1643
|
+
font-size: 14px;
|
|
1644
|
+
}
|
|
1645
|
+
.profile-field-hint {
|
|
1646
|
+
display: block;
|
|
1647
|
+
font-size: 12.5px;
|
|
1648
|
+
color: var(--text-muted);
|
|
1649
|
+
margin: 2px 0 7px;
|
|
1650
|
+
}
|
|
1651
|
+
.profile-field-gap {
|
|
1652
|
+
display: block;
|
|
1653
|
+
height: 7px;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
/* REQUIRED AND OPTIONAL. Filled for the one a form cannot do without, quiet for the rest, so the eye finds
|
|
1657
|
+
the required field without reading every tag. Sized against the label it follows, and lowered a pixel
|
|
1658
|
+
so an uppercase tag sits on the label's line rather than above it. */
|
|
1659
|
+
.field-tag {
|
|
1660
|
+
display: inline-block;
|
|
1661
|
+
margin-left: 8px;
|
|
1662
|
+
padding: 1px 6px;
|
|
1663
|
+
border-radius: 5px;
|
|
1664
|
+
font-size: 10px;
|
|
1665
|
+
font-weight: 700;
|
|
1666
|
+
letter-spacing: 0.08em;
|
|
1667
|
+
line-height: 1.5;
|
|
1668
|
+
text-transform: uppercase;
|
|
1669
|
+
vertical-align: 1px;
|
|
1670
|
+
color: var(--text-faint);
|
|
1671
|
+
background: var(--surface-sunken);
|
|
1672
|
+
}
|
|
1673
|
+
.field-tag-required {
|
|
1674
|
+
color: var(--text-on-accent);
|
|
1675
|
+
background: var(--accent);
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
/* The class search: the chosen classes as chips, then the box that finds one. */
|
|
1679
|
+
.chip-row {
|
|
1680
|
+
display: flex;
|
|
1681
|
+
align-items: center;
|
|
1682
|
+
gap: 6px;
|
|
1683
|
+
flex-wrap: wrap;
|
|
1684
|
+
}
|
|
1685
|
+
.class-picker > .chip-row {
|
|
1686
|
+
margin-top: 2px;
|
|
1006
1687
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
.fw-bmrungs {
|
|
1010
|
-
grid-template-columns: 1fr;
|
|
1011
|
-
row-gap: 1px;
|
|
1012
|
-
}
|
|
1688
|
+
.class-picker-box {
|
|
1689
|
+
position: relative;
|
|
1013
1690
|
}
|
|
1014
1691
|
|
|
1015
|
-
.
|
|
1016
|
-
|
|
1692
|
+
/* The New company rating card's one row: the framework a company starts on, and the way to its own. */
|
|
1693
|
+
.rating-row {
|
|
1694
|
+
display: flex;
|
|
1695
|
+
align-items: center;
|
|
1696
|
+
justify-content: space-between;
|
|
1697
|
+
gap: 12px;
|
|
1698
|
+
margin-top: 12px;
|
|
1699
|
+
}
|
|
1700
|
+
.rating-row-name {
|
|
1701
|
+
font-size: 14px;
|
|
1702
|
+
font-weight: 700;
|
|
1703
|
+
color: var(--text-strong);
|
|
1017
1704
|
}
|
|
1018
1705
|
|
|
1019
|
-
/* The
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1706
|
+
/* The page's one action row: the button, and the line that says what state it is in. */
|
|
1707
|
+
.row-foot {
|
|
1708
|
+
display: flex;
|
|
1709
|
+
align-items: center;
|
|
1710
|
+
gap: 12px;
|
|
1711
|
+
flex-wrap: wrap;
|
|
1712
|
+
margin-top: 18px;
|
|
1713
|
+
}
|
|
1714
|
+
.row-foot-note {
|
|
1715
|
+
font-size: 13px;
|
|
1027
1716
|
color: var(--text-muted);
|
|
1028
1717
|
}
|
|
1029
1718
|
|
|
1030
|
-
/*
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
.save-done {
|
|
1035
|
-
display: inline-flex;
|
|
1036
|
-
align-items: center;
|
|
1037
|
-
gap: 7px;
|
|
1038
|
-
font-size: 12.5px;
|
|
1039
|
-
color: var(--text-body);
|
|
1040
|
-
background: var(--surface-sunken);
|
|
1719
|
+
/* A project row: the whole left side opens it; its menu and chevron sit at the right. */
|
|
1720
|
+
.row-card {
|
|
1721
|
+
padding: 12px 14px;
|
|
1722
|
+
border-radius: 10px;
|
|
1041
1723
|
border: 1px solid var(--border-hairline);
|
|
1042
|
-
|
|
1043
|
-
|
|
1724
|
+
background: var(--surface-raised);
|
|
1725
|
+
display: flex;
|
|
1726
|
+
align-items: center;
|
|
1727
|
+
gap: 12px;
|
|
1044
1728
|
}
|
|
1045
|
-
.
|
|
1046
|
-
|
|
1729
|
+
.row-card-open {
|
|
1730
|
+
flex: 1;
|
|
1731
|
+
min-width: 0;
|
|
1732
|
+
text-align: left;
|
|
1733
|
+
background: none;
|
|
1734
|
+
border: 0;
|
|
1735
|
+
padding: 0;
|
|
1736
|
+
cursor: pointer;
|
|
1737
|
+
font: inherit;
|
|
1738
|
+
color: inherit;
|
|
1739
|
+
}
|
|
1740
|
+
.row-card-name {
|
|
1741
|
+
font-weight: 700;
|
|
1742
|
+
color: var(--text-strong);
|
|
1743
|
+
}
|
|
1744
|
+
.row-chev {
|
|
1745
|
+
display: inline-flex;
|
|
1047
1746
|
flex: none;
|
|
1747
|
+
color: var(--text-faint);
|
|
1048
1748
|
}
|
|
1049
1749
|
|
|
1050
|
-
.
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1750
|
+
/* A row's "More actions" menu, under its button and aligned to its right edge. */
|
|
1751
|
+
.actions-menu {
|
|
1752
|
+
position: relative;
|
|
1753
|
+
flex: none;
|
|
1054
1754
|
}
|
|
1055
|
-
.
|
|
1056
|
-
|
|
1755
|
+
.actions-menu-button {
|
|
1756
|
+
width: 28px;
|
|
1757
|
+
height: 28px;
|
|
1057
1758
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1759
|
+
.actions-menu-list {
|
|
1760
|
+
position: absolute;
|
|
1761
|
+
right: 0;
|
|
1762
|
+
top: 32px;
|
|
1763
|
+
z-index: 30;
|
|
1764
|
+
min-width: 150px;
|
|
1765
|
+
padding: 6px;
|
|
1766
|
+
}
|
|
1767
|
+
.actions-menu-list .nav-item {
|
|
1768
|
+
font-size: 13px;
|
|
1769
|
+
padding: 7px 10px;
|
|
1770
|
+
margin: 0;
|
|
1771
|
+
white-space: nowrap;
|
|
1066
1772
|
}
|
|
1067
1773
|
|
|
1068
1774
|
/* ── the New clearance composer ──────────────────────────────────────────────────────────────────────
|
|
@@ -1227,20 +1933,7 @@ input.filter {
|
|
|
1227
1933
|
text-decoration: underline;
|
|
1228
1934
|
}
|
|
1229
1935
|
|
|
1230
|
-
/*
|
|
1231
|
-
.entry-grid {
|
|
1232
|
-
display: grid;
|
|
1233
|
-
grid-template-columns: 1fr 1fr;
|
|
1234
|
-
gap: 12px;
|
|
1235
|
-
margin-top: 24px;
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
@media (max-width: 640px) {
|
|
1239
|
-
.entry-grid {
|
|
1240
|
-
grid-template-columns: 1fr;
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1936
|
+
/* A card to choose by: the rows of the company picker. */
|
|
1244
1937
|
.entry-card {
|
|
1245
1938
|
text-align: left;
|
|
1246
1939
|
padding: 18px;
|
|
@@ -1310,35 +2003,8 @@ input.filter {
|
|
|
1310
2003
|
color: var(--text-muted);
|
|
1311
2004
|
}
|
|
1312
2005
|
|
|
1313
|
-
.
|
|
1314
|
-
|
|
1315
|
-
gap: 2px;
|
|
1316
|
-
padding: 3px;
|
|
1317
|
-
background: var(--surface-sunken);
|
|
1318
|
-
border-radius: 9px;
|
|
1319
|
-
border: 1px solid var(--border-hairline);
|
|
1320
|
-
margin-top: 18px;
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
.segmented-entry button {
|
|
1324
|
-
padding: 6px 14px;
|
|
1325
|
-
border: none;
|
|
1326
|
-
border-radius: 6px;
|
|
1327
|
-
font-family: var(--font-body);
|
|
1328
|
-
font-size: 12.5px;
|
|
1329
|
-
font-weight: 600;
|
|
1330
|
-
cursor: pointer;
|
|
1331
|
-
background: transparent;
|
|
1332
|
-
color: var(--text-muted);
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
.segmented-entry button[aria-pressed='true'] {
|
|
1336
|
-
background: var(--surface-raised);
|
|
1337
|
-
color: var(--text-strong);
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
/* The column the wizard's steps live in. 720px, the design's measure for a form — NOT the footer's,
|
|
1341
|
-
which spans the screen. */
|
|
2006
|
+
/* The column the form lives in. 720px, the design's measure for a form — NOT the footer's, which spans
|
|
2007
|
+
the screen. */
|
|
1342
2008
|
/* ── §B — THE MEASURE MOVES OFF THE COLUMN AND ONTO ITS BLOCKS ────────────────────────────────────
|
|
1343
2009
|
The owner: the New clearance page "is bound to an artificially narrow width; the table side-scrolls
|
|
1344
2010
|
or wraps and looks worse than its content deserves. The top panel already fits the screen width."
|
|
@@ -1367,26 +2033,10 @@ input.filter {
|
|
|
1367
2033
|
max-width: none;
|
|
1368
2034
|
}
|
|
1369
2035
|
|
|
1370
|
-
/* ── §B —
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
the only signal, because a marker distinguishable by hue alone is not a marker for every reader. */
|
|
1374
|
-
.carries {
|
|
1375
|
-
margin: 8px 0 0;
|
|
1376
|
-
padding: 0;
|
|
1377
|
-
list-style: none;
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
.carries li {
|
|
1381
|
-
display: flex;
|
|
1382
|
-
gap: 9px;
|
|
1383
|
-
align-items: baseline;
|
|
1384
|
-
font-size: 12.5px;
|
|
1385
|
-
line-height: 1.55;
|
|
1386
|
-
color: var(--text-muted);
|
|
1387
|
-
padding: 2px 0;
|
|
1388
|
-
}
|
|
1389
|
-
|
|
2036
|
+
/* ── §B — what a search carries, in or out at a glance ───────────────────────────────────────────────
|
|
2037
|
+
A list of three sentences of equal weight buried whether an axis ran at all in the clause after the
|
|
2038
|
+
dash. The tick and the cross carry the answer, on every search's row; the colour is a reinforcement,
|
|
2039
|
+
never the only signal, because a marker distinguishable by hue alone is not a marker for every reader. */
|
|
1390
2040
|
.carries-mark {
|
|
1391
2041
|
flex: none;
|
|
1392
2042
|
width: 15px;
|
|
@@ -1544,50 +2194,6 @@ input.filter {
|
|
|
1544
2194
|
background: var(--accent);
|
|
1545
2195
|
}
|
|
1546
2196
|
|
|
1547
|
-
/* The saved-search book SCROLLS rather than growing the page. A customer with forty of them should not
|
|
1548
|
-
push the levers below the fold. */
|
|
1549
|
-
.saved-list {
|
|
1550
|
-
display: flex;
|
|
1551
|
-
flex-direction: column;
|
|
1552
|
-
gap: 7px;
|
|
1553
|
-
max-height: 224px;
|
|
1554
|
-
overflow-y: auto;
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
.saved-row {
|
|
1558
|
-
display: flex;
|
|
1559
|
-
align-items: center;
|
|
1560
|
-
gap: 11px;
|
|
1561
|
-
padding: 11px 14px;
|
|
1562
|
-
border-radius: 9px;
|
|
1563
|
-
border: 1px solid var(--border-hairline);
|
|
1564
|
-
background: var(--surface-raised);
|
|
1565
|
-
cursor: pointer;
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
.saved-row:hover {
|
|
1569
|
-
border-color: var(--accent-ink);
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
.saved-row-on {
|
|
1573
|
-
border-color: var(--accent);
|
|
1574
|
-
background: var(--accent-wash);
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
.saved-retire {
|
|
1578
|
-
flex: none;
|
|
1579
|
-
display: inline-flex;
|
|
1580
|
-
background: none;
|
|
1581
|
-
border: none;
|
|
1582
|
-
color: var(--text-faint);
|
|
1583
|
-
cursor: pointer;
|
|
1584
|
-
padding: 4px;
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
.saved-retire:hover {
|
|
1588
|
-
color: var(--text-accent);
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
2197
|
.lever {
|
|
1592
2198
|
display: flex;
|
|
1593
2199
|
align-items: center;
|
|
@@ -1832,6 +2438,13 @@ input.filter {
|
|
|
1832
2438
|
border-color: var(--text-strong);
|
|
1833
2439
|
}
|
|
1834
2440
|
|
|
2441
|
+
/* The page header's buttons: the same two kinds, sized to sit beside a title. */
|
|
2442
|
+
.btn-sm {
|
|
2443
|
+
padding: 8px 14px;
|
|
2444
|
+
font-size: 13px;
|
|
2445
|
+
border-radius: 8px;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
1835
2448
|
/* ── the confirm dialog ─────────────────────────────────────────────────────────────────────────────
|
|
1836
2449
|
The mandatory step. Nothing is spent until Start is pressed, and Back returns to a fully preserved
|
|
1837
2450
|
form — so the scrim closes it rather than trapping anyone. */
|
|
@@ -1877,7 +2490,10 @@ input.filter {
|
|
|
1877
2490
|
}
|
|
1878
2491
|
|
|
1879
2492
|
.stop-choice-opt {
|
|
1880
|
-
display:
|
|
2493
|
+
display: grid;
|
|
2494
|
+
grid-template-columns: auto 1fr;
|
|
2495
|
+
column-gap: 10px;
|
|
2496
|
+
align-items: baseline;
|
|
1881
2497
|
width: 100%;
|
|
1882
2498
|
text-align: left;
|
|
1883
2499
|
padding: 13px 15px;
|
|
@@ -1892,7 +2508,15 @@ input.filter {
|
|
|
1892
2508
|
border-color: var(--accent-ink);
|
|
1893
2509
|
}
|
|
1894
2510
|
|
|
2511
|
+
/* The radio is the row's own control, drawn in the accent so the selected option reads at a glance. */
|
|
2512
|
+
.stop-choice-opt input {
|
|
2513
|
+
grid-row: 1 / span 2;
|
|
2514
|
+
margin: 2px 0 0;
|
|
2515
|
+
accent-color: var(--accent);
|
|
2516
|
+
}
|
|
2517
|
+
|
|
1895
2518
|
.stop-choice-opt b {
|
|
2519
|
+
grid-column: 2;
|
|
1896
2520
|
display: block;
|
|
1897
2521
|
font-size: 14px;
|
|
1898
2522
|
color: var(--text-strong);
|
|
@@ -1900,6 +2524,7 @@ input.filter {
|
|
|
1900
2524
|
}
|
|
1901
2525
|
|
|
1902
2526
|
.stop-choice-opt span {
|
|
2527
|
+
grid-column: 2;
|
|
1903
2528
|
display: block;
|
|
1904
2529
|
font-size: 12.5px;
|
|
1905
2530
|
line-height: 1.5;
|
|
@@ -1910,6 +2535,12 @@ input.filter {
|
|
|
1910
2535
|
border-color: var(--tone-medium);
|
|
1911
2536
|
}
|
|
1912
2537
|
|
|
2538
|
+
/* THE SELECTED OPTION IS THE ONE THE BUTTON NAMES, so it carries the same accent the button does. */
|
|
2539
|
+
.stop-choice-opt.selected {
|
|
2540
|
+
border-color: var(--accent);
|
|
2541
|
+
background: var(--accent-wash);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
1913
2544
|
.modal-rule {
|
|
1914
2545
|
position: absolute;
|
|
1915
2546
|
left: 0;
|
|
@@ -1968,6 +2599,78 @@ input.filter {
|
|
|
1968
2599
|
.home2-band-count { font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
|
|
1969
2600
|
.home2-band-rule { height: 1px; background: var(--border-hairline); }
|
|
1970
2601
|
|
|
2602
|
+
/* THE ALLOWANCE LINE. Quiet by construction — no band, no heading, no colour — because it states a fact
|
|
2603
|
+
about the account rather than a fault with the form. It appears only at five searches or fewer. */
|
|
2604
|
+
.nc-allowance { margin: -6px 0 18px; font-size: 13px; color: var(--text-muted); }
|
|
2605
|
+
|
|
2606
|
+
/* ── New clearance: one form, top to bottom ──────────────────────────────────────────────────────────
|
|
2607
|
+
Quiet additions to the kit the form already used. The recommendation tag is the one accent on a row
|
|
2608
|
+
that is not selected, because it is the one thing on it the reader did not choose. */
|
|
2609
|
+
.nc-company { max-width: 340px; }
|
|
2610
|
+
.nc-company-name { font-size: 15px; font-weight: 600; color: var(--text-strong); }
|
|
2611
|
+
.nc-project { max-width: 340px; flex: 1; }
|
|
2612
|
+
.nc-describe-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 7px; }
|
|
2613
|
+
.nc-optional { font-size: 11.5px; color: var(--text-faint); }
|
|
2614
|
+
.nc-which-head {
|
|
2615
|
+
display: flex;
|
|
2616
|
+
align-items: flex-end;
|
|
2617
|
+
justify-content: space-between;
|
|
2618
|
+
gap: 12px;
|
|
2619
|
+
flex-wrap: wrap;
|
|
2620
|
+
margin-bottom: 10px;
|
|
2621
|
+
}
|
|
2622
|
+
.nc-templates { display: inline-flex; align-items: flex-end; gap: 8px; }
|
|
2623
|
+
.nc-templates label { display: block; }
|
|
2624
|
+
.nc-templates select { min-width: 190px; }
|
|
2625
|
+
.nc-template-line { margin: 0 0 10px; font-size: 12.5px; line-height: 1.6; color: var(--text-muted); }
|
|
2626
|
+
|
|
2627
|
+
/* A small action beside the thing it acts on — Manage, Manage projects, Clear template, Show all. */
|
|
2628
|
+
.chip-btn {
|
|
2629
|
+
display: inline-flex;
|
|
2630
|
+
align-items: center;
|
|
2631
|
+
padding: 3px 10px;
|
|
2632
|
+
border-radius: 999px;
|
|
2633
|
+
border: 1px solid var(--border-hairline);
|
|
2634
|
+
background: var(--surface-sunken);
|
|
2635
|
+
color: var(--text-muted);
|
|
2636
|
+
font-family: var(--font-body);
|
|
2637
|
+
font-size: 11px;
|
|
2638
|
+
font-weight: 700;
|
|
2639
|
+
white-space: nowrap;
|
|
2640
|
+
cursor: pointer;
|
|
2641
|
+
}
|
|
2642
|
+
.chip-btn:hover { border-color: var(--accent-ink); color: var(--text-accent); }
|
|
2643
|
+
|
|
2644
|
+
/* The search row as a card holding its pick button and, when selected, its own option. */
|
|
2645
|
+
.pick-row-stack { flex-direction: column; align-items: stretch; gap: 10px; }
|
|
2646
|
+
.pick-row-hit {
|
|
2647
|
+
display: flex;
|
|
2648
|
+
align-items: flex-start;
|
|
2649
|
+
gap: 12px;
|
|
2650
|
+
width: 100%;
|
|
2651
|
+
padding: 0;
|
|
2652
|
+
border: 0;
|
|
2653
|
+
background: none;
|
|
2654
|
+
font: inherit;
|
|
2655
|
+
color: inherit;
|
|
2656
|
+
text-align: left;
|
|
2657
|
+
cursor: pointer;
|
|
2658
|
+
}
|
|
2659
|
+
.pick-row-hit:disabled { cursor: default; }
|
|
2660
|
+
.pick-row-inside { margin-left: 27px; }
|
|
2661
|
+
.pick-tag {
|
|
2662
|
+
padding: 1px 8px;
|
|
2663
|
+
border-radius: 999px;
|
|
2664
|
+
border: 1px solid var(--accent-ink);
|
|
2665
|
+
background: var(--accent-wash);
|
|
2666
|
+
color: var(--text-accent);
|
|
2667
|
+
font-size: 10.5px;
|
|
2668
|
+
font-weight: 700;
|
|
2669
|
+
}
|
|
2670
|
+
.pick-row-reason { display: block; margin-top: 3px; font-size: 12px; color: var(--text-body); }
|
|
2671
|
+
.pick-chips { display: flex; flex-wrap: wrap; gap: 3px 16px; margin-top: 6px; font-size: 12px; color: var(--text-muted); }
|
|
2672
|
+
.pick-chips > span { display: inline-flex; align-items: baseline; gap: 6px; }
|
|
2673
|
+
|
|
1971
2674
|
/* A RUNNING RUN AS A ROW. The queue's grid, with the two columns a running row has and a waiting one
|
|
1972
2675
|
does not. Declared as a modifier rather than a new grid so the narrow-screen rule that hides columns
|
|
1973
2676
|
keeps one definition for both. */
|
|
@@ -2120,6 +2823,20 @@ input.filter {
|
|
|
2120
2823
|
margin: 0 0 10px; font-size: 12.5px; font-weight: 600; letter-spacing: .02em; color: var(--text-muted);
|
|
2121
2824
|
}
|
|
2122
2825
|
|
|
2826
|
+
/* THE FOLDS: the key door beside a sign-in door, and "Setup steps" once connected. Both open only when the
|
|
2827
|
+
reader opens them; the summary is the heading, with a chevron that turns when open. */
|
|
2828
|
+
.steps-alt-fold > summary,
|
|
2829
|
+
.steps-fold > summary { display: flex; align-items: center; gap: 10px; list-style: none; cursor: pointer; }
|
|
2830
|
+
.steps-alt-fold > summary::-webkit-details-marker,
|
|
2831
|
+
.steps-fold > summary::-webkit-details-marker { display: none; }
|
|
2832
|
+
.steps-alt-fold > summary .steps-alt-head,
|
|
2833
|
+
.steps-fold > summary .steps-alt-head { margin: 0; }
|
|
2834
|
+
.fold-chev { margin-left: auto; flex: none; color: var(--text-faint); transition: transform 0.15s var(--ease-out); }
|
|
2835
|
+
.steps-alt-fold[open] > summary .fold-chev,
|
|
2836
|
+
.steps-fold[open] > summary > .fold-chev { transform: rotate(90deg); }
|
|
2837
|
+
.steps-alt-fold > ol.steps { margin-top: 14px; }
|
|
2838
|
+
.steps-fold-body { margin-top: 14px; }
|
|
2839
|
+
|
|
2123
2840
|
.home2-acked { margin-top: 13px; }
|
|
2124
2841
|
.home2-acked-toggle {
|
|
2125
2842
|
padding: 0; background: none; border: 0; cursor: pointer; font: inherit; font-size: 12.5px;
|
|
@@ -2304,7 +3021,24 @@ input.filter {
|
|
|
2304
3021
|
|
|
2305
3022
|
.ai-connect { margin-top: 34px; }
|
|
2306
3023
|
|
|
2307
|
-
.ai-screen .ai-connect-head { margin: 0
|
|
3024
|
+
.ai-screen .ai-connect-head { margin: 0; }
|
|
3025
|
+
|
|
3026
|
+
/* "Connect it" and, beside it, whether this reader's assistant has been seen calling. */
|
|
3027
|
+
.ai-connect-top { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
|
3028
|
+
.conn-state {
|
|
3029
|
+
display: inline-flex; align-items: center; gap: 7px; padding: 3px 11px 3px 9px;
|
|
3030
|
+
border: 1px solid var(--border-hairline); border-radius: 999px; background: var(--surface-raised);
|
|
3031
|
+
font-size: 12.5px; color: var(--text-muted);
|
|
3032
|
+
}
|
|
3033
|
+
.conn-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); }
|
|
3034
|
+
.conn-dot-on { background: var(--tone-minimal); }
|
|
3035
|
+
|
|
3036
|
+
/* "Optional", quietly, at the end of the standfirst — never the word the page opens with. */
|
|
3037
|
+
.lede-opt {
|
|
3038
|
+
display: inline-block; margin-left: 6px; padding: 2px 7px; vertical-align: 2px; border-radius: 5px;
|
|
3039
|
+
background: var(--surface-sunken); font-size: 11px; font-weight: 700; letter-spacing: 0.06em;
|
|
3040
|
+
text-transform: uppercase; color: var(--text-faint);
|
|
3041
|
+
}
|
|
2308
3042
|
|
|
2309
3043
|
/* ── THE WHERE-CHOICE ─────────────────────────────────────────────────────────────────────────────
|
|
2310
3044
|
ONE control, the same size before and after a pick. Selection is shown the way every other choice in
|
|
@@ -2370,6 +3104,13 @@ input.filter {
|
|
|
2370
3104
|
card can show — so neither picking an app nor pressing Copy moves anything around it. */
|
|
2371
3105
|
.ai-slot { position: relative; min-height: 180px; }
|
|
2372
3106
|
|
|
3107
|
+
/* A closed fold reserves nothing: the reserved height is for steps that are drawn. */
|
|
3108
|
+
.ai-slot.is-folded { min-height: 0; }
|
|
3109
|
+
|
|
3110
|
+
/* The way back to the report the reader came from, above the steps. */
|
|
3111
|
+
.back-to-report { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
|
|
3112
|
+
.back-to-report-line { font-size: 13.5px; color: var(--text-muted); }
|
|
3113
|
+
|
|
2373
3114
|
/* The hidden copy of every panel the slot's height is taken from. Laid out at the slot's own width, never
|
|
2374
3115
|
seen, never reached by a pointer or a keyboard. */
|
|
2375
3116
|
.ai-probe {
|
|
@@ -2486,6 +3227,9 @@ ol.steps > li::before {
|
|
|
2486
3227
|
|
|
2487
3228
|
.secret-btn { margin-top: 8px; }
|
|
2488
3229
|
|
|
3230
|
+
/* A folded list's buttons are quiet: the steps above the fold are the way in. */
|
|
3231
|
+
.ai-screen .btn-sm { padding: 6px 11px; font-size: 12.5px; }
|
|
3232
|
+
|
|
2489
3233
|
/* THE PRESSED CONTROL IS THE CONFIRMATION: solid accent on the button pressed, never a muted caption. */
|
|
2490
3234
|
.is-copied,
|
|
2491
3235
|
.is-copied:hover,
|
|
@@ -2530,8 +3274,31 @@ ol.steps > li::before {
|
|
|
2530
3274
|
|
|
2531
3275
|
.ai-help p { margin: 6px 0 0; color: var(--text-muted); font-size: 13.5px; line-height: 1.55; }
|
|
2532
3276
|
|
|
3277
|
+
.ai-help-guide { font-size: 12px; text-decoration: none; cursor: pointer; }
|
|
3278
|
+
|
|
3279
|
+
|
|
3280
|
+
/* ── People: what the Permissions column's words mean, under the column ─────────────────────────────────
|
|
3281
|
+
A two-column key, term beside meaning, so each word lines up with the sentence it stands for. */
|
|
3282
|
+
.perm-key {
|
|
3283
|
+
display: grid;
|
|
3284
|
+
grid-template-columns: auto 1fr;
|
|
3285
|
+
gap: 3px 14px;
|
|
3286
|
+
margin: 14px 0 0;
|
|
3287
|
+
font-size: 12.5px;
|
|
3288
|
+
color: var(--text-muted);
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
.perm-key dt {
|
|
3292
|
+
color: var(--text-strong);
|
|
3293
|
+
font-weight: 600;
|
|
3294
|
+
white-space: nowrap;
|
|
3295
|
+
}
|
|
3296
|
+
|
|
3297
|
+
.perm-key dd {
|
|
3298
|
+
margin: 0;
|
|
3299
|
+
}
|
|
2533
3300
|
|
|
2534
|
-
/* ── Give
|
|
3301
|
+
/* ── Give access: the points on the tree a new person can be given ───────────────────────────────────────
|
|
2535
3302
|
One row per point. A BUTTON, because choosing a point is an action and a keyboard has to reach it; the
|
|
2536
3303
|
resets below are what make a button read as a row. `.sub` indents a company under the organisation
|
|
2537
3304
|
it sits in. A row covered by a wider choice above it — everything, or its whole organisation — is
|