/* index.css - styles for index.html and generally main parts of the app
   For shared styles (such as color definitions) check out base.css. */

html {
    /* On the main page, we don't really want to permit selecting things.
       It comes off as janky-looking. */
    user-select: none;
}

/* Main container layout */

html {
    /* Don't want any scrollbars to ruin our layout.
       Technically this will cause jank in case the view _does_ scroll somehow, but that's less of
       an annoying bug than browser layout triggering scrollbars and ruining the page size...
       I'm not sure what caused the browser to show scrollbars when I switched my displays to 4k,
       but it did, and I didn't like it.
       CSS remains a mystery, as it always has. */
    overflow: hidden;
}

body {
    width: 100vw;
    height: 100vh;

    font-size: 14px;
}

main {
    width: 100%;
    height: 100%;
    position: relative;

    & > .fullscreen {
        width: 100%;
        height: 100%;
        max-width: 100%;
        max-height: 100%;
        position: absolute;
        left: 0;
        top: 0;
    }

    & > .panels {
        --right-width: 384px; /* Overridden by JavaScript */

        box-sizing: border-box;
        padding: 16px;

        display: grid;
        grid-template-columns: [left] 1fr [right-resize] auto [right] minmax(
                0,
                var(--right-width)
            );

        /* Pass all events through. Children may receive events as normal. */
        pointer-events: none;

        & > * {
            pointer-events: all;
        }

        & > .left {
            display: flex;
            flex-direction: column;

            pointer-events: none;

            & > * {
                pointer-events: auto;
            }

            & > rkgk-zoom-indicator {
                margin-block-start: auto;
            }
        }

        & > .right {
            grid-column: right / right;
            min-height: 0;

            display: grid;
            grid-template-rows: minmax(0, min-content);
            grid-template-columns: [floating] max-content [resize] min-content [docked] auto;

            padding-left: 16px;

            pointer-events: none;

            & > * {
                min-width: 0;
                min-height: 0;
            }

            & > rkgk-resize-handle {
                pointer-events: auto;
            }

            & > .docked {
                display: flex;
                flex-direction: column;

                & > * {
                    pointer-events: auto;
                }
            }

            & > .docked > rkgk-brush-editor {
                max-height: 100%;
            }

            & > .floating {
                display: flex;
                flex-direction: column;

                gap: 12px;

                & > rkgk-brush-preview {
                    width: 128px;
                    height: 128px;
                    pointer-events: auto;
                }

                & > rkgk-brush-cost-gauges {
                    width: 100%;
                    pointer-events: auto;
                }
            }
        }
    }

    & > rkgk-canvas-renderer {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
    }

    & > rkgk-reticle-renderer {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        overflow: hidden;
    }

    & > #js-loading {
        background-color: var(--color-panel-background);

        display: flex;
        align-items: center;
        justify-content: center;
    }
}

/* Resize handle */

rkgk-resize-handle {
    --width: 16px;
    --line-width: 2px;

    display: flex;
    justify-content: center;
    flex-shrink: 0;

    &[data-direction="horizontal"] {
        width: 100%;
        height: var(--width);
        flex-direction: column;

        cursor: row-resize;

        & > .visual {
            width: 100%;
            height: var(--line-width);
        }
    }

    &[data-direction="vertical"] {
        width: var(--width);
        height: 100%;
        flex-direction: row;

        cursor: col-resize;

        & > .visual {
            width: var(--line-width);
            height: 100%;
        }
    }

    & > .visual {
        background-color: var(--color-brand-blue);
        opacity: 0%;
    }

    &:hover > .visual,
    &.dragging > .visual {
        opacity: 100%;
    }
}

/* Canvas renderer */

rkgk-canvas-renderer {
    display: block;

    & > canvas {
        display: block;

        /* Fill the parent, don't overflow it.
           This is important because under HiDPI, the canvas's pixel size is larger than the layout size. */
        max-width: 100%;
        max-height: 100%;
    }
}

/* Reticle renderer */

rkgk-reticle-renderer {
    display: block;

    pointer-events: none;

    & > .reticles {
        position: relative;
    }
}

rkgk-reticle-cursor {
    --color: black; /* Overridden by JavaScript to set a per-user color. */

    position: absolute;
    display: block;

    & > .container {
        & > .arrow {
            width: 24px;
            height: 24px;
            background-color: var(--color);
            clip-path: path("M 0,0 L 13,13 L 6,13 L 0,19 Z");
        }

        & > .nickname {
            position: absolute;
            top: 20px;
            left: 8px;
            width: max-content;

            color: white;
            background-color: var(--color);
            padding: 1px 6px;
            border-radius: 9999px;
            text-align: center;
            font-weight: bold;
        }
    }
}

/* Brush box */

rkgk-brush-box.rkgk-panel {
    --button-size: 56px;

    height: var(--height);
    padding: 12px;

    & > .brushes {
        display: grid;
        grid-template-columns: repeat(
            auto-fit,
            minmax(var(--button-size), 1fr)
        );

        max-height: 100%;
        overflow-x: hidden;
        overflow-y: auto;

        & > button {
            padding: 0;
            border: 1px solid transparent;
            border-radius: 4px;
            width: 100%;

            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;

            overflow: hidden;
            white-space: nowrap;

            &.current {
                border-color: var(--color-brand-blue);
            }

            & > rkgk-brush-preview {
                width: var(--button-size);
                aspect-ratio: 1 / 1;
                background: none;
            }

            & > .label {
                margin: 0;
                font-size: 80%;
            }

            &.save-button {
                display: none; /* visible when current brush is modified */

                & > .icon {
                    width: var(--button-size);
                    height: var(--button-size);
                }

                & > .icon,
                & > .label {
                    opacity: 35%;
                }
            }
        }
    }

    &.unsaved > .brushes {
        & > .current > .label::after {
            content: "*";
        }

        & > .save-button {
            display: flex;
        }
    }
}

/* Code editor */

rkgk-code-editor {
    --gutter-width: 2.75em;

    display: block;
    position: relative;
    width: 100%;

    overflow: auto;

    & > .layer {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        box-sizing: border-box;

        margin: 0;

        pointer-events: none;

        display: flex;
        flex-direction: column;

        & > .line {
            flex-shrink: 0;
            white-space: pre-wrap;

            min-height: var(--line-height-em);
        }
    }

    & > .layer-gutter {
        counter-reset: line;

        color: transparent;

        & > .line {
            display: flex;
            flex-direction: row;

            counter-increment: line;

            &::before {
                flex-shrink: 0;

                display: block;
                width: var(--gutter-width);
                padding-right: 0.75em;
                box-sizing: border-box;

                content: counter(line);
                text-align: right;

                color: var(--color-text);
                opacity: 40%;
            }
        }
    }

    & > .layer:not(.layer-gutter) {
        margin-left: var(--gutter-width);
        width: calc(100% - var(--gutter-width));
    }

    & > .layer-error-squiggles {
        color: transparent;

        & > .line {
            & > .squiggle {
                text-decoration: underline wavy black;
                text-decoration-skip-ink: none;
            }

            & > .squiggle-error {
                text-decoration-color: var(--color-error);

                &.squiggle-colored {
                    --color: oklch(40% 100% calc(var(--color-index) * 300));
                    text-decoration-color: var(--color);
                    background-color: oklch(from var(--color) 60% c h / 0.13);

                    &.squiggle-highlighted {
                        --highlight-color-index: var(--color-index);
                        text-decoration: none;
                        background-color: oklch(
                            40% 100% calc(var(--highlight-color-index) * 300)
                        );
                        color: white;
                        font-weight: bold;
                    }
                }
            }
        }
    }

    & > .layer-syntax {
        white-space: pre-wrap;
    }

    & > textarea {
        display: block;
        width: calc(100% - var(--gutter-width));

        margin: 0;
        margin-left: var(--gutter-width);
        padding: 0;
        border: none;

        overflow: hidden;
        resize: none;

        white-space: pre-wrap;

        background: none;
        color: transparent;
        caret-color: var(--color-text);

        &:focus {
            /* The outline is displayed on the parent element to also surround the gutter. */
            outline: none;
        }

        &::selection {
            /* The selection color has to be overridden for a good contrast ratio between text and
               the selection. */
            background-color: rgba(from var(--color-brand-blue) r g b / 0.3);
        }
    }

    &:has(textarea:focus) {
        outline: 1px solid var(--color-brand-blue);
        outline-offset: 4px;
    }
}

/* Brush editor */

rkgk-brush-editor.rkgk-panel {
    padding: 12px;

    display: flex;
    flex-direction: column;
    gap: 4px;

    position: relative;

    & > .name {
        margin-bottom: 4px;
        font-weight: bold;
    }

    & > .text-area {
        display: block;
        width: 100%;
        margin: 0;
        resize: none;
        white-space: pre-wrap;
        border: none;
        overflow: hidden;
        box-sizing: border-box;
    }

    & > .errors:empty,
    & > .error-header:empty {
        display: none;
    }

    & > .error-header {
        margin: 0;
        margin-top: 0.5em;
        font-size: 1rem;
        color: var(--color-error);
    }

    & > .errors {
        margin: 0;
        color: var(--color-error);
        white-space: pre-wrap;

        user-select: text;

        max-height: 20em;
        overflow-y: auto;
    }
}

rkgk-brush-editor-error-exception {
    & > .message {
        margin: 4px 0;
    }

    & > .stack-trace {
        margin: 0;
        margin-left: 4ch;

        color: var(--color-text);

        & > li {
            &::marker {
                color: var(--color-text-dim);
            }

            & > button.function-name {
                border: none;
                border-radius: 0;
                padding: 0;
                background: none;

                user-select: text;

                font-weight: bold;

                &:not(:disabled) {
                    text-decoration: underline;
                    cursor: pointer;
                }

                &:disabled {
                    opacity: 100%;
                }

                &.source-link {
                    --color-index: 0; /* set by JavaScript */
                    --color: oklch(40% 100% calc(var(--color-index) * 300));

                    color: var(--color);

                    &:hover {
                        text-decoration: none;
                        background-color: var(--color);
                        color: white;
                    }
                }
            }

            & > .system {
                color: var(--color-text-dim);
            }
        }
    }
}

/* Brush preview */

rkgk-brush-preview {
    --checkerboard-light: #f2f2f2;
    --checkerboard-dark: #e1e1e1;
    --checkerboard-size: 64px;

    display: block;
    position: relative;

    background: repeating-conic-gradient(
            var(--checkerboard-light) 0% 25%,
            var(--checkerboard-dark) 0% 50%
        )
        50% 50% / var(--checkerboard-size) var(--checkerboard-size);
    border-radius: 4px;

    & > canvas {
        display: block;
        border-radius: 4px;

        max-width: 100%;
        height: auto;

        /* The brush preview doesn't scale with DPI as easily as the canvas renderer does,
           so instead we pixelate it. */
        image-rendering: pixelated;
    }

    &.error {
        & > canvas {
            display: none;
        }

        &::before {
            content: "(error)";
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
    }
}

/* Brush cost gauges */

rkgk-brush-cost-gauges,
rkgk-brush-cost-gauges.rkgk-panel {
    --gauge-size: 20px;

    height: var(--gauge-size);
    border-radius: 4px;

    display: flex;
    flex-direction: row;

    overflow: clip; /* clip corners */

    &.hidden {
        display: none;
    }

    & > rkgk-brush-cost-gauge {
        display: block;
        height: var(--gauge-size);
        flex-grow: 1;

        &.hidden {
            display: none;
        }

        & > .full {
            width: 100%;
            height: 100%;

            clip-path: xywh(0 0 var(--progress) 100%);

            background-color: var(--gauge-color);
        }

        &.code-size {
            --gauge-color: var(--color-brand-blue);
        }
        &.fuel {
            --gauge-color: #f44096;
        }
        &.objects {
            --gauge-color: #fd9916;
        }
        &.memory {
            --gauge-color: #5aca40;
        }
    }
}

/* Zoom indicator */

rkgk-zoom-indicator,
rkgk-zoom-indicator.rkgk-panel {
    border-radius: 4px;

    display: flex;
    flex-direction: row;
    align-items: center;

    width: min-content;

    overflow: clip; /* corners */

    & > button {
        width: 24px;
        height: 24px;
    }

    & > p {
        margin: 0;
        padding: 0 4px;
        line-height: 1;
        width: 6ch;

        font-variant-numeric: tabular-nums;
        text-align: center;
    }
}

/* Welcome screen */

rkgk-welcome {
    & > dialog {
        h3 {
            margin: 0.5rem 0;
            font-size: 2rem;
            font-weight: bold;
        }
    }
}

/* Connection status dialogs */

rkgk-connection-status {
    & > dialog[name="logging-in-dialog"][open],
    & > dialog[name="disconnected-dialog"][open] {
        border: none;
        outline: none;
        background: none;

        display: flex;
        gap: 8px;
        align-items: center;
    }

    & > dialog[name="error-dialog"][open] {
        & textarea[name="error-text"] {
            box-sizing: border-box;
            width: 100%;
            resize: none;
            border: 1px solid var(--color-panel-border);
            padding: 4px;
        }
    }
}

/* Context menu */

rkgk-context-menu-space {
    pointer-events: none;

    & > rkgk-context-menu {
        pointer-events: all;
    }
}

rkgk-context-menu.rkgk-panel {
    width: max-content;
    display: flex;
    flex-direction: column;

    border-radius: 4px;
    overflow: clip;

    & > p {
        margin: 0;
        padding: 6px 12px;

        &.small {
            padding: 4px 12px;
            font-size: 80%;
            opacity: 75%;
        }
    }

    & > button {
        padding: 6px 12px;

        border: none;
        border-radius: 0;

        text-align: left;
    }

    & > hr {
        margin: 0;
        width: 100%;
        border-bottom: 1px solid var(--color-panel-border);
    }
}

/* Menu bar */

.menu-bar {
    --border-radius: 4px;

    display: flex;
    align-items: center;
    box-sizing: border-box;

    width: fit-content;
    height: 24px;
    border-radius: var(--border-radius);

    & > a {
        display: block;

        color: var(--color-text);
        padding: 4px 8px;
        text-decoration: none;

        line-height: 1;

        &:hover {
            background-color: var(--color-shaded-background);
        }

        &.icon {
            width: 24px;
            height: 24px;
        }

        &:first-child {
            border-top-left-radius: var(--border-radius);
            border-bottom-left-radius: var(--border-radius);
        }

        &:last-child {
            border-top-right-radius: var(--border-radius);
            border-bottom-right-radius: var(--border-radius);
        }
    }

    & > hr {
        height: 100%;
        margin: 0;
        border: none;
        border-right: 1px solid var(--color-panel-border);
    }
}
