@graview/primitives 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/dist/declared-lenses.d.ts.map +1 -1
- package/dist/declared-lenses.js +3 -0
- package/dist/declared-lenses.js.map +1 -1
- package/dist/default-views.js +1 -1
- package/dist/default-views.js.map +1 -1
- package/dist/figure.d.ts.map +1 -1
- package/dist/figure.js +2 -1
- package/dist/figure.js.map +1 -1
- package/dist/frame.d.ts +3 -3
- package/dist/frame.d.ts.map +1 -1
- package/dist/frame.js +4 -3
- package/dist/frame.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lens/columns.d.ts +40 -0
- package/dist/lens/columns.d.ts.map +1 -0
- package/dist/lens/columns.js +197 -0
- package/dist/lens/columns.js.map +1 -0
- package/dist/notices.js +1 -1
- package/dist/notices.js.map +1 -1
- package/dist/primitives/index.d.ts +2 -31
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +3 -42
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/measure.d.ts +32 -0
- package/dist/primitives/measure.d.ts.map +1 -0
- package/dist/primitives/measure.js +51 -0
- package/dist/primitives/measure.js.map +1 -0
- package/dist/scene-css.d.ts +13 -0
- package/dist/scene-css.d.ts.map +1 -0
- package/dist/scene-css.js +735 -0
- package/dist/scene-css.js.map +1 -0
- package/dist/scene.d.ts +1 -0
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +2 -0
- package/dist/scene.js.map +1 -1
- package/dist/spec-views.d.ts +8 -2
- package/dist/spec-views.d.ts.map +1 -1
- package/dist/spec-views.js +8 -4
- package/dist/spec-views.js.map +1 -1
- package/dist/theme.d.ts +3 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +13 -706
- package/dist/theme.js.map +1 -1
- package/dist/workbench/back-out.d.ts +2 -16
- package/dist/workbench/back-out.d.ts.map +1 -1
- package/dist/workbench/back-out.js +3 -22
- package/dist/workbench/back-out.js.map +1 -1
- package/dist/workbench/descent.d.ts +17 -0
- package/dist/workbench/descent.d.ts.map +1 -0
- package/dist/workbench/descent.js +24 -0
- package/dist/workbench/descent.js.map +1 -0
- package/package.json +6 -6
package/dist/theme.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* without reaching into the UI package.
|
|
27
27
|
*/
|
|
28
28
|
export { DARK, LIGHT, SCHEMES } from "@graview/core";
|
|
29
|
-
import {
|
|
29
|
+
import { SCHEMES, kitVariables, layer, layerVariables, resolveKit, SCENE_LAYERS, shapeOf, TYPOGRAPHY, typographyOf } from "@graview/core";
|
|
30
30
|
import { SPEC_VIEW_CSS } from "./spec-css.js";
|
|
31
31
|
/**
|
|
32
32
|
* The framework's own brand, expressed as an ordinary declared one.
|
|
@@ -104,8 +104,16 @@ function stillness(asking, within) {
|
|
|
104
104
|
* <style> (FR-57). As a JS comment in an empty interpolation the words stay
|
|
105
105
|
* where they explain the rule, and a minifier folds them away.
|
|
106
106
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
/*
|
|
108
|
+
* THE SHEET WITHOUT THE SCENE (FR-104). What every face draws on: the
|
|
109
|
+
* tokens, the type, the panels, the views as data, motion. The scene's own
|
|
110
|
+
* rules — the districts from altitude, the plots, the village, the roads,
|
|
111
|
+
* the billboards, the bands — are `sceneCss` (scene-css.ts), which the
|
|
112
|
+
* scene face draws beside it, so a page that opens on the pages face
|
|
113
|
+
* carries none of them. `themeCss` is the two together, in that order.
|
|
114
|
+
*/
|
|
115
|
+
export function themeBaseCss(scheme = "dark", brand = GRAVIEW_BRAND, options = {}) {
|
|
116
|
+
const css = baseSheet(scheme, brand, options);
|
|
109
117
|
return options.scope === undefined ? css : withinTheBox(css, options.scope);
|
|
110
118
|
}
|
|
111
119
|
/*
|
|
@@ -124,7 +132,7 @@ export function themeCss(scheme = "dark", brand = GRAVIEW_BRAND, options = {}) {
|
|
|
124
132
|
* keyframes) names no element and is left as it is; @media and @supports
|
|
125
133
|
* are walked into.
|
|
126
134
|
*/
|
|
127
|
-
function withinTheBox(css, scope) {
|
|
135
|
+
export function withinTheBox(css, scope) {
|
|
128
136
|
const under = `:where(${scope}) `;
|
|
129
137
|
const at = (selector) => selector === scope ||
|
|
130
138
|
selector.startsWith(`${scope} `) ||
|
|
@@ -211,11 +219,7 @@ function splitSelectors(list) {
|
|
|
211
219
|
out.push(current.trim());
|
|
212
220
|
return out;
|
|
213
221
|
}
|
|
214
|
-
|
|
215
|
-
const face = (f) => `${f.saturation}% ${f.lightness}%`;
|
|
216
|
-
/** A translucent one, with its alpha. */
|
|
217
|
-
const wash = (f) => `${face(f)} / ${f.alpha}`;
|
|
218
|
-
function sheet(scheme, brand, options) {
|
|
222
|
+
export function baseSheet(scheme, brand, options) {
|
|
219
223
|
const tokens = brand.schemes[scheme];
|
|
220
224
|
const root = options.scope ?? ":root";
|
|
221
225
|
const surface = options.scope ?? "html, body";
|
|
@@ -251,7 +255,6 @@ function sheet(scheme, brand, options) {
|
|
|
251
255
|
*/
|
|
252
256
|
const shape = shapeOf(brand);
|
|
253
257
|
const type = typographyOf(brand);
|
|
254
|
-
const iso = isoShade(scheme);
|
|
255
258
|
const kit = resolveKit(brand.kit);
|
|
256
259
|
return `${root} {
|
|
257
260
|
${themeVariables(tokens)}
|
|
@@ -441,9 +444,6 @@ ${ /* A card on the kinds plane.
|
|
|
441
444
|
floats above the card and the block stands up out of it. */""}
|
|
442
445
|
overflow: clip;
|
|
443
446
|
}
|
|
444
|
-
[data-graview-altitude] .graview-kind-card {
|
|
445
|
-
overflow: visible;
|
|
446
|
-
}
|
|
447
447
|
.graview-kind-card:hover,
|
|
448
448
|
.graview-kind-card:focus-within {
|
|
449
449
|
height: auto;
|
|
@@ -452,15 +452,6 @@ ${ /* A card on the kinds plane.
|
|
|
452
452
|
position: relative;
|
|
453
453
|
z-index: ${SCENE_LAYERS.lines};
|
|
454
454
|
}
|
|
455
|
-
${ /* From altitude a district is a village on its plot, not a card: hovering
|
|
456
|
-
it must not raise a white panel over the buildings. The lift stays in
|
|
457
|
-
the stack, where the card is a card. */""}
|
|
458
|
-
[data-graview-altitude] .graview-kind-card:hover,
|
|
459
|
-
[data-graview-altitude] .graview-kind-card:focus-within {
|
|
460
|
-
transform: none;
|
|
461
|
-
box-shadow: none;
|
|
462
|
-
background: transparent;
|
|
463
|
-
}
|
|
464
455
|
|
|
465
456
|
${ /* FROM ALTITUDE the ground is an ISOMETRIC LATTICE — diamond cells at the
|
|
466
457
|
classic 2:1 pitch, a finer far weave above, dissolving toward the
|
|
@@ -501,79 +492,6 @@ ${ /* DRAWN AS TILES, one cell each. A repeating gradient at the lattice's
|
|
|
501
492
|
-webkit-mask-image: linear-gradient(to top, #000 42%, rgba(0,0,0,0.35) 70%, transparent 92%);
|
|
502
493
|
}
|
|
503
494
|
|
|
504
|
-
${ /* THE GROUND UNDER A DISTRICT: its plot, drawn. Four lattice corners in
|
|
505
|
-
the kind's hue, a kerb, a cast shadow toward the light — the arithmetic
|
|
506
|
-
the layout already did, made visible, so a district stands on land
|
|
507
|
-
rather than floating on a hatch. Fades in with the altitude number the
|
|
508
|
-
lattice fades in with; a hand-placed district's kerb is dashed, which is
|
|
509
|
-
the pinned mark on the ground rather than a box over the drawing. */""}
|
|
510
|
-
.graview-plots {
|
|
511
|
-
z-index: ${SCENE_LAYERS.plots};
|
|
512
|
-
opacity: var(--graview-altitude);
|
|
513
|
-
transition: opacity 640ms cubic-bezier(0.33, 0, 0.2, 1);
|
|
514
|
-
}
|
|
515
|
-
.graview-plot-tile {
|
|
516
|
-
fill: hsl(var(--graview-hue, 200) ${wash(iso.plot)});
|
|
517
|
-
stroke: hsl(var(--graview-hue, 200) ${wash(iso.plotEdge)});
|
|
518
|
-
stroke-width: 1;
|
|
519
|
-
stroke-linejoin: round;
|
|
520
|
-
pointer-events: auto;
|
|
521
|
-
cursor: pointer;
|
|
522
|
-
filter: drop-shadow(${scheme === "light" ? "5px 4px 6px rgba(20,30,32,0.14)" : "6px 5px 8px rgba(0,0,0,0.4)"});
|
|
523
|
-
transition: fill 170ms ease;
|
|
524
|
-
}
|
|
525
|
-
.graview-plot-tile:hover {
|
|
526
|
-
fill: hsl(var(--graview-hue, 200) 45% ${scheme === "light" ? "58%" : "48%"} / ${scheme === "light" ? "0.2" : "0.3"});
|
|
527
|
-
}
|
|
528
|
-
.graview-plot[data-graview-pinned] .graview-plot-tile {
|
|
529
|
-
stroke-dasharray: 4 3;
|
|
530
|
-
}
|
|
531
|
-
${ /* THE VILLAGE on the tile: one small iso building per member in the kind's
|
|
532
|
-
own faces (the same roof and walls the block had), a flagged member's roof
|
|
533
|
-
in the warning colour, a selected member's building lit in the accent.
|
|
534
|
-
Architecture, not controls: the tile under them takes the click. */""}
|
|
535
|
-
.graview-village { pointer-events: none; }
|
|
536
|
-
.graview-building polygon { stroke-width: 0.8; }
|
|
537
|
-
.graview-building[data-graview-flagged] .graview-iso-roof { fill: var(--graview-warn); stroke: var(--graview-warn); }
|
|
538
|
-
.graview-building[data-graview-selected] polygon { stroke: var(--graview-accent); stroke-width: 1.4; }
|
|
539
|
-
.graview-building[data-graview-selected] .graview-iso-roof { fill: color-mix(in oklab, var(--graview-accent) 45%, var(--graview-panel)); }
|
|
540
|
-
.graview-village-rest {
|
|
541
|
-
font-size: 0.75rem;
|
|
542
|
-
letter-spacing: 0.06em;
|
|
543
|
-
fill: var(--graview-ink-muted);
|
|
544
|
-
}
|
|
545
|
-
${ /* THE ROADS between plots: the lattice's own two legs from kerb to kerb, a
|
|
546
|
-
bed between two edges in the ground's ink. Under the tiles and the
|
|
547
|
-
buildings, over the fields. A road the legend is asking about comes up
|
|
548
|
-
in the accent. */""}
|
|
549
|
-
.graview-road-edge {
|
|
550
|
-
fill: none;
|
|
551
|
-
stroke: var(--graview-ink);
|
|
552
|
-
stroke-opacity: ${scheme === "light" ? "0.28" : "0.4"};
|
|
553
|
-
stroke-width: 7;
|
|
554
|
-
stroke-linejoin: round;
|
|
555
|
-
stroke-linecap: round;
|
|
556
|
-
}
|
|
557
|
-
.graview-road-bed {
|
|
558
|
-
fill: none;
|
|
559
|
-
stroke: var(--graview-ground);
|
|
560
|
-
stroke-width: 5;
|
|
561
|
-
stroke-linejoin: round;
|
|
562
|
-
stroke-linecap: round;
|
|
563
|
-
}
|
|
564
|
-
.graview-road[data-graview-lit] .graview-road-edge {
|
|
565
|
-
stroke: var(--graview-accent);
|
|
566
|
-
stroke-opacity: 0.9;
|
|
567
|
-
}
|
|
568
|
-
${ /* FIELDS. From altitude the ground darkens a shade toward the near edge and
|
|
569
|
-
fades to the page at the horizon, so the lattice is land with a distance
|
|
570
|
-
rather than paper with a pattern. */""}
|
|
571
|
-
.graview-ground[data-graview-altitude] {
|
|
572
|
-
background:
|
|
573
|
-
linear-gradient(to top, color-mix(in oklab, var(--graview-ground) ${scheme === "light" ? "93%" : "88%"}, var(--graview-ink)) 0%, var(--graview-ground) 78%),
|
|
574
|
-
var(--graview-ground);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
495
|
${ /* THE KEEPER'S BLOCK IN THE PROFILE, which hides itself when it is empty.
|
|
578
496
|
Both controls inside it draw nothing for a seat that may not administer,
|
|
579
497
|
and a heading with nothing under it is worse than no heading — so the
|
|
@@ -587,72 +505,11 @@ ${ /* A host's own action in the profile (FR-72): a row of the pane, lit where t
|
|
|
587
505
|
background: var(--graview-wash);
|
|
588
506
|
color: var(--graview-accent);
|
|
589
507
|
}
|
|
590
|
-
|
|
591
|
-
${ /* THE OPEN CHEVRON APPEARS WHEN REACHED FOR. Drawn on every plate at
|
|
592
|
-
altitude it was noise times the number of districts; it shows on hover,
|
|
593
|
-
on keyboard focus, and while the district is open — and stays a real
|
|
594
|
-
button in between, so Tab still finds it and Enter still opens. */""}
|
|
595
|
-
[data-graview-altitude] .graview-kind-open {
|
|
596
|
-
opacity: 0.5;
|
|
597
|
-
transition: opacity 150ms ease;
|
|
598
|
-
}
|
|
599
|
-
${ /* Quiet: the chevron alone until reached for. Never opacity zero — a
|
|
600
|
-
button nobody can see is a button a driven browser cannot press either,
|
|
601
|
-
and Tab must land on something that looks like something. */""}
|
|
602
|
-
[data-graview-altitude] .graview-kind-open-word {
|
|
603
|
-
display: none;
|
|
604
|
-
}
|
|
605
|
-
[data-graview-altitude] .graview-kind-card:hover .graview-kind-open,
|
|
606
|
-
[data-graview-altitude] .graview-kind-card:focus-within .graview-kind-open,
|
|
607
|
-
[data-graview-altitude] .graview-kind-open[aria-expanded="true"] {
|
|
608
|
-
opacity: 1;
|
|
609
|
-
}
|
|
610
|
-
[data-graview-altitude] .graview-kind-card:hover .graview-kind-open-word,
|
|
611
|
-
[data-graview-altitude] .graview-kind-card:focus-within .graview-kind-open-word,
|
|
612
|
-
[data-graview-altitude] .graview-kind-open[aria-expanded="true"] .graview-kind-open-word {
|
|
613
|
-
display: inline;
|
|
614
|
-
}
|
|
615
508
|
${ /* The district-open control and its roster: altitude-only chrome. Inside
|
|
616
509
|
the stack expanding dissolves a card, so the control does not exist
|
|
617
510
|
there. A full fingertip even though the glyph is small — the audit holds
|
|
618
511
|
every control to 24px. */""}
|
|
619
512
|
.graview-kind-open { display: none; }
|
|
620
|
-
[data-graview-altitude] .graview-kind-open {
|
|
621
|
-
display: inline-flex;
|
|
622
|
-
align-items: center;
|
|
623
|
-
justify-content: center;
|
|
624
|
-
flex: 0 0 auto;
|
|
625
|
-
${ /* A FINGERTIP, AND THE READER'S FINGERTIP IF IT IS BIGGER. 24px is the
|
|
626
|
-
floor audit-ui holds every control to; 1.5rem is the same 24 at the
|
|
627
|
-
default text size and grows with a reader who asked for more, so the
|
|
628
|
-
control never drifts under the words it sits beside. A max() rather than
|
|
629
|
-
either one alone: rem alone drops below the fingertip at a smaller
|
|
630
|
-
setting, px alone ignores the setting altogether. */""}
|
|
631
|
-
min-height: max(1.5rem, 24px);
|
|
632
|
-
padding: 1px 9px;
|
|
633
|
-
margin: -3px 0;
|
|
634
|
-
border-radius: 999px;
|
|
635
|
-
border: 1px solid var(--graview-edge);
|
|
636
|
-
background: var(--graview-panel);
|
|
637
|
-
box-shadow: none;
|
|
638
|
-
color: var(--graview-ink-muted);
|
|
639
|
-
cursor: pointer;
|
|
640
|
-
${ /* IN REM, LIKE EVERY OTHER SIZE HERE. At 10px this control's words were
|
|
641
|
-
the one piece of text in the framework that ignored the reader's text
|
|
642
|
-
size completely: set to Largest, every name on the screen doubled and
|
|
643
|
-
"open" stayed ten pixels tall. A size a person chose and a control that
|
|
644
|
-
will not take it is the accessibility setting failing on its own
|
|
645
|
-
surface. */""}
|
|
646
|
-
font-size: 0.75rem;
|
|
647
|
-
letter-spacing: 0.08em;
|
|
648
|
-
text-transform: uppercase;
|
|
649
|
-
line-height: 1;
|
|
650
|
-
white-space: nowrap;
|
|
651
|
-
}
|
|
652
|
-
[data-graview-altitude] .graview-kind-open:hover {
|
|
653
|
-
color: var(--graview-accent);
|
|
654
|
-
border-color: var(--graview-accent-dim);
|
|
655
|
-
}
|
|
656
513
|
${ /* The roster reads as a LIST, one member a row — chips wrapping at their
|
|
657
514
|
own widths read as spilled tiles, and a district's population is a roll
|
|
658
515
|
call, not a mosaic. */""}
|
|
@@ -764,68 +621,6 @@ ${ /* The press: the whole frame, laid over the picture and the title rather tha
|
|
|
764
621
|
overflow: hidden;
|
|
765
622
|
text-overflow: ellipsis;
|
|
766
623
|
}
|
|
767
|
-
${ /* THE BILLBOARD'S FULL-SCREEN CONTROL: the one way down from a picture. */""}
|
|
768
|
-
${ /* THE RAIL A BILLBOARD IS MOVED BY: a title bar, in the board's own frame
|
|
769
|
-
ink, along its top edge. Positioned like the full-screen control beside
|
|
770
|
-
it — the host wraps its children, so the rail is a grandchild of the
|
|
771
|
-
screen box and a child selector never reaches it. Wide enough to be an
|
|
772
|
-
easy target, short enough that the picture underneath is still what you
|
|
773
|
-
see, and present only at altitude, because only up there is the board
|
|
774
|
-
standing on a plot it could be moved around. */""}
|
|
775
|
-
.graview-screen-grip {
|
|
776
|
-
display: none;
|
|
777
|
-
}
|
|
778
|
-
[data-graview-altitude] [data-graview-screen] .graview-screen-grip {
|
|
779
|
-
display: flex;
|
|
780
|
-
align-items: center;
|
|
781
|
-
gap: 8px;
|
|
782
|
-
position: absolute;
|
|
783
|
-
left: 0;
|
|
784
|
-
right: 0;
|
|
785
|
-
top: 0;
|
|
786
|
-
${ /* Drawn height, not CSS height: a district's plane is scaled down at
|
|
787
|
-
altitude, and 14 here reached the screen as an eight-pixel strip that
|
|
788
|
-
took three attempts to catch. */""}
|
|
789
|
-
height: 32px;
|
|
790
|
-
padding: 0 6px 0 12px;
|
|
791
|
-
box-sizing: border-box;
|
|
792
|
-
cursor: grab;
|
|
793
|
-
${ /* A title bar in the panel's own colours, not a grey strip: the board is
|
|
794
|
-
a window onto the picture, and its bar reads as the window's. */""}
|
|
795
|
-
background: var(--graview-panel-muted);
|
|
796
|
-
border-bottom: 1px solid var(--graview-edge);
|
|
797
|
-
z-index: ${SCENE_LAYERS.lines};
|
|
798
|
-
}
|
|
799
|
-
[data-graview-altitude] [data-graview-screen] .graview-screen-title {
|
|
800
|
-
flex: 1 1 auto;
|
|
801
|
-
min-width: 0;
|
|
802
|
-
overflow: hidden;
|
|
803
|
-
text-overflow: ellipsis;
|
|
804
|
-
white-space: nowrap;
|
|
805
|
-
font-size: 0.8125rem;
|
|
806
|
-
font-weight: 600;
|
|
807
|
-
color: var(--graview-ink);
|
|
808
|
-
}
|
|
809
|
-
[data-graview-altitude] [data-graview-screen] .graview-screen-grip:active {
|
|
810
|
-
cursor: grabbing;
|
|
811
|
-
}
|
|
812
|
-
.graview-screen-fullscreen {
|
|
813
|
-
flex: 0 0 auto;
|
|
814
|
-
min-height: max(1.5rem, 24px);
|
|
815
|
-
padding: 1px 10px;
|
|
816
|
-
border-radius: 999px;
|
|
817
|
-
border: 1px solid var(--graview-edge);
|
|
818
|
-
background: var(--graview-panel);
|
|
819
|
-
color: var(--graview-accent);
|
|
820
|
-
font-size: 0.8125rem;
|
|
821
|
-
font-weight: 600;
|
|
822
|
-
white-space: nowrap;
|
|
823
|
-
cursor: pointer;
|
|
824
|
-
box-shadow: none;
|
|
825
|
-
}
|
|
826
|
-
.graview-screen-fullscreen:hover:not(:disabled) {
|
|
827
|
-
border-color: var(--graview-accent);
|
|
828
|
-
}
|
|
829
624
|
.graview-drive-in-marquee > button.graview-drive-in-thumb {
|
|
830
625
|
font-size: 0.75rem;
|
|
831
626
|
line-height: 1.2;
|
|
@@ -967,255 +762,6 @@ ${ /* Off the visible ground: an indicator at the border, pointing at it. */""}
|
|
|
967
762
|
margin-top: 7px;
|
|
968
763
|
animation: graview-settle 240ms ease backwards;
|
|
969
764
|
}
|
|
970
|
-
[data-graview-altitude] .graview-kind-members > [data-graview-pick] {
|
|
971
|
-
width: 100%;
|
|
972
|
-
box-sizing: border-box;
|
|
973
|
-
justify-content: flex-start;
|
|
974
|
-
max-width: none;
|
|
975
|
-
}
|
|
976
|
-
${ /* An OPENED district is a PANEL, not a pill with a list stuffed in it:
|
|
977
|
-
name and count share the header line, the roster sits under a hairline,
|
|
978
|
-
and the block behind fades — the plate IS the district while it is
|
|
979
|
-
open, so no roof pokes out above the roster. */""}
|
|
980
|
-
[data-graview-altitude] .graview-kind-face[data-graview-opened] {
|
|
981
|
-
${ /* A header that WRAPS rather than a grid that squeezes: the name's column
|
|
982
|
-
was minmax(0, 1fr) beside the count's auto, so "VEHICLES" beside
|
|
983
|
-
"291 · +29 past · close" got 25 pixels and the count was drawn over it. */""}
|
|
984
|
-
display: flex !important;
|
|
985
|
-
flex-wrap: wrap;
|
|
986
|
-
justify-content: flex-start !important;
|
|
987
|
-
align-items: baseline !important;
|
|
988
|
-
column-gap: 10px;
|
|
989
|
-
row-gap: 2px;
|
|
990
|
-
border-radius: 12px !important;
|
|
991
|
-
padding: 10px 12px 11px !important;
|
|
992
|
-
width: 236px;
|
|
993
|
-
max-width: 236px;
|
|
994
|
-
box-shadow: var(--graview-lift-high) !important;
|
|
995
|
-
}
|
|
996
|
-
[data-graview-altitude] .graview-kind-face[data-graview-opened] .graview-kind-members {
|
|
997
|
-
flex: 1 0 100%;
|
|
998
|
-
margin-top: 8px;
|
|
999
|
-
padding-top: 8px;
|
|
1000
|
-
border-top: 1px solid var(--graview-edge);
|
|
1001
|
-
}
|
|
1002
|
-
[data-graview-altitude] .graview-kind-block[data-graview-opened] {
|
|
1003
|
-
opacity: calc(var(--graview-altitude) * 0.22);
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
${ /* WHAT KIND OF THING THIS IS, astride the focus panel's top-right edge —
|
|
1007
|
-
the kind's dot and its name, the same thread the chips and the legend
|
|
1008
|
-
carry. Scene chrome, so no view has to remember to say it. */""}
|
|
1009
|
-
.graview-kind-tag {
|
|
1010
|
-
position: absolute;
|
|
1011
|
-
top: -9px;
|
|
1012
|
-
right: 14px;
|
|
1013
|
-
z-index: ${SCENE_LAYERS.tag};
|
|
1014
|
-
display: var(--graview-kit-tags, inline-flex);
|
|
1015
|
-
align-items: center;
|
|
1016
|
-
gap: 5px;
|
|
1017
|
-
padding: 2px 8px;
|
|
1018
|
-
border-radius: 999px;
|
|
1019
|
-
${ /* The kind's own hue on the border and the words, so the tag and the
|
|
1020
|
-
district it belongs to read as one thread. */""}
|
|
1021
|
-
border: 1px solid hsl(var(--graview-hue, 200) 45% var(--graview-tint-lightness) / 0.55);
|
|
1022
|
-
color: hsl(var(--graview-hue, 200) 45% calc(var(--graview-tint-lightness) + ${scheme === "light" ? "-32%" : "28%"}));
|
|
1023
|
-
background: var(--graview-float);
|
|
1024
|
-
box-shadow: var(--graview-lift-low);
|
|
1025
|
-
font-size: 0.6875rem;
|
|
1026
|
-
letter-spacing: 0.14em;
|
|
1027
|
-
text-transform: uppercase;
|
|
1028
|
-
color: var(--graview-ink-faint);
|
|
1029
|
-
pointer-events: none;
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
${ /* A LINE UNDER THE POINTER says it will take the press: the invisible hit
|
|
1033
|
-
run ghosts in, so editability is discoverable by hovering the relation
|
|
1034
|
-
itself rather than by rumor. */""}
|
|
1035
|
-
.graview-edge-hit:hover {
|
|
1036
|
-
stroke: var(--graview-accent);
|
|
1037
|
-
opacity: 0.3;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
${ /* THE DISTRICTS THE ROW COULD NOT HOLD.
|
|
1041
|
-
Not a district: no figure, no count, no tint of its own. A card that is
|
|
1042
|
-
one control — how many more, and a press — and, open, a panel above the
|
|
1043
|
-
row naming every district with what it holds. Solid rather than dashed
|
|
1044
|
-
and faded: a dashed, translucent card read as a placeholder, and the only
|
|
1045
|
-
way to five districts should not look like something that failed to load. */""}
|
|
1046
|
-
${ /* A RELATION THE BAND COULD NOT HOLD: a group with its count and first names,
|
|
1047
|
-
or the door to the rest. A card like the others, never the kind's lens small. */""}
|
|
1048
|
-
.graview-band-group {
|
|
1049
|
-
display: grid;
|
|
1050
|
-
align-content: center;
|
|
1051
|
-
gap: 2px;
|
|
1052
|
-
height: 100%;
|
|
1053
|
-
${ /* A card you press, held to the floor every pressable piece of chrome keeps. */""}
|
|
1054
|
-
min-height: max(1.75rem, 28px);
|
|
1055
|
-
box-sizing: border-box;
|
|
1056
|
-
padding: 6px 10px;
|
|
1057
|
-
border-radius: var(--graview-radius-sm, 8px);
|
|
1058
|
-
border: 1px solid var(--graview-edge);
|
|
1059
|
-
background: var(--graview-panel);
|
|
1060
|
-
color: var(--graview-ink);
|
|
1061
|
-
overflow: hidden;
|
|
1062
|
-
cursor: pointer;
|
|
1063
|
-
}
|
|
1064
|
-
.graview-band-group[data-graview-band="picture"] {
|
|
1065
|
-
border-style: dashed;
|
|
1066
|
-
}
|
|
1067
|
-
.graview-band-group[data-graview-emphasis="lit"] {
|
|
1068
|
-
border-color: var(--graview-accent);
|
|
1069
|
-
}
|
|
1070
|
-
.graview-band-group[data-graview-emphasis="dimmed"] {
|
|
1071
|
-
opacity: 0.5;
|
|
1072
|
-
}
|
|
1073
|
-
.graview-band-group-head {
|
|
1074
|
-
display: flex;
|
|
1075
|
-
align-items: baseline;
|
|
1076
|
-
gap: 6px;
|
|
1077
|
-
min-width: 0;
|
|
1078
|
-
}
|
|
1079
|
-
.graview-band-group-name {
|
|
1080
|
-
flex: 1;
|
|
1081
|
-
min-width: 0;
|
|
1082
|
-
font-weight: 600;
|
|
1083
|
-
font-size: 0.9375rem;
|
|
1084
|
-
line-height: 1.25;
|
|
1085
|
-
white-space: nowrap;
|
|
1086
|
-
overflow: hidden;
|
|
1087
|
-
text-overflow: ellipsis;
|
|
1088
|
-
}
|
|
1089
|
-
.graview-band-group-open {
|
|
1090
|
-
font-size: 0.75rem;
|
|
1091
|
-
color: var(--graview-accent);
|
|
1092
|
-
}
|
|
1093
|
-
.graview-band-group-names {
|
|
1094
|
-
font-size: 0.8125rem;
|
|
1095
|
-
line-height: 1.3;
|
|
1096
|
-
color: var(--graview-ink-muted);
|
|
1097
|
-
white-space: nowrap;
|
|
1098
|
-
overflow: hidden;
|
|
1099
|
-
text-overflow: ellipsis;
|
|
1100
|
-
}
|
|
1101
|
-
.graview-band-group-count {
|
|
1102
|
-
color: var(--graview-ink);
|
|
1103
|
-
font-variant-numeric: tabular-nums;
|
|
1104
|
-
}
|
|
1105
|
-
.graview-beyond {
|
|
1106
|
-
position: relative;
|
|
1107
|
-
height: 100%;
|
|
1108
|
-
box-sizing: border-box;
|
|
1109
|
-
border-radius: var(--graview-radius-sm, 8px);
|
|
1110
|
-
border: 1px solid var(--graview-edge);
|
|
1111
|
-
background: var(--graview-panel);
|
|
1112
|
-
}
|
|
1113
|
-
.graview-beyond-more {
|
|
1114
|
-
display: flex;
|
|
1115
|
-
align-items: center;
|
|
1116
|
-
gap: 6px;
|
|
1117
|
-
width: 100%;
|
|
1118
|
-
height: 100%;
|
|
1119
|
-
min-height: max(1.75rem, 28px);
|
|
1120
|
-
padding: var(--graview-pad-sm, 8px);
|
|
1121
|
-
box-sizing: border-box;
|
|
1122
|
-
border: none;
|
|
1123
|
-
border-radius: inherit;
|
|
1124
|
-
background: none;
|
|
1125
|
-
color: var(--graview-ink-muted);
|
|
1126
|
-
cursor: pointer;
|
|
1127
|
-
font: inherit;
|
|
1128
|
-
font-size: 0.875rem;
|
|
1129
|
-
text-align: left;
|
|
1130
|
-
}
|
|
1131
|
-
.graview-beyond-more:hover,
|
|
1132
|
-
.graview-beyond[data-graview-beyond-open] .graview-beyond-more {
|
|
1133
|
-
color: var(--graview-accent);
|
|
1134
|
-
background: var(--graview-wash);
|
|
1135
|
-
}
|
|
1136
|
-
.graview-beyond-count {
|
|
1137
|
-
font-family: var(--graview-font-display);
|
|
1138
|
-
font-size: 1.1875rem;
|
|
1139
|
-
line-height: 1;
|
|
1140
|
-
color: inherit;
|
|
1141
|
-
}
|
|
1142
|
-
.graview-beyond-word {
|
|
1143
|
-
font-size: 0.75rem;
|
|
1144
|
-
letter-spacing: 0.08em;
|
|
1145
|
-
text-transform: uppercase;
|
|
1146
|
-
}
|
|
1147
|
-
.graview-beyond-chevron {
|
|
1148
|
-
margin-left: auto;
|
|
1149
|
-
font-size: 0.8125rem;
|
|
1150
|
-
}
|
|
1151
|
-
${ /* The panel stands above the card, inside the scene, and never clips: the
|
|
1152
|
-
card's box is a district's height, which holds a count and not a list. */""}
|
|
1153
|
-
.graview-beyond-list {
|
|
1154
|
-
position: absolute;
|
|
1155
|
-
left: 0;
|
|
1156
|
-
bottom: calc(100% + 6px);
|
|
1157
|
-
${ /* On the ground, over every plane — the focused card on plane zero
|
|
1158
|
-
painted over a panel drawn on plane two, and a menu under a card is
|
|
1159
|
-
no menu. Above the zoom control too, which is the only other thing
|
|
1160
|
-
that stands on the ground. */""}
|
|
1161
|
-
z-index: ${layer("popover")};
|
|
1162
|
-
margin: 0;
|
|
1163
|
-
padding: 6px;
|
|
1164
|
-
list-style: none;
|
|
1165
|
-
display: flex;
|
|
1166
|
-
flex-direction: column;
|
|
1167
|
-
gap: 1px;
|
|
1168
|
-
${ /* Its own width, not the ground's: portalled, a percentage here is the
|
|
1169
|
-
whole scene. */""}
|
|
1170
|
-
min-width: 200px;
|
|
1171
|
-
max-width: min(280px, 92%);
|
|
1172
|
-
max-height: 60vh;
|
|
1173
|
-
overflow: auto;
|
|
1174
|
-
border-radius: var(--graview-radius-sm, 8px);
|
|
1175
|
-
border: 1px solid var(--graview-edge);
|
|
1176
|
-
background: var(--graview-panel);
|
|
1177
|
-
box-shadow: 0 18px 44px -18px rgba(0, 0, 0, 0.45);
|
|
1178
|
-
}
|
|
1179
|
-
.graview-beyond-list button {
|
|
1180
|
-
display: flex;
|
|
1181
|
-
align-items: center;
|
|
1182
|
-
gap: 10px;
|
|
1183
|
-
width: 100%;
|
|
1184
|
-
${ /* A FINGERTIP WHERE IT IS ACTUALLY DRAWN, not where it was designed.
|
|
1185
|
-
Every other control in this sheet is floored at 24 and the audit divides
|
|
1186
|
-
by the plane's scale before judging it, which is right for a control
|
|
1187
|
-
that sits ON a large target: the chip's disclosure is small, and the
|
|
1188
|
-
card behind it is the size of a card. These names are not that. They are
|
|
1189
|
-
the ONLY way to the districts the row could not hold, and plane two is
|
|
1190
|
-
drawn at 0.90 — so a designed 24 meets a finger as 21.7. Designed at 28
|
|
1191
|
-
it is drawn at 25, which is the number the floor was always about. */""}
|
|
1192
|
-
min-height: max(1.75rem, 28px);
|
|
1193
|
-
padding: 0 8px;
|
|
1194
|
-
border: none;
|
|
1195
|
-
border-radius: var(--graview-radius-sm, 6px);
|
|
1196
|
-
background: none;
|
|
1197
|
-
color: var(--graview-ink);
|
|
1198
|
-
cursor: pointer;
|
|
1199
|
-
font: inherit;
|
|
1200
|
-
font-size: 0.875rem;
|
|
1201
|
-
text-align: left;
|
|
1202
|
-
overflow-wrap: anywhere;
|
|
1203
|
-
white-space: nowrap;
|
|
1204
|
-
}
|
|
1205
|
-
.graview-beyond-list button:hover {
|
|
1206
|
-
color: var(--graview-accent);
|
|
1207
|
-
background: var(--graview-wash);
|
|
1208
|
-
}
|
|
1209
|
-
.graview-beyond-list button[aria-current] {
|
|
1210
|
-
color: var(--graview-ink-muted);
|
|
1211
|
-
cursor: default;
|
|
1212
|
-
}
|
|
1213
|
-
.graview-beyond-tally {
|
|
1214
|
-
margin-left: auto;
|
|
1215
|
-
font-size: 0.75rem;
|
|
1216
|
-
font-variant-numeric: tabular-nums;
|
|
1217
|
-
color: var(--graview-ink-faint);
|
|
1218
|
-
}
|
|
1219
765
|
|
|
1220
766
|
${ /* The way into the archive, on the card that fed it: quiet, but a real
|
|
1221
767
|
control at a real size. */""}
|
|
@@ -1303,17 +849,6 @@ ${ /* A district STANDS: an isometric block — roof, two shaded walls — whose
|
|
|
1303
849
|
transform: translateY(calc((1 - var(--graview-altitude)) * 18px));
|
|
1304
850
|
filter: drop-shadow(${scheme === "light" ? "10px 7px 14px rgba(20,30,32,0.28)" : "12px 8px 18px rgba(0,0,0,0.6)"});
|
|
1305
851
|
}
|
|
1306
|
-
.graview-iso-roof {
|
|
1307
|
-
fill: hsl(var(--graview-hue, 200) ${face(iso.roof)});
|
|
1308
|
-
stroke: ${iso.roofEdge};
|
|
1309
|
-
stroke-width: 1;
|
|
1310
|
-
}
|
|
1311
|
-
.graview-iso-right {
|
|
1312
|
-
fill: hsl(var(--graview-hue, 200) ${face(iso.right)});
|
|
1313
|
-
}
|
|
1314
|
-
.graview-iso-left {
|
|
1315
|
-
fill: hsl(var(--graview-hue, 200) ${face(iso.left)});
|
|
1316
|
-
}
|
|
1317
852
|
|
|
1318
853
|
${ /* WHERE THE KIND HAS ITS OWN DRAWING, the drawing is the building.
|
|
1319
854
|
Same footprint as the block, same ground line, same cast shadow — the
|
|
@@ -1395,175 +930,6 @@ ${ /* From altitude the card's face becomes the district's NAMEPLATE: an
|
|
|
1395
930
|
padding 640ms cubic-bezier(0.33, 0, 0.2, 1),
|
|
1396
931
|
box-shadow 640ms ease;
|
|
1397
932
|
}
|
|
1398
|
-
${ /* A SIGNPOST at the plot's front corner. From altitude the nameplate stood
|
|
1399
|
-
at the top of the card — over the back row of the village — and the
|
|
1400
|
-
screen had to clear it. It is planted at the front vertex of the tile
|
|
1401
|
-
now, on a short post, where a sign stands at the entrance to a place;
|
|
1402
|
-
the scene says where that vertex is in --graview-front-y. */""}
|
|
1403
|
-
[data-graview-altitude] .graview-kind-face {
|
|
1404
|
-
position: absolute !important;
|
|
1405
|
-
left: 50% !important;
|
|
1406
|
-
top: 2% !important;
|
|
1407
|
-
transform: translateX(-50%);
|
|
1408
|
-
width: max-content;
|
|
1409
|
-
${ /* Wider than the block when the name is: a label overflows its building
|
|
1410
|
-
the way a map label does. "REQUIRE / MENTS" on two lines does not. */""}
|
|
1411
|
-
max-width: none;
|
|
1412
|
-
white-space: nowrap;
|
|
1413
|
-
height: auto !important;
|
|
1414
|
-
flex-direction: row !important;
|
|
1415
|
-
align-items: baseline !important;
|
|
1416
|
-
gap: 7px !important;
|
|
1417
|
-
padding: 3px 11px !important;
|
|
1418
|
-
border-radius: 999px !important;
|
|
1419
|
-
box-shadow: var(--graview-lift-low) !important;
|
|
1420
|
-
z-index: ${SCENE_LAYERS.tag};
|
|
1421
|
-
}
|
|
1422
|
-
[data-graview-altitude] [data-graview-plot] .graview-kind-face {
|
|
1423
|
-
top: calc(var(--graview-front-y) - 22px) !important;
|
|
1424
|
-
}
|
|
1425
|
-
[data-graview-altitude] [data-graview-plot] .graview-kind-face::after {
|
|
1426
|
-
content: "";
|
|
1427
|
-
position: absolute;
|
|
1428
|
-
left: 50%;
|
|
1429
|
-
top: 100%;
|
|
1430
|
-
width: 1px;
|
|
1431
|
-
height: 10px;
|
|
1432
|
-
background: var(--graview-ink-faint);
|
|
1433
|
-
}
|
|
1434
|
-
${ /* A landmark WITHOUT a plot — a nested card — keeps its plate floating
|
|
1435
|
-
above the drawing rather than across its head; one on a plot stands at
|
|
1436
|
-
the signpost like every other district (the rule above). */""}
|
|
1437
|
-
[data-graview-altitude] [data-graview-landmark]:not([data-graview-plot] *) .graview-kind-face {
|
|
1438
|
-
top: 0 !important;
|
|
1439
|
-
transform: translate(-50%, calc(-100% - 7px));
|
|
1440
|
-
}
|
|
1441
|
-
${ /* The drive-in's board hangs UNDER the signpost, in the ground the layout
|
|
1442
|
-
reserved for it below the tile's front corner, not over the village. */""}
|
|
1443
|
-
[data-graview-altitude] .graview-drive-in {
|
|
1444
|
-
top: calc(var(--graview-front-y, 42px) + 12px);
|
|
1445
|
-
}
|
|
1446
|
-
${ /* An OPENED district's listing takes the ground under the signpost; the
|
|
1447
|
-
board steps up over the village, which the listing covers anyway. */""}
|
|
1448
|
-
[data-graview-altitude] .graview-kind-face[data-graview-opened] ~ .graview-drive-in {
|
|
1449
|
-
top: calc(var(--graview-front-y, 42px) - 22px - var(--graview-marquee-room, 0px) + 8px);
|
|
1450
|
-
}
|
|
1451
|
-
${ /* THE LANDMARK STANDS IN THE SQUARE: its feet at the plot's centre, among
|
|
1452
|
-
the buildings, rather than at the card's bottom edge — which, once the
|
|
1453
|
-
card grew for a board, was out in the road in front of the village. */""}
|
|
1454
|
-
[data-graview-altitude] [data-graview-plot] .graview-kind-landmark {
|
|
1455
|
-
bottom: auto;
|
|
1456
|
-
top: calc(var(--graview-centre-y, 50%) + 10px);
|
|
1457
|
-
transform: translate(-50%, -100%) scale(calc(0.55 + var(--graview-altitude) * 0.45));
|
|
1458
|
-
}
|
|
1459
|
-
${ /* ZOOM, in the ground's corner: the way a map carries its own. Two
|
|
1460
|
-
fingertip-sized buttons and the level between them, shown from altitude. */""}
|
|
1461
|
-
.graview-zoom {
|
|
1462
|
-
position: absolute;
|
|
1463
|
-
right: 16px;
|
|
1464
|
-
bottom: 16px;
|
|
1465
|
-
${ /* Above the occupants: a robot walking past a control must not cover it. */""}
|
|
1466
|
-
z-index: ${SCENE_LAYERS.zoom};
|
|
1467
|
-
display: inline-flex;
|
|
1468
|
-
align-items: center;
|
|
1469
|
-
gap: 2px;
|
|
1470
|
-
padding: 2px;
|
|
1471
|
-
border-radius: 999px;
|
|
1472
|
-
border: 1px solid var(--graview-edge);
|
|
1473
|
-
background: var(--graview-panel);
|
|
1474
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
1475
|
-
}
|
|
1476
|
-
.graview-zoom-button {
|
|
1477
|
-
min-width: 32px;
|
|
1478
|
-
min-height: 32px;
|
|
1479
|
-
border: 0;
|
|
1480
|
-
border-radius: 999px;
|
|
1481
|
-
background: transparent;
|
|
1482
|
-
color: var(--graview-ink);
|
|
1483
|
-
font: inherit;
|
|
1484
|
-
font-size: 1.0625rem;
|
|
1485
|
-
line-height: 1;
|
|
1486
|
-
cursor: pointer;
|
|
1487
|
-
}
|
|
1488
|
-
.graview-zoom-button:hover:not(:disabled) {
|
|
1489
|
-
background: var(--graview-edge);
|
|
1490
|
-
}
|
|
1491
|
-
.graview-zoom-button:disabled {
|
|
1492
|
-
opacity: 0.35;
|
|
1493
|
-
cursor: default;
|
|
1494
|
-
}
|
|
1495
|
-
.graview-zoom-level {
|
|
1496
|
-
min-width: 3.2em;
|
|
1497
|
-
text-align: center;
|
|
1498
|
-
font-size: 0.8125rem;
|
|
1499
|
-
color: var(--graview-ink-faint);
|
|
1500
|
-
font-variant-numeric: tabular-nums;
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
${ /* THE SCREEN IS A BILLBOARD at the back of the village: a frame, and two
|
|
1504
|
-
posts into the ground at its foot. */""}
|
|
1505
|
-
${ /* On the NATURAL BOX, which is the picture now: the layout cuts the
|
|
1506
|
-
billboard to what the lens drew (measured by the scene), never shorter
|
|
1507
|
-
than a screen's worth — so the box is the picture, and an empty lens is a
|
|
1508
|
-
header over an empty screen rather than a strip floating over the
|
|
1509
|
-
village. The frame used to sit on the drawing itself, from the days the
|
|
1510
|
-
box was as tall as the window with the picture in its top third. It
|
|
1511
|
-
carries the panel's own ground so the empty part of a screen is a screen
|
|
1512
|
-
and not the field showing through a frame. */""}
|
|
1513
|
-
[data-graview-altitude] [data-graview-screen] > [data-graview-natural],
|
|
1514
|
-
[data-graview-altitude] [data-graview-screen] > :not([data-graview-natural]):not(.graview-kind-tag) {
|
|
1515
|
-
outline: 2px solid color-mix(in oklab, var(--graview-ink) 60%, var(--graview-panel));
|
|
1516
|
-
outline-offset: 0;
|
|
1517
|
-
background: var(--graview-panel);
|
|
1518
|
-
}
|
|
1519
|
-
[data-graview-altitude] [data-graview-screen] > :not([data-graview-natural]):not(.graview-kind-tag) {
|
|
1520
|
-
position: relative;
|
|
1521
|
-
}
|
|
1522
|
-
[data-graview-altitude] [data-graview-screen] > [data-graview-natural]::before,
|
|
1523
|
-
[data-graview-altitude] [data-graview-screen] > [data-graview-natural]::after,
|
|
1524
|
-
[data-graview-altitude] [data-graview-screen] > :not([data-graview-natural]):not(.graview-kind-tag)::before,
|
|
1525
|
-
[data-graview-altitude] [data-graview-screen] > :not([data-graview-natural]):not(.graview-kind-tag)::after {
|
|
1526
|
-
content: "";
|
|
1527
|
-
position: absolute;
|
|
1528
|
-
top: 100%;
|
|
1529
|
-
width: 3px;
|
|
1530
|
-
height: 16px;
|
|
1531
|
-
background: color-mix(in oklab, var(--graview-ink) 60%, var(--graview-panel));
|
|
1532
|
-
}
|
|
1533
|
-
[data-graview-altitude] [data-graview-screen] > [data-graview-natural]::before,
|
|
1534
|
-
[data-graview-altitude] [data-graview-screen] > :not([data-graview-natural]):not(.graview-kind-tag)::before { left: 22%; }
|
|
1535
|
-
[data-graview-altitude] [data-graview-screen] > [data-graview-natural]::after,
|
|
1536
|
-
[data-graview-altitude] [data-graview-screen] > :not([data-graview-natural]):not(.graview-kind-tag)::after { right: 22%; }
|
|
1537
|
-
|
|
1538
|
-
${ /* A thing inside a view that is itself a thing: an event in a calendar, a
|
|
1539
|
-
person in a list. It has to look reachable, and it has to SHOW focus —
|
|
1540
|
-
these are the primary way anyone moves through the graph, so a keyboard
|
|
1541
|
-
user who cannot see where they are is stuck. */""}
|
|
1542
|
-
${ /* A card someone dragged into place. Marked, not decorated: a dotted tie to
|
|
1543
|
-
say this position is held rather than computed. */""}
|
|
1544
|
-
${ /* On the CHILD, not the host: the host is the layout's box, and a view
|
|
1545
|
-
that sizes to its content (a zoomed record, a fit panel) fills only part
|
|
1546
|
-
of it — a dashed box around the empty remainder read as a drawing
|
|
1547
|
-
mistake, not a mark. */""}
|
|
1548
|
-
${ /* And never on the natural box either — a view drawn scaled sits inside a
|
|
1549
|
-
box the size of the whole scene, and the mark belongs on the drawing, not
|
|
1550
|
-
on the box; nor on the kind tag, which is a label and not the thing. */""}
|
|
1551
|
-
[data-graview-pinned] > :not([data-graview-natural]):not(.graview-kind-tag),
|
|
1552
|
-
[data-graview-pinned] > [data-graview-natural] > * {
|
|
1553
|
-
outline: 1px dashed var(--graview-edge-bright);
|
|
1554
|
-
outline-offset: 3px;
|
|
1555
|
-
border-radius: 12px;
|
|
1556
|
-
}
|
|
1557
|
-
${ /* AND NOT FROM ALTITUDE, where a district is a village on a plot and its
|
|
1558
|
-
card is a box with nothing drawn in it: the dashed outline was the only
|
|
1559
|
-
visible part, so a hand-placed district read as an empty rounded
|
|
1560
|
-
rectangle sitting on the ground — several of them, in a picture that had
|
|
1561
|
-
no rectangles in it. The plot's own kerb goes dashed up here, which is
|
|
1562
|
-
the same fact said where the district actually is. */""}
|
|
1563
|
-
[data-graview-altitude] [data-graview-pinned] > :not([data-graview-natural]):not(.graview-kind-tag),
|
|
1564
|
-
[data-graview-altitude] [data-graview-pinned] > [data-graview-natural] > * {
|
|
1565
|
-
outline: none;
|
|
1566
|
-
}
|
|
1567
933
|
|
|
1568
934
|
[data-graview-pick] {
|
|
1569
935
|
cursor: pointer;
|
|
@@ -1645,13 +1011,6 @@ ${ /* WHAT YOU CAN PRESS IS WHAT YOU CAN SEE.
|
|
|
1645
1011
|
[data-graview-stage="dom"] [data-graview-view] > [data-graview-natural] {
|
|
1646
1012
|
pointer-events: none;
|
|
1647
1013
|
}
|
|
1648
|
-
[data-graview-stage="dom"] [data-graview-view] > :not([data-graview-natural]),
|
|
1649
|
-
[data-graview-stage="dom"] [data-graview-view] > [data-graview-natural] > * {
|
|
1650
|
-
pointer-events: auto;
|
|
1651
|
-
}
|
|
1652
|
-
[data-graview-view][data-graview-selected] {
|
|
1653
|
-
filter: drop-shadow(0 0 14px var(--graview-accent-dim));
|
|
1654
|
-
}
|
|
1655
1014
|
|
|
1656
1015
|
${ /* A node implicated by the last change, whoever made it. The pulse is the
|
|
1657
1016
|
same for a human edit and an agent edit, because the diff is. */""}
|
|
@@ -1728,47 +1087,12 @@ ${ /* A QUESTION THE SEAT ASKED, standing at the node it is about: it says
|
|
|
1728
1087
|
35% { box-shadow: 0 0 26px 3px var(--graview-accent-dim); }
|
|
1729
1088
|
100% { box-shadow: 0 0 0 0 transparent; }
|
|
1730
1089
|
}
|
|
1731
|
-
[data-graview-touched] > * {
|
|
1732
|
-
animation: graview-touched 1100ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
1733
|
-
border-radius: 10px;
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
${ /* ------------------------------------------------------------ watching
|
|
1737
|
-
*
|
|
1738
|
-
* From outside the plane stack, activity has somewhere to HAPPEN: a kind
|
|
1739
|
-
* lights where an edit landed, an edge pulses where a relation was made or
|
|
1740
|
-
* broken, and a flag appears where a rule started failing. All of it is
|
|
1741
|
-
* derived from the op log — author, intent, reads and writes — and all of it
|
|
1742
|
-
* is drawn by these rules rather than by a frame loop, which is why watching
|
|
1743
|
-
* costs nothing while nothing is happening.
|
|
1744
|
-
*
|
|
1745
|
-
* Who moved is carried in HUE, not in a badge. A person is the accent the
|
|
1746
|
-
* whole interface already uses for "you did this"; an agent is a colder cast,
|
|
1747
|
-
* so a turn it took on its own is distinguishable at a glance from one you
|
|
1748
|
-
* directed; both at once takes both.
|
|
1749
|
-
*/""}
|
|
1750
|
-
[data-graview-activity] {
|
|
1751
|
-
--graview-activity: var(--graview-accent);
|
|
1752
|
-
}
|
|
1753
|
-
[data-graview-activity="autonomous"] {
|
|
1754
|
-
--graview-activity: hsl(212 72% 62%);
|
|
1755
|
-
}
|
|
1756
|
-
[data-graview-activity="co-edited"] {
|
|
1757
|
-
--graview-activity: hsl(280 60% 66%);
|
|
1758
|
-
}
|
|
1759
|
-
[data-graview-activity="rule"] {
|
|
1760
|
-
--graview-activity: var(--graview-warn);
|
|
1761
|
-
}
|
|
1762
1090
|
|
|
1763
1091
|
@keyframes graview-landed {
|
|
1764
1092
|
0% { box-shadow: 0 0 0 0 var(--graview-activity); opacity: 0.55; }
|
|
1765
1093
|
30% { box-shadow: 0 0 30px 4px var(--graview-activity); opacity: 1; }
|
|
1766
1094
|
100% { box-shadow: 0 0 0 0 transparent; opacity: 1; }
|
|
1767
1095
|
}
|
|
1768
|
-
[data-graview-view][data-graview-wrote] > * {
|
|
1769
|
-
animation: graview-landed 900ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
1770
|
-
border-radius: 10px;
|
|
1771
|
-
}
|
|
1772
1096
|
|
|
1773
1097
|
${ /* What an agent READ is the half a diff cannot show, and the half that says
|
|
1774
1098
|
whether to trust what it then did. Quieter than a write on purpose: it is
|
|
@@ -1778,20 +1102,6 @@ ${ /* What an agent READ is the half a diff cannot show, and the half that says
|
|
|
1778
1102
|
25% { outline-color: var(--graview-activity); }
|
|
1779
1103
|
100% { outline-color: transparent; }
|
|
1780
1104
|
}
|
|
1781
|
-
[data-graview-view][data-graview-read] > :not([data-graview-natural]):not(.graview-kind-tag),
|
|
1782
|
-
[data-graview-view][data-graview-read] > [data-graview-natural] > * {
|
|
1783
|
-
outline: 1px dashed transparent;
|
|
1784
|
-
outline-offset: 3px;
|
|
1785
|
-
border-radius: 10px;
|
|
1786
|
-
animation: graview-considered 1800ms ease-out;
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
|
-
${ /* A rule that has just begun to fail. It outlives the edit that caused it,
|
|
1790
|
-
because the problem does. */""}
|
|
1791
|
-
[data-graview-view][data-graview-broke] > * {
|
|
1792
|
-
box-shadow: 0 0 0 1px var(--graview-warn), 0 0 22px -6px var(--graview-warn);
|
|
1793
|
-
border-radius: 10px;
|
|
1794
|
-
}
|
|
1795
1105
|
|
|
1796
1106
|
${ /* A relation made or broken: both ends were written, so the line between
|
|
1797
1107
|
them is the thing that changed. */""}
|
|
@@ -1800,9 +1110,6 @@ ${ /* A relation made or broken: both ends were written, so the line between
|
|
|
1800
1110
|
30% { stroke-opacity: 1; stroke-width: 3; }
|
|
1801
1111
|
100% { stroke-opacity: 0.28; stroke-width: 1.4; }
|
|
1802
1112
|
}
|
|
1803
|
-
[data-graview-connector][data-graview-activity] {
|
|
1804
|
-
animation: graview-relation 1200ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
1805
|
-
}
|
|
1806
1113
|
|
|
1807
1114
|
${ /*
|
|
1808
1115
|
* MOTION, ASKED OF THE SYSTEM AND OVERRIDABLE BY THE PERSON.
|