/* Root styles */

*, *::before, *::after {
    box-sizing: border-box;
}

:root {
    /* UI colours. Each accent means one thing, so that a colour says what it marks. */
    --ui-black: hsl(0, 0%, 6%); /* Almost black. */
    --ui-white: hsl(0, 0%, 96%); /* Almost white. */
    --ui-raised: hsl(0, 0%, 22%); /* The mode line's badge at rest. */
    --ui-accent: #f8a7b7; /* Pink: keys, and what has the focus. */
    --ui-secondary: #a7c8f8; /* Blue: prompts, cell codes, and values. */
    --ui-warning: hsl(50, 100%, 70%); /* Yellow: what waits, unsaved changes or a mark. */
    --ui-error: hsl(0, 50%, 50%);

    --ui-background: transparent;
    --ui-border: hsla(0, 0%, 100%, 0.2);
    --ui-rule: hsla(0, 0%, 100%, 0.1); /* The faint lines between the key list's cells. */
    --ui-hover: hsla(0, 0%, 100%, 0.1);
    --ui-active: hsla(0, 0%, 100%, 0.2);
    --ui-focus: var(--ui-accent);
    /* What is secondary (hints, titles, and the chords beside keys) is dimmed by one amount, and
       what is unavailable by another. */
    --ui-dim: 0.6;
    --ui-disabled: 0.3;
    --ui-text: hsla(0, 0%, 100%, var(--ui-dim));

    /* The canvas: its background, the grid, and the ink that the default colour (black) is
       drawn in. Every other colour is drawn exactly. */
    --canvas: white;
    --grid: #eee;
    --ink: black;
    /* A faint wash of the ink. */
    --ink-faint: hsla(0, 0%, 0%, 0.1);

    /* Cell states. An arrow being drawn runs from the source, in blue, to the target, in the
       focus's pink, so that its ends are told apart from the selection. */
    --cell-hover: hsla(0, 0%, 0%, 0.1);
    --cell-selected: hsla(0, 0%, 0%, 0.2);
    --cell-source: color-mix(in srgb, var(--ui-secondary) 60%, transparent);
    --cell-target: color-mix(in srgb, var(--ui-accent) 60%, transparent);

    /* The height of the mode line along the bottom of the window (0 when it is hidden). */
    --mode-line-height: 24px;
    /* The height of the error on its line above the mode line (0 while there is none), which
       what opens above the mode line sits above (see `ModeLine.place_message`). */
    --message-height: 0px;
}

/* Dark mode (`:dark-mode`): a grey canvas, with the default colour drawn in white. It changes only how
   the diagram is shown, never the colours it holds or exports. */
body.dark {
    --canvas: #303030;
    --grid: #3e3e3e;
    --ink: white;
    --ink-faint: hsla(0, 0%, 100%, 0.1);

    --cell-hover: hsla(0, 0%, 100%, 0.1);
    --cell-selected: hsla(0, 0%, 100%, 0.2);
    --cell-source: color-mix(in srgb, var(--ui-secondary) 45%, transparent);
    --cell-target: color-mix(in srgb, var(--ui-accent) 45%, transparent);
}

/* Arrows draw in their colour's exact `hsla`, as SVG attributes, which these override for black
   alone. Masks keep theirs. */
body.dark svg [stroke="hsla(0, 0%, 0%, 1)"]:not(mask *) {
    stroke: var(--ink);
}
body.dark svg [fill="hsla(0, 0%, 0%, 1)"]:not(mask *) {
    fill: var(--ink);
}

/* The highlight behind a hovered or selected arrow. */
body.dark path.arrow-background {
    stroke: var(--ink);
}
body.dark circle.arrow-background {
    fill: var(--ink);
}

body {
    position: absolute;
    width: 100%; height: 100%;
    margin: 0;
    overflow: hidden;

    background: var(--canvas);

    font-family: Arial, sans-serif;

    touch-action: none;
    user-select: none;
}

kbd {
    white-space: pre;
}

/* The canvas of cells */

.container {
    position: fixed;
    width: 100%;
    height: 100%;
}

.canvas {
    position: absolute;
    left: 50%;
    top: 50%;
    transform-origin: top left;
}

.ui.pan .container {
    cursor: grab;
}

.ui.pan .container:active {
    cursor: grabbing;
}

/* Grid interaction */

.grid {
    position: fixed;
    pointer-events: none;
    z-index: -100;
}

.grid.hidden {
    display: none;
}

.focus-point {
    display: block;
    position: absolute;
    margin-left: 1px; margin-top: 1px;
    width: 126px; height: 126px;

    background: hsla(0, 0%, 0%, 0);
}

.focus-point.revealed {
    background: var(--ink-faint);
}

.focus-point.focused {
    border: var(--ui-focus) 4px solid;
    border-radius: 0px;
}

.focus-point.smooth {
    transition: left 0.1s, top 0.1s, width 0.1s, height 0.1s;
}

/* The rectangle from the mark to the focus point, and the cells it would take. */
.mark-region {
    position: absolute;
    margin-left: 1px; margin-top: 1px;
    box-sizing: border-box;
    border: var(--ui-focus) 2px dashed;
    background: var(--ink-faint);
    pointer-events: none;
    transition: left 0.1s, top 0.1s, width 0.1s, height 0.1s;
}

.mark-region.hidden {
    display: none;
}

.vertex.in-mark:not(.selected) .content {
    background: var(--cell-hover);
}

/* Vertices */

.vertex {
    position: absolute;
}

.ui.default .vertex {
    cursor: move;
}

.vertex .content {
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 2;

    border-radius: 16px;

    text-align: center;
}

.grid:not(.hidden) + .container .vertex.empty:not(.selected) .content:not(:hover),
.ui.keyboard .grid:not(.hidden) + .container .vertex.empty:not(.selected) .content {
    border: var(--cell-hover) 2px solid;
}

.ui.default .vertex .content {
    cursor: default;
}

/* This is so explicit because of the CSS specificity rules. While the keys are in use
   (`.keyboard`, see `Pointer.initialise`), nothing is highlighted for the pointer resting on it. */
.ui.default:not(.keyboard) .vertex:not(.selected):not(.source):not(.target) .content:hover,
.ui.command:not(.keyboard) .vertex:not(.selected):not(.source):not(.target) .content:hover {
    background: var(--cell-hover);
}

.vertex.selected .content {
    background: var(--cell-selected);
}

/* After the selection, which the cell an arrow is drawn from usually has. */
.vertex.source .content {
    background: var(--cell-source);
}

.vertex.target .content {
    background: var(--cell-target);
}

/* Labels in the default colour have no colour of their own (see `Cell.initialise`). */
.label {
    color: var(--ink);
    display: block;
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);

    text-align: center;
    font-family: inherit;
    /* The `ui.label_size` setting (see `UI.initialise`). */
    font-size: var(--label-size, 26px);
    white-space: nowrap;

    pointer-events: none;
    user-select: none;
}

/* The overlay edge drawn while connecting cells. */
.overlay, .overlay .arrow-background  {
    pointer-events: none !important;
}

/* The minibuffer: the label input, and the search and command prompts, in a line just above the mode
line. It is only visible while focused. */
.label-input-container {
    position: fixed;
    left: 0; right: 0;
    bottom: calc(var(--mode-line-height) + var(--message-height));
    height: 32px;
    z-index: 151;

    background: var(--ui-black);

    color: var(--ui-white);

    transition: opacity 0.1s;
}

.label-input-container:not(:focus-within),
.label-input-container.hidden {
    opacity: 0;

    pointer-events: none;
}

.ui.connect .label-input-container {
    pointer-events: none;
}

.label-input {
    width: 100%; height: 32px;
    padding: 4px 6px;
    padding-right: calc(24px + 6px);

    background: transparent;
    border: none;
    border-radius: 8px;
    outline: none;

    font-family: monospace;
    font-size: 18px;
    color: inherit;
    text-align: left;
}

.label-input:hover:not(:disabled):not(:focus) {
    background: var(--ui-hover);
}

.label-input:focus {
    width: calc(100% - 80px);
}

/* The prompt: "label" while editing, in white as the mode line's `EDIT` is, or the kind of prompt,
   in blue. */
.input-mode {
    display: inline-block;
    vertical-align: bottom;
    width: 80px; height: 32px;
    line-height: 32px;

    background: var(--ui-white);

    font-family: monospace;
    font-size: 16px;
    color: var(--ui-black);
    text-align: center;
}

.ui:not(.command) .input-mode::before {
    content: "label";
}

.command .input-mode {
    background: var(--ui-secondary);
}

.command .label-input:focus {
    /* Make `shadow-flash` the prompt's colour. */
    --ui-accent: var(--ui-secondary);
}

/* The command line's completions, listed above it. Clicking one inserts it. */
.prompt-completions {
    position: absolute;
    left: 0; right: 0; bottom: 100%;
    max-height: 40vh;
    padding: 8px;
    overflow-y: auto;

    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 2px 12px;

    background: var(--ui-black);
    border-bottom: var(--ui-border) solid 1px;

    font-family: monospace;
    font-size: 14px;
}

.prompt-completions.hidden {
    display: none;
}

.prompt-completions span {
    display: flex;
    justify-content: space-between;
    padding: 2px 6px;

    border-radius: 4px;

    cursor: pointer;
}

.prompt-completions span:hover {
    background: var(--ui-hover);
}

.prompt-completions span.current {
    background: var(--ui-secondary);

    color: var(--ui-black);
}

.prompt-completions kbd {
    margin-left: 12px;

    opacity: var(--ui-dim);
}

/* Cells matching the `/` search. */
.cell.search-match .label {
    outline: 2px solid var(--ui-secondary);
    outline-offset: 2px;
    border-radius: 4px;
}

.label-input::selection {
    background: var(--ui-white);

    color: var(--ui-black);
}

.label-input-container .colour-indicator {
    position: absolute;
    top: 50%;
    right: 8px;
    width: 24px;
    transform: translateY(-50%);
    border-radius: 4px;
}

.command .label-input-container .colour-indicator {
    display: none;
}

input[type="text"].flash {
    animation: shadow-flash 0.2s;
}

@keyframes shadow-flash {
    from {
        box-shadow: 0 0 0 4px var(--ui-accent);
    }

    to {
        box-shadow: 0 0 0 var(--ui-accent);
    }
}

kbd.hint {
    position: absolute;
    min-width: 20px;
    padding: 2px 4px;

    background: var(--ui-secondary);
    border-radius: 2px;

    color: var(--ui-black);
    text-align: center;

    pointer-events: none;
}

.colour-indicator {
    display: inline-block;
    vertical-align: middle;
    position: relative;
    width: 48px;
    height: 24px;

    border: var(--ui-border) solid 1px;
    border-radius: 2px;

    cursor: pointer;
}

/* Highlight the hints when their codes are (partially) typed. */
kbd.hint.focused, kbd.hint .focused {
    color: var(--ui-white);
}

.ui:not(.command).show-queue kbd.hint.queue.next {
    background: var(--ui-white);
    border: var(--ui-accent) 1px solid;

    color: var(--ui-accent);
}

/* Cells' codes are shown while typing one (after `/`), and, while cycling the queue, the hint of
   the queued cell Tab goes to next. */
.ui:not(.command):not(.show-queue) kbd.hint.queue,
.ui:not(.command) kbd.hint.queue:not(.next) {
    display: none;
}

kbd.hint:not(.queue) {
    display: none;
}

.ui.command .cell kbd.hint {
    display: block;
}

.vertex kbd.hint {
    left: 50%; top: 0;
    transform: translateX(-50%);
}

.arrow kbd {
    z-index: 10;
    transform: translate(-50%, -50%);
}

.ui.command kbd.hint:empty::after,
.cell kbd.hint:empty:not(.queue)::after,
.ui:not(.show-queue) kbd.hint:empty::after {
    content: attr(data-code);
}

/* When cells are queued, we can press Tab to select the next. */
.ui:not(.command).show-queue .cell kbd.queue.next.hint::before {
    content: "⇥";
}

/* The flash of a button triggered from the keyboard. */

button.flash {
    animation: background-flash 0.4s ease-in;
}

@keyframes background-flash {
    from {
        background: var(--ui-accent);
    }
}

/* Arrows */

.arrow > svg {
    position: absolute;
    left: 0;
    top: 0;
    overflow: visible;
    pointer-events: none;
}

.arrow.invalid, .arrow .invalid {
    display: none;
}

.arrow > svg:first-child {
    z-index: 1;
}

.arrow > svg:nth-child(2) {
    z-index: 4;
}

/* An arrow crossing over others is drawn above them, and the band under it, in the canvas colour,
   cuts the gap in them. */
.arrow.crossing-over > svg:nth-child(2) {
    z-index: 5;
}

.arrow path.arrow-crossing {
    stroke: var(--canvas);
}

/* A route's checkpoints: a ring at each while the arrow is selected, filled while one is carried
   with the focus point (see `Keys.carry`). */
.arrow .arrow-checkpoint {
    display: none;
    fill: var(--canvas);
    stroke: var(--ui-focus);
    stroke-width: 1.5;
    pointer-events: none;
}

.arrow.selected .arrow-checkpoint {
    display: inline;
}

.arrow .arrow-checkpoint.carried {
    fill: var(--ui-focus);
}

/* The area round a checkpoint the pointer drags it by (see `Pointer.grab`), only while it shows. */
.arrow .arrow-checkpoint-handle {
    display: none;
    fill: transparent;
    stroke: none;
    pointer-events: all;
    cursor: grab;
}

.arrow.selected .arrow-checkpoint-handle {
    display: inline;
}

.arrow:not(.reconnecting) > svg:first-child > .arrow-background {
    pointer-events: stroke;
}

.arrow:not(.target):not(.selected):not(.in-mark) > svg:first-child:not(:hover) > .arrow-background,
.ui.keyboard .arrow:not(.target):not(.selected):not(.in-mark) > svg:first-child > .arrow-background,
.ui.connect .cell:not(.target):not(.selected) > svg:first-child:hover > .arrow-background,
.ui.pointer-move .cell:not(.selected) > svg:first-child:hover > .arrow-background {
    opacity: 0;
}

.ui:not(.keyboard) .arrow:not(.target):not(.selected) > svg:first-child:hover {
    opacity: 0.1 !important;
}

/* An arrow an arrow is being drawn to is a target as a cell is, in pink. Its highlight is drawn in
   black, faintly (see `Arrow.redraw`), so it is coloured, and made stronger, here. */
.ui.connect .arrow.target > svg:first-child {
    opacity: 0.6 !important;
}

.ui.connect .arrow.target > svg:first-child path.arrow-background {
    stroke: var(--ui-accent);
}

.ui.connect .arrow.target > svg:first-child circle.arrow-background {
    fill: var(--ui-accent);
}

.arrow-endpoint {
    display: none;
}

.ui.default:not(.keyboard) .arrow:hover .arrow-endpoint,
.ui.default .arrow.selected .arrow-endpoint {
    display: block;
}

.arrow-endpoint {
    position: absolute;
    z-index: 3;

    background: var(--canvas);
}

.arrow-endpoint:hover {
    border: var(--ui-accent) 2px solid;
}

/* Arrow labels */

/* tikz-cd sets labels in `\scriptstyle`, 0.7 of the cells' size, and KaTeX draws at 1.21 times its
   font size, as it does for the cells. */
.arrow .katex, .arrow .katex-error {
    font-size: calc(0.7 * 1.21em);
}

/* The mode line */

.mode-line {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    height: var(--mode-line-height);
    z-index: 150;

    display: flex;
    align-items: stretch;

    background: var(--ui-black);

    font: 12px monospace;
    line-height: var(--mode-line-height);
    color: var(--ui-white);
    white-space: nowrap;
}

.hide-mode-line {
    --mode-line-height: 0px;
}

.hide-mode-line .mode-line {
    display: none;
}

.mode-line button {
    padding: 0 8px;

    background: transparent;
    border: none;
    outline: none;

    font: inherit;
    color: inherit;

    cursor: pointer;
}

.mode-line button:hover:not(:disabled) {
    background: var(--ui-hover);
}

.mode-line button:disabled {
    opacity: var(--ui-disabled);

    cursor: default;
}

/* The badge, by the kind of state it names (see `ModeLine.mode`): grey at rest, pink while keys
   are awaited, white while a label is edited, blue in a prompt, yellow while something waits, and
   light while the pointer moves, draws, or pans. */
.mode-line .mode {
    min-width: 64px;
    padding: 0 10px;

    background: var(--ui-raised);

    text-align: center;
}

.mode-line[data-mode="layer"] .mode {
    background: var(--ui-accent);

    color: var(--ui-black);
}

.mode-line[data-mode="edit"] .mode {
    background: var(--ui-white);

    color: var(--ui-black);
}

.mode-line[data-mode="prompt"] .mode {
    background: var(--ui-secondary);

    color: var(--ui-black);
}

.mode-line[data-mode="pending"] .mode {
    background: var(--ui-warning);

    color: var(--ui-black);
}

.mode-line[data-mode="pointer"] .mode {
    background: var(--ui-active);
}

.mode-line .mode .detail {
    margin-left: 8px;
}

/* What describes the diagram gives way first when the window is narrow, so that a message, which
   is what is new, keeps its room. */
.mode-line .file, .mode-line .target, .mode-line .arrow {
    flex-shrink: 1;
    min-width: 0;
    overflow: hidden;

    text-overflow: ellipsis;
}

.mode-line .file {
    padding: 0 10px;
}

.mode-line .file .unsaved {
    color: var(--ui-warning);
}

/* The export options other than the defaults, which saving writes too. */
.mode-line .file .export-options {
    color: var(--ui-secondary);
}

.mode-line .target {
    max-width: 40vw;
}

.mode-line .arrow {
    max-width: 40vw;
    padding: 0 8px;

    color: var(--ui-secondary);
}

.mode-line .arrow:empty {
    display: none;
}

.mode-line .queue {
    padding: 0 8px;
}

.mode-line .queue:empty {
    display: none;
}

.mode-line .message {
    flex-shrink: 0;
    max-width: 60vw;
    padding: 0 8px;
    overflow: hidden;

    text-overflow: ellipsis;
}

/* Errors stay until dismissed (by Escape, or a click), on a line of their own above the mode line,
   which wraps rather than cutting them short. */
.mode-line .message.error {
    position: absolute;
    left: 0; right: 0; bottom: 100%;
    max-width: none;
    padding: 4px 10px;

    background: var(--ui-error);

    line-height: 16px;
    color: var(--ui-white);
    white-space: normal;

    cursor: pointer;
}

/* What opens above the mode line (the key list, the minibuffer and its completions) sits above an
   error, which pushes it up, rather than either covering the other (see `ModeLine.place_message`). */

.mode-line .message:empty {
    display: none;
}

.mode-line .fill {
    flex: 1;
}

.mode-line .hint {
    opacity: var(--ui-dim);
}

/* The hints other than the command layer's are in the help too, so they give way before anything
   else: where the mode line is short of room, those that do not fit wrap onto a line of their own,
   which is out of sight, so that they drop off whole, from the right, and come back as room does. */
.mode-line .hints {
    display: flex;
    flex-wrap: wrap;
    flex-shrink: 100;
    min-width: 0;
    height: var(--mode-line-height);
    overflow: hidden;
}

.mode-line kbd {
    color: var(--ui-accent);
}

.mode-line .zoom {
    display: flex;
    margin: 0 8px;
}

.mode-line .zoom .level {
    min-width: 56px;
}

.mode-line .menu {
    padding: 0 12px;

    font-size: 16px;
}

/* The command layer's hint, lit while the layer is active. */
.mode-line .layer.active {
    background: var(--ui-active);
    opacity: 1;
}

/* The tips along the top while the diagram is empty. */
.tip {
    position: fixed;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 140;

    display: flex;
    gap: 20px;
    padding: 0 14px;

    background: var(--ui-black);
    border-radius: 0 0 4px 4px;

    font: 12px monospace;
    line-height: 22px;
    color: var(--ui-text);
    white-space: nowrap;

    pointer-events: none;
}

.tip kbd {
    color: var(--ui-accent);
}

.tip.hidden {
    display: none;
}

/* The command layer's bindings, listed above the mode line while the layer is active. */

.which-key {
    position: fixed;
    left: 0; right: 0;
    bottom: calc(var(--mode-line-height) + var(--message-height));
    z-index: 140;
    padding: 12px 16px;

    background: var(--ui-black);
    border-bottom: var(--ui-border) solid 1px;

    font: 12px monospace;
    color: var(--ui-white);
}

/* One row per group: its title in a column on the left, then its bindings in a grid of equal
   columns, each line its key, what it does, and what it is set to. */
.which-key .main, .which-key .submenu {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.which-key .group {
    position: relative;

    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(32ch, 1fr));
    padding-left: 150px;
}

.which-key.descriptive .group {
    grid-template-columns: repeat(auto-fill, minmax(52ch, 1fr));
}

/* After the layouts above, which would otherwise override it. */
.which-key.hidden, .which-key .hidden {
    display: none;
}

.which-key h3 {
    position: absolute;
    top: 0; left: 0;
    width: 150px;
    margin: 0;
    /* The height of a cell, borders included, so that the title sits level with its first row. */
    line-height: 22px;

    font-size: 11px;
    font-weight: normal;
    color: var(--ui-text);
    text-transform: uppercase;
}

.which-key .entry {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
    /* Each cell is outlined, and overlaps its neighbours by the width of the line, so that the
       lines between cells are single. */
    margin: 0 -1px -1px 0;
    padding: 2px 8px;

    border: var(--ui-rule) solid 1px;

    line-height: 16px;
}

.which-key .entry kbd {
    flex: none;
    min-width: 4ch;

    color: var(--ui-accent);
}

/* What the line does takes the room left, so that the values and buttons line up on the right. */
.which-key .entry kbd + span, .which-key .entry i + span {
    flex: 1;
    min-width: 0;
    overflow: hidden;

    text-overflow: ellipsis;
    white-space: nowrap;
}

.which-key.descriptive .entry kbd + span {
    white-space: normal;
}

/* The help's About links. */
.which-key a {
    color: var(--ui-secondary);
}

/* The chord also bound to a command layer binding. */
.which-key .entry kbd.chord {
    min-width: 0;

    opacity: var(--ui-dim);
}

.which-key .entry kbd.chord:empty {
    display: none;
}

/* A line said at length, as a problem, across the group, wrapping rather than cut short. */
.which-key .entry.wide {
    grid-column: 1 / -1;
}
.which-key .entry.wide span {
    overflow: visible;

    white-space: normal;
}
.which-key .entry.wide .value {
    flex: 1;
}

/* The current value of what a binding changes, or the current option. */
.which-key .entry .value {
    flex: none;

    color: var(--ui-secondary);
}

.which-key .entry .value:empty {
    display: none;
}

/* A colour in the colour layer. */
.which-key .entry i.swatch {
    display: inline-block;
    flex: none;
    width: 10px; height: 10px;
    align-self: center;

    border: var(--ui-border) solid 1px;
    border-radius: 2px;
}

.which-key .entry.current span:first-of-type::after {
    content: " ●";

    color: var(--ui-secondary);
}

/* A line whose key a click presses. */
.which-key .entry.clickable {
    cursor: pointer;
}

.which-key .entry.clickable:hover {
    background: var(--ui-hover);
}

/* The sliders' step buttons. */
.which-key .entry .steps {
    flex: none;
}

.which-key .entry .steps button {
    width: 16px;
    padding: 0;

    background: transparent;
    border: var(--ui-border) solid 1px;
    border-radius: 2px;

    font: inherit;
    line-height: 12px;
    color: var(--ui-white);

    cursor: pointer;
}

.which-key .entry .steps button:hover {
    background: var(--ui-active);
}

.which-key .entry .steps button + button {
    margin-left: 2px;
}

.which-key.no-edge .needs-edge {
    display: none;
}

.which-key.no-frame .needs-frame {
    display: none;
}

.which-key.no-selection .needs-selection {
    opacity: var(--ui-disabled);
}

/* What amscd cannot draw, while the diagram is in amscd. */
.which-key.amscd .not-amscd {
    opacity: var(--ui-disabled);
}

/* The axes of a spectral sequence (see `SpectralSequence.draw`). */
svg.frame-axes {
    position: absolute;
    overflow: visible;

    pointer-events: none;
}
svg.frame-axes polyline,
svg.frame-axes line {
    stroke: var(--ink);
}
/* What is pressed on, in place of the thin line it lies under. */
svg.frame-axes .hit {
    stroke: transparent;

    pointer-events: stroke;
}

/* The cells a preset's stamp would land on, which keep it from landing (see `Layer.Preset`). */
.vertex.in-the-way .content {
    outline: 2px solid var(--ui-error);

    color: var(--ui-error);
}

/* A preset's ghost: what RET in its setup layer would stamp (see `Layer.Preset`). */
.cell.ghost {
    opacity: 0.4;

    pointer-events: none;
}

/* A layer's line that would do nothing now (e.g. copying maths when the diagram is not a row). */
.which-key .entry.disabled {
    opacity: var(--ui-disabled);
}

/* The compact list: each line only its key and value (what it does shows on hovering), packed
   along its group's row, under a narrower title. Lists other than the command layer's keep their
   descriptions, which they need. */
.which-key.compact .main .group {
    display: flex;
    flex-wrap: wrap;
    padding-left: 120px;
}

/* After the layout above, which would otherwise override it. */
.which-key.compact.no-edge .main .needs-edge,
.which-key.compact.no-frame .main .needs-frame {
    display: none;
}

.which-key.compact .main h3 {
    width: 120px;
    overflow: hidden;

    text-overflow: ellipsis;
    white-space: nowrap;
}

.which-key.compact .main .entry kbd {
    min-width: 2ch;
}

.which-key.compact .main .entry kbd:first-child + span, .which-key.compact .main .entry kbd.chord {
    display: none;
}

.which-key.compact .main .entry.current kbd::after {
    content: " ●";

    color: var(--ui-secondary);
}
