/* ============================================================================
   responsive.css  —  BU-289 mobile responsiveness baseline
   ----------------------------------------------------------------------------
   Loaded LAST in index.html so it overrides bootstrap + design-system + app +
   compose-workbench. Every rule lives inside a max-width media query, so the
   desktop layout (>= 992px) is completely untouched.

   Canonical breakpoints (Bootstrap 5 aligned):
     phone        <= 767.98px   (primary mobile target)
     small phone  <= 575.98px   (extra tightening)
     tablet       <= 991.98px   (light adjustments only)

   Contrast rule: the mobile table-cards (.table-mobile-cards) route bg/text/
   border through the semantic vibe tokens (--color-surface / --color-ink /
   --color-ink-muted / --color-line / --color-line-strong) so the cards repaint
   per vibe (navy under Harbor Night, cream under Sepia) and stay AA on every
   skin at phone width. Do NOT reintroduce hardcoded #ffffff/#6b7280 here — the
   token ramp is contrast-balanced per vibe. (BU-385, 2026-06-19)
   ============================================================================ */

/* ---- Universal media safety (all viewports): never let media force overflow ---- */
img, video, canvas, iframe, embed, object {
    max-width: 100%;
}

/* ===========================================================================
   TABLET + PHONE  (<= 991.98px)
   Any data table swipe-scrolls so a wide table never forces PAGE overflow.
   Lives in a broader query than the phone block so wide tables stay contained
   on tablets too (the 8-/10-column lists overflowed ~200px at 768px otherwise).
   Phone additionally upgrades the 6 list tables to labeled cards (.table-mobile-cards,
   defined later in the cascade so it wins at <=767.98px).
   =========================================================================== */
@media (max-width: 991.98px) {
    .table,
    table.table,
    .table-modern,
    table.table-modern {
        display: block;
        width: 100%;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .table thead th,
    .table-modern thead th {
        white-space: nowrap;
    }
}

/* ===========================================================================
   PHONE  (<= 767.98px)
   =========================================================================== */
@media (max-width: 767.98px) {

    /* ---- Page shell: kill any stray horizontal scroll, reclaim padding ---- */
    html, body {
        overflow-x: hidden;
        max-width: 100%;
    }
    main.flex-grow-1,
    main {
        padding: 0.75rem !important;
    }
    main .container,
    .container,
    .container-fluid {
        max-width: 100% !important;
        padding-left: 0.75rem !important;
        padding-right: 0.75rem !important;
    }
    /* Bootstrap p-4 / px-4 on content wrappers eats half a phone screen */
    .p-4 { padding: 0.85rem !important; }
    .px-4 { padding-left: 0.85rem !important; padding-right: 0.85rem !important; }
    .p-5 { padding: 1rem !important; }

    /* ---- Tables: default = swipe-scroll so NO table forces page overflow ----
       Works for every Bootstrap .table and .table-modern with zero markup.
       The table becomes its own horizontal scroll container; the page stays put.
       (List pages that opt into the labeled card layout add .table-mobile-cards,
        whose rules below come later in the cascade and win.) */
    .table,
    table.table,
    .table-modern,
    table.table-modern {
        display: block;
        width: 100%;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .table thead th,
    .table-modern thead th,
    .table tbody td,
    .table-modern tbody td {
        white-space: nowrap;   /* keep columns intact; scroll instead of squish */
    }

    /* ---- Touch targets: action icons & icon-only buttons, 36x36 ----
       BU-823. This rule is the mechanism behind "big shapes". It is the ONE
       global control floor in Jargan.Client and it only ever pushes UP: it was
       written to lift small controls to a 44px touch target on phones, and it
       has no desktop equivalent, so the net effect across every page is that
       CONTROLS get inflated at exactly the width where display type never
       shrinks. That combination is what reads as a kid's toy.

       The floor is not removed - a phone still needs a target you can hit - it
       is moved to the house small-viewport control height of 36px, which is
       where the density gate asserts it. 36px is still a comfortable target
       (Apple's own compact controls sit at 32-38), and it is 8px less chrome on
       every action icon on every list page at once. */
    .action-icon {
        min-width: 36px;
        min-height: 36px;
    }
    .action-icon + .action-icon { margin-left: 2px; }
    .btn-sm, .btn-icon, button.icon-only {
        min-height: 36px;
    }

    /* ---- Forms: every control goes full width, nothing fixed ---- */
    .form-control,
    .form-select,
    textarea.form-control,
    input.form-control,
    .input-group {
        width: 100% !important;
        max-width: 100% !important;
    }
    /* Bootstrap col-sm-N is already full-width < 576px; this catches col-md-N
       used as input width hints on tablets-down without breaking real grids */
    .form-group > .col-md-6,
    .form-group > .col-md-4,
    .form-group > .col-md-3 {
        flex: 0 0 100%;
        max-width: 100%;
    }

    /* ---- Toolbars / button rows: wrap instead of overflow ---- */
    .btn-toolbar,
    .d-flex.justify-content-between,
    .page-actions,
    .toolbar-actions {
        flex-wrap: wrap;
        gap: 8px;
    }

    /* ---- Fixed-width carousels (channel packs / applied packs) ---- */
    .pack-scroll-item,
    .applied-pack-scroll-item {
        width: 86vw !important;
        min-width: 86vw !important;
        max-width: 86vw !important;
    }

    /* ---- Bootstrap modals: fit the viewport (use dvh for mobile chrome) ---- */
    .modal-dialog {
        max-width: calc(100vw - 1rem) !important;
        margin: 0.5rem auto !important;
    }
    .modal-body {
        max-height: calc(100dvh - 8rem);
        overflow-y: auto;
    }

    /* ---- Generic fixed-position dialog/panel shells used across the app ----
       (CreateNewModal, SearchPalette, drawers etc. carry their own scoped CSS;
        this is a defensive clamp so nothing overruns the viewport.) */
    [role="dialog"]:not(.modal-dialog),
    .dialog-shell,
    .drawer-panel {
        max-width: calc(100vw - 1rem) !important;
        max-height: calc(100dvh - 1rem);
    }

    /* ---- Cards / panels: drop desktop min-widths that force overflow ---- */
    .card { max-width: 100%; }

    /* =====================================================================
       BU-301 - ultra-dense list rows (replaces the verbose label-above-value
       stack that made one record fill the whole screen). Applies to the 6
       .table-mobile-cards lists at phone width. Each row is a compact card:
       a bold NAME on line 1 with the row actions pinned right, then ONE muted
       dot-separated META line below. The repeated uppercase per-field labels
       are gone; noisy / widget / sub-nav columns are dropped on mobile (they
       stay on the record detail page). Target ~6-10 records per screen instead
       of one. Desktop (>=992px) is untouched (this lives in the phone query).
       ===================================================================== */
    .table-mobile-cards,
    table.table-mobile-cards { display: block; overflow: visible; white-space: normal; border: 0; }
    .table-mobile-cards thead { display: none; }
    .table-mobile-cards tbody { display: block; width: 100%; }

    /* row = card. Block flow: NAME is its own line, META flows inline on the
       line below, ACTIONS are absolutely pinned right. The right padding
       reserves the actions lane so name/meta never run under it. */
    .table-mobile-cards tr {
        display: block;
        position: relative;
        width: 100%;
        padding: 8px 58px 8px 13px;
        margin-bottom: 7px;
        border: 1px solid var(--color-line);
        border-radius: 10px;
        background: var(--color-surface);
        box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
    }

    /* default cell reset: inline, no borders, no uppercase labels */
    .table-mobile-cards td {
        display: inline;
        width: auto;
        padding: 0 !important;   /* beat .table-modern td padding (higher specificity) */
        border: 0 !important;    /* and its cell border-bottom (the stray divider) */
        text-align: left !important;
        white-space: normal;
        overflow-wrap: anywhere;
    }
    .table-mobile-cards td::before { content: ""; display: none; }
    /* kill Bootstrap .table-striped's inset box-shadow stripe on the card cells
       (it paints odd rows via box-shadow, not background-color, so it leaked a
       grey bar behind the name). The card's own shadow lives on the tr. */
    .table-mobile-cards tr > * {
        box-shadow: none !important;
        background-color: transparent !important;
        --bs-table-bg-type: transparent;
        --bs-table-accent-bg: transparent;
    }

    /* NAME (first cell): its own bold line, truncates with an ellipsis */
    .table-mobile-cards td:first-child {
        display: block;
        font-weight: 700;
        font-size: 0.95rem;
        line-height: 1.3;
        color: var(--color-ink);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .table-mobile-cards td:first-child * { font-weight: 700; color: inherit; }

    /* META (every other cell): inline, on the line below the name, dot-separated */
    .table-mobile-cards td:not(:first-child):not([data-label="Actions"]):not([data-label=""]) {
        display: inline;
        font-size: 0.8rem;
        color: var(--color-ink-muted);
        line-height: 1.3;
    }
    .table-mobile-cards td:nth-child(n+3):not([data-label="Actions"]):not([data-label=""])::before {
        content: "\00b7";
        display: inline;
        margin: 0 6px;
        color: var(--color-line-strong);
    }
    .table-mobile-cards td:not(:first-child):not([data-label="Actions"]) * {
        white-space: normal;
        font-weight: 400;
    }
    /* neutralize the desktop neutral badge so Type reads as plain meta text */
    .table-mobile-cards td:not(:first-child) .badge-neutral {
        background: transparent !important;
        box-shadow: none !important;
        border: 0 !important;
        padding: 0 !important;
        color: var(--color-ink-muted) !important;
        font-size: inherit !important;
    }
    .table-mobile-cards td:empty { display: none; }

    /* ACTIONS: pinned to the right, vertically centered over the card */
    .table-mobile-cards td[data-label="Actions"],
    .table-mobile-cards td[data-label=""] {
        position: absolute;
        top: 50%;
        right: 8px;
        transform: translateY(-50%);
        display: flex;
        align-items: center;
        gap: 2px;
        margin: 0;
        padding: 0;
    }
    .table-mobile-cards td[data-label="Actions"] .action-icon { min-width: 40px; min-height: 40px; }
    /* hide button text labels in the dense action lane (desktop keeps them) */
    .table-mobile-cards .mobile-hide-inline { display: none; }

    /* keep just the primary action on the row; secondary / destructive actions
       live on the record detail page (a couple actions behind the tap). */
    .table-mobile-cards td[data-label="Actions"] [title="Plan"],
    .table-mobile-cards td[data-label="Actions"] [title="Delete"],
    .table-mobile-cards td[data-label="Actions"] [title="Quick Edit"],
    .table-mobile-cards td[data-label="Actions"] [title="Close"] { display: none; }

    /* Curate the mobile meta line: drop noisy / widget / sub-nav columns on phone.
       They remain on the record detail page. Keeps each row to name + 2-3 fields. */
    .table-mobile-cards td[data-label="Timeline"],
    .table-mobile-cards td[data-label="Stages"],
    .table-mobile-cards td[data-label="Voices"],
    .table-mobile-cards td[data-label="Channels"],
    .table-mobile-cards td[data-label="Attributes"],
    .table-mobile-cards td[data-label="Protected"] { display: none !important; }
}

/* ===========================================================================
   SMALL PHONE  (<= 575.98px) — extra tightening
   =========================================================================== */
@media (max-width: 575.98px) {
    main.flex-grow-1, main { padding: 0.5rem !important; }
    main .container, .container { padding-left: 0.5rem !important; padding-right: 0.5rem !important; }
    h1, .h1 { font-size: 1.5rem; }
    h2, .h2 { font-size: 1.25rem; }
}

/* ===========================================================================
   TABLET  (768px - 991.98px) — light touch only
   =========================================================================== */
@media (min-width: 768px) and (max-width: 991.98px) {
    main .container, .container { max-width: 100%; }
    /* BU-289 e2e re-verify (2026-06-02): a swipe-scroll table's container can
       overshoot the viewport by a few px at the tablet band — the phone block's
       overflow-x guard stops below 768px, so the tablet band had no equivalent.
       Mirror that guard here so the tablet band is also overflow-free. The table
       keeps its own overflow-x:auto, so horizontal column scrolling inside the
       table still works. */
    html, body { overflow-x: hidden; max-width: 100%; }
}

/* ===========================================================================
   Shared list-page chrome (used by Partner/Engagement/Voice/Channel/... lists):
   the title row (h1 + "Add X" button) and the filter bar must wrap on phones
   instead of clipping the action button off the right edge.
   =========================================================================== */
@media (max-width: 767.98px) {
    .list-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
    }
    /* stop the "+ Add X" button from shrinking + clipping its own label */
    .list-header .btn-add { flex-shrink: 0; }

    /* Entity detail/view headers (Partner/Engagement/Voice View, browse pages)
       use Bootstrap `d-flex justify-content-between align-items-center` for the
       title-block + actions row. On phones let it wrap so the actions drop below
       the title (+ chips) instead of clipping off the right edge. */
    .d-flex.justify-content-between.align-items-center {
        flex-wrap: wrap;
        gap: 8px;
    }
    .list-header .btn-add { margin-left: 0; }
    .filter-bar {
        flex-wrap: wrap;
        gap: 8px;
    }
    .filter-bar .search-pill { flex: 1 1 100%; }
    .filter-bar .filter-pill,
    .filter-bar select { flex: 1 1 auto; min-width: 0; }

    /* Detail/View pages (Partner/Engagement/Voice…) use inline
       `grid-template-columns:1fr 1fr` for their info + quick-stats panels.
       Collapse those to a single column on phones so labels and values stop
       clipping off the right edge. */
    [style*="grid-template-columns:1fr 1fr"],
    [style*="grid-template-columns: 1fr 1fr"] {
        grid-template-columns: 1fr !important;
    }
}

/* ===========================================================================
   BU-823 — THE ANONYMOUS AUTH CARD FAMILY  (<= 900px)
   ---------------------------------------------------------------------------
   /user/register, /user/forgot-password and /user/reset-password are the pages
   the sign-in card links out to, and unlike /user/login they carry no CSS of
   their own at all: they are bare Bootstrap (.card > .card-body.p-4) and take
   every size from the global cascade. That cascade already scales their
   headings and form controls; what it does NOT scale is a bare <a> and a
   Bootstrap .alert, both of which inherit the 16px body size straight down to a
   390px phone. Measured with the density gate, that was the ENTIRE defect on
   all three routes: 1 violation on /user/register, 1 on /user/forgot-password,
   2 on /user/reset-password, every one of them a 16px inherit.

   WHY THIS IS SCOPED TO A CLASS RATHER THAN WRITTEN AS `a { font-size: 13px }`.
   responsive.css is loaded last and applies to every page in Jargan.Client, so
   an unscoped rule here would resize links on ~140 other surfaces that other
   BU-823 units own and that nobody has measured. .jgn-auth-card is added to the
   three card wrappers by hand, so the blast radius of this block is exactly the
   three pages named above and nothing else.

   The breakpoint is 900px to match the sign-in card's own block and the width
   at which the house small-viewport scale is asserted (390 and 768 both sit
   inside it; responsive.css's 767.98 phone query would leave 768 unscaled).
   =========================================================================== */
@media (max-width: 900px) {

    /* UI role -> 13px. These are the "Already have an account? Sign in",
       "Back to Sign In" and "Request Reset Link" links. */
    .jgn-auth-card a {
        font-size: 13px;
    }

    /* Body role -> 14px max. Bootstrap alerts on these pages carry the
       "Invalid reset link" / "reset link has been sent" messages. 13px keeps
       them a step below the form they interrupt and clear of the 12px floor. */
    .jgn-auth-card .alert {
        font-size: 13px;
    }

    /* DataAnnotations output. Not currently rendered on a clean load, so the
       gate cannot see it — but it is the same 16px inherit as everything else
       above, and it appears exactly when the user is already having a bad time. */
    .jgn-auth-card .validation-message,
    .jgn-auth-card .validation-errors {
        font-size: 13px;
    }
}
