/*
 * Mobile / tablet layer for the new client portal.
 *
 * Loaded AFTER style.css by every new-portal layout. Every rule lives inside a
 * max-width media query, so desktop (>= 992px) renders exactly as before.
 *
 *   <= 991.98px  tablet + phone: sidebar becomes an off-canvas drawer, the page
 *                scrolls as a normal document, fixed viewport heights let go.
 *   <= 767.98px  phone: headers stack, modals/offcanvas go (nearly) full width.
 *   <= 575.98px  small phone: tighter spacing.
 *
 * Many of the overrides need !important because the desktop layout sets
 * heights/widths inline or with !important of its own.
 */

/* The mobile top bar and drawer backdrop exist in the DOM on every size but are
   only shown below the drawer breakpoint. */
.mobile-topbar,
.mobile-nav-backdrop {
    display: none;
}

@media (max-width: 991.98px) {

    /* ---------------------------------------------------------------
     * Page shell
     * ------------------------------------------------------------- */
    html,
    body {
        height: auto;
        min-height: 100%;
        overflow-x: hidden;
    }

    /* The shell is "sidebar | page" in one flex row; the page takes it all. */
    .app-shell {
        display: block !important;
    }

    .mobile-topbar {
        display: flex;
        align-items: center;
        gap: 10px;
        position: sticky;
        top: 0;
        z-index: 1030;
        height: 52px;
        padding: 0 12px;
        background: var(--white);
        border-bottom: 1px solid var(--border);
    }

    .mobile-topbar .mobile-nav-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 38px;
        height: 38px;
        border: 1px solid var(--border);
        border-radius: 10px;
        background: var(--active-sidbar-bg);
        color: var(--primary-blue);
        flex-shrink: 0;
    }

    /* Sidebar -> off-canvas drawer.
       Slides with `left`, never `transform`: the notification modal is
       rendered inside the sidebar, and a transformed ancestor would make its
       position:fixed relative to the drawer instead of the viewport.
       z-index sits above Bootstrap's modal backdrop (1050) for the same
       reason: the drawer is a stacking context, and that modal must paint
       above the backdrop. The drawer closes whenever a modal opens. */
    .sidebar-wrapper {
        position: fixed;
        top: 0;
        bottom: 0;
        left: -300px;
        z-index: 1055;
        width: 270px;
        max-width: 85vw;
        background: var(--white);
        box-shadow: none;
        transition: left .28s ease-in-out, box-shadow .28s ease-in-out;
    }

    body.mobile-nav-open .sidebar-wrapper {
        left: 0;
        box-shadow: 0 0 24px rgba(2, 2, 15, .18);
    }

    .mobile-nav-backdrop {
        position: fixed;
        inset: 0;
        z-index: 1040;
        background: rgba(2, 2, 15, .45);
    }

    body.mobile-nav-open .mobile-nav-backdrop {
        display: block;
    }

    body.mobile-nav-open {
        overflow: hidden;
    }

    /* The desktop collapse toggle means nothing in a drawer. */
    #toggleSidebar {
        display: none !important;
    }

    /* Inside the drawer the menu is always shown fully labelled, whatever the
       saved desktop collapse state is. */
    .sidebar,
    .sidebar.sidebar-expanded {
        width: 100% !important;
        height: 100vh;
        height: 100dvh;
        padding-bottom: 12px;
    }

    .sidebar ul li a,
    .sidebar.sidebar-expanded ul li a {
        width: 100% !important;
        padding-top: 8px;
        padding-bottom: 8px;
    }

    .sidebar p {
        width: auto;
    }

    .sidebar.sidebar-expanded .nav-item a span {
        display: block;
        opacity: 1;
    }

    .sidebar.sidebar-expanded .hide-p-expaned {
        display: block !important;
        opacity: 1 !important;
    }

    /* Page containers become normal document flow. */
    .main-white-box {
        height: auto !important;
        min-height: calc(100vh - 64px);
        overflow: visible;
        border-radius: 14px;
        margin: 6px 0;
    }

    /* .main-white-box is also used INSIDE pages (lazy-load placeholders such
       as the dashboard's Tasks / Comments skeletons, inner panels). The
       screen-height minimum is for the outer page panel only: on a nested
       one it stretched a loading placeholder into a full empty screen. */
    .main-white-box .main-white-box {
        min-height: 0;
        margin: 0;
    }

    /* Lazy-load skeletons are drawn for a desktop box (e.g. 40.5vh with
       overflow hidden) and hold far more skeleton rows than fit; with the
       height released they ran ~1600px tall. Keep them short. */
    .main-white-box .main-white-box:has(.skeleton) {
        max-height: 70vh;
        overflow: hidden !important;
        /* fade out instead of cutting a skeleton row in half */
        -webkit-mask-image: linear-gradient(to bottom, #000 78%, transparent);
        mask-image: linear-gradient(to bottom, #000 78%, transparent);
    }

    /* Skeleton tables are placeholders, not data: they fit the screen
       instead of taking the data-table minimum widths (which pushed the
       third skeleton column out of the box). */
    table:has(.skeleton),
    table:has(.skeleton) > * > tr > th,
    table:has(.skeleton) > * > tr > td {
        min-width: 0 !important;
    }

    /* Page wrapper ("w-100 me-2"), either straight in the shell or inside
       the dashboard's "d-flex w-100" row. In that row it is a flex item, so
       it must GROW to the row width: width:auto alone shrinks it to its
       content and leaves an empty strip on the right. */
    .app-shell > .w-100:not(.d-flex),
    .app-shell > .d-flex.w-100 > .w-100 {
        flex: 1 1 0%;
        width: auto !important;
        min-width: 0;
        margin: 0 6px !important;
    }

    /* Screens are laid out to fit exactly one viewport with inner scroll
       panels. On a phone the columns stack, so release those fixed heights
       and let the page scroll instead. */
    .app-shell [style*="height: calc(100vh"],
    .app-shell [style*="height:calc(100vh"],
    .framework-height-calc,
    .framework-releted-height-calc,
    .Circular-height-calc,
    .teamwork-height-calc,
    .teamworkuser-height-calc,
    .circular-left-twobox-height,
    .cxo-height-calc,
    .cxo-in-box-height-calc,
    .cxo-in-1-box-height-calc,
    .cxo-in-2-box-height-calc,
    .main-calc-87-height,
    .main-calc-82-height,
    .main-calc-112-height,
    .report-height-table,
    .user-guide-height,
    .new-whats-new-height,
    .new-whats-new-height .whats-new-height {
        height: auto !important;
    }

    /* Inner scroll panels keep scrolling, but get a phone-sized cap instead
       of a viewport-derived height. */
    .table-scroll,
    .table-scroll.h-100,
    .table-scroll-modal,
    .table-scroll-modal.h-100,
    .col-6-scroll,
    .col-6-scroll.h-100 {
        height: auto !important;
        max-height: 70vh;
        overflow: auto;
        -webkit-overflow-scrolling: touch;
    }

    .table-scroll.reduced-height,
    .table-scroll-modal.reduced-height {
        height: auto !important;
    }

    /* Fixed-pixel desktop widths (tuned per zoom level in style.css). */
    .width-carosal,
    .my-new-class .width-carosal,
    .width-table,
    .tabel-scroll-add .width-table,
    .width-table1,
    .tabel-scroll-add1 .width-table1 {
        width: 100% !important;
        max-width: 100%;
    }

    /* ---------------------------------------------------------------
     * Generic content
     * ------------------------------------------------------------- */
    img,
    svg,
    video,
    canvas,
    iframe {
        max-width: 100%;
    }

    /* Header/toolbar rows are "space-between" flex rows sized for desktop;
       let them wrap instead of pushing content off screen. */
    .main-white-box .d-flex.justify-content-between,
    .main-white-box .d-flex.justify-content-end,
    .main-white-box-in .d-flex.justify-content-between,
    .modal .d-flex.justify-content-between,
    .offcanvas .d-flex.justify-content-between {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    /* Every block in a header row may shrink to the screen. A plain wrapper
       around the tab pills (Setup, Incident Management ...) otherwise stays
       as wide as all its tabs (~1400px): the pills' own sideways scroll
       never kicks in and the whole panel slides sideways. */
    .main-white-box .d-flex.justify-content-between > * {
        min-width: 0;
        max-width: 100%;
    }

    /* A table in a right-aligned flex row (Circular Repository summary):
       when wider than the row, right alignment pushes it off the LEFT edge. */
    .main-white-box .d-flex.justify-content-end:has(> table) {
        justify-content: flex-start !important;
        overflow-x: auto;
    }

    /* Risk Register table controls: the right-hand group is flex-shrink-0
       (Bootstrap, !important) and ran 50px past the screen. */
    .rr-table-controls > .flex-shrink-0 {
        flex-shrink: 1 !important;
        flex-wrap: wrap;
        min-width: 0;
        max-width: 100%;
    }

    /* Button groups inside those header rows ("Download PDF" | "Download
       Excel" | ...) wrap too, instead of poking past the panel edge. */
    .main-white-box .d-flex.justify-content-between > .d-flex {
        flex-wrap: wrap;
        min-width: 0;
        max-width: 100%;
        row-gap: 6px;
    }

    /* A .row placed directly inside another .row (no column between) keeps
       both negative gutters and sticks out past the panel edge. */
    .row > .row {
        margin-left: 0;
        margin-right: 0;
    }

    /* Tab/pill bars scroll sideways rather than wrap. */
    .nav-pills,
    .nav-tabs {
        flex-wrap: nowrap !important;
        overflow-x: auto;
        overflow-y: hidden;
        max-width: 100%;
        -webkit-overflow-scrolling: touch;
    }

    .nav-pills .nav-item,
    .nav-tabs .nav-item,
    .nav-pills > .nav-link,
    .nav-tabs > .nav-link {
        flex-shrink: 0;
    }

    .nav-pills > .nav-link,
    .nav-tabs > .nav-link {
        white-space: nowrap;
    }

    /* A centred bar that overflows spills off BOTH edges and its first
       pill cannot be scrolled to (What's New Feature: "All" cut in half).
       "safe center" centres while it fits and start-aligns once it does
       not; flex-start is the fallback where "safe" is unsupported. */
    .nav-pills.justify-content-center,
    .nav-tabs.justify-content-center {
        justify-content: flex-start !important;
        justify-content: safe center !important;
    }

    .navbar-pills-1 {
        max-width: 100%;
        min-width: 0;
    }

    /* Form controls never exceed their column. Not checkboxes / radios /
       switches: a .form-check input sits in its wrapper's left padding,
       whose content box can be 0 wide, so 100% of it squashed every switch
       into a circle (Setup > Users "Active/De-Active"). */
    input:not([type="checkbox"]):not([type="radio"]),
    select,
    textarea,
    .form-control,
    .form-select,
    .ts-wrapper {
        max-width: 100%;
    }

    /* ---------------------------------------------------------------
     * Tables
     * ------------------------------------------------------------- */
    .table-responsive,
    .table-scroll,
    .table-scroll-modal,
    .col-6-scroll {
        overflow-x: auto;
    }

    /* Headers stay on one line; the wrapper scrolls sideways when the
       columns do not fit. */
    .table th {
        white-space: nowrap;
    }

    /* A table that is not inside a scrolling wrapper scrolls on its own. */
    .main-white-box table:not(:is(.table-responsive, .table-scroll, .table-scroll-modal, .col-6-scroll, .dropdown-menu, .position-absolute, .fc) table),
    .main-white-box-in table:not(:is(.table-responsive, .table-scroll, .table-scroll-modal, .col-6-scroll, .dropdown-menu, .position-absolute, .fc) table),
    .modal table:not(:is(.table-responsive, .table-scroll, .table-scroll-modal, .col-6-scroll, .dropdown-menu, .position-absolute, .fc) table),
    .offcanvas table:not(:is(.table-responsive, .table-scroll, .table-scroll-modal, .col-6-scroll, .dropdown-menu, .position-absolute, .fc) table) {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* ---------------------------------------------------------------
     * Offcanvas + modals
     * ------------------------------------------------------------- */
    html body .offcanvas.offcanvas-end,
    html body .offcanvas.offcanvas-start {
        width: min(650px, calc(100vw - 10px)) !important;
        max-width: calc(100vw - 10px) !important;
        /* Some drawers set `style="width: 25% !important"` inline, which no
           stylesheet can override; min-width wins over width, so they still
           get a usable size (Setup > User was 97px wide on a phone). */
        min-width: min(560px, calc(100vw - 10px)) !important;
    }

    .offcanvas-body {
        height: auto;
        max-height: calc(100dvh - 90px);
        overflow-y: auto;
    }

    .modal-xl,
    .modal-lg {
        --bs-modal-width: calc(100vw - 24px);
    }

    .modal-body {
        overflow-x: auto;
    }

    /* Bootstrap dropdowns sized for desktop stay on screen. */
    .dropdown-menu {
        max-width: calc(100vw - 16px);
    }

    /* ---------------------------------------------------------------
     * Dashboard (livewire/new/client/dashboard)
     * ------------------------------------------------------------- */

    /* Header: title + welcome line, then the actions, then the tab pills
       on their own full-width scrolling row. */
    .dash-header {
        flex-wrap: wrap;
        gap: 8px 10px;
        margin-bottom: 8px !important;
    }

    .dash-header > div:first-child {
        flex: 1 1 auto;
        min-width: 0;
    }

    .dash-header-actions {
        min-width: 0 !important;
        flex-wrap: wrap;
        gap: 6px 0;
    }

    .dash-header-sub {
        order: 2;
        flex: 1 1 100%;
    }

    .dash-header-sub .ml-3 {
        margin-left: 0;
    }

    .dash-header-sub p {
        text-align: left !important;
    }

    .dash-header-pills {
        order: 3;
        flex: 1 1 100%;
    }

    /* "Quick summary" dropdown: a 4 x 200px grid on desktop. Pin it to the
       screen and use 3 / 2 columns. */
    .bg-drop-down .dropdown-menu.show {
        position: fixed !important;
        inset: 64px 8px auto 8px !important;
        transform: none !important;
        width: auto !important;
        max-height: calc(100dvh - 80px);
        margin: 0 !important;
    }

    .grid-container {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .bg-drop-down .heading-value-text {
        width: auto !important;
        max-width: none !important;
        white-space: normal;
    }

    /* Left column (Tasks / Comments, department list ...): stacked above the
       main panels, each list keeps its own scroll. */
    .circular-left-twobox-height {
        margin-bottom: 10px;
    }

    /* The column's halves (Tasks / Comments, ...) are `flex: 1` wrappers.
       In a column that sizes to its content, flex:1 makes every half as tall
       as the tallest one — a still-loading Comments skeleton stretched the
       Tasks block into a tall empty grey box. Each half sizes to itself. */
    .circular-left-twobox-height [style*="flex: 1"],
    .circular-left-twobox-height [style*="flex:1"] {
        flex: 0 0 auto !important;
    }

    .circular-left-twobox-height .main-white-box-1 {
        max-height: 340px;
        min-height: 120px;
    }

    /* Count tiles carousel. */
    .carousel-container {
        margin-left: 18px !important;
        margin-right: 18px !important;
    }

    /* Security tab score cards: 2 x 2 grid. */
    .sec-kpis {
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    .sec-kpis > .heading-value-text {
        margin: 0 !important;
        width: auto;
        min-width: 0;
        white-space: normal !important;
    }

    .sec-kpis .heading-value {
        overflow-wrap: anywhere;
    }

    /* The security chart component prints its own <style> (140px labels,
       non-wrapping legend) after this file, hence the extra specificity. */
    html body .legend {
        flex-wrap: wrap;
        gap: 6px 14px;
        margin-left: 8px;
        margin-right: 8px;
    }

    html body .legend .legend-item {
        white-space: nowrap;
    }

    html body #Compliancechart {
        margin: 0 6px;
    }

    html body #Compliancechart .row-container {
        justify-content: flex-start;
    }

    html body #Compliancechart .row-label {
        width: 96px;
        flex-shrink: 0;
    }

    /* Pagination: see the all-widths block at the end of the file. */
    .pagination-div input.form-control {
        width: 64px !important;
        margin-left: 6px !important;
    }

    /* Security compliance matrix (d3): label + five boxes share the width. */
    #Compliancechart .row-container {
        gap: 6px;
    }

    #Compliancechart .row-label {
        width: 96px;
        flex-shrink: 0;
        margin-right: 0;
        font-size: 12px;
    }

    #Compliancechart .boxes-container {
        flex: 1 1 auto;
        min-width: 0;
    }

    #Compliancechart .security-box {
        flex: 1 1 0;
        min-width: 0;
        width: auto !important;
        height: 40px !important;
        margin: 2px !important;
        border-radius: 8px;
    }

    /* CXO: charts sized in vw / from a viewport-height parent. */
    .width-vw {
        width: 100% !important;
    }

    .cxo-height-calc .chart-container,
    .central-view-content .chart-container {
        height: 240px !important;
    }

    /* KPI cards (Completion / Departments / Critical / Overdue): a 2 x 2 grid
       (col-6 col-lg-3), equal heights per row, even 8px gutters. */
    .cxo-kpi > div {
        height: 100%;
        padding-bottom: 8px;
    }

    .cxo-kpi:nth-child(odd) > div {
        padding-right: 4px !important;
        padding-left: 0 !important;
    }

    .cxo-kpi:nth-child(even) > div {
        padding-right: 0 !important;
        padding-left: 4px !important;
    }

    .cxo-kpi .heading-value-text {
        height: 100%;
        margin: 0 !important;
        width: 100%;
    }

    /* Chart row (Completion Trends / Performance | Risk): stacked. Chart.js
       only shrinks a canvas when its container can get narrower than the
       width it was first drawn at, so nothing here may size to content. */
    .cxo-in-box-height-calc > *,
    .cxo-in-2-box-height-calc > *,
    .cxo-in-box-height-calc .heading-value-text,
    .cxo-in-2-box-height-calc .heading-value-text {
        min-width: 0;
        max-width: 100%;
    }

    .cxo-in-box-height-calc > .col-lg-5,
    .cxo-in-2-box-height-calc > .col-lg-5 {
        margin-top: 8px;
    }

    /* Completion Trends filters (period / month / year): each select was
       width:100% in a non-wrapping row, so they squeezed each other down
       to "Mont". Size to the longest option and wrap when needed. */
    .cxo-in-box-height-calc .d-flex.gap-2:has(> .form-select-sm),
    .cxo-in-2-box-height-calc .d-flex.gap-2:has(> .form-select-sm) {
        flex-wrap: wrap;
    }

    .cxo-in-box-height-calc .d-flex.gap-2 > .form-select-sm,
    .cxo-in-2-box-height-calc .d-flex.gap-2 > .form-select-sm {
        width: auto;
        flex: 0 0 auto;
        padding-right: 2rem;
    }

    /* Line charts only: the department bar chart is deliberately wider than
       its box (one slot per department) and scrolls sideways. */
    .cxo-in-box-height-calc .heading-value-text > div > canvas,
    .cxo-in-2-box-height-calc .heading-value-text > div > canvas {
        max-width: 100% !important;
    }
}

@media (max-width: 767.98px) {

    .heading-main {
        font-size: 16px;
    }

    .grid-container {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    /* Modals: near full width, scroll inside when tall. */
    .modal-dialog,
    .modal-dialog[style] {
        max-width: calc(100vw - 16px) !important;
        width: auto !important;
        margin: 8px auto !important;
    }

    .modal-dialog-centered {
        min-height: calc(100% - 16px);
    }

    .modal-content {
        max-height: calc(100dvh - 16px);
    }

    .modal-body {
        overflow-y: auto;
    }

    /* Body + footer wrapped in a <form> or <div> (Add / Edit Observation,
       ~100 dialogs): the wrapper is a plain block, so the body could not
       shrink inside the capped .modal-content and the rest of the form ran
       out of the white box over the backdrop. Make the wrapper part of the
       flex column; the body scrolls and the footer buttons stay in view. */
    .modal-content > :not(.modal-header):not(.modal-body):not(.modal-footer):has(> .modal-body) {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
    }

    .modal-content > * > .modal-body {
        flex: 1 1 auto;
        min-height: 0;
    }

    /* Modal: the title shrinks; the close button stays on the header line. */
    .modal-header {
        flex-wrap: nowrap !important;
        gap: 8px;
    }

    /* Offcanvas panels carry real buttons (Cancel / Update / Download ...)
       next to titles that are often whole sentences. The button group gets
       its own right-aligned row on top and the title takes the full width
       below it; before, the long title pushed Cancel off the screen. A
       header that is just "title + ✕" keeps them on one line. */
    .offcanvas-header {
        flex-wrap: wrap !important;
        gap: 8px;
    }

    .offcanvas-header > div.d-flex:last-child:not(:first-child) {
        order: -1;
        flex: 1 1 100%;
        justify-content: flex-end;
        flex-wrap: wrap;
        row-gap: 6px;
    }

    .offcanvas-header > div.d-flex:last-child:not(:first-child) > :last-child {
        margin-right: 0 !important;
    }

    .offcanvas-header > h5,
    .offcanvas-header > .offcanvas-title {
        flex: 1 1 0;
        min-width: 0;
    }

    .offcanvas-header:has(> div.d-flex:last-child:not(:first-child)) > h5,
    .offcanvas-header:has(> div.d-flex:last-child:not(:first-child)) > .offcanvas-title {
        flex: 1 1 100%;
        width: auto !important;
    }

    .modal-header .modal-title,
    .offcanvas-header .offcanvas-title,
    .offcanvas-header h5 {
        min-width: 0;
        font-size: 1.05rem;
        overflow-wrap: anywhere;
    }

    .modal-header .btn-close {
        flex-shrink: 0;
    }

    /* Summary rows inside a header ("Complied: 4  Partial: 4  Not
       Complied: 566 ..."): the header's text block may shrink, its rows
       wrap, and each "label: value" pair stays in one piece. */
    .modal-header > div,
    .offcanvas-header > div {
        min-width: 0;
    }

    .modal-header div.d-flex,
    .offcanvas-header div.d-flex {
        flex-wrap: wrap;
        row-gap: 4px;
    }

    /* Bootstrap's gap-* is `gap: X !important` (rows AND columns). */
    .modal-header .d-flex[class*="gap-"],
    .offcanvas-header .d-flex[class*="gap-"] {
        column-gap: 14px !important;
        row-gap: 4px !important;
    }

    .modal-header .d-flex > span,
    .offcanvas-header .d-flex > span {
        white-space: nowrap;
    }

    /* Narrow tables (Code / Name / Status ...) fit without sideways
       scrolling: tighter cells, and status badges may break onto two lines
       ("Not / Complied") instead of forcing the column wider. */
    .table > :not(caption) > * > * {
        padding-left: .45rem;
        padding-right: .45rem;
    }

    .table td .badge {
        white-space: normal;
        line-height: 1.25;
        text-align: center;
    }

    /* Wide tables (4+ columns) scroll sideways instead of squeezing every
       column down to one word per line. The first column (checkbox / Sr No)
       keeps its natural width. */
    /* Exactly 4 columns only: 5+ column tables get a table-level minimum
       width below, and a per-cell minimum there flattened every column to
       110px, ignoring the view's own proportions (Description 47% ...). */
    table:has(> tbody > tr > td:nth-child(4)):not(:has(> tbody > tr > td:nth-child(5))) > tbody > tr > td:not(:first-child),
    table:has(> tbody > tr > td:nth-child(4)):not(:has(> tbody > tr > td:nth-child(5))) > thead > tr > th:not(:first-child) {
        min-width: 110px;
    }

    /* ...and the table as a whole gets a realistic width. Column widths in
       these views are percentages (or table-layout: fixed), so on a 360px
       phone a description column came out ~40px wide and rows ran 30 lines
       tall, or headers overlapped. The wrapper scrolls sideways. The task
       list (cards) is excluded. */
    table.table:has(> tbody > tr > td:nth-child(5)):not(:has(> tbody > tr.tl-row)) {
        min-width: 560px;
    }

    table.table:has(> tbody > tr > td:nth-child(7)):not(:has(> tbody > tr.tl-row)) {
        min-width: 760px;
    }

    table.table:has(> tbody > tr > td:nth-child(9)):not(:has(> tbody > tr.tl-row)) {
        min-width: 960px;
    }

    .modal-footer {
        flex-wrap: wrap;
        gap: 6px;
    }

    .modal-footer > * {
        margin: 0 !important;
    }

    /* Offcanvas panels take the full screen width on a phone. */
    html body .offcanvas.offcanvas-end,
    html body .offcanvas.offcanvas-start {
        width: calc(100vw - 10px) !important;
        min-width: calc(100vw - 10px) !important;
    }

    html body .offcanvas.offcanvas-bottom,
    html body .offcanvas.offcanvas-top {
        width: auto !important;
    }

    /* Non-responsive bootstrap columns (col-3 / col-4 ...) used for form
       layouts stack on a phone. Only inside forms/modals/offcanvas rows, so
       inline icon + text rows elsewhere keep their proportions. */
    .modal .row > [class^="col-"]:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not(.col-auto),
    .offcanvas .row > [class^="col-"]:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not(.col-auto),
    form .row > [class^="col-"]:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not(.col-auto) {
        flex: 0 0 100%;
        max-width: 100%;
    }

    /* Grids of switches / checkboxes built as "form-check col-3" (Setup >
       Setting: OpenAI, Task Creation Approve, Sunday Working ...) were four
       ~70px columns of wrapped words on a phone; two per row instead. */
    .row > .form-check[class*="col-"]:not(.form-switch):not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not(.col-12) {
        flex: 0 0 50%;
        max-width: 50%;
    }

    /* Switches read best as a plain list: one per row, switch then label.
       (Two per row wrapped every label into an indented column of words.) */
    .row > .form-check.form-switch[class*="col-"]:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]) {
        flex: 0 0 100%;
        max-width: 100%;
        display: flex;
        align-items: center;
        gap: 12px;
        padding-left: 0;
        margin: 0 0 12px;
    }

    .row > .form-check.form-switch[class*="col-"] > .form-check-input {
        float: none;
        margin: 0;
        flex-shrink: 0;
    }

    .row > .form-check.form-switch[class*="col-"] > .form-check-label {
        flex: 1 1 auto;
        min-width: 0;
    }

    .row.px-4:has(> .form-check.form-switch) {
        padding-left: 8px !important;
        padding-right: 8px !important;
    }

    /* The second settings block (Compulsory documents, Password Policy and
       its inputs + "Require ..." switches) is a padded row holding nested
       rows, some inside an x-data <div>: Bootstrap's ".row > *" gutters and
       the nested rows' negative margins stacked into three different left
       edges, and py-3 left a gap above it. Same 8px edge as the block above. */
    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) {
        padding: 0 8px !important;
    }

    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) > * {
        padding-left: 0;
        padding-right: 0;
    }

    /* the policy inputs line up with the Login Expired / Revert Time inputs */
    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) .row > [class*="col-sm"] {
        padding-left: 8px;
        padding-right: 8px;
    }

    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) .row {
        margin-left: 0;
        margin-right: 0;
    }

    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) .row.mb-3:has(> .form-check.form-switch) {
        margin-bottom: 0 !important;
    }

    /* A .table-scroll box holding a form or settings (no table) scrolls with
       the page; the 70vh scroll cap is meant for data tables. */
    .table-scroll:not(:has(table)),
    .table-scroll.h-100:not(:has(table)) {
        max-height: none !important;
        overflow: visible !important;
    }

    /* Button groups in toolbars wrap. */
    .btn-group {
        flex-wrap: wrap;
    }

    /* Snackbar toasts fit the screen. */
    .snackbar-container {
        min-width: 0 !important;
        max-width: calc(100vw - 16px) !important;
        left: 8px !important;
        right: 8px !important;
    }
}

@media (max-width: 575.98px) {

    /* Login: "Forgot Password ?" / "Login with OTP ?" keep their "?" and
       drop to two lines only if they really do not fit. */
    .dark-blue-text-1 {
        white-space: nowrap;
    }

    .d-flex:has(> div > p.dark-blue-text-1) {
        flex-wrap: wrap;
        gap: 6px 12px;
    }

    .main-white-box {
        border-radius: 12px;
        border-width: 1px;
    }

    .app-shell > .w-100:not(.d-flex),
    .app-shell > .d-flex.w-100 > .w-100 {
        margin: 0 4px !important;
    }
}

/* ===================================================================
 * Width-of-the-box rules (container queries).
 *
 * These widgets break when THEIR box gets narrow, which happens on small
 * laptops too (1000-1100px, sidebar open), not only on phones. Each rule
 * only applies below the width at which the widget currently breaks, so
 * wider boxes render exactly as before.
 * =================================================================== */

/* Creator / Manager / Maker / Checker / Tester chips on dashboard task cards */
.role-chips {
    container-type: inline-size;
    container-name: role-chips;
}

@container role-chips (max-width: 215px) {
    .role-chips > * {
        flex: 1 1 0;
        min-width: 0;
        margin-right: 0 !important;
    }

    .role-chips > * + * {
        margin-left: 3px;
    }

    .role-chips .name-short-box {
        padding: 2px 1px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .role-chips .label-font-dark-new {
        font-size: 9.5px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

/* Circular Compliance treemap: below ~340px the 4-column mosaic cannot hold
   its "Total / Pending" pills, so it becomes a plain 2-column grid. */
.treemap-box {
    container-type: inline-size;
    container-name: treemap-box;
}

@container treemap-box (max-width: 340px) {
    .treemap-wrapper {
        aspect-ratio: auto;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-rows: none;
        grid-auto-rows: auto;
        gap: 6px;
    }

    .treemap-wrapper .box {
        grid-column: auto !important;
        grid-row: auto !important;
        min-width: 0;
        padding: 8px 10px;
        gap: 6px;
    }

    .treemap-wrapper .box .d-flex {
        flex-direction: column;
        gap: 6px;
    }

    .treemap-wrapper .panding-complied,
    .treemap-wrapper .column-150-ps-0 {
        margin-left: 0 !important;
        margin-top: 0 !important;
    }

    .treemap-wrapper .total-complied,
    .treemap-wrapper .panding-complied {
        padding: 4px 6px;
    }
}

/* Pagination (x-new.custom.pagination.* and the report-list copies):
   "records" text | page links | page input + "Go To Page". When the row
   does not fit its panel (half-width panels on small laptops, phones) the
   blocks wrap instead of spilling out, and the button never breaks its
   label. Wrapping changes nothing while the row fits, so wide screens
   render as before. */
.pagination-div,
.pagination-div > div > div {
    flex-wrap: wrap;
    row-gap: 8px;
}

.pagination-div > div {
    max-width: 100%;
}

.pagination-div .pagination {
    flex-wrap: wrap;
}

.pagination-div button,
.sar-goto-btn {
    white-space: nowrap;
}

/* Dashboard, all widths. style.css pins the tile carousel to fixed pixel
   widths per zoom band (750px for everything up to 1280px wide, 912px at
   1440 with the sidebar open), which is wider than its column on ~992-1050px
   and some 1440px screens. Anything wider than .main-white-box makes the box
   scroll sideways, and focusing a header button (Quick summary) then slides
   the whole page under the sidebar. No-op while the carousel fits. */
.width-carosal {
    max-width: 100%;
}

/* Security Compliance matrix (security-chart component): label + five
   52-83px boxes need ~420px. Its half-width panel is ~390px at 1280 but
   ~290px on 1000px laptops, where the boxes spilled into the next panel.
   Below 340px of panel the label and boxes share the width. `html body`
   because the component prints its own <style> after this file. The panel
   holds no modal (the controls modal is its sibling), so the containment a
   container brings cannot trap one. */
.security-chart-box {
    container-type: inline-size;
    container-name: security-chart-box;
}

@container security-chart-box (max-width: 340px) {
    html body .legend {
        flex-wrap: wrap;
        gap: 6px 12px;
        margin-left: 8px;
        margin-right: 8px;
    }

    html body .legend .legend-item {
        white-space: nowrap;
    }

    html body #Compliancechart {
        margin: 0 6px;
    }

    html body #Compliancechart .row-container {
        justify-content: flex-start;
        gap: 6px;
    }

    html body #Compliancechart .row-label {
        width: 32%;
        flex-shrink: 0;
    }

    html body #Compliancechart .boxes-container {
        display: flex;
        flex: 1 1 auto;
        min-width: 0;
    }

    html body #Compliancechart .security-box {
        flex: 1 1 0;
        min-width: 0;
        width: auto !important;
        margin: 2px !important;
    }
}

/* Small laptops (992-1199px): the dashboard header keeps title, tabs and
   actions on one line, but the "Subscription Expiring Soon" notice no
   longer fits between them and overlapped the buttons. It moves to its
   own line under the header. */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .dash-header {
        flex-wrap: wrap;
    }

    .dash-header-sub {
        order: 5;
        flex: 1 1 100%;
    }

    .dash-header-sub .ml-3 {
        margin-left: 0;
    }

    .dash-header-sub p {
        display: inline;
        text-align: left !important;
        margin-right: 6px;
    }
}

/* ===================================================================
 * Task lists (All / Assigned to me / Created by me / To do / Upcoming, and
 * the framework "related task" lists) — phones.
 * Rows come from components/new/widgets/_task-view_new.blade.php; each
 * cell carries a tl-* class so the card layout does not depend on which
 * optional columns (checkbox, Action, Auto-purge) are present.
 * =================================================================== */
@media (max-width: 767.98px) {

    /* Header: title + count + view pills on one block, toolbar below. */
    .tl-head {
        flex-direction: column;
        align-items: stretch !important;
        gap: 8px;
    }

    .tl-head > div:first-child {
        flex-wrap: wrap;
        row-gap: 6px;
    }

    .tl-head > div:last-child {
        flex-wrap: wrap;
        align-items: center;
        gap: 8px;
    }

    .tl-head > div:last-child > * {
        margin-right: 0 !important;
    }

    .tl-head .icon-input-main {
        flex: 1 1 100%;
    }

    .tl-head .icon-input-main input {
        width: 100%;
        min-height: 36px;
    }

    .tl-head .filter-section .filter-btn {
        width: auto;
        min-width: 120px;
        min-height: 34px;
    }

    .tl-head .view-box-fill {
        white-space: nowrap;
    }

    /* Filter panel: part of the page, full width under the toolbar (it was
       320px wide, anchored to the button's right edge). It must NOT float
       over the toolbar: the Filter button (which closes it) and Reset have
       to stay visible while it is open. */
    .tl-head .filter-section:has(> .dropdown-content:not([style*="display: none"])) {
        flex: 1 1 100%;
        order: 10;
    }

    .tl-head .filter-section .dropdown-content {
        position: static;
        width: 100%;
        max-height: none;
        margin-top: 8px;
        box-shadow: none;
    }

    /* The list scrolls with the page, not in a box of its own. */
    .table-scroll:has(> table > tbody > tr.tl-row) {
        max-height: none;
        overflow: visible;
    }

    /* Rows -> cards. */
    table:has(> tbody > tr.tl-row) {
        display: block;
        width: 100%;
    }

    table:has(> tbody > tr.tl-row) > thead {
        display: none;
    }

    table:has(> tbody > tr.tl-row) > tbody {
        display: block;
    }

    tr.tl-row {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 6px 10px;
        margin: 0 0 8px;
        padding: 10px 12px;
        border: 1px solid var(--border);
        border-radius: 12px;
        background: var(--white);
    }

    tr.tl-row > td {
        display: block;
        padding: 0 !important;
        border: 0 !important;
        width: auto !important;
        min-width: 0 !important;
        background: transparent;
        box-shadow: none !important;
    }

    tr.tl-row > .tl-check  { order: 0; }
    tr.tl-row > .tl-no     { order: 1; font-size: 13px; }
    tr.tl-row > .tl-status { order: 2; margin-left: auto; }
    tr.tl-row > .tl-action { order: 3; }

    tr.tl-row > .tl-action > div {
        margin-bottom: 0 !important;
    }

    tr.tl-row > .tl-name {
        order: 4;
        flex: 1 1 100%;
    }

    tr.tl-row > .tl-sub {
        order: 5;
        flex: 1 1 100%;
        font-size: 12px;
        color: var(--nav-color);
        text-align: left;
    }

    /* Expanded sub-task table: attached under its card, scrolls sideways
       inside it. Alpine / Livewire hide it with an inline display:none,
       which still wins over this rule. */
    tr.tl-expand {
        display: block;
        margin: -6px 0 8px;
    }

    tr.tl-expand > td {
        display: block;
        width: 100%;
        overflow-x: auto;
        border-radius: 0 0 12px 12px;
        padding: 10px !important;
    }

    /* The sub-task table's columns are percentages (Name 20%, Department
       11% ...) of a table squeezed to phone width, so a long sub-task name
       ran 12 lines tall in a ~110px column. Give the table a real width;
       it scrolls sideways inside its card. */
    tr.tl-expand > td > table.table,
    tr.tl-expand table.table {
        min-width: 900px;
    }

    /* !important: the generic "wide table" cell minimum (110px) uses a
       :has() selector, which out-specifies this one. */
    tr.tl-expand td[data-bs-target="#offcanvasDetailTaskRight"] {
        width: 240px;
        min-width: 240px !important;
    }
}

/* ===================================================================
 * Expanded sub-task table — ALL widths (no-ops while the table fits).
 * Department / Circular cells carry .table-w-100 (max-width: 50px), so on
 * a laptop the Circular column shrank below its "Circular - 1" pill and
 * the pill ran over the Users Involved chips. The cells now keep their
 * content width; when the row is narrower than the table, the table
 * scrolls sideways inside .tl-sub-scroll (width 0 + min-width 100%: fills
 * the cell without widening the main task table). The Circular dropdown
 * uses popper strategy "fixed" so the scroll box does not clip it.
 * =================================================================== */
.tl-sub-scroll {
    width: 0;
    min-width: 100%;
    overflow-x: auto;
}

html body tr.tl-expand td.tl-sub-dept,
html body tr.tl-expand td.tl-sub-circ {
    max-width: none;
}

tr.tl-expand td.tl-sub-dept {
    min-width: 90px;
}

tr.tl-expand td.tl-sub-circ {
    min-width: 135px;
}

/* A long circular file name (underscores, no spaces) stretched the column to
   its full one-line width and pushed the table into a sideways scroll. Cap
   the column and let the name wrap anywhere; it is clamped to 2 lines. */
tr.tl-expand td.tl-sub-circ > .d-flex {
    max-width: 220px;
}

tr.tl-expand td.tl-sub-circ .truncate-2-lines {
    min-width: 0;
    overflow-wrap: anywhere;
    word-break: break-all;
}

tr.tl-expand td.tl-sub-circ .btn-group {
    white-space: nowrap;
}

/* Below its desktop width the table keeps that width and scrolls, rather
   than squeezing the role chips / pills into each other. ~980px is what
   it gets at 1280 with the sidebar open, where it already looks right. */
.tl-sub-scroll > table.table {
    min-width: 980px;
}

/* Start date | Deadline: in a narrow Name cell the "|" ended up dangling
   on a line of its own; put Deadline (and its overdue clock) on the next
   line instead. The sub-task Name cell (20%) is narrower than the main
   one, so it needs this up to a wider screen. */
@media (max-width: 1399.98px) {
    tr.tl-row .devider-line {
        display: none;
    }

    tr.tl-row .row > .label-font-dark:first-child {
        flex: 0 0 100%;
    }
}

@media (max-width: 1599.98px) {
    tr.tl-expand .devider-line {
        display: none;
    }

    tr.tl-expand .row > .label-font-dark:first-child {
        flex: 0 0 100%;
    }
}

/* ===================================================================
 * Task create / edit form (livewire/new/client/task/create.blade.php).
 * =================================================================== */
@media (max-width: 991.98px) {

    /* The form is its own scroll box (table-scroll-modal) sized to the
       viewport; on small screens the page scrolls instead, and the sticky
       Save footer sticks to the bottom of the screen. */
    form.table-scroll-modal:has(.task-form-container) {
        max-height: none !important;
        height: auto !important;
        overflow: visible !important;
    }

    form.table-scroll-modal:has(.task-form-container) > .modal-body {
        overflow: visible !important;
    }

    /* Side-by-side field pairs (approver | ..., creation date | due date,
       frequency | ...) stack. */
    .task-form-container .d-flex.gap-3,
    .task-form-container .d-flex.gap-2 {
        flex-wrap: wrap;
    }

    .task-form-container .d-flex.gap-3 > *,
    .task-form-container .d-flex.gap-2 > * {
        min-width: 0;
    }

    .task-form-container {
        padding: 6px 0;
    }

    /* Task 1 / Task 2 / + tabs scroll sideways. */
    .task-form-container ~ * .nav-pills,
    form .navbar-pills-1 .nav-pills {
        flex-wrap: nowrap !important;
        overflow-x: auto;
    }
}

/* ===================================================================
 * Offcanvas detail panels (task detail and the others built the same
 * way) — phones.
 * =================================================================== */
@media (max-width: 767.98px) {

    /* Rows sized for the 650px desktop panel (Creator / Manager / Maker /
       Checker / Tester / Approver / Completer ...) wrap when they do not
       fit. Column stacks and explicit no-wrap rows are left alone. */
    .offcanvas-body .d-flex:not(.flex-column):not(.flex-nowrap) {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    /* Hover / tap pop-ups (evidence files, assignee lists) are absolutely
       positioned with inline min-widths of 300-450px next to their trigger.
       Pin them across the panel instead. .offcanvas has a backdrop-filter
       in style.css, which makes the panel (not the viewport) the box that
       position:fixed resolves against — so left/right are panel edges. */
    .offcanvas .position-absolute[style*="min-width"] {
        position: fixed !important;
        left: 12px !important;
        right: 12px !important;
        /* Inline "top: 100%" would now mean 100% of the panel's height;
           auto keeps the pop-up right under its trigger. */
        top: auto !important;
        width: auto !important;
        min-width: 0 !important;
        max-width: none !important;
        max-height: 60vh;
        overflow: auto;
        transform: none !important;
    }
}

/* Team Workload > User table: "icon + name/role/email" cells broke after
   the icon on phones. One line per cell; the table scrolls sideways. */
@media (max-width: 767.98px) {
    .team-user-table td {
        white-space: nowrap;
    }
}

/* ===================================================================
 * Auth pages (login, OTP / forgot password inside it, 2FA setup, 2FA
 * verify, forgot 2FA, admin login) — phones.
 * All share .auth-container > .container > .row > [form col][bg-image-login].
 * The login page's own <style> gives .card 50px side padding and
 * .card-body 25px !important, leaving ~144px for the form on a 320px
 * phone; scoped selectors below win over those.
 * =================================================================== */
@media (max-width: 767.98px) {

    .auth-container {
        background-color: #ffffff;
    }

    .auth-container > .container {
        max-width: 100%;
        padding-left: 12px;
        padding-right: 12px;
    }

    .auth-container > .container > .row {
        width: 100%;
        margin-left: 0;
        margin-right: 0;
    }

    /* Form column: full width, form centred vertically on the screen. */
    .auth-container > .container > .row > div:first-child {
        flex: 0 0 100%;
        max-width: 100%;
        min-height: 100vh;
        min-height: 100dvh;
        justify-content: center !important;
        padding-left: 0;
        padding-right: 0;
    }

    .auth-container > .container > .row > div:first-child > div {
        width: 100%;
        max-width: 440px;
        margin-left: auto;
        margin-right: auto;
        padding: 24px 0;
    }

    .auth-container .card {
        padding: 0 !important;
    }

    .auth-container .card .card-body {
        padding: 20px 16px !important;
    }

    .auth-container img[width="200px"] {
        width: 170px;
        margin-top: 0;
    }

    /* The decorative picture panel (with the typing headline) only pushed
       the form around; phones get the form alone. */
    .auth-container .bg-image-login {
        display: none !important;
    }

    /* Google / Microsoft / SSO stay on one line. */
    .auth-container .social-icon-btn {
        flex-shrink: 0;
    }

    .auth-container .d-flex.justify-content-center.gap-3 {
        gap: 12px !important;
    }
}

/* All widths. The shell is a flex row (sidebar | page). A flex item may not
   shrink below its content's minimum width, so one wide table (Incident
   Register: 11 no-wrap columns, 1474px) stretched the whole page past the
   screen on a 1280px desktop, instead of scrolling inside its own box,
   which is already overflow:auto. Letting the page column shrink changes
   nothing on pages that fit. */
.app-shell > .w-100,
.app-shell > .d-flex.w-100 > .w-100 {
    min-width: 0;
}

/* Public DPDPA self-assessment (layouts/dpdpa): its own stylesheet already
   handles phones, except the top bar, where logo + brand + "2023 + Rules
   2025" + the deadline pill ran 33px past a 360px screen. */
@media (max-width: 575.98px) {
    .dp-topbar-inner {
        flex-wrap: wrap;
        row-gap: 8px;
        padding-left: 20px;
        padding-right: 20px;
    }

    .dp-topbar-spacer {
        display: none;
    }

    .dp-deadline {
        flex: 1 1 100%;
        justify-content: center;
    }
}

/* Framework detail > Requirements: requirement list + detail panel stack
   below 992px (col-12 col-lg-3 / col-lg-9). The list stays a short
   scrolling box above the detail, instead of pushing it down the page. */
@media (max-width: 991.98px) {
    .fw-req-split .table-scroll.white-box-chart {
        max-height: 45vh !important;
        overflow-y: auto !important;
    }

    .fw-req-split > .col-12:first-child > .inside-main-box-chart {
        margin-right: 0 !important;
        margin-bottom: 10px;
        height: auto !important;
    }
}

/* Long unbroken strings in drawers / modals (evidence file names such as
   "_SELECT_cu_FROM_client_users_cu...") break inside the word instead of
   being cut off with a sideways scrollbar under the list. */
@media (max-width: 767.98px) {
    .offcanvas-body a,
    .offcanvas-body li,
    .modal-body a,
    .modal-body li {
        overflow-wrap: anywhere;
        word-break: break-word;
    }
}

/* Tables in drawers / modals whose wrapper is deliberately overflow:visible
   (Control detail > Artifacts: each row has an action dropdown a scroll box
   would clip). A scrolling minimum width is not possible there, so on a
   phone the table fits the drawer and its cells wrap instead; otherwise
   the whole drawer body scrolled sideways and cut off its left edge. */
@media (max-width: 767.98px) {
    .offcanvas-body [style*="overflow: visible"] > table,
    .modal-body [style*="overflow: visible"] > table {
        min-width: 0 !important;
        width: 100%;
    }

    .offcanvas-body [style*="overflow: visible"] > table > * > tr > th,
    .offcanvas-body [style*="overflow: visible"] > table > * > tr > td,
    .modal-body [style*="overflow: visible"] > table > * > tr > th,
    .modal-body [style*="overflow: visible"] > table > * > tr > td {
        min-width: 0 !important;
        white-space: normal;
        padding-left: .3rem;
        padding-right: .3rem;
        /* break only a word longer than its column ("anywhere" also split
           short ones: "Ty pe", "Po lic y", "Stat us") */
        overflow-wrap: break-word;
        word-break: normal;
    }

    .offcanvas-body [style*="overflow: visible"] > table > * > tr > th,
    .modal-body [style*="overflow: visible"] > table > * > tr > th {
        white-space: nowrap;
    }
}

/* Rows-per-page + search toolbar (x-new.custom.table.search_pageLength and
   the VAPT copy). Several pages put it inside a right-aligned flex row
   (d-flex justify-content-end), which shrank it to its content and pushed
   it right; on a phone it always takes the full row. */
@media (max-width: 575.98px) {
    /* keeps the row's own negative gutters, so the selector lines up with
       the table's left edge like on pages without the wrapper */
    .d-flex > .search-page-length {
        flex: 1 1 100%;
    }
}

/* Work Calendar (FullCalendar; switches itself to the List view on small
   screens). Its toolbar crammed arrows + today, the date range and four
   view buttons onto one line, wrapping the date range into four lines. */
@media (max-width: 767.98px) {
    .fc .fc-toolbar.fc-header-toolbar {
        flex-wrap: wrap;
        gap: 8px;
    }

    .fc .fc-toolbar.fc-header-toolbar > .fc-toolbar-chunk:nth-child(2) {
        order: -1;
        flex: 1 1 100%;
        text-align: center;
    }

    .fc .fc-toolbar-title {
        font-size: 1.05rem;
    }

    .fc .fc-button {
        padding: .3rem .55rem;
        font-size: .8rem;
    }
}

/* ...and the calendar keeps a full-screen panel: FullCalendar sizes its
   list / grid from its container, so releasing the panel's fixed height
   (as on other pages) collapsed the calendar body to nothing. */
@media (max-width: 991.98px) {
    .main-white-box-in:has(.calendar) {
        height: calc(100vh - 70px) !important;
        height: calc(100dvh - 70px) !important;
    }
}

/* SEBI (type 7) report editors — Cyber Audit / VAPT / SOC Efficacy
   (report/partials/designed-form-styles). The 235px section menu sat next to
   the editor, leaving the editor ~60px on a phone. Menu becomes a scrolling
   row of section chips above a full-width editor. */
@media (max-width: 767.98px) {
    html body .soc7-body {
        flex-direction: column;
    }

    html body .soc7-nav {
        width: auto;
        display: flex;
        align-items: center;
        gap: 6px;
        overflow-x: auto;
        overflow-y: hidden;
        padding: 8px 10px;
        border-right: 0;
        border-bottom: 1px solid var(--c-line);
        -webkit-overflow-scrolling: touch;
    }

    html body .soc7-nav .soc7-eyebrow {
        display: none;
    }

    html body .soc7-nav .soc7-nav-item {
        width: auto;
        flex: 0 0 auto;
        white-space: nowrap;
        margin-bottom: 0;
        border: 1px solid var(--c-line);
    }

    html body .soc7-nav .soc7-logged {
        flex: 0 0 auto;
        margin: 0 0 0 4px;
        padding: 4px 10px;
        white-space: nowrap;
    }

    /* Stacked, the editor is `flex: 1 1 0` + overflow-y:auto in a column —
       that collapses it to 0px tall. Body and editor size to their content
       and the page scrolls (the desktop frame is a fixed-height app pane). */
    html body .soc7-main {
        width: auto;
        flex: 0 0 auto;
        overflow: visible;
        padding: 16px 12px 24px;
    }

    html body .soc7-frame {
        overflow: visible;
    }

    /* Preview mode: the document iframe was `flex: 1` in a frame that now
       sizes to content, so it collapsed to a strip. A real height instead;
       the document scales its A4 pages to the frame width itself. */
    html body .soc7-preview {
        flex: 0 0 auto;
        height: 75vh;
        height: 75dvh;
    }

    html body .soc7-body {
        flex: 0 0 auto;
    }

    html body .soc7-head .form-select {
        width: auto;
        min-width: 110px;
    }
}

/* Risk Register dashboard (risk-register/dashboard.blade.php prints its own
   <style> after this file, hence `html body`). The heat matrix kept its
   desktop 40px side padding + 100px label column, leaving five skinny pills;
   grid tracks could not shrink below the charts, pushing cards off screen. */
@media (max-width: 767.98px) {
    html body .rrd-grid-2 > *,
    html body .rrd-kpi-grid > * {
        min-width: 0;
    }

    html body .rrd-card {
        padding: 14px 12px;
    }

    /* KPI tiles: value + label | icon stay on one line (the generic header
       wrap rule dropped the icon under longer labels, e.g. "Very High"). */
    html body .rrd-kpi-card > .d-flex {
        flex-wrap: nowrap !important; /* outranks the 3-class header wrap rule */
        gap: 8px;
    }

    html body .rrd-kpi-card > .d-flex > div:first-child {
        min-width: 0;
    }

    html body .rrd-kpi-icon {
        width: 32px;
        height: 32px;
        margin-bottom: 0;
        flex-shrink: 0;
    }

    html body .rrd-heat-matrix {
        padding: 0;
        gap: 6px;
    }

    html body .rrd-heat-label {
        width: 78px;
        padding-right: 8px;
        font-size: 12px;
    }

    html body .rrd-heat-cells {
        gap: 5px;
        min-width: 0;
    }

    html body .rrd-heat-cell {
        height: 40px;
        font-size: 13px;
    }
}

/* Consent Management (its components print their own <style> after this
   file, hence `html body`). */
@media (max-width: 767.98px) {
    /* Loading skeletons: fixed 150-260px bars ran past a 320px screen. */
    html body .cm-sk,
    html body .cm-sk-row,
    html body .cm-sk-card {
        max-width: 100%;
    }

    html body .cm-sk-row {
        overflow: hidden;
    }

    /* Previous Consents: one card per row with a column that may shrink
       (a plain 1fr grew to the longest unbroken word and pushed the
       response-rate bar past the card), long words wrap, and the search
       box / recipient rows drop their 260px minimums. */
    html body .cv-card {
        grid-template-columns: minmax(0, 1fr);
        padding: 14px;
    }

    html body .cv-title,
    html body .cv-desc {
        overflow-wrap: anywhere;
    }

    html body .cr-item-main {
        min-width: 0;
    }

    html body .cm-tabs,
    html body .cr-tabs {
        display: flex;
        max-width: 100%;
        overflow-x: auto;
    }
}

@media (max-width: 767.98px) {
    /* Previous Consents search takes its own full-width line. */
    html body .cv-search {
        flex: 1 1 100%;
        min-width: 0;
    }
}

/* ===================================================================
   Auditor portal: the stand-alone audit screens (VAPT Report Generator,
   New VAPT List Report, SAR / SFMS / IS / ISO / NEFT-RTGS / UPI / GAP /
   GSC / GDPR / CCPA). Their layouts (vapt-layout + the *-assessment
   layouts) put class="audit-shell" on <body>, so nothing here reaches
   the client portal. Two header families:
     .header-main-box        + .header-pages-a       (vapt-style.css)
     .vapt-assessment-header + .vapt-header-actions  (vapt-assessment-style.css)
   =================================================================== */
@media (max-width: 991.98px) {
    /* Title (+ logo) on its own line, the tab strip under it. */
    body.audit-shell .header-main-box > .d-flex,
    body.audit-shell .vapt-assessment-header .container-fluid > .d-flex {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    /* Tabs + Log Out: one line that scrolls sideways instead of running
       off-screen (New VAPT List Report adds .flex-wrap, hence !important). */
    body.audit-shell .header-pages-a,
    body.audit-shell .vapt-header-actions {
        flex: 1 1 100%;
        min-width: 0;
        flex-wrap: nowrap !important;
        overflow-x: auto;
        scrollbar-width: none;
    }

    body.audit-shell .header-pages-a::-webkit-scrollbar,
    body.audit-shell .vapt-header-actions::-webkit-scrollbar {
        display: none;
    }

    body.audit-shell .header-pages-a > *,
    body.audit-shell .vapt-header-actions > * {
        flex-shrink: 0;
    }

    body.audit-shell .header-pages-a .d-flex,
    body.audit-shell .vapt-header-actions .d-flex {
        flex-wrap: nowrap;
    }

    body.audit-shell .header-pages-a a,
    body.audit-shell .vapt-header-actions a {
        white-space: nowrap;
        flex-shrink: 0;
    }

    /* List boxes are pinned to the viewport (height: calc(100vh - 60px))
       with the table scrolling inside; below the header that leaves the
       pager cut off. Let the page scroll as a document instead. */
    body.audit-shell .client-height {
        height: auto;
        min-height: calc(100vh - 60px);
    }
}

@media (max-width: 767.98px) {
    body.audit-shell .vapt-assessment-wrapper > .bg-light {
        padding: 12px !important;
    }

    /* Tables keep their column proportions and scroll inside their card
       rather than squeezing every column to a word per line. */
    body.audit-shell :is(.table-responsive, .table-scroll, .high-risk-users) {
        overflow-x: auto;
    }

    body.audit-shell :is(.table-responsive, .table-scroll, .high-risk-users) > .table {
        min-width: 720px;
    }

    /* 6+ columns (e.g. All Clients: 7) still wrap names to 3-4 lines at 720. */
    body.audit-shell :is(.table-responsive, .table-scroll, .high-risk-users) > .table:has(> thead th:nth-child(6)) {
        min-width: 960px;
    }

    body.audit-shell .table thead th {
        white-space: nowrap;
    }
}

/* ===================================================================
 * Auditor portal (vapt-layout / *-assessment-layout, dark VAPT theme in
 * public/new/vapt-style.css, which has no phone rules of its own).
 * =================================================================== */
@media (max-width: 767.98px) {
    /* Header: brand on the first line, the section tabs (Clients / Reports /
       Network VA ... / Log Out) as one sideways-scrolling row below. */
    .header-main-box > .d-flex {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .header-main-box .header-pages-a {
        flex: 1 1 100%;
        min-width: 0;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        flex-wrap: nowrap;
    }

    .header-main-box .header-pages-a > div,
    .header-main-box .header-pages-a > div > div,
    .header-main-box .header-pages-a ul {
        display: flex;
        flex-wrap: nowrap;
        flex-shrink: 0;
    }

    .header-main-box .header-pages-a a {
        flex-shrink: 0;
        white-space: nowrap;
        padding: 6px 10px;
    }

    .header-main-box .header-headding {
        font-size: .95rem;
    }
}

@media (max-width: 767.98px) {
    /* The other audits (SAR, SFMS, IS, ISO, NEFT-RTGS, UPI, GAP, GSC, GDPR,
       CCPA ...) use .vapt-assessment-header / .vapt-header-actions
       (vapt-assessment-style.css) - same shape, same treatment. */
    .vapt-assessment-header .container-fluid > .d-flex {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .vapt-assessment-header .vapt-header-actions {
        flex: 1 1 100%;
        min-width: 0;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        flex-wrap: nowrap;
    }

    .vapt-assessment-header .vapt-header-actions > div,
    .vapt-assessment-header .vapt-header-actions > div > div,
    .vapt-assessment-header .vapt-header-actions ul {
        display: flex;
        flex-wrap: nowrap;
        flex-shrink: 0;
    }

    .vapt-assessment-header .vapt-header-actions a {
        flex-shrink: 0;
        white-space: nowrap;
    }

    .vapt-assessment-header .vapt-header-title {
        font-size: .95rem;
    }
}

/* VAPT header (.header-main-box) at tablet / iPad widths too: at 1024 and
   1180px its tab row (Clients / Reports / Network VA / ... / Log Out) was
   still one line, 223px wider than the screen. */
@media (min-width: 768px) and (max-width: 1199.98px) {
    .header-main-box > .d-flex {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .header-main-box .header-pages-a {
        flex: 1 1 100%;
        min-width: 0;
        overflow-x: auto;
        flex-wrap: nowrap;
    }

    .header-main-box .header-pages-a > div,
    .header-main-box .header-pages-a > div > div,
    .header-main-box .header-pages-a ul {
        display: flex;
        flex-wrap: nowrap;
        flex-shrink: 0;
    }

    .header-main-box .header-pages-a a {
        flex-shrink: 0;
        white-space: nowrap;
    }
}

/* VAPT List Report: "<Type> Report List" + All / AMBAK / CERT-In view
   buttons + a right-hand button ran 150px past a phone screen. */
@media (max-width: 767.98px) {
    .d-flex.justify-content-between:has(> .chart-headding) {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .chart-headding.d-flex {
        flex-wrap: wrap;
        row-gap: 6px;
        min-width: 0;
    }

    .chart-headding > .d-flex {
        flex: 1 1 100%;
        flex-wrap: wrap;
        margin-left: 0 !important;
    }
}

/* Audit pagination copies (sar_paginate / sfms_paginate:
   .sar-pagination-div) - same wrapping as .pagination-div above; at 360px
   their "Go To Page" block ran 80px past the screen. */
.sar-pagination-div,
.sar-pagination-div > div > div {
    flex-wrap: wrap;
    row-gap: 8px;
}

.sar-pagination-div > div {
    max-width: 100%;
}

.sar-pagination-div .pagination {
    flex-wrap: wrap;
}

.sar-pagination-div button {
    white-space: nowrap;
}

@media (max-width: 767.98px) {
    .sar-pagination-div input.form-control {
        width: 64px !important;
        margin-left: 6px !important;
    }
}

/* VAPT list tabs (Appendices / Excluded / Reports / Vulnerabilities /
   Network VA): "Filter by:" + dropdowns (inline min-width 150px) + dates +
   buttons formed one ~1200px row; below 1200px it wraps. Scoped to the VAPT
   portal (pages carrying its .header-main-box header). */
@media (max-width: 1199.98px) {
    body:has(.header-main-box) .d-flex.justify-content-between:has(> .d-flex.gap-3),
    body:has(.header-main-box) .d-flex.justify-content-between > .d-flex.gap-3,
    body:has(.header-main-box) .d-flex.justify-content-between > .d-flex.gap-3 > .d-flex {
        flex-wrap: wrap;
        row-gap: 8px;
        min-width: 0;
    }

    /* The inline 150px minimum stays: the rows wrap here, so 150px always
       fits, and any smaller minimum clipped "All Auditors" to "All Audit(". */
    body:has(.header-main-box) .custom-select-wrapper {
        max-width: 100%;
    }

    body:has(.header-main-box) .d-flex.justify-content-between > .d-flex.gap-3 input.form-select-sm,
    body:has(.header-main-box) .d-flex.justify-content-between > .d-flex.gap-3 input.form-control {
        max-width: 100%;
    }
}

/* Phones: each "Label: [select]" filter takes a line of its own with the
   select stretched to the end of it, instead of a narrow select that cut
   its option text off. The search + page-length row (VAPT Tools) wraps so
   a filter beside it drops below instead of squeezing the search box. */
@media (max-width: 575.98px) {
    body:has(.header-main-box) .d-flex.align-items-center:has(> .custom-select-wrapper) {
        flex: 1 1 100%;
    }

    body:has(.header-main-box) .d-flex.align-items-center > .custom-select-wrapper {
        flex: 1 1 auto;
    }

    body:has(.header-main-box) .custom-select-wrapper > select {
        width: 100%;
    }

    body:has(.header-main-box) .d-flex.justify-content-between:has(> .search-page-length) {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    body:has(.header-main-box) .d-flex.justify-content-between:has(> .search-page-length) > .search-page-length,
    body:has(.header-main-box) .d-flex.justify-content-between:has(> .search-page-length) > .d-flex {
        flex: 1 1 100%;
    }
}

/* Auditor portal forms (VAPT New Report / Network VA and the assessment
   modules) are laid out with fixed col-3 / col-6 columns at every width and
   are not inside a <form>, so the form-column rule above never reached them:
   two cramped columns with cut-off inputs on a phone. */
@media (max-width: 575.98px) {
    body:has(.header-main-box) .row > [class*="col-"]:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]):not(.col-auto),
    body:has(.vapt-assessment-header) .row > [class*="col-"]:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]):not(.col-auto) {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

@media (min-width: 576px) and (max-width: 991.98px) {
    body:has(.header-main-box) .row > :is(.col-2, .col-3, .col-4):not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]),
    body:has(.vapt-assessment-header) .row > :is(.col-2, .col-3, .col-4):not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]) {
        flex: 0 0 50%;
        max-width: 50%;
    }
}

/* Audit modules (SAR, SFMS, GAP, ISO, IS, GSC, GDPR, CCPA, UPI, NEFT-RTGS
   report lists) - shared shapes, phones. */
@media (max-width: 767.98px) {
    /* "Assessment | Saved Reports" tabs + Back / Save buttons in one row
       collided; tabs take the row (50 / 50), the buttons sit under them. */
    .d-flex.justify-content-between:has(> .nav.nav-tabs) {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .d-flex.justify-content-between:has(> .nav.nav-tabs) > .nav.nav-tabs {
        flex: 1 1 100%;
    }

    .d-flex.justify-content-between:has(> .nav.nav-tabs) > .nav.nav-tabs > .nav-link {
        flex: 1 1 0;
        padding-left: 8px !important;
        padding-right: 8px !important;
        text-align: center;
    }

    .d-flex.justify-content-between:has(> .nav.nav-tabs) > .d-flex:last-child {
        margin-left: auto;
    }

    /* Saved report rows: icon + title / client / auditor / date | six action
       buttons were one row, so the buttons were cut off. Details first,
       buttons wrap on their own line below. */
    .list-group-item.d-flex.justify-content-between {
        flex-wrap: wrap;
        row-gap: 10px;
    }

    .list-group-item.d-flex.justify-content-between > :first-child {
        flex: 1 1 100%;
        min-width: 0;
    }

    .list-group-item.d-flex.justify-content-between > .d-flex:last-child {
        flex-wrap: wrap;
        margin-left: auto;
    }

    .list-group-item .d-flex.small.text-muted {
        flex-wrap: wrap;
        row-gap: 2px;
    }
}

@media (max-width: 991.98px) {
    /* Framework detail skeleton: same stacking as the page (fw-skel-split);
       its requirement-list placeholder stays short above the detail one. */
    .fw-skel-split > .col-12:first-child .inside-main-box-chart {
        max-height: 40vh;
        overflow: hidden;
        margin-bottom: 10px;
    }
}

@media (max-width: 767.98px) {
    /* Framework detail > requirement rows (framework-detail-rm-point): a
       one-row table of requirement text (80%) + Status / Controls / Expand.
       Squeezed, the text cell ended ~20px wide and, being break-all, ran one
       letter per line. On a phone each row is a small card: text full width,
       the other cells on a line below. */
    .fw-req-split table.table > tbody > tr:has(> td[style*="width: 80%"]) {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 6px 12px;
        padding: 8px 4px;
    }

    .fw-req-split table.table > tbody > tr:has(> td[style*="width: 80%"]) > td {
        display: block;
        width: auto !important;
        min-width: 0 !important;
        padding: 0 !important;
        border: 0 !important;
    }

    .fw-req-split table.table > tbody > tr:has(> td[style*="width: 80%"]) > td:first-child {
        flex: 1 1 100%;
    }

    .fw-req-split table.table:has(> tbody > tr > td[style*="width: 80%"]) {
        min-width: 0 !important;
    }
}

@media (max-width: 767.98px) {
    /* ...and with room to read, wrap at word boundaries instead of the
       page's break-all ("household / s"). */
    .fw-req-split .word-break {
        word-break: normal;
        overflow-wrap: break-word;
    }
}

/* Incident Management dashboard (incident-dashboard.blade.php prints its own
   <style> after this file, hence `html body`). Its grids are `1fr` columns,
   which cannot shrink below their content, so the 2-up KPI grid ran past a
   phone screen and cut off Open / Critical / Avg Closure. */
@media (max-width: 767.98px) {
    html body .ind-kpi-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    html body .ind-kpi {
        min-width: 0;
        padding: 10px;
        gap: 8px;
    }

    html body .ind-kpi > :last-child {
        min-width: 0;
    }

    html body .ind-kpi-num {
        font-size: 18px;
        overflow-wrap: anywhere;
    }

    html body .ind-kpi-lab {
        overflow-wrap: break-word;
    }

    html body .ind-grid-2,
    html body .ind-grid-equal {
        grid-template-columns: minmax(0, 1fr);
    }

    html body .ind-grid-2 > *,
    html body .ind-grid-equal > *,
    html body .ind-card {
        min-width: 0;
    }

    html body .ind-range-select,
    html body .ind-date-input input {
        min-width: 0;
        max-width: 100%;
    }
}

/* Incident Register (incident-list.blade.php, own <style> after this file).
   The search box had min-width 240px and poked out of the toolbar card,
   "+ Add Incident" wrapped and overflowed it, IDs broke over three lines,
   and the 340px filter menu was wider than the space under its button. */
@media (max-width: 767.98px) {
    html body .in-toolbar {
        padding: 12px;
        gap: 10px;
    }

    html body .in-toolbar > * {
        min-width: 0;
        max-width: 100%;
    }

    html body .in-toolbar > .d-flex:first-child {
        flex: 1 1 100%;
    }

    /* CSV | PDF | + Add Incident: one nowrap row, ~290px - wider than a
       small phone's toolbar (Add Incident ran off the card at 274px). It
       wraps; whatever drops to the next line fills it. */
    html body .in-toolbar > .d-flex:last-child {
        flex-wrap: wrap;
    }

    html body .in-search-input {
        min-width: 0;
        flex: 1 1 100%;
    }

    html body .in-btn {
        white-space: nowrap;
        padding: 8px 12px;
    }

    html body .in-id-cell {
        white-space: nowrap;
    }

    html body .in-filter-menu {
        width: min(340px, calc(100vw - 40px));
    }
}

/* Phones: the buttons fill their line(s), so a wrapped "+ Add Incident"
   spans the row instead of hanging at the left under CSV | PDF. */
@media (max-width: 575.98px) {
    html body .in-toolbar > .d-flex:last-child > * {
        flex: 1 1 auto;
        justify-content: center;
    }
}

/* One-time-code boxes (2FA verify / setup, OTP login, forgot 2FA): six
   inputs, each in a `col-sm-2 col-3` column of a flex row - below 576px
   that is 6 x 25% = 150% of the row, so the sixth box was cut off. They
   share the row equally instead. */
@media (max-width: 575.98px) {
    .password-input:has(.opt-input) {
        gap: 6px;
    }

    .password-input:has(.opt-input) > [class*="col-"] {
        flex: 1 1 0;
        width: auto;
        max-width: none;
        min-width: 0;
        display: flex;
        justify-content: center;
    }
}

/* Filter panels everywhere (.filter-section, 12 list pages: Suggested Task,
   Controls, Artifacts, the task tabs ...). The panel hangs off the Filter
   button's right edge at 320px wide, so on a phone it opened mostly off the
   left of the screen. Open, it becomes a full-width block in the page under
   its button (the button stays visible to close it). */
@media (max-width: 767.98px) {
    *:has(> .filter-section) {
        flex-wrap: wrap;
    }

    .filter-section:has(> .dropdown-content:not([style*="display: none"])) {
        flex: 1 1 100%;
        width: 100%;
    }

    .filter-section .dropdown-content {
        position: static;
        width: 100%;
        right: auto;
        max-height: none;
        margin-top: 8px;
        box-shadow: none;
    }
}

/* All widths. A tab bar (.nav-scroll-wrapper, Setup's 10 tabs) inside a
   header row: its wrapper could not shrink below the full tab width, so at
   1024px (iPad Pro, desktop layout) it pushed the panel 15px sideways. The
   bar already scrolls itself; let its wrapper shrink. No-op while it fits. */
.main-white-box .d-flex.justify-content-between > div:has(.nav-scroll-wrapper),
.main-white-box .d-flex.justify-content-between > div:has(.nav-scroll-wrapper) .navbar-pills-1 {
    min-width: 0;
}

/* ===================================================================
 * Compliance Assessment > Security Audit: the findings dashboard
 * (livewire/new/client/framework/vulnerability-dashboard.blade.php).
 * Its toolbar (page length + search + 4 radio filters + Add observation)
 * was one non-wrapping row ~900px wide, which pushed the whole audit
 * pane sideways on a phone: "Add observation" stuck out on the right and
 * the table's first columns were scrolled out of view. Small laptops
 * (1024 with the sidebar open) too, so the wrap itself is all-widths:
 * row-gap only, a no-op while the row fits on one line.
 * =================================================================== */
.vd-head,
.vd-toolbar,
.vd-head > div:last-child {
    flex-wrap: wrap;
    row-gap: 8px;
}

/* The findings table box has the theme's fixed laptop width (.width-table:
   978px up to 1280, 1197px up to 1536 ...), tuned for a full-width page;
   inside the audit pane it is wider than the pane. Cap it there: the table
   scrolls in its own box. No-op whenever the fixed width already fits. */
.vd-toolbar ~ .width-table {
    max-width: 100%;
}

@media (max-width: 991.98px) {
    .vd-head {
        flex-wrap: wrap;
        gap: 10px;
    }

    .vd-head > div:last-child {
        flex-wrap: wrap;
        gap: 8px !important;
        min-width: 0;
    }

    .vd-head > div:last-child > .d-flex {
        flex-wrap: wrap;
    }

    /* Total / Pending / Completed: equal tiles (the first two carried
       pe-3 and the last none, so stacked they came out different widths). */
    .vd-kpis {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8px;
    }

    .vd-kpis > [class*="col-"] {
        width: auto;
        padding: 0;
    }

    .vd-kpis > [class*="col-"] > div {
        height: 100%;
        padding-right: 0 !important;
    }

    .vd-kpis .card-filter {
        height: 100%;
    }

    .vd-toolbar {
        flex-wrap: wrap;
        gap: 10px;
    }

    /* the radio filters: own line, no desktop ms-4 indent */
    .vd-toolbar > .d-flex.flex-wrap {
        flex: 1 1 100%;
        margin-left: 0 !important;
        gap: 8px 16px !important;
    }
}

@media (max-width: 575.98px) {
    /* "Vulnerabilities" alone is wider than a third of a phone: Total on
       its own line, Pending | Completed under it. */
    .vd-kpis {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .vd-kpis > [class*="col-"]:first-child {
        grid-column: 1 / -1;
    }

    .vd-kpis .card-filter .label-font {
        display: block;
        font-size: 11px;
        line-height: 1.25;
    }

    .vd-toolbar > .ms-auto {
        margin-left: 0 !important;
        flex: 1 1 100%;
    }

    .vd-toolbar > .ms-auto > .view-box-fill-btn {
        width: 100%;
    }
}

/* ===================================================================
 * Report > Instant Report results (report/report-detail.blade.php +
 * partials/task-report-cards) - PHONES. Every report type (Task, User,
 * Task Status, Custom, Circular, Circular Report, Multiple Task, Summary)
 * sits in an inline-styled box padded 20px 24px / 16px 20px, inside two
 * more padded boxes: a task card ended up ~185px wide, its title squeezed
 * beside the status pill (which ran out of the card) and every value
 * broken over lines ("30-08- / 2025"). Inline styles, hence the attribute
 * selectors and !important.
 * =================================================================== */
@media (max-width: 575.98px) {
    body:has(#report) [style*="border-radius: 10px; padding: 20px 24px"],
    body:has(#report) [style*="border-radius: 10px; padding: 16px 20px"] {
        padding: 12px !important;
    }

    body:has(#report) #disabled-option {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }

    /* label | value rows: the value may drop under the label, never out */
    body:has(#report) [style*="justify-content: space-between"][style*="padding: 12px 0"],
    body:has(#report) [style*="justify-content: space-between"][style*="padding: 10px 0"] {
        flex-wrap: wrap;
        gap: 4px 12px !important;
    }

    body:has(#report) [style*="justify-content: space-between"][style*="padding: 12px 0"] > :last-child,
    body:has(#report) [style*="justify-content: space-between"][style*="padding: 10px 0"] > :last-child {
        min-width: 0;
        overflow-wrap: anywhere;
        margin-left: auto;
        text-align: right;
    }

    /* two-column summaries: drop the 2rem gutter */
    body:has(#report) .row[style*="--bs-gutter-x: 2rem"] {
        margin-left: 0;
        margin-right: 0;
    }

    body:has(#report) .row[style*="--bs-gutter-x: 2rem"] > [class*="col-"] {
        padding-left: 0;
        padding-right: 0;
    }

    /* Circular / Circular Report task rows: "27046 - task name" + status
       pill + chevron. The title took the room and squeezed "Pending @
       maker" onto three lines, pushing the chevron out of the card. The
       title wraps; the pill and chevron keep one line. */
    body:has(#report) [style*="justify-content: space-between; align-items: center; cursor: pointer; gap: 12px"] {
        gap: 8px !important;
    }

    body:has(#report) [style*="justify-content: space-between; align-items: center; cursor: pointer; gap: 12px"] > div:first-child {
        flex: 1 1 auto;
        min-width: 0;
        overflow-wrap: break-word;
    }

    body:has(#report) [style*="justify-content: space-between; align-items: center; cursor: pointer; gap: 12px"] > div:last-child {
        flex-shrink: 0;
        gap: 6px !important;
    }

    body:has(#report) [style*="justify-content: space-between; align-items: center; cursor: pointer; gap: 12px"] > div:last-child > span {
        white-space: nowrap;
        font-size: 11px !important;
        padding: 3px 8px !important;
    }

    /* task cards (Custom Report / Multiple Task) */
    html body .trc-card {
        padding: 10px 12px;
    }

    html body .trc-head {
        flex-wrap: wrap;
        gap: 6px;
    }

    html body .trc-head > .trc-title {
        flex: 1 1 100%;
        order: 2;
        overflow-wrap: break-word;
    }

    html body .trc-head > .trc-pill {
        order: 1;
    }

    html body .trc-label {
        flex: 0 0 88px;
    }

    html body .trc-value {
        min-width: 0;
    }

    /* The card's Comments table has exactly four columns, so the generic
       4-column rule gave every cell min-width 110px: a ~440px table that
       stretched the card, and the report's table-responsive wrapper then
       scrolled the WHOLE card sideways (the screen showed the middle of
       each line). It fits the card instead; long comments wrap. */
    /* Four columns are still too narrow at 320 (words broke mid-letter),
       so on a phone each comment is a small stacked block: Name / Date /
       Status / Comment, labelled like the table head. */
    html body .trc-comments,
    html body .trc-comments > tbody {
        display: block;
        width: 100%;
        min-width: 0 !important;
    }

    html body .trc-comments > thead {
        display: none;
    }

    html body .trc-comments > tbody > tr {
        display: block;
        border: 1px solid #E8EDF4;
        border-radius: 6px;
        padding: 6px 8px;
        margin-bottom: 6px;
    }

    html body .trc-comments > tbody > tr > td {
        display: flex;
        gap: 8px;
        border: 0 !important;
        padding: 2px 0 !important;
        min-width: 0 !important;
        width: auto !important;
        word-break: normal;
        overflow-wrap: anywhere;
    }

    html body .trc-comments > tbody > tr > td[colspan] {
        display: block;
        text-align: center;
    }

    html body .trc-comments > tbody > tr > td:not([colspan])::before {
        flex: 0 0 66px;
        font-weight: 600;
        color: #646464;
    }

    html body .trc-comments > tbody > tr > td:nth-child(1):not([colspan])::before { content: "Name"; }
    html body .trc-comments > tbody > tr > td:nth-child(2)::before { content: "Date"; }
    html body .trc-comments > tbody > tr > td:nth-child(3)::before { content: "Status"; }
    html body .trc-comments > tbody > tr > td:nth-child(4)::before { content: "Comment"; }
}

/* Summary report tiles (Total / Overdue / Maker My Work ...): rows of two
   col-6 tiles with ms-/me- margins (50% + margins > half), so the generic
   "toolbar rows wrap" rule put each tile on its own line at half width.
   The two share the row instead. Phones + tablets (where that rule runs). */
@media (max-width: 991.98px) {
    body:has(#report) .d-flex.justify-content-between.my-2:has(> .col-6 > .white-box-chart-data) {
        flex-wrap: nowrap;
        gap: 8px;
    }

    body:has(#report) .d-flex.justify-content-between.my-2:has(> .col-6 > .white-box-chart-data) > .col-6 {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
        margin: 0 !important;
    }
}

/* ===================================================================
 * Switch grids ("form-check form-switch col-3", Setup > Setting) on
 * TABLETS (768-991). The four columns stay, but a label longer than its
 * ~140px column dropped under its switch (Bootstrap floats the switch and
 * the label wraps below it): the switch and label sit side by side and the
 * label wraps beside it. Both settings blocks share one left edge (the
 * Password Policy block's nested rows had their own gutters).
 * =================================================================== */
@media (min-width: 768px) and (max-width: 991.98px) {
    .row > .form-check.form-switch[class*="col-"]:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]) {
        display: flex;
        align-items: flex-start;
        gap: 8px;
        padding-left: 0;
    }

    .row > .form-check.form-switch[class*="col-"] > .form-check-input {
        float: none;
        margin: 2px 0 0;
        flex-shrink: 0;
    }

    .row > .form-check.form-switch[class*="col-"] > .form-check-label {
        flex: 1 1 auto;
        min-width: 0;
    }

    .row.px-4:has(> .form-check.form-switch) {
        padding-left: 12px !important;
        padding-right: 12px !important;
    }

    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) {
        padding: 0 12px !important;
    }

    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) > * {
        padding-left: 0;
        padding-right: 0;
    }

    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) .row {
        margin-left: 0;
        margin-right: 0;
    }

    /* policy inputs start where Login Expired / Revert Time start */
    .row.px-4:has(.row > .form-check.form-switch):not(:has(> .form-check.form-switch)) .row > [class*="col-sm"] {
        padding-left: 4px;
    }
}

/* ===================================================================
 * Table Action cells (last column: edit / add / delete / view icons) -
 * phones and tablets. In a narrow scrolling table the action column is
 * ~40px, so its icon row squeezed: the 16px SVGs shrank (the generic
 * svg max-width:100% lets them) and touched each other ("+" and the bin
 * on Suggested Task). Icons keep their size, get a small gap and at least
 * a 28px tap area (~14px visible space between icons); the column widens instead (the table scrolls anyway).
 * Up to 991px: the svg max-width rule that shrank them reaches that far.
 * =================================================================== */
@media (max-width: 991.98px) {
    table td:last-child svg {
        flex-shrink: 0;
        max-width: none;
    }

    /* icon row built as a flex box */
    table td:last-child > .d-flex:has(> :nth-child(2)):has(svg) {
        flex-wrap: nowrap;
        gap: 2px;
    }

    table td:last-child > .d-flex:has(> :nth-child(2)):has(svg) > :is(a, span, button, div):has(svg) {
        flex-shrink: 0;
        margin-left: 0 !important;
        margin-right: 0 !important;
        min-width: 28px;
        min-height: 28px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* icons placed straight in the cell, side by side */
    table td:last-child:has(> :nth-child(2)) > :is(a, span, button):has(> svg, > span > svg, > i) {
        min-width: 28px;
        min-height: 28px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        margin: 0 1px;
        vertical-align: middle;
    }

    /* ...and keep a row of such icons on one line (a ~45px cell otherwise
       stacked them one per line). Not when the cell also holds paragraphs /
       blocks / line breaks. (:has() cannot nest, hence the plain form.) */
    table td:last-child:has(> :is(a, span, button):nth-child(2) > svg):not(:has(> p, > div, > br, > ul)) {
        white-space: nowrap;
    }
}

/* ===================================================================
 * Pagination - PHONES (every list: x-new.custom.pagination.paginate /
 * vapt_ / sar_ / sfms_paginate and the inline audit report-list copies,
 * all ".pagination-div" or ".sar-pagination-div" with the same shape:
 * [records text] [ [page links] [page input + Go To Page] ]).
 * The desktop row only wrapped: text left-aligned, small 26px page
 * buttons, the input indented on a line of its own. Phones get one
 * centred column: text, then bigger tap targets, then input + button
 * joined into a single control.
 * =================================================================== */
@media (max-width: 575.98px) {
    html body :is(.pagination-div, .sar-pagination-div) {
        flex-direction: column;
        align-items: stretch !important;
        gap: 10px;
        margin-left: 0 !important;
        margin-right: 0 !important;
        text-align: center;
    }

    html body :is(.pagination-div, .sar-pagination-div) > div:first-child p {
        font-size: 12px;
        line-height: 1.4;
        margin-bottom: 0 !important;
    }

    html body :is(.pagination-div, .sar-pagination-div) > div:last-child,
    html body :is(.pagination-div, .sar-pagination-div) > div:last-child > div {
        width: 100%;
    }

    html body :is(.pagination-div, .sar-pagination-div) > div:last-child > div {
        flex-direction: column;
        align-items: center !important;
        gap: 10px;
    }

    html body :is(.pagination-div, .sar-pagination-div) .pagination {
        justify-content: center;
        row-gap: 6px;
    }

    html body :is(.pagination-div, .sar-pagination-div) .page-link {
        min-width: 36px;
        height: 36px;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0 10px !important;
        font-size: 14px;
    }

    /* page input + Go To Page: a compact pair centred under the links, as
       tall as them - a small number box, then the button. (A box stretched
       across the row read as a big empty, unlabelled field.) */
    html body :is(.pagination-div, .sar-pagination-div) > div:last-child > div > .d-flex {
        justify-content: center;
        gap: 8px;
    }

    html body :is(.pagination-div, .sar-pagination-div) > div:last-child > div > .d-flex > input {
        flex: 0 0 72px;
        width: 72px !important;
        height: 36px;
        margin: 0 !important;
        border-radius: 8px;
        text-align: center;
        font-size: 14px !important;
    }

    html body :is(.pagination-div, .sar-pagination-div) > div:last-child > div > .d-flex > button {
        height: 36px;
        margin: 0 !important;
        padding: 0 16px;
        border-radius: 8px;
    }
}

/* ===================================================================
 * VAPT report editor (vapt/tab/manage-report.blade.php) - PHONES.
 * - "URL/Name: https://..." was a nowrap flex line wider than the screen.
 * - Vulnerabilities toolbar: count block + "Select from Audit Type List" +
 *   "Select from All Vulnerability" on one line; the buttons wrapped to
 *   five lines and the second poked out of the card.
 * - Finding card header: move arrows + number + title + severity badge +
 *   edit/delete on one line; the title broke one word per line and the
 *   badge stuck out of the card.
 * =================================================================== */
@media (max-width: 575.98px) {
    .d-flex.gray-font-color-1 {
        flex-wrap: wrap;
        min-width: 0;
    }

    .d-flex.gray-font-color-1 > span:last-child {
        min-width: 0;
        overflow-wrap: anywhere;
    }

    .vuln-actions-sticky {
        flex-wrap: wrap;
        row-gap: 10px;
    }

    .vuln-actions-sticky > div:first-child {
        flex: 1 1 100%;
    }

    .vuln-actions-sticky > div:last-child {
        flex: 1 1 100%;
        flex-wrap: wrap;
        gap: 8px;
    }

    .vuln-actions-sticky > div:last-child > * {
        flex: 1 1 0;
        justify-content: center;
        margin: 0 !important;
    }

    .card-body > .d-flex.justify-content-between:has(> .d-flex:first-child > h6.card-title) {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    /* The page styles every .badge min-width 70px, so number + severity
       pills + arrows left the title ~20px (one letter per line). Arrows,
       number and severity share the first line; the title gets its own. */
    .card-body > .d-flex.justify-content-between:has(> .d-flex:first-child > h6.card-title) > .d-flex:first-child {
        flex: 1 1 100%;
        min-width: 0;
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .card-body > .d-flex.justify-content-between:has(> .d-flex:first-child > h6.card-title) > .d-flex:first-child > h6 {
        order: 10;
        flex: 1 1 100%;
        min-width: 0;
        overflow-wrap: break-word;
    }

    .card-body > .d-flex.justify-content-between:has(> .d-flex:first-child > h6.card-title) > .d-flex:first-child > .badge:last-child {
        margin-left: auto !important;
        flex-shrink: 0;
    }

    /* "Steps To Reproduce" label + "Add Steps To Reproduce" and "Type All
       Steps At Once" switches: one nowrap line that ran off the card. The
       label takes a line, the switches wrap under it. */
    body:has(.header-main-box) .d-flex.align-items-center.gap-3:has(> .form-check.form-switch) {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    body:has(.header-main-box) .d-flex.align-items-center.gap-3:has(> .form-check.form-switch) > label {
        flex: 1 1 100%;
    }

    .card-body > .d-flex.justify-content-between:has(> .d-flex:first-child > h6.card-title) > .d-flex:last-child {
        margin-left: auto;
    }
}

/* ===================================================================
 * Auditor > client drill-down task list (task/view-task.blade.php): six
 * count tiles (Total / Manager / Maker / Checker / Tester / Overdue) in
 * fixed col-2 columns - ~30px each on a phone, so "1,456 Total Tasks"
 * stacked one letter per line. Phones: 3 x 2 grid of equal tiles.
 * =================================================================== */
@media (max-width: 575.98px) {
    .task-filter-cards {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8px;
        margin-left: 0;
        margin-right: 0;
    }

    .task-filter-cards > .col-2 {
        width: auto;
        max-width: none;
        padding: 0;
    }

    .task-filter-cards > .col-2 > .card {
        height: 100%;
        margin: 0;
    }

    .task-filter-cards .custom-card-body {
        padding: 8px 6px;
        text-align: center;
    }

    .task-filter-cards .card-title,
    .task-filter-cards .custom-card-body p {
        overflow-wrap: normal;
        word-break: normal;
    }

    .task-filter-cards .custom-card-body p {
        font-size: 11px;
        line-height: 1.25;
    }
}

/* ===================================================================
 * Security Audit Report (report/security-audit-report.blade.php) - PHONES.
 * Security Type | Target | Scheduled Audits were three fixed col-4 boxes
 * (~85px each: "Main We", "02-11-20"), and the Reported Status / Status as
 * of Now cards two col-6 halves whose h5 broke as "Report / ed".
 * =================================================================== */
@media (max-width: 575.98px) {
    .sar-filters > .col-4 {
        flex: 0 0 100%;
        max-width: 100%;
        margin-bottom: 6px;
    }

    /* padding 0: the row carries mx-3 itself, so with the column gutter
       the cards sat 12px inside the filters' edges */
    .sar-status > .col-6 {
        flex: 0 0 100%;
        max-width: 100%;
        padding-left: 0;
        padding-right: 0;
    }

    .sar-status .card-header h5 {
        font-size: 1rem;
    }
}

/* ===================================================================
 * Task Create / Own Task Create, right-hand settings panel - PHONES ONLY.
 * - Four nested paddings (px-2 + grey box 13px + white card + mx-2, ~35px
 *   a side) left the fields ~210px wide on a 320px screen; trimmed.
 * - Dates: on a touch device flatpickr swaps the text input for a native
 *   one (.flatpickr-mobile) that does not get the original's inline
 *   "padding: 7px 30px", so the date ran under the calendar icon
 *   (.search-icone-1). Give it the same room.
 * =================================================================== */
@media (max-width: 575.98px) {
    .col-12.col-lg-5 > .inside-main-box-chart {
        padding: 6px !important;
    }

    .col-12.col-lg-5 > .inside-main-box-chart > .white-box-chart > .input-form-style {
        margin-left: 6px !important;
        margin-right: 6px !important;
    }

    .form-group:has(> .search-icone-1) > input.flatpickr-mobile {
        padding-left: 30px !important;
        font-size: 12px;
    }
}

/* ===================================================================
 * Compliance Assessment > Security Audit counters (Total / In Progress /
 * Completed / Pending Review). The row is pe-3 and the first three cards
 * carry their own pe-3 but the last does not, so stacked on a phone the
 * last tile came out wider than the others. Even grid instead: four
 * across on a tablet, 2 x 2 on a phone. The row keeps its own pe-3: the
 * audit cards above sit in pe-3 wrappers too, so both end at the same edge.
 * =================================================================== */
@media (max-width: 991.98px) {
    .sa-kpis {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 8px;
    }

    .sa-kpis > [class*="col-"] {
        width: auto;
        padding: 0;
    }

    .sa-kpis > [class*="col-"] > div {
        height: 100%;
        padding-right: 0 !important;
    }

    .sa-kpis .heading-value-text {
        height: 100%;
    }
}

@media (max-width: 575.98px) {
    .sa-kpis {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ===================================================================
 * Empty-table message (x-new.custom.no-data inside no-data-row): it is
 * centred across the WHOLE table, and on a phone the table is wider than
 * its sideways-scrolling box, so "No Cyber Audit report saved yet" was cut
 * in half. Pin it to the left of the scroll box and cap it to roughly the
 * visible width, so it centres in what is on screen. No-op when the table
 * fits (the cap is wider than the table then).
 * =================================================================== */
@media (max-width: 767.98px) {
    tr.no-data-row > td > .d-flex.flex-column.w-100 {
        position: sticky;
        left: 0;
        max-width: calc(100vw - 80px);
    }
}

/* ===================================================================
 * Incident Management > Manage: each lookup card's toolbar is search +
 * "Add <thing>" input + Add button on one nowrap line; on a phone the two
 * inputs shrank to "Search cate" and "Ac". Below 992 they take a line each.
 * (html body: the component prints its own <style> after this file.)
 * =================================================================== */
@media (max-width: 991.98px) {
    html body .in-manage-toolbar {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    html body .in-manage-toolbar .in-manage-search,
    html body .in-manage-toolbar .in-manage-add-wrap {
        flex: 1 1 100%;
    }
}

/* ===================================================================
 * UPI Audit > Categories & Controls (auditor portal). A category row is
 * name + "N controls" + "N rules" chips + three action buttons; on a phone
 * the name truncated to nothing and the chips ran under "+ Add Control".
 * The name wraps on its own line, chips under it, buttons on a line of
 * their own at the right. Control rows get the same treatment.
 * =================================================================== */
@media (max-width: 575.98px) {
    .upi-cat-head,
    .upi-ctrl-row {
        flex-wrap: wrap;
        row-gap: 6px;
    }

    .upi-cat-head > .upi-cat-toggle,
    .upi-ctrl-row > div:first-child {
        flex: 1 1 100%;
        flex-wrap: wrap;
        row-gap: 4px;
    }

    .upi-cat-head > .upi-cat-toggle > .text-truncate,
    .upi-ctrl-row > div:first-child > .text-truncate {
        flex: 1 1 0;
        min-width: 60%;
        white-space: normal;
        overflow-wrap: break-word;
    }

    .upi-cat-head > .flex-shrink-0,
    .upi-ctrl-row > .flex-shrink-0 {
        margin-left: auto;
    }
}

/* ===================================================================
 * SBOM Register (sbom-register/sbom-list.blade.php, type-5 only).
 * The component prints its own <style> after this file, so every rule
 * here carries `html body` for specificity, not source order.
 *
 * Unlike the rest of this file the register starts changing at 1599px:
 * nine columns beside the open sidebar do not fit 1280-1440 laptops, and on
 * anything narrower than 1200 (tablets, small laptops) the rows become
 * cards rather than a table that scrolls sideways.
 * =================================================================== */

/* Small laptops: same table, tighter - headers wrap onto two lines and the
   name column wraps, so all nine columns fit beside the sidebar. */
@media (max-width: 1599.98px) {
    html body .sb-table thead th {
        white-space: normal;
        padding: 11px 10px;
        letter-spacing: 0.03em;
        vertical-align: bottom;
    }

    html body .sb-table tbody td {
        padding: 12px 10px;
    }

    html body .sb-table .sb-app {
        min-width: 140px;
    }

    html body .sb-badge {
        padding: 3px 10px;
    }
}

/* Below 1200: register rows are cards (two a row, one on phones); the
   add/edit dialog, which Bootstrap narrows to 800px here, puts two fields
   a row instead of four. */
@media (max-width: 1199.98px) {
    html body .sb-grid.cols-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    html body .sb-kpis {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    html body .sb-table-wrap {
        border: 0;
        box-shadow: none;
        background: transparent;
        overflow: visible;
        flex: 0 0 auto;
    }

    html body .sb-table,
    html body .sb-table tbody,
    html body .sb-table tbody tr,
    html body .sb-table tbody td {
        display: block;
        width: 100%;
    }

    html body .sb-table thead {
        display: none;
    }

    html body .sb-table tbody {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    html body .sb-table tbody tr {
        background: #fff;
        border: 1px solid #e2e8f0;
        border-radius: 12px;
        padding: 4px 14px;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
        min-width: 0;
    }

    html body .sb-table tbody tr:hover {
        background: #fff;
        border-color: #9fd8ef;
    }

    html body .sb-table tbody td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 9px 0;
        border-bottom: 1px dashed #eef2f7;
        text-align: right;
        min-width: 0;
        overflow-wrap: anywhere;
    }

    html body .sb-table tbody td:last-child {
        border-bottom: 0;
    }

    html body .sb-table tbody td::before {
        content: attr(data-label);
        flex: 0 0 42%;
        text-align: left;
        font-size: 11px;
        font-weight: 600;
        color: #64748b;
        text-transform: uppercase;
        letter-spacing: 0.03em;
    }

    /* The name cell stacks its "Match in:" line under the name. */
    html body .sb-table tbody td[data-label="Application / Software Name"] {
        flex-wrap: wrap;
    }

    html body .sb-table tbody td[data-label="Application / Software Name"] > div {
        flex: 1 1 50%;
        min-width: 0;
    }

    html body .sb-table .sb-app {
        min-width: 0;
    }

    html body .sb-table tbody td.sb-actions {
        justify-content: flex-end;
        gap: 6px;
    }

    html body .sb-table tbody td.sb-actions::before {
        margin-right: auto;
    }

    html body .sb-action {
        width: 36px;
        height: 36px;
    }

    /* Empty state: the whole width, no label, centred. */
    html body .sb-table tbody tr.no-data-row {
        grid-column: 1 / -1;
        padding: 0;
    }

    html body .sb-table tbody tr.no-data-row td {
        justify-content: center;
        text-align: center;
    }

    html body .sb-table tbody tr.no-data-row td::before {
        display: none;
    }
}

/* Tablet: two fields a row, the file box and the document reference on
   lines of their own, and the toolbar wraps instead of overflowing. */
@media (max-width: 991.98px) {
    html body .sb-toolbar {
        padding: 12px;
        gap: 10px;
    }

    html body .sb-toolbar > * {
        min-width: 0;
        max-width: 100%;
    }

    html body .sb-toolbar-left {
        flex: 1 1 100%;
        position: relative;
    }

    /* The filter menu spans the toolbar: under its button it ran off the
       right edge (768: the button sits at the end of the search line). */
    html body .sb-toolbar-left > .position-relative {
        position: static !important;
    }

    html body .sb-filter-menu {
        top: calc(100% + 6px);
        left: 0;
        right: 0;
        width: auto;
        max-width: 420px;
    }

    html body .sb-search {
        flex: 1 1 260px;
        min-width: 0;
    }

    html body .sb-grid,
    html body .sb-dl {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    html body .sb-grid .sb-span-2 {
        grid-column: 1 / -1;
    }

    html body .sb-grid.sb-file-grid {
        grid-template-columns: minmax(0, 1fr) !important;
        gap: 8px;
    }

    html body .sb-or {
        text-align: left;
    }

    html body .sb-modal .modal-header,
    html body .sb-modal .modal-body,
    html body .sb-modal .modal-footer {
        padding-left: 16px;
        padding-right: 16px;
    }
}

/* Phone: one card a row, one field a row, the vulnerability table in the
   view dialog stacks into label / value cards. */
@media (max-width: 767.98px) {
    html body .sb-toolbar-right {
        flex: 1 1 100%;
    }

    html body .sb-toolbar-right > * {
        flex: 1 1 auto;
        justify-content: center;
    }

    html body .sb-search {
        flex: 1 1 100%;
    }

    html body .sb-table tbody {
        grid-template-columns: minmax(0, 1fr);
        gap: 10px;
    }

    html body .sb-grid,
    html body .sb-grid.cols-4,
    html body .sb-dl {
        grid-template-columns: minmax(0, 1fr);
    }

    html body .sb-grid .sb-span-2,
    html body .sb-dl .sb-span-2 {
        grid-column: auto;
    }

    html body .sb-section {
        padding: 14px 12px;
    }

    html body .sb-comp-body {
        padding: 12px;
    }

    html body .sb-vuln {
        padding: 40px 12px 12px;
    }

    html body .sb-modal .modal-footer > * {
        flex: 1 1 auto;
        justify-content: center;
    }

    html body .sb-vtable thead {
        display: none;
    }

    html body .sb-vtable,
    html body .sb-vtable tbody,
    html body .sb-vtable tr,
    html body .sb-vtable td {
        display: block;
        width: 100%;
    }

    html body .sb-vtable tr {
        border: 1px solid #e2e8f0;
        border-radius: 10px;
        padding: 4px 12px;
        margin-bottom: 8px;
        background: #fff;
    }

    html body .sb-vtable td {
        display: flex;
        justify-content: space-between;
        gap: 12px;
        padding: 6px 0;
        text-align: right;
        border-bottom: 1px dashed #eef2f7;
    }

    html body .sb-vtable tr td:last-child {
        border-bottom: 0;
    }

    html body .sb-vtable td::before {
        content: attr(data-label);
        flex: 0 0 45%;
        text-align: left;
        font-size: 10px;
        font-weight: 700;
        color: #64748b;
        text-transform: uppercase;
    }
}

/* Small phones: tighter KPI tiles, and the date picker (307px, opened at
   the input's left edge) is centred under its input so it stays on screen. */
@media (max-width: 575.98px) {
    html body .flatpickr-calendar.sb-cal.static {
        left: 50% !important;
        transform: translateX(-50%);
    }

    html body .flatpickr-calendar.sb-cal.static::before,
    html body .flatpickr-calendar.sb-cal.static::after {
        display: none;
    }

    html body .sb-kpis {
        gap: 8px;
    }

    html body .sb-kpi {
        padding: 10px 12px;
    }

    html body .sb-kpi-value {
        font-size: 17px;
    }
}
