/**
 * Remmerzelt Reservation — Mobile DOM Map (≤ 1024 px)
 *
 * Plain-DOM renderer that replaces the Konva canvas on phones + tablets. No
 * GPU backing-store, no canvas allocation — fixes iOS Safari memory crashes.
 * Full prose: docs/CLAUDE-CONTRACTS.md § Mobile DOM map contract.
 */

.remmerzelt-dom-map { display: none; }
@media (max-width: 1024px) {
    .remmerzelt-dom-map { display: block; }
    .remmerzelt-canvas-wrap { display: none; }
}

/* Outer frame — non-scrolling, height computed from base × scale by JS (--scale).
   Stays the scroll-free, positioned host for the ::after scroll-edge hint; the
   actual horizontal scroll happens on the JS-injected __scroll child. */
.remmerzelt-dom-map {
    position: relative;
    width: 100%;
    border: 2px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
    background: #f9f9f9;
}

/* Scroller — the horizontal pan layer (overflow-y hidden so it never adds a
   vertical scrollbar or traps the page's vertical scroll). Injected by
   table-map-dom.js between the frame and the sizer. */
.remmerzelt-dom-map__scroll {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    /* Stop a horizontal swipe past the edge from triggering the browser's back
       gesture (iOS Safari) / pull-to-refresh (Firefox Android). */
    overscroll-behavior-x: contain;
}

/* Sizer — real layout box = base × scale (set inline by JS), with overflow:hidden
   clipping the canvas's full-size (transform-only) layout box so the scroller's
   scrollWidth equals the painted width (no dead space past the last table).
   content-box guards against a host theme's global border-box. */
.remmerzelt-dom-map__sizer {
    position: relative;
    overflow: hidden;
    box-sizing: content-box;
    /* Right/bottom gutter so the focus ring of edge tables (paints up to 5px
       beyond the button) isn't clipped by overflow:hidden; the frame height adds
       the matching bottom room (RING_GUTTER in table-map-dom.js). The clip still
       trims the canvas's full-size layout box → no dead-space scrolling. */
    padding: 0 6px 6px 0;
}

/* Inner canvas — base dimensions, scaled via transform. transform-origin
   top-left so the scaled origin stays anchored to the wrap's top-left. */
.remmerzelt-dom-map__canvas {
    position: relative;
    width: calc(var(--base-w, 1200) * 1px);
    height: calc(var(--base-h, 800) * 1px);
    transform: scale(var(--scale, 1));
    transform-origin: top left;
    will-change: transform;
}

/* Shapes — z stacked via --z (sort_order); always below tables (no
   cross-layer z support per CLAUDE.md). */
.remmerzelt-dom-shape {
    position: absolute;
    left: calc(var(--x, 0) * 1px);
    top: calc(var(--y, 0) * 1px);
    width: calc(var(--w, 0) * 1px);
    height: calc(var(--h, 0) * 1px);
    background-color: var(--fill, #95a5a6);
    border: 1px solid #999;
    opacity: 0.6;
    transform: rotate(calc(var(--rot, 0) * 1deg));
    /* Matches Konva.Group origin (top-left) so admin-positioned shapes
       render in the same place on canvas and DOM paths. */
    transform-origin: top left;
    z-index: var(--z, 0);
    pointer-events: none;
    display: flex;
    align-items: center;
    justify-content: center;
}

.remmerzelt-dom-shape--rect {
    border-radius: 4px;
}

.remmerzelt-dom-shape--circle {
    border-radius: 50%;
}

.remmerzelt-dom-shape__label {
    color: #fff;
    text-shadow: 0 0 3px rgba(0, 0, 0, 0.7);
    font-size: 14px;
    font-weight: bold;
    text-align: center;
    padding: 4px;
    pointer-events: none;
}

/* Tables — base layer above shapes via z-index. min-w/h floors keep tap
   targets reliable when the admin draws very small rects (WCAG 2.5.8). */
.remmerzelt-dom-table {
    position: absolute;
    left: calc(var(--x, 0) * 1px);
    top: calc(var(--y, 0) * 1px);
    width: calc(var(--w, 0) * 1px);
    height: calc(var(--h, 0) * 1px);
    min-width: 28px;
    min-height: 28px;
    z-index: 100;
    border: 2px solid #333;
    border-radius: 4px;
    padding: 6px;
    margin: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    color: #fff;
    font-family: inherit;
    -webkit-tap-highlight-color: transparent;
}

/* Pressed feedback — works across all six state colours without per-state
   rules. Suppressed under prefers-reduced-motion below. */
.remmerzelt-dom-table:active {
    filter: brightness(0.85);
}

.remmerzelt-dom-table[data-layout-mode="name-only"] {
    justify-content: center;
}

/* State colours — WCAG-AA white-on-fill (≥ 4.5:1). Mirrors the canonical
   tokens in table-map.js and table-map.css. */
.remmerzelt-dom-table[data-state="free"]      { background-color: #388E3C; }
.remmerzelt-dom-table[data-state="partial"]   { background-color: #B56B00; }
.remmerzelt-dom-table[data-state="full"]      { background-color: #D32F2F; cursor: not-allowed; }
.remmerzelt-dom-table[data-state="blocked"]   { background-color: #9E9E9E; cursor: not-allowed; }
.remmerzelt-dom-table[data-state="selected"]  { background-color: #1976D2; }
.remmerzelt-dom-table[data-state="suggested"] { background-color: #7B1FA2; }

/* Two-tone ring — white inner + dark outer keeps the focus indicator
   visible against every state colour, including [data-state="selected"]
   whose background is #1976D2 (WCAG 2.4.11 + 1.4.11). */
.remmerzelt-dom-table:focus-visible {
    outline: 3px solid #fff;
    outline-offset: 2px;
    box-shadow: 0 0 0 5px #222;
}

.remmerzelt-dom-table__name,
.remmerzelt-dom-table__status {
    color: #fff;
    text-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
    text-align: center;
    line-height: 1.1;
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.remmerzelt-dom-table__name {
    font-size: 15px;
    font-weight: bold;
    word-break: break-word;
}

.remmerzelt-dom-table__status {
    font-size: 12px;
}

.remmerzelt-dom-map[aria-busy="true"] {
    opacity: 0.65;
    pointer-events: none;
    transition: opacity 0.18s ease-out;
}
.remmerzelt-dom-map:not([aria-busy="true"]) {
    opacity: 1;
    transition: opacity 0.25s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .remmerzelt-dom-map[aria-busy="true"],
    .remmerzelt-dom-map:not([aria-busy="true"]) {
        transition: none;
    }
    .remmerzelt-dom-map__canvas {
        will-change: auto;
    }
    .remmerzelt-dom-table:active {
        filter: none;
    }
}

/* Match canvas-wrap visual pattern at this breakpoint. */
@media (max-width: 600px) {
    .remmerzelt-dom-map {
        border-radius: 0;
        border-left: none;
        border-right: none;
    }

    /* Scroll-edge hint — a fade on the frame's right edge signalling more map to
       the right. Hosted on the non-scrolling frame (not the scroller) so it pins
       to the visible edge; toggled by updateScrollIndicator(). Mirrors
       table-map.css; scoped to .remmerzelt-dom-map to avoid colliding with the
       Konva rule of the same class name. */
    .remmerzelt-dom-map.remmerzelt-canvas-scrollable::after {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 24px;
        background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.08));
        pointer-events: none;
        z-index: 1;
        transition: opacity 0.3s;
    }

    .remmerzelt-dom-map.remmerzelt-canvas-scrolled-end::after {
        opacity: 0;
    }
}

/* Gradient fade suppressed for reduced-motion users. The combined query is placed
   AFTER the ≤600px block: it has equal specificity to the gradient's own
   `transition: opacity 0.3s` above, so it must win by source order — a plain
   reduced-motion block earlier in the file would be silently overridden. */
@media (max-width: 600px) and (prefers-reduced-motion: reduce) {
    .remmerzelt-dom-map.remmerzelt-canvas-scrollable::after,
    .remmerzelt-dom-map.remmerzelt-canvas-scrolled-end::after {
        transition: none;
    }
}
