/* Arcade — the teleport map on a Table page: a machine with a radar on its
 * screen, built from the same parts as the Feature cabinets above it.
 *
 *   the cabinets   the map and the list each stand in one: T-molding in the
 *                  game's tone, hard shadow (.tp-group's recipe)
 *   the screen     near black behind a bezel, with the canvas painted in pixel
 *                  style; the status line is an LCD under it
 *   the list       a menu on a second screen: a pixel arrow on the row in hand,
 *                  blinking on the one that is selected
 *   the cursor     the selection on the map: the family's select cursor, cut
 *                  down to a marker's size
 *
 * --tm-tone rather than the page's --tp-tone: the expanded map leaves the
 * section for <body>. It reads --game-rgb, which the module keeps on the shell
 * for exactly that reason.
 *
 * The stage has no border of its own here, its bezel is a box-shadow. The
 * module sizes the canvas buffer from the stage's outer box, so a border would
 * squeeze the buffer into a smaller canvas and blur every pixel font on it. */

html[data-theme="arcade"] .tm-shell {
    --tm-tone: var(--game-rgb, var(--arc-fg-rgb));
    --tm-screen: var(--ds-bg-deep);
    --tm-ink: color-mix(in srgb, var(--arc-fg) 84%, var(--arc-bg));

    /* The canvas's palette (see CSS/TableMap.css). The height ramp mixes in
       sRGB, the space the screens derive every other shade in, so the steps
       stay shades of the screen's colour. */
    --tm-bg: var(--tm-screen);
    --tm-grid-minor: rgba(var(--tm-tone), 0.07);
    --tm-grid-major: rgba(var(--tm-tone), 0.17);
    --tm-axis: rgba(var(--tm-tone), 0.42);
    --tm-ruler: var(--arc-dim);
    --tm-hud: color-mix(in srgb, var(--arc-dim) 50%, var(--arc-fg));
    --tm-marker: rgb(var(--tm-tone));
    --tm-marker-dim: var(--arc-dim);
    --tm-label: var(--tm-ink);
    --tm-label-strong: var(--arc-wild);
    --tm-label-dim: var(--arc-dim);
    --tm-selection: var(--arc-wild);
    --tm-hover: var(--arc-fg);
    --tm-badge: rgb(var(--tm-tone));
    --tm-badge-edge: rgba(var(--tm-tone), 0.55);
    --tm-caption: rgb(var(--tm-tone));
    --tm-ramp-space: srgb;
    --tm-ramp-fade: 0.36;
    --tm-style: pixel;
    --tm-glow: 7;
    --tm-font: 13px var(--arc-text);
    --tm-font-strong: 13px var(--arc-text);
    --tm-font-caption: 8px var(--arc-pixel);
    --tm-font-count: 8px var(--arc-pixel);
    --tm-font-hud: 8px var(--arc-pixel);

    gap: 1.25rem;
}

/* ---- the cabinets -------------------------------------------------------------- */

html[data-theme="arcade"] :is(.tm-map, .tm-side) {
    gap: 10px;
    padding: 12px 14px;
    border: 2px solid var(--ds-line-2);
    background:
        linear-gradient(90deg, rgba(var(--tm-tone), 0.45) 0 3px, transparent 3px calc(100% - 3px), rgba(var(--tm-tone), 0.45) calc(100% - 3px)),
        linear-gradient(180deg, color-mix(in srgb, var(--arc-fg) 6%, var(--arc-bg)), color-mix(in srgb, var(--arc-fg) 3%, var(--arc-bg)));
    box-shadow: 6px 6px 0 color-mix(in srgb, var(--arc-fg) 10%, transparent);
}

/* ---- the screen ---------------------------------------------------------------- */

html[data-theme="arcade"] .tm-stage {
    margin: 4px;
    border: 0;
    background: var(--tm-bg);
    box-shadow: 0 0 0 2px #000, 0 0 0 4px rgba(var(--tm-tone), 0.4);
}

/* The glass: the screen's own light, gathered at its edges. */
html[data-theme="arcade"] .tm-stage::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    box-shadow: inset 0 0 56px rgba(var(--tm-tone), 0.1);
    pointer-events: none;
}

/* Clipped by the stage where the page's focus ring would go. */
html[data-theme="arcade"] .tm-stage:has(.tm-canvas:focus-visible) {
    box-shadow: 0 0 0 2px #000, 0 0 0 4px var(--arc-wild);
}

/* Under the screen, as an LCD. */
html[data-theme="arcade"] .tm-status {
    padding: 2px 8px;
    border: 2px solid rgba(var(--tm-tone), 0.4);
    background: #000;
    color: rgb(var(--tm-tone));
}

html[data-theme="arcade"] .tm-status.is-error {
    border-color: rgba(var(--arc-bad-rgb), 0.6);
    color: var(--arc-bad);
}

/* ---- the select cursor ------------------------------------------------------- */

html[data-theme="arcade"] .tm-cursor {
    --tm-arm: 6px;
    background:
        linear-gradient(var(--arc-wild) 0 0) 0 0 / var(--tm-arm) 2px no-repeat,
        linear-gradient(var(--arc-wild) 0 0) 0 0 / 2px var(--tm-arm) no-repeat,
        linear-gradient(var(--arc-wild) 0 0) 100% 0 / var(--tm-arm) 2px no-repeat,
        linear-gradient(var(--arc-wild) 0 0) 100% 0 / 2px var(--tm-arm) no-repeat,
        linear-gradient(var(--arc-wild) 0 0) 0 100% / var(--tm-arm) 2px no-repeat,
        linear-gradient(var(--arc-wild) 0 0) 0 100% / 2px var(--tm-arm) no-repeat,
        linear-gradient(var(--arc-wild) 0 0) 100% 100% / var(--tm-arm) 2px no-repeat,
        linear-gradient(var(--arc-wild) 0 0) 100% 100% / 2px var(--tm-arm) no-repeat;
    filter: drop-shadow(0 0 3px rgba(var(--arc-wild-rgb), 0.8));
    animation: tm-cursor-in 0.24s steps(4, end) both, arc-cab-cursor-blink 1.2s steps(1, end) 0.6s infinite;
}

@keyframes tm-cursor-in {
    from { transform: scale(4); }
    to { transform: none; }
}

/* ---- the buttons on the screen ----------------------------------------------- */

html[data-theme="arcade"] .tm-tools {
    gap: 2px;
    padding: 2px;
    border: 2px solid #000;
    background: var(--arc-bg);
    box-shadow: 0 0 0 2px var(--ds-line-1), 4px 4px 0 rgba(0, 0, 0, 0.55);
    backdrop-filter: none;
}

html[data-theme="arcade"] .tm-tool {
    width: 30px;
    height: 30px;
    border: 2px solid var(--ds-line-1);
    background: color-mix(in srgb, var(--arc-fg) 5%, var(--arc-bg));
    color: var(--tm-ink);
    transition: none;
}

/* A switch that is off is a lamp that is out; the plain buttons stay readable. */
html[data-theme="arcade"] .tm-tool[data-map-toggle][aria-pressed="false"] {
    background: var(--arc-bg);
    color: var(--arc-dim);
}

html[data-theme="arcade"] .tm-tool[aria-pressed="false"]:not([data-map-toggle]) {
    color: var(--tm-ink);
}

html[data-theme="arcade"] .tm-tool[aria-pressed="true"] {
    border-color: rgb(var(--tm-tone));
    background: rgba(var(--tm-tone), 0.16);
    color: rgb(var(--tm-tone));
    box-shadow: 0 0 8px rgba(var(--tm-tone), 0.45);
}

html[data-theme="arcade"] .tm-tool:focus-visible {
    border-color: var(--arc-wild);
    background: rgba(var(--tm-tone), 0.16);
    color: var(--arc-fg);
}

@media (hover: hover) {
    html[data-theme="arcade"] .tm-tool:hover {
        border-color: rgb(var(--tm-tone));
        background: rgba(var(--tm-tone), 0.16);
        color: var(--arc-fg);
    }
}

html[data-theme="arcade"] .tm-tool:active {
    transform: translate(1px, 1px);
}

/* ---- what floats over the screen ----------------------------------------------- */

html[data-theme="arcade"] .tm-card {
    padding: 6px 10px;
    border: 2px solid rgb(var(--tm-tone));
    background: var(--arc-bg);
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.6), 0 0 14px rgba(var(--tm-tone), 0.3);
    color: var(--arc-fg);
    font-size: 1rem;
    line-height: 1.2;
}

html[data-theme="arcade"] .tm-card b {
    font-weight: 400;
}

html[data-theme="arcade"] .tm-card .tm-card-meta {
    color: var(--arc-dim);
    font-size: 0.8rem;
}

html[data-theme="arcade"] .tm-card .tm-card-coords {
    color: rgb(var(--tm-tone));
    font-size: 0.8rem;
}

html[data-theme="arcade"] .tm-card ul {
    color: var(--tm-ink);
    font-size: 0.8rem;
    list-style: square;
}

html[data-theme="arcade"] .tm-hint {
    padding: 4px 10px;
    border: 2px solid var(--arc-wild);
    background: var(--arc-bg);
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.6);
    font-size: 0.9rem;
    animation-timing-function: steps(3, end);
}

html[data-theme="arcade"] .tm-hint kbd {
    border-width: 2px;
    background: #000;
    color: var(--arc-wild);
    font-size: 0.85rem;
}

/* ---- the controls ------------------------------------------------------------------ */

html[data-theme="arcade"] .tm-search {
    border-color: var(--ds-line-2);
    background: var(--tm-screen);
}

html[data-theme="arcade"] .tm-search:focus-within {
    border-color: rgb(var(--tm-tone));
}

/* The plane is three characters, an area can be a whole name. */
html[data-theme="arcade"] .tm-selects {
    grid-template-columns: minmax(0, 1fr) 6rem;
}

/* The arrow: three rows of pixels. */
html[data-theme="arcade"] .tm-select select {
    padding: 4px 28px 4px 8px;
    border: 2px solid var(--ds-line-2);
    background:
        linear-gradient(rgb(var(--tm-tone)) 0 0) right 8px top calc(50% - 2px) / 10px 2px no-repeat,
        linear-gradient(rgb(var(--tm-tone)) 0 0) right 10px top 50% / 6px 2px no-repeat,
        linear-gradient(rgb(var(--tm-tone)) 0 0) right 12px top calc(50% + 2px) / 2px 2px no-repeat,
        var(--tm-screen);
    color: var(--arc-fg);
    font-size: 0.9rem;
    cursor: pointer;
    appearance: none;
}

html[data-theme="arcade"] .tm-select select:disabled {
    cursor: default;
}

html[data-theme="arcade"] .tm-select select:focus-visible {
    border-color: rgb(var(--tm-tone));
    outline: none;
    box-shadow: var(--ds-focus);
}

@media (hover: hover) {
    html[data-theme="arcade"] .tm-select select:hover:not(:disabled) {
        border-color: rgb(var(--tm-tone));
    }
}

html[data-theme="arcade"] .tm-select option {
    background: var(--arc-bg);
    color: var(--arc-fg);
}

/* ---- the list: a menu on a second screen --------------------------------------- */

html[data-theme="arcade"] .tm-list {
    margin: 4px;
    padding: 0 4px 6px;
    background: var(--tm-screen);
    box-shadow: 0 0 0 2px #000, 0 0 0 4px var(--ds-line-1);
    scrollbar-color: rgba(var(--tm-tone), 0.6) transparent;
}

html[data-theme="arcade"] .tm-list:focus-visible {
    box-shadow: 0 0 0 2px #000, 0 0 0 4px var(--arc-wild);
}

html[data-theme="arcade"] .tm-list-group {
    margin-bottom: 2px;
    padding: 8px 4px 6px;
    border-bottom: 2px dashed var(--ds-line-1);
    background: var(--tm-screen);
    color: rgb(var(--tm-tone));
}

html[data-theme="arcade"] .tm-entry {
    position: relative;
    padding: 2px 6px 2px 18px;
    color: var(--tm-ink);
    transition: none;
}

html[data-theme="arcade"] .tm-entry::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 6px;
    width: 6px;
    height: 10px;
    margin-top: -5px;
    color: rgb(var(--tm-tone));
    background:
        linear-gradient(currentColor 0 0) 0 0 / 2px 10px no-repeat,
        linear-gradient(currentColor 0 0) 2px 2px / 2px 6px no-repeat,
        linear-gradient(currentColor 0 0) 4px 4px / 2px 2px no-repeat;
    opacity: 0;
}

html[data-theme="arcade"] .tm-entry:focus-visible {
    background: rgba(var(--tm-tone), 0.1);
    color: var(--arc-fg);
}

html[data-theme="arcade"] .tm-entry:focus-visible::before {
    opacity: 1;
}

@media (hover: hover) {
    html[data-theme="arcade"] .tm-entry:hover {
        background: rgba(var(--tm-tone), 0.1);
        color: var(--arc-fg);
    }

    html[data-theme="arcade"] .tm-entry:hover::before {
        opacity: 1;
    }

    html[data-theme="arcade"] .tm-entry:hover .tm-entry-height {
        color: rgb(var(--tm-tone));
    }
}

html[data-theme="arcade"] .tm-entry.is-selected {
    background: rgba(var(--tm-tone), 0.2);
    color: var(--arc-fg);
}

html[data-theme="arcade"] .tm-entry.is-selected::before {
    color: var(--arc-wild);
    opacity: 1;
    animation: arc-cab-cursor-blink 1.2s steps(1, end) infinite;
}

html[data-theme="arcade"] .tm-entry.is-selected .tm-entry-height {
    color: rgb(var(--tm-tone));
}

html[data-theme="arcade"] :is(.tm-list-more, .tm-list-empty) {
    color: var(--arc-dim);
    font-size: 0.85rem;
}

/* ---- the selected location: a ticket ----------------------------------------------- */

html[data-theme="arcade"] .tm-details {
    margin: 4px;
    padding: 10px 12px;
    border: 2px solid rgba(var(--tm-tone), 0.5);
    background: var(--tm-screen);
}

html[data-theme="arcade"] .tm-details h3 {
    margin: 0 0 6px;
    font-family: var(--arc-pixel);
    font-size: 10px;
    font-weight: 400;
    line-height: 1.6;
    overflow-wrap: anywhere;
    text-shadow: 0 0 10px rgba(var(--tm-tone), 0.45);
}

html[data-theme="arcade"] .tm-details-meta {
    color: var(--arc-dim);
    font-size: 0.8rem;
}

html[data-theme="arcade"] .tm-details-note {
    color: var(--tm-ink);
    font-size: 0.9rem;
}

html[data-theme="arcade"] .tm-coord {
    border: 2px solid rgba(var(--tm-tone), 0.4);
    background: #000;
    color: rgb(var(--tm-tone));
    font-size: 0.8rem;
}

html[data-theme="arcade"] .tm-coord span {
    color: var(--arc-dim);
}

/* ---- the two cabinets stand the same height ------------------------------------- */

/* The list takes what the map's cabinet leaves it, instead of the map's column
   and the list's column each ending somewhere. height: 0 keeps the list out of
   the row's sizing; min-height then fills the row the map decided. */
@media (min-width: 900px) {
    html[data-theme="arcade"] .tm-shell:not(.is-expanded) {
        align-items: stretch;
    }

    html[data-theme="arcade"] .tm-shell:not(.is-expanded) .tm-side {
        height: 0;
        min-height: 100%;
    }

    html[data-theme="arcade"] .tm-shell:not(.is-expanded) .tm-list {
        flex: 1 1 0;
        min-height: 5rem;
        max-height: none;
    }

    html[data-theme="arcade"] .tm-shell:not(.is-expanded) .tm-details {
        flex: 0 1 auto;
        min-height: 0;
        overflow-y: auto;
        scrollbar-color: rgba(var(--tm-tone), 0.6) transparent;
        scrollbar-width: thin;
    }
}

/* ---- expanded --------------------------------------------------------------------- */

html[data-theme="arcade"] .tm-shell.is-expanded {
    padding: 10px 16px 16px 10px;
    background: var(--arc-bg);
}

@media (prefers-reduced-motion: reduce) {
    html[data-theme="arcade"] .tm-cursor,
    html[data-theme="arcade"] .tm-entry.is-selected::before {
        animation: none;
    }
}
