/*
 * ui.responsive.css — Site-wide mobile / tablet responsiveness
 * ---------------------------------------------------------------------------
 * Loaded LAST in <head> (see index.php) so it wins the cascade over every
 * component stylesheet and can override inline layout widths via !important
 * where the markup stamps them directly on elements.
 *
 * Breakpoints:
 *   <= 900px  tablet portrait: content two-column grid already collapses at 980
 *   <= 768px  "mobile": sidebar becomes an off-canvas drawer, shell/header stack
 *   <= 600px  "phone": full single-column forms, controls go full-width
 *
 * The drawer is driven by `body.nav-open` (toggled in ui.mobile-nav.js).
 */

/* ===========================================================================
   1. SIDEBAR OFF-CANVAS DRAWER  (<= 768px)
   =========================================================================== */

/* Hamburger + scrim are desktop-hidden by default. */
.nav-hamburger { display: none; }
.nav-scrim     { display: none; }

@media (max-width: 768px) {

    /* Shell stacks; the aside is pulled out of flow into a fixed drawer. */
    main {
        flex-direction: column;
    }

    .site-aside {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        height: 100dvh;
        width: 84vw;
        max-width: 320px;
        margin: 0;
        padding: var(--net-spacing-sm);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        background: var(--net-bg-primary);
        box-shadow: var(--net-shadow-lg);
        z-index: var(--net-z-modal, 1000);
        transform: translateX(-100%);
        transition: transform var(--net-transition-base, 0.3s ease);
        will-change: transform;
    }

    body.nav-open .site-aside {
        transform: translateX(0);
    }

    /* Full-screen dimmer behind the open drawer. */
    .nav-scrim {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.5);
        opacity: 0;
        pointer-events: none;
        transition: opacity var(--net-transition-base, 0.3s ease);
        z-index: var(--net-z-overlay, 500);
    }

    body.nav-open .nav-scrim {
        opacity: 1;
        pointer-events: auto;
    }

    /* Hamburger toggle lives in the site header. */
    .nav-hamburger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto;
        width: 44px;
        height: 44px;
        padding: 0;
        margin-right: var(--net-spacing-xs);
        background: transparent;
        border: 1px solid var(--net-border-medium);
        border-radius: var(--net-border-radius-base);
        color: var(--net-text-primary);
        font-size: 1.4rem;
        line-height: 1;
        cursor: pointer;
    }

    .nav-hamburger:active {
        background: var(--net-bg-accent);
    }

    /* The drawer nav should fill its width, not sit at a fixed 220px. */
    .site-aside nav {
        margin-top: 0;
    }
}

/* ===========================================================================
   2. SITE HEADER  (<= 768px)
   =========================================================================== */

@media (max-width: 768px) {

    header {
        padding: var(--net-spacing-sm);
    }

    .site-header .site-header-inner {
        padding: 0;
        gap: var(--net-spacing-sm);
    }

    /* Allow the title to shrink so the profile menu never gets pushed off-screen. */
    .site-header .site-header-title h1 {
        font-size: 1.1rem;
        white-space: normal;
    }

    .site-header .site-header-title h2 {
        white-space: normal;
    }

    /* Entity sub-header: quick-links column + 62/38 grid stack vertically. */
    .entity-subheader {
        flex-direction: column;
        align-items: stretch !important;
    }

    .entity-quicklinks,
    .page-quicklinks {
        width: 100% !important;
    }

    /* minmax(0,1fr), not 1fr: a bare 1fr track floors at the child's min-content
       (the wide content-rating buttongroup), which blows the track past the
       viewport. minmax(0,...) lets it shrink so the buttongroup can wrap. */
    .entity-header-grid {
        grid-template-columns: minmax(0, 1fr) !important;
        gap: var(--net-spacing-sm) !important;
    }

    /* Release min-width:auto down the flex chain inside the header columns so
       the buttongroup can actually shrink/wrap instead of forcing overflow. */
    .entity-header-grid > div,
    .buttongroup-wrapper,
    .buttongroup-control {
        min-width: 0 !important;
    }

    /* Entity edit First/Prev/List/New/Next/Last row: 6 buttons at 16.66% + gaps
       overflow a nowrap row. Wrap them ~3-per-row on mobile. */
    .entity-nav-row {
        flex-wrap: wrap;
        justify-content: stretch;
    }

    .entity-nav-row > .ctrl-wrapper,
    .entity-nav-row > .control {
        width: auto !important;
        flex: 1 1 30% !important;
        min-width: 0 !important;
    }
}

/* ===========================================================================
   3. SHARED LAYOUT PRIMITIVES  (rows / columns / entity form rows)
   =========================================================================== */

@media (max-width: 768px) {

    /* Rows and columns wrap instead of forcing a horizontal overflow. */
    .row,
    .column {
        flex-wrap: wrap;
    }

    /* Entity edit forms: the detail rows are display:flex (their existing
       980px "grid-template-columns:1fr" rule is inert), so stack them here.
       IMPORTANT: keep nowrap — these rows also carry the `.row` class (which
       gets flex-wrap:wrap above), and column-direction + wrap + a fixed inline
       height makes children wrap into a SECOND column to the right. Force
       nowrap and release any fixed inline height so children stack cleanly. */
    .content .details-row,
    .content .details-row-primary,
    .content .details-row-secondary,
    .content .details-row-tertiary,
    .content .details-row-quaternary,
    .content .details-row-plans {
        flex-direction: column;
        align-items: stretch;
        flex-wrap: nowrap;
        height: auto !important;
    }

    /* Inline width params are stamped on .ctrl-wrapper/.ctrl-container, so they
       need !important to release to full width inside a stacked row. */
    .content .details-row .ctrl-wrapper,
    .content .details-row .ctrl-container {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
    }

    /* Two-up columns with inline width:50% (places/items edit) go full-width. */
    .content .column {
        width: 100% !important;
    }

    /* Picture / alignment editors: stack to one column. Use minmax(0,1fr) —
       a bare 1fr floors at the image-picker's min-content and blows out. */
    .content .picture-alignment-row {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    .content .picture-alignment-row > .ctrl-wrapper,
    .content .picture-alignment-row .image-picker-wrapper,
    .content .picture-alignment-row .alignment-grid-wrapper,
    .content .picture-alignment-row .image-picker-preview,
    .content .picture-alignment-row .preview-image-wrap {
        min-width: 0 !important;
        max-width: 100% !important;
        width: 100% !important;
    }

    /* Preview images must never exceed their (now full-width) column. */
    .content .image-picker-preview img,
    .content .preview-thumbnail,
    .content .preview-image-wrap img {
        max-width: 100% !important;
    }

    /* Some rows (e.g. the content-rating control) carry an inline min-width
       floor (min-width:486px) that forces horizontal overflow. Release it. */
    .details-row[style*="min-width"],
    .row[style*="min-width"] {
        min-width: 0 !important;
    }

    /* Segmented buttongroups: let the options wrap instead of forcing a wide
       min-content row that gets clipped by the content column. */
    .buttongroup-control {
        flex-wrap: wrap;
    }

    /* Association / relationship pickers are nowrap flex rows that won't shrink;
       let them wrap and let their draggable rows ellipsis their labels. */
    .association-picker-container {
        flex-wrap: wrap;
        min-width: 0;
    }

    .association-picker-container > *,
    .draggable-list,
    .draggable-item,
    .draggable-item__content {
        min-width: 0;
    }
}

/* ===========================================================================
   4. DASHBOARDS  (<= 600px)
   =========================================================================== */

@media (max-width: 600px) {

    /* Inline `grid-template-columns: 1fr 1fr` blocks (site/api/chat dashboards)
       are unreachable by class selectors, so collapse any 2-up grid inside the
       content area to a single column on phones. */
    .content [style*="1fr 1fr"] {
        grid-template-columns: 1fr !important;
    }

    /* Paired 50%-width tool/utility buttons wrap instead of cramping. */
    .content .details-row {
        gap: var(--net-spacing-sm);
    }

    /* Tight up the shared panel padding to reclaim horizontal space. */
    .content .panel-card > .section-content,
    .content .panel-header {
        padding-left: var(--net-spacing-sm);
        padding-right: var(--net-spacing-sm);
    }
}

/* Wide data tables (threat intel, blocked IPs) scroll horizontally rather
   than clip — their PHP wrappers set overflow-x:auto; reinforce it here. */
@media (max-width: 768px) {
    .content table {
        max-width: 100%;
    }
}

/* ===========================================================================
   4b. ENTITY LIST CARDS  (characters / items / species / ... galleries)
   =========================================================================== */

@media (max-width: 768px) {

    /* Cards are stamped with a fixed width:220px + margins, so they overflow
       the responsive `.list-grid` tracks (2-up spills past the viewport).
       Let each card fill its grid cell and size to content instead. */
    .list-grid .card,
    .card-container .card {
        width: 100%;
        min-width: 0;
        height: auto;
        min-height: 300px;
        margin: 0;
    }

    /* The card-container grid has no small-screen step of its own. */
    .card-container {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    }
}

/* ===========================================================================
   5. TREEVIEWS  (places / stories hierarchy list pages)
   =========================================================================== */

@media (max-width: 768px) {

    /* Tree rows are nowrap flex rows; let them wrap so the right-hand badge
       cluster (.tree-right, margin-left:auto, nowrap) drops to its own line
       instead of forcing the row past the viewport. */
    .treeview-content,
    .entity-tree-content,
    .place-tree-content,
    .story-tree-content,
    .section-tree-content {
        flex-wrap: wrap;
        row-gap: 0.2rem;
    }

    .tree-label,
    .place-name,
    .story-name,
    .section-name {
        min-width: 0;
    }

    .tree-description,
    .place-type,
    .story-type,
    .section-type {
        white-space: normal !important;
        overflow: visible;
    }

    .tree-right {
        margin-left: 0;
        width: 100%;
        flex-wrap: wrap;
        min-width: 0;
    }

    /* Reduce deep-nesting indentation so wrapped labels keep usable width. */
    .treeview-children .treeview-children {
        margin-left: 12px;
    }
}

/* ===========================================================================
   6. POPOVERS / PANELS — keep floating panels inside the viewport
   =========================================================================== */

@media (max-width: 768px) {

    .search-bar-panel,
    .emoji-picker-panel,
    .action-dropdown,
    .dropdown-list {
        max-width: 92vw;
    }

    /* Search controls in the header release their fixed floors. */
    .search-bar-wrap {
        min-width: 0;
    }

    .search-bar-dropdown {
        width: auto;
        min-width: 0;
    }
}

/* ===========================================================================
   7. TOUCH TARGETS & INPUT ZOOM  (<= 768px)
   =========================================================================== */

@media (max-width: 768px) {

    /* Primary action buttons reach a comfortable tap height. */
    .btn,
    .btn-sm,
    .action-btn,
    .modal-close {
        min-height: 40px;
    }

    /* Roomier nav rows for touch. */
    .nav-item a,
    .nav-item.selected {
        padding-top: 0.55rem;
        padding-bottom: 0.55rem;
    }

    /* iOS zooms in on focus for inputs under 16px — keep form fields at 16px. */
    input,
    textarea,
    select,
    .ctrl-field {
        font-size: 16px;
    }
}
