/* ==========================================================================
   OpZone - Designer page shell
   Role: the /Dashboard/SiteAdmin/Designer two-pane split - the Game Designer
         panel (vertical icon rail + collapsible body) and the site layout
         builder that owns the map - plus the dashboard-chrome removal and the
         full-height contract the map lane depends on.
   Load position: 7 of 10 in the website opz-*.css chain (before
         opz-layout-builder.css and opz-mud-overrides.css, hence the extra
         specificity on the rail button rules).
   Colour/spacing values come from the shared tokens in opzone-ui.css and the
   MudBlazor palette variables; no new palette entries belong here.
   ========================================================================== */

/* ==========================================================================
   01 DASHBOARD CHROME - flattened for this page only
   DashboardCommon wraps every page in <section class="mt-1 pa-2"> at 90vw.
   Those are MudBlazor spacing classes, so they carry !important. The designer
   needs the whole column and the whole height, so the section is flattened ONLY
   when it directly contains this page's root - every other dashboard page keeps
   its chrome untouched. The dashboard hero above it loses its padding for the
   same reason: the page is a viewport frame, not a document.
   ========================================================================== */

section:has(> .opz-designer) {
    flex: 1 1 0%;
    width: auto !important;
    min-width: 0;
    margin: 0 !important;
    padding: 0 !important;
}

.opz-about-hero:has(.opz-designer) {
    /* opz-about.css gives this shell 28px/40px padding at <=768 ("height:auto"),
       which would push 68px of document scroll out of a fixed-height page. The
       designer is a viewport frame, so all four sides go to zero here - the page
       root's own height then lands exactly on 100dvh - 68px at every width. */
    padding: 0 !important;
}

/* The dashboard sidebar carries an inline min-height:93vh (DashboardCommon). At
   1440x900 that is 837px against this page's 832px column - five pixels of
   document scroll for no reason. Here it simply stretches to the column. */
.opz-about-hero:has(.opz-designer) .opz-dashboard-sidebar {
    min-height: 0 !important;
    align-self: stretch;
}

/* ==========================================================================
   02 PAGE ROOT - the height / grid contract
   height: 100dvh minus the 68px fixed app bar (opz-landing.css pins both the
   toolbar height and .mud-main-content's top padding to 68px), so the hero
   above it needs no scrolling. min-height keeps a usable map on a short
   laptop screen; below that the hero scrolls, the document does not.
   ONE grid row of minmax(0, 1fr): both cells are exactly as tall as the page
   and can never push it taller.
   ========================================================================== */

.opz-designer {
    --opz-designer-rail: 48px;
    --opz-designer-panel: 33%;

    display: grid;
    grid-template-columns: var(--opz-designer-panel) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);

    height: calc(100vh - 68px);
    height: calc(100dvh - 68px);
    min-height: 520px;
    overflow: hidden;

    box-sizing: border-box;
    background: var(--mud-palette-background);
    transition: grid-template-columns 0.18s ease;
}

.opz-designer--collapsed {
    grid-template-columns: var(--opz-designer-rail) minmax(0, 1fr);
}

/* Below ~970px, 33% is a map-eating slice, so the panel stops growing there.
   Width cap only - the rail itself is never hidden, and this block cannot
   reach the collapsed rule above (it is guarded by :not). */
@media (max-width: 970px) {
    .opz-designer:not(.opz-designer--collapsed) {
        grid-template-columns: min(33%, 320px) minmax(0, 1fr);
    }
}

/* Before the viewport callback there is no width to judge: the prerendered HTML
   and the first interactive frame are always "expanded", which on a phone is a
   visible snap once the circuit hydrates. So narrow screens START closed, and
   --open (the user pressed the toggle) is the only thing that overrides it. */
@media (max-width: 899.98px) {
    .opz-designer:not(.opz-designer--open) {
        grid-template-columns: var(--opz-designer-rail) minmax(0, 1fr);
    }
}

@media (prefers-reduced-motion: reduce) {
    .opz-designer {
        transition: none;
    }
}

/* ==========================================================================
   03 LEFT PANEL - rail + collapsible body
   The panel is a flex row inside the grid cell: the rail is a fixed 48px block
   that never moves, the body takes whatever is left. Collapsed, the grid column
   IS the rail width, so the body resolves to 0 with nothing jumping.
   ========================================================================== */

.opz-designer__panel {
    display: flex;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    background: var(--mud-palette-surface);
    border-right: 1px solid var(--opz-panel-border);
}

.opz-designer__rail {
    display: flex;
    flex: 0 0 var(--opz-designer-rail);
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: var(--opz-designer-rail);
    padding: 8px 0 10px;
    box-sizing: border-box;
    background: var(--mud-palette-surface);
    border-right: 1px solid var(--opz-panel-border);
}

/* 34px square targets, icon-only. The global icon-button rules (40px circle,
   hover lift) are out-specified here: an icon rail that nudges on hover jitters,
   and the rail is only 48px wide. */
.opz-designer__rail .mud-icon-button {
    width: 34px;
    height: 34px;
    min-width: 34px;
    min-height: 34px;
    padding: 0;
    border-radius: 6px;
    color: var(--opz-ink-3);
    background-color: transparent;
    transition: background-color 140ms ease-out, color 140ms ease-out;
}

.opz-designer__rail .mud-icon-button:not(:disabled):not(.mud-disabled):hover {
    color: var(--opz-signal-deep);
    background-color: color-mix(in srgb, var(--opz-signal) 12%, transparent);
    transform: none;
}

/* MudBlazor's .mud-icon-size-medium pins the glyph at 1.5rem (24px), which fills a
   34px target edge to edge. 20px gives the rail its quiet, console-like rhythm. */
.opz-designer__rail .mud-icon-button .mud-icon-root {
    font-size: 1.25rem;
}

/* Deliberately disabled, not broken: solid muted ink instead of MudBlazor's
   faded 26% black, no hover fill, and a not-allowed cursor on the wrapper so
   the tooltip ("lands with the game designer") can still explain itself.
   The glyph needs its own rule: MudBlazor paints .mud-disabled .mud-icon-root
   from --mud-palette-text-disabled, so colouring the button alone is not enough. */
.opz-designer__rail .mud-icon-button:is(:disabled, .mud-disabled) {
    color: var(--opz-ink-4) !important;
    background-color: transparent !important;
    cursor: not-allowed;
}

.opz-designer__rail .mud-icon-button:is(:disabled, .mud-disabled) .mud-icon-root {
    color: var(--opz-ink-4);
}

.opz-designer__rail-hold {
    display: inline-flex;
    cursor: not-allowed;
}

.opz-designer__rail-rule {
    flex: 0 0 auto;
    width: 18px;
    height: 0;
    margin: 3px 0;
    border: 0;
    border-top: 1px solid var(--opz-panel-border);
}

.opz-designer__body {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    transition: opacity 0.18s ease, visibility 0s linear 0s;
}

/* Fixed measure for the copy: the column slides shut, so without this the text
   reflows on every frame. Clipped on the right instead, like a drawer. */
.opz-designer__body-inner {
    min-width: 220px;
    padding: 14px 18px 18px;
    box-sizing: border-box;
}

/* On a phone the expanded panel is a slip of paper beside the map. Below 600px
   the copy reflows into it rather than being cut off mid-word - cramped and
   obviously something to collapse again, instead of looking broken. */
@media (max-width: 600px) {
    .opz-designer__body-inner {
        min-width: 0;
    }
}

.opz-designer--collapsed .opz-designer__body {
    flex-basis: 0;
    width: 0;
    opacity: 0;
    /* visibility (not just opacity) removes the body from the tab order and the
       accessibility tree; the delay lets the fade finish before it snaps. */
    visibility: hidden;
    transition: opacity 0.18s ease, visibility 0s linear 0.18s;
}

.opz-designer__eyebrow {
    margin: 0 0 6px;
    font-family: var(--opz-font-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--opz-ink-4);
}

.opz-designer__copy {
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.45;
    color: var(--opz-panel-text-soft);
}

/* ==========================================================================
   04 RIGHT CELL - the layout builder's slot
   The builder takes no parameters and owns its own state; this cell only lends
   it a column of known height. The .opz-layout-builder rule below repeats the
   contract its own stylesheet documents, so the map cannot collapse to 0 if
   that rule is ever missing.
   ========================================================================== */

.opz-designer__map {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    background: var(--mud-palette-background);
}

.opz-designer__map > .opz-layout-builder {
    flex: 1 1 auto;
    min-height: 0;
}
