html, body { margin: 0; height: 100%; background: #000; overflow: hidden; overscroll-behavior: none; }
body { touch-action: none; user-select: none; -webkit-user-select: none; cursor: crosshair;
  -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
#field { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; }
body.grab #field { cursor: grabbing; }

/* the film gate: four hairline corner marks, the only chrome */
#gate { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
#gate path { fill: none; stroke: #fff; stroke-width: 0.75; opacity: 0.55; }
#gate .tr { transform: translateX(100%); }
#gate .bl { transform: translateY(100%); }
#gate .br { transform: translate(100%, 100%); }

#nogpu[hidden] { display: none; }
#nogpu { position: fixed; left: 50%; top: 50%; width: 80px; height: 80px; margin: -40px 0 0 -40px; }
#nogpu circle, #nogpu path { fill: none; stroke: #fff; stroke-width: 0.75; opacity: 0.7; }

/* the grab overlay: the formula's own objects as hairlines (ui/overlay.js) */
#grab { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible;
  opacity: 0; transition: opacity 150ms ease-out; }
#grab.on { opacity: 1; }
/* a graph zoomed by the fingers keeps its hairlines hairline */
#grab .vz * { vector-effect: non-scaling-stroke; }
#grab path, #grab circle, #grab rect { fill: none; stroke: #fff; stroke-width: 0.75; }
#grab .hd { opacity: 0.6; }
#grab .rt { opacity: 0.7; }
#grab .rt .ax { opacity: 0.55; }
#grab .rt .dot { fill: #fff; stroke: none; }
#grab .ob path { stroke-width: 0.5; opacity: 0.35; }
#grab .ob circle { stroke: none; }
#grab .dm { opacity: 0.8; }
#grab text { fill: #fff; stroke: none; font: 11px ui-monospace, Menlo, monospace; text-anchor: middle; }
#grab .ln { opacity: 0.85; }
#grab .ln .axis { opacity: 0.3; }
#grab .ln .dot { fill: #fff; stroke: none; }
#grab text.l { text-anchor: start; }

/* the graph: folded in the structure layer as the strip, unfolded over the dimmed field (ui/graph.js) */
:is(#structure, #grab) .gr .ed { stroke-width: 0.75; opacity: 0.5; }
:is(#structure, #grab) .gr .ed.on { opacity: 1; stroke-width: 1.5; }
:is(#structure, #grab) .gr .br { opacity: 0.45; }
:is(#structure, #grab) .gr .ps { stroke-width: 1.2; opacity: 0.9; }
:is(#structure, #grab) .gr text.on { opacity: 1; }
:is(#structure, #grab) .gr .sl { stroke-width: 1.2; }
/* the shading frame (ui/shadegraph.js): links, ports, the ramp's gradient, its editor, the hue ring */
:is(#structure, #grab) .sh .bus { opacity: 0.35; stroke-dasharray: 2 3; }
:is(#structure, #grab) .sh .tap { opacity: 0.25; }
:is(#structure, #grab) .sh .ln { opacity: 0.55; }
:is(#structure, #grab) .sh .ln.on { opacity: 1; stroke-width: 1.4; }
:is(#structure, #grab) .sh .pt { fill: #fff; stroke: none; opacity: 0.7; }
:is(#structure, #grab) .sh .rb { stroke: none; }
:is(#structure, #grab) .sh .rf { opacity: 0.6; }
:is(#structure, #grab) .sh .nd.hv path, :is(#structure, #grab) .sh .rf.hv { stroke-width: 1.5; opacity: 1; }
:is(#structure, #grab) .sh .op path { opacity: 0.8; }
:is(#structure, #grab) .sh .tg.off path { opacity: 0.3; }
:is(#structure, #grab) .sh .tk { opacity: 0.7; }
:is(#structure, #grab) .sh .tk.sel { opacity: 1; stroke-width: 1.4; }
:is(#structure, #grab) .sh .sw { stroke: #fff; stroke-width: 0.5; }
:is(#structure, #grab) .sh .start { stroke-width: 1.4; }
#grab .hring .hr, #grab .hring .hs { opacity: 0.35; }
#grab .hring .ht { stroke-width: 2; }
#grab .hring .hp { opacity: 0.6; }
#grab .hring .hc { stroke: #fff; stroke-width: 1; }
#grab .hring .hl { opacity: 0.7; }
#grab .pk .pa { stroke-width: 3; fill: none; }
:is(#structure, #grab) .gr .io, :is(#structure, #grab) .gr .fk { fill: #fff; stroke: none; opacity: 0.7; }
:is(#structure, #grab) .gr .nd path { opacity: 0.85; }
:is(#structure, #grab) .gr .nd.fd path { opacity: 1; }
:is(#structure, #grab) .gr .nd.hv path { stroke-width: 1.5; }
:is(#structure, #grab) .gr .zn { opacity: 0.25; }
:is(#structure, #grab) .gr .fr { stroke-dasharray: 4 3; opacity: 0.6; }
:is(#structure, #grab) .gr text.ul { opacity: 0.65; }
:is(#structure, #grab) .gr .lp { opacity: 0.4; }
:is(#structure, #grab) .gr .att { opacity: 0.9; }
:is(#structure, #grab) .gr text { fill: #fff; stroke: none; font: 11px ui-monospace, Menlo, monospace; text-anchor: middle; opacity: 0.8; }
:is(#structure, #grab) .gr .pm path { opacity: 0.6; }
:is(#structure, #grab) .gr .pm.held path { opacity: 1; stroke-width: 1.2; }
:is(#structure, #grab) .gr .tb { opacity: 0.8; }
:is(#structure, #grab) .gr .nt { opacity: 0.9; }
/* the drivers (ui/drivegraph.js): the lane, links, bindings' hairlines, a bound line's band */
:is(#structure, #grab) .dvg .lnr { opacity: 0.25; stroke-dasharray: 2 3; }
:is(#structure, #grab) .dvg .ln { opacity: 0.55; }
:is(#structure, #grab) .dvg .ln.on { opacity: 1; stroke-width: 1.4; }
:is(#structure, #grab) .dvg .bl { opacity: 0.55; stroke-dasharray: 3 3; }
:is(#structure, #grab) .dvg .bl.on { opacity: 0.9; stroke-dasharray: none; }
:is(#structure, #grab) .dvg .pt { fill: #fff; stroke: none; opacity: 0.7; }
:is(#structure, #grab) .dvg .tie { opacity: 0.25; }
:is(#structure, #grab) .dvg .tg.off path { opacity: 0.3; }
:is(#structure, #grab) .gr .pm .bd { stroke-width: 2.5; opacity: 0.7; }
:is(#structure, #grab) .gr .pm .bd.sel { opacity: 1; stroke-width: 3; }
:is(#structure, #grab) .gr .pm .lv { stroke-width: 5; opacity: 0.18; }
:is(#structure, #grab) .gr .pm .lt { stroke-width: 1.2; opacity: 1; }
#grab .gv { fill: #000; stroke: none; opacity: 0.55; }

/* the Metasurface (M): the sites' soft walls over the dimmed field (ui/metasurface.js) */
#grab .ms .veil { fill: #000; stroke: none; opacity: 0.55; }
#grab .ms .band { stroke-width: 0.5; }
#grab .ms .hard { opacity: 0.6; }
#grab .ms .corner { opacity: 0.25; }
#grab .ms .corner.on { opacity: 0.9; }
#grab .ms .site.held { opacity: 1; stroke-width: 1.5; }
#grab .ms .home { opacity: 0.5; stroke-dasharray: 2 3; }
#grab .ms .gone { opacity: 0.9; }
#grab .ms .ring { opacity: 0.2; }
#grab .ms .ring.on { opacity: 1; stroke-width: 1.5; }
#grab .ms .axis { opacity: 0.35; }
#grab .ms .spoke { stroke-width: 0.5; }
#grab .ms .site { opacity: 0.55; }
#grab .ms .site.on { opacity: 1; }
#grab .ms .gl path { opacity: 0.6; }
#grab .ms .stroke { stroke-width: 1.5; opacity: 0.9; }
#grab .ms .stroke.field { stroke-dasharray: 2 4; }
#grab .ms .cross .dot { fill: #fff; stroke: none; }

/* the structure layer (Tab): ruler, op strip, lineage (ui/structure.js) */
#structure { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
#structure path, #structure circle, #structure rect { fill: none; stroke: #fff; stroke-width: 0.75; }
#structure .ru { opacity: 0.6; }
#structure .ru .now { stroke-width: 1.5; opacity: 1; }
#structure .st { opacity: 0.55; }
#structure .st .att { stroke-width: 1.5; opacity: 1; }
#structure .st .sep { opacity: 0.4; }
#structure .sf { opacity: 0.6; }
#structure .lg path { opacity: 0.45; }
#structure .ky path { opacity: 0.5; }
#structure .ky path.on { opacity: 1; stroke-width: 1.2; }
#structure .lg .node { fill: #fff; stroke: none; opacity: 0.55; }
#structure .lg .node.cur { opacity: 1; }
#structure .lg .hit { fill: transparent; stroke: none; pointer-events: all; cursor: pointer; }
#structure text { fill: #fff; stroke: none; font: 11px ui-monospace, Menlo, monospace; opacity: 0.8; }
#structure .st text { text-anchor: middle; }
#grab .kb { opacity: 0.8; }
#grab .kb .tk { opacity: 0.5; }
#structure .pn { opacity: 0.8; }
#structure .pn .pd { fill: #fff; stroke: none; }
#grab .rg { opacity: 0.9; }
#grab .rg .sp { opacity: 0.35; }
#grab .rg .dot { fill: #fff; stroke: none; }
#grab .rg .sel { stroke-width: 1.5; }
#grab .rg .far { stroke-dasharray: 2 3; }
#structure .ex { opacity: 0.6; }
#structure > .hit { fill: transparent; stroke: none; pointer-events: all; cursor: pointer; }
#structure :is(.ex, .ky) .hit { fill: transparent; stroke: none; pointer-events: all; cursor: pointer; }
#structure.under .hit { pointer-events: none; }
#structure.under .ky .hit { pointer-events: all; }
#structure .pg { stroke-width: 1.5; opacity: 0.9; }

/* a collage (ui/collagegraph.js, ui/gizmo.js): the joins' own contours, the folding links, the selected
   piece's affine frame and its repetition's cells */
:is(#structure, #grab) .cg .cl { opacity: 0.45; }
:is(#structure, #grab) .cg .jn path { opacity: 0.9; }
:is(#structure, #grab) .cg .jn.hv path, :is(#structure, #grab) .cg .jn.sel path { stroke-width: 1.5; }
:is(#structure, #grab) .cg .psel { opacity: 0.9; }
:is(#structure, #grab) .cg .rp path { opacity: 0.6; }
:is(#structure, #grab) .cg .sm path { opacity: 0.7; }
#grab .gz .fx { opacity: 0.85; }
#grab .gz .fx.on, #grab .gz .ri.on, #grab .gz .co.on { stroke-width: 1.5; opacity: 1; }
#grab .gz .ri { opacity: 0.4; }
#grab .gz .co { opacity: 0.85; }
#grab .gz .od { fill: #fff; stroke: none; }
/* the world's axes (a tap on the centre dot): the same frame, dimmer */
#grab .gz.wd .fx, #grab .gz.wd .co { opacity: 0.5; }
#grab .gz.wd .ri { opacity: 0.25; }
#grab .gz.halo.wd .fx, #grab .gz.halo.wd .co, #grab .gz.halo.wd .ri { opacity: 0.2; }
#grab .gz .dl { opacity: 0.8; }
#grab .gz .rc { stroke-width: 0.6; opacity: 0.8; }
#grab .gz .rc.gh { opacity: 0.5; stroke-dasharray: 3 3; }
#grab .gz.halo path, #grab .gz.halo circle { stroke: #000; stroke-width: 2.5; opacity: 0.35; }
#grab .gz.halo .rc.gh { opacity: 0.25; }
#grab .gz.halo .od { fill: #000; }

/* the overlay toggles (ui/toggles.js): the site's menu mark, a hairline on this page only (assets/menu.css
   stays the site's; these rules out-rank it here), and the row of glyphs it unfolds */
#site-menu.site-menu .menuToggle { right: max(0px, calc(env(safe-area-inset-right, 0px) - 24px)); }
#site-menu.site-menu .menuToggle > span:nth-of-type(n) { width: 26px; height: 0; right: 57px; top: 61px; margin: 0 0 7.25px;
  border: 0; border-top: 0.75px solid #fff; border-radius: 0; opacity: 0.55; transform-origin: 50% 50%;
  transition: transform 0.3s cubic-bezier(0.77, 0.2, 0.05, 1), opacity 0.2s ease; }
#site-menu.site-menu.fe-row .menuToggle > span:nth-of-type(n) { opacity: 1; }
#site-menu.site-menu .menuToggle input:checked ~ span:nth-of-type(n) { opacity: 1; transform: none; }
#site-menu.site-menu .menuToggle input:checked ~ span:nth-of-type(1) { transform: translateY(8px) rotate(45deg); }
#site-menu.site-menu .menuToggle input:checked ~ span:nth-of-type(2) { opacity: 0; }
#site-menu.site-menu .menuToggle input:checked ~ span:nth-of-type(3) { transform: translateY(-8px) rotate(-45deg); }
#toggles { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; z-index: 2; }
#toggles path { fill: none; stroke: #fff; stroke-width: 0.75; opacity: 0.45; }
#toggles .tg.on path { opacity: 1; stroke-width: 1.2; }
#toggles path.halo, #toggles .tg.on path.halo { stroke: #000; stroke-width: 3; opacity: 0.3; }
#toggles .hit { fill: transparent; stroke: none; pointer-events: all; cursor: pointer; }
/* the Metasurface's "add a piece" plus, and the collage graph's */
#grab .ms .add path, #grab .ms .add circle { opacity: 0.9; }
:is(#structure, #grab) .cg .pl path, :is(#structure, #grab) .cg .pl circle { opacity: 0.8; }

/* hover labels (ui/labels.js): a name beside what the pointer rests on — white, a faint dark halo, no box */
#labels { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; z-index: 3; }
#labels text { fill: #fff; font: 11px ui-monospace, Menlo, monospace; letter-spacing: 0.02em;
  paint-order: stroke; stroke: #000; stroke-width: 3px; stroke-opacity: 0.45; stroke-linejoin: round; }
#labels .k { fill-opacity: 0.5; }

/* a figure in the engine's paper (app.js EMBED): the site's menu belongs to the page around it */
html.embed #site-menu .menuItem { display: none; }
