/* ══════════════════════════════════════════════════════════════════════
   ClickFq — shared mobile/responsive layer
   Loaded by the admin dashboards (/admin/*) and the customer portal
   (/dashboard). Every page here was authored as a fixed desktop app
   shell: a 220–236px sidebar that never collapses, `body{overflow:hidden}`
   so only an inner pane scrolls, and multi-column grids written as inline
   styles. That works at 1440px and falls apart on a phone.

   This file is loaded LAST on each page so it wins over the inline
   <style> block without needing to touch those rules. Because the grids
   are inline `style=""` attributes, collapsing them needs attribute
   selectors + !important — there is no class to hook onto. When you add
   a new grid to one of these pages, prefer a class over an inline style
   and add it to the collapse list at the bottom.

   Breakpoints
     ≤900px  tablet / large phone — sidebar goes off-canvas, page scrolls
     ≤560px  phone — everything collapses to a single column
   ══════════════════════════════════════════════════════════════════════ */

/* The toggle + backdrop live in the markup on every page but must never
   be visible on desktop. */
.cfq-nav-toggle { display: none; }
#cfq-nav-backdrop { display: none; }

@media (max-width: 900px) {

  /* ── 1. Give the page back its scroll ──────────────────────────────
     The desktop shell pins body to 100vh and hides its overflow so the
     inner .content pane is the only scroller. On mobile that traps
     content: 100vh is taller than the visible area once browser chrome
     is accounted for, and with the outer scroll off there is no way to
     reach what's underneath. Hand scrolling back to the document. */
  html, body {
    height: auto !important;
    overflow: visible !important;
    overflow-x: hidden !important;
  }

  /* NB: never force `display` on .shell or .main. Several dashboards gate
     the shell behind an auth check by toggling inline display:none/flex —
     an !important display here would reveal the app behind the login
     overlay. Sidebar is position:fixed below, so the flex container is
     left with a single in-flow child and lays out correctly as-is. */
  .shell {
    height: auto !important;
    min-height: 100vh;
    min-height: 100dvh;
  }

  /* min-width:0 is load-bearing. .main is a flex item, and a flex item's
     default min-width:auto refuses to shrink below its content — so one
     nowrap table stretched .main to ~700px on a 375px screen. The page
     didn't appear to scroll only because body's overflow-x:hidden was
     clipping the excess, which hides the content rather than fixing it. */
  .main {
    margin-left: 0 !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    min-width: 0 !important;
    overflow: visible !important;
  }

  .content, .cnt {
    overflow: visible !important;
    height: auto !important;
    min-width: 0 !important;
    padding: 16px 14px 48px !important;
  }

  /* Same flex-item shrink problem as .main, for the publisher's panes. */
  .editor-main, .editor-body, .editor-content-area, .settings-panel {
    min-width: 0 !important;
  }

  /* ── 2. Off-canvas sidebar ─────────────────────────────────────────
     Slides in over the content rather than stealing 60% of a 375px
     viewport. Width is capped at 82vw so the backdrop stays tappable —
     users expect to dismiss by tapping beside the drawer. */
  .sidebar {
    position: fixed !important;
    top: 0;
    left: 0;
    bottom: 0;
    width: 264px !important;
    max-width: 82vw;
    height: 100vh;
    height: 100dvh;
    z-index: 120;
    transform: translateX(-100%);
    transition: transform .22s ease;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  .sidebar.open { transform: translateX(0); }

  #cfq-nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 110;
    background: rgba(8, 15, 30, .5);
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s ease;
  }

  #cfq-nav-backdrop.open {
    opacity: 1;
    pointer-events: auto;
  }

  /* While the drawer is open the page behind it must not scroll. */
  body.cfq-nav-open { overflow: hidden !important; }

  /* ── 3. Top bar ────────────────────────────────────────────────────
     `.topbar` on most pages, `.top` on billing/provision, `.head` on
     case-studies. Fixed 56–60px heights overflow once the title wraps,
     so height becomes a minimum and buttons are allowed to wrap. */
  .topbar, .top, .head {
    height: auto !important;
    min-height: 56px;
    padding: 10px 12px !important;
    gap: 8px !important;
    flex-wrap: wrap !important;
    position: sticky;
    top: 0;
    z-index: 60;
  }

  .topbar-title, .top-t {
    font-size: 15px !important;
    flex: 1 1 auto !important;
    min-width: 0;
  }

  .head h1 { font-size: 20px !important; }

  .cfq-nav-toggle {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 10px;
    border: 1px solid #E2E8F0;
    background: #fff;
    color: #4A5568;
    cursor: pointer;
    padding: 0;
  }

  .cfq-nav-toggle:active { background: #EDF2F7; }
  .cfq-nav-toggle .material-symbols-outlined { font-size: 20px; }

  /* Pages with no top bar to sit in get a floating one instead. Without it
     the sidebar is parked off-canvas by the rule above with nothing to bring
     it back — the navigation is on the page and unreachable. Pinned rather
     than in flow because there is, by definition, no bar to be in. */
  .cfq-nav-toggle--floating {
    position: fixed;
    top: 12px;
    left: 12px;
    z-index: 60;
    box-shadow: 0 2px 10px rgba(15, 23, 42, .18);
  }

  /* ── 4. Tables ─────────────────────────────────────────────────────
     Headers are `white-space:nowrap` by design, so a table with 6+
     columns is always wider than a phone. Rather than squashing it into
     unreadability, let it scroll horizontally inside its own container
     while the page itself stays put. */
  .cfq-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }

  .cfq-table-scroll .data-table,
  .cfq-table-scroll .table { min-width: 620px; }

  /* ── 5. Touch targets ──────────────────────────────────────────────
     .btn-xs (26px), .btn-sm (30px) and .btn-md (36px) are all below the
     44px comfortable-tap minimum. Height becomes auto + padding so the
     label still fits when the font grows. */
  .btn, .btn-xs, .btn-sm, .btn-md {
    height: auto !important;
    min-height: 40px;
    padding: 8px 14px !important;
  }

  .btn-lg { min-height: 46px; }

  .icon-btn, .cfq-nav-toggle {
    width: 40px !important;
    height: 40px !important;
    min-height: 40px;
  }

  /* ── 6. Inputs — stop iOS auto-zoom ────────────────────────────────
     Mobile Safari zooms the whole viewport when a focused input has a
     font-size below 16px. These pages use 12–13.5px throughout, so
     every tap on a filter or form field jerked the layout sideways. */
  input, select, textarea,
  .form-input, .form-select, .form-textarea, .field-input {
    font-size: 16px !important;
    max-width: 100%;
  }

  /* Height is forced only on the text-ish inputs — checkboxes, radios,
     range/colour swatches and file pickers size themselves. */
  .form-input, .form-select, .field-input,
  input[type=text], input[type=email], input[type=password], input[type=number],
  input[type=search], input[type=tel], input[type=url], input[type=date],
  input[type=datetime-local], input[type=time], input:not([type]), select {
    height: 44px !important;
  }

  textarea, .form-textarea { min-height: 120px; }

  /* Checkboxes and radios keep their 13-16px browser default (or an
     explicit 16px in .toggle/.scope-chip), well under the ~20px a finger
     can reliably hit. These are consequential controls — "tax inclusive"
     on a quotation, the select-all on the leads table, human-verification
     mode in settings — so they get clamped up rather than left as targets
     you have to aim at. */
  input[type=checkbox], input[type=radio] {
    width: 20px !important;
    height: 20px !important;
    min-width: 20px !important;
    min-height: 20px !important;
    flex-shrink: 0;
  }

  /* Bare <button> elements. The button sizing further up keys off .btn,
     .icon-btn and .tab, so plain buttons — the portal's currency and
     newsletter toggles, the emails copy/reload buttons — stayed at their
     30-32px desktop heights. min-height clamps without fighting any
     inline height. */
  .content button, .cnt button, .container button, .wrap button,
  .topbar button, .top button, .head button, .header button {
    min-height: 40px;
  }

  /* The publisher's formatting toolbar is deliberately denser — it is a
     scrolling strip of many single-glyph tools, already set to 36px. */
  .editor-topbar button.tool-btn { min-height: 36px; }

  /* Filter/search rows are laid out as nowrap flex on desktop. The
     min-widths on their inputs (200–260px) are what force the row wider
     than the screen once two controls sit side by side. */
  .filters, .filter-bar, .toolbar { flex-wrap: wrap !important; }
  .filters > *, .filter-bar > *, .toolbar > * { min-width: 0 !important; }
  .toolbar input { min-width: 0 !important; width: 100% !important; }

  /* Clearing min-width above is what lets the row wrap, but it also removes
     the floor from the one child that is *meant* to stretch: a search field
     wrapped for its magnifier icon, styled `flex:1;min-width:200px`. Its
     basis is 0 while every sibling select carries an explicit width, so it is
     the only child that can absorb the shortfall — and it collapses to a
     ~36px stub with no room to type. `.toolbar input{width:100%}` above then
     resolves against that stub, so the input cannot recover on its own.
     Measured on Leads at 390px: wrapper 36px, input 48px, overflowing it.
     A direct input child is already full-width by that rule; this is for the
     wrapped ones (Leads, Affiliates). Give the search its own row. */
  .filters   > *:has(> input[type="text"]),
  .filter-bar > *:has(> input[type="text"]),
  .toolbar   > *:has(> input[type="text"]) { flex: 1 0 100% !important; }

  /* The portal's notification dropdown is a fixed 320px pinned 20px from
     the right — nearly the whole width of a small phone. Let it span the
     screen with even margins instead. */
  #notif-panel {
    left: 12px !important;
    right: 12px !important;
    width: auto !important;
    max-width: none !important;
  }

  /* ── 7. Modals ─────────────────────────────────────────────────────
     Bottom-sheet style reads better on a phone than a centred box, and
     dvh keeps the sheet inside the visible area when the URL bar is up. */
  /* Three markup conventions are in play, and they disagree about what
     `.modal` means:
       .modal-overlay > .modal-box    admin shell + customer portal
       .modal         > .modal-content blog generator  (.modal is the overlay)
       .modal-bg      > .modal         VL billing      (.modal is the BOX)
     So `.modal` cannot be matched bare — on billing that would apply
     overlay rules to the box. Each convention is addressed by its own
     unambiguous selector instead. */
  .modal-overlay,
  .modal-bg,
  .modal:has(> .modal-content) {
    padding: 0 !important;
    align-items: flex-end !important;
  }

  .modal-box,
  .modal-content,
  .modal-bg > .modal {
    max-width: 100% !important;
    width: 100% !important;
    max-height: 92vh !important;
    max-height: 92dvh !important;
    border-radius: 18px 18px 0 0 !important;
    overflow-y: auto !important;
  }

  .modal-content { padding: 20px 16px !important; }

  .modal-header { border-radius: 18px 18px 0 0 !important; }

  /* The close button is the most-tapped control in a modal and was the
     smallest thing on screen — inline-styled circles of 20-32px, and a
     17px-tall text button in the portal's math check. They sit in varied
     containers (.modal-header, .modal-head, .mh, or none at all), so the
     rule keys off the modal/drawer root instead. min-* clamps them up
     without fighting the inline width/height. */
  .modal-overlay button, .modal-bg button, .modal:has(> .modal-content) button,
  [id$="-modal"] button, [id="modal"] button, [id$="-drawer"] button,
  .modal-header button, .modal-head button, .mh button, .modal-close {
    min-width: 40px !important;
    min-height: 40px !important;
  }

  /* Footer actions stack rather than squeezing side by side. */
  .modal-footer { flex-wrap: wrap !important; gap: 8px !important; }
  .modal-footer .btn { flex: 1 1 140px; justify-content: center; }

  /* Right-hand detail drawers (services client detail) are sized in vw and
     already cap at 92vw, but the panel inside needs to stack. */
  .drawer-panel, [id$="-drawer"] > aside { width: 100% !important; }

  /* ── 8. Grid collapse — two columns ────────────────────────────────
     Stat/KPI rows. Dropping straight to one column makes a 5-tile row
     five screens tall, so they pair up here and only go single-column
     at ≤560px. */
  [style*="grid-template-columns:repeat(5,1fr)"],
  [style*="grid-template-columns:repeat(4,1fr)"],
  [style*="grid-template-columns:repeat(3,1fr)"],
  [style*="grid-template-columns: repeat(4, 1fr)"],
  [style*="grid-template-columns: repeat(3, 1fr)"],
  .grid-4, .stat-row, .stats-row, .kpi-row {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }

  /* ── 9. Grid collapse — single column ──────────────────────────────
     Anything with a fixed-width rail (the 200–360px detail panes) or
     three-plus asymmetric columns. A 340px rail alone overflows a 375px
     viewport, so these can never survive as columns. */
  [style*="grid-template-columns:1fr 360px"],
  [style*="grid-template-columns:1fr 320px"],
  [style*="grid-template-columns:1fr 300px"],
  [style*="grid-template-columns:1fr 200px"],
  [style*="grid-template-columns:280px 1fr"],
  [style*="grid-template-columns:340px minmax(0,1fr)"],
  [style*="grid-template-columns:140px 1fr"],
  [style*="grid-template-columns:110px minmax(0,1fr)"],
  [style*="grid-template-columns:2fr 1fr 1fr"],
  [style*="grid-template-columns:1fr 1fr 1fr"],
  [style*="grid-template-columns:90px 1fr 1fr"],
  [style*="grid-template-columns:80px 1fr 1fr 1fr"],
  [style*="grid-template-columns:64px 1fr 140px auto"],
  [style*="grid-template-columns: 1fr 2fr"],
  .grid, .cols, .cols-3, .imgs, .metrics-row {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* The portal's message centre is a 280px thread list beside a reading
     pane, sized to the viewport. Stacked, that fixed height would leave
     the thread scrolling inside a stub — let both panes size to content. */
  .cfq-msg-pane {
    height: auto !important;
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .cfq-msg-pane > * { max-height: 60vh; overflow-y: auto; }

  .msg-bubble { max-width: 88% !important; }

  /* Tab and filter strips sized to their content overflow once there are
     4+ entries. Billing's status filter was 472px wide at 375px, so
     "Refunded" and "Cancelled" were clipped off-screen and unreachable —
     a strip like this should scroll, not wrap. */
  .tab-bar, .tabs {
    width: 100% !important;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .tab, .tabs > * { flex: 0 0 auto; }

  /* Tabs are <button class="tab">, not .btn, so the button sizing above
     never reached them — they stayed at their desktop heights (28px on
     billing, 32px on the portal, 37px on emails) against a 40px target. */
  .tab, .tabs > button, .tab-bar > button {
    height: auto !important;
    min-height: 40px !important;
    padding: 8px 14px !important;
  }

  /* The strips themselves are width:fit-content, which fights the
     scroll container above once the tabs no longer fit. */
  .tabs, .tab-bar { width: 100% !important; }

  /* Action clusters pushed to the right of a top bar with margin-left:auto.
     On the blog publisher that cluster is 528px of Save/Preview/Publish —
     wider than the phone, so posts could not be saved. The bar wraps, so
     drop the auto margin and let the cluster start a fresh line. */
  .topbar-right, .top-right, .head-actions {
    flex-wrap: wrap !important;
    margin-left: 0 !important;
    justify-content: flex-start !important;
    max-width: 100%;
  }


  /* Long unbroken strings (IDs, URLs, emails) are a common source of
     horizontal overflow in these admin tables. */
  .card, .panel, .member { overflow-wrap: anywhere; }

  /* Team page is a plain centred container rather than a shell. */
  .container { padding: 16px 14px 48px !important; max-width: 100% !important; }
  .header { flex-wrap: wrap !important; gap: 10px !important; }

  /* ── 11. Blog publisher ────────────────────────────────────────────
     This page uses the standard .shell/.sidebar/.main frame (so the
     off-canvas rules in section 2 already cover its nav), but inside
     .main it is a two-pane editor: the document and a 300px settings
     rail. On a phone the rail drops below the document it describes. */
  .admin-layout {
    flex-direction: column !important;
    flex: none !important;
    overflow: visible !important;
  }

  .editor-main, .editor-body {
    flex-direction: column !important;
    overflow: visible !important;
    flex: none !important;
  }

  .editor-content-area {
    overflow: visible !important;
    padding: 20px 14px 32px !important;
  }

  .settings-panel {
    width: 100% !important;
    border-left: none !important;
    border-top: 1px solid var(--border, #E2E8F0) !important;
    overflow: visible !important;
    padding-bottom: 32px;
  }

  /* The formatting toolbar already scrolls horizontally — just keep the
     tool buttons tappable without letting them wrap into two rows. */
  .editor-topbar { height: 52px !important; padding: 0 12px !important; }
  .tool-btn { width: 36px !important; height: 36px !important; min-height: 36px; }

  .word-count-bar { flex-wrap: wrap !important; padding: 8px 14px !important; }
}

/* ── 10. Phone — one column for everything ───────────────────────────
   Below 560px even paired stat tiles get cramped, and any remaining
   inline grid is flattened regardless of its declared template. */
@media (max-width: 560px) {
  [style*="grid-template-columns"],
  .grid-4, .grid, .cols, .cols-3, .row2, .imgs, .field-grid, .metrics-row,
  .stat-row, .stats-row, .kpi-row {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .content, .cnt, .container { padding: 14px 12px 48px !important; }

  /* Desktop card padding (18–28px a side) eats a fifth of a phone screen. */
  .card, .card-lg, .stat-card, .panel { padding: 16px !important; }

  .topbar-title, .top-t { font-size: 14px !important; }

  /* Buttons in a wrapped topbar read better full-width than ragged. */
  .topbar .btn, .top .btn, .head .btn { flex: 1 1 auto; justify-content: center; }

  /* Inline `display:flex` card headers — a title beside an action button —
     default to nowrap, which pushed the action off-screen with nothing to
     scroll it (the services Billing tab's "Configure" sat at 422px on a
     375px screen).
     Column-direction containers must be excluded: wrapping a column flex
     spills items into *new columns* rather than new rows, which turned the
     emails template list into a 5416px-wide strip. Rows that declare their
     own flex-wrap keep it, and rows that scroll horizontally are left alone. */
  [style*="display:flex"]:not([style*="flex-direction:column"]):not([style*="flex-direction: column"]):not([style*="flex-flow:column"]):not([style*="flex-wrap"]):not([style*="overflow-x"]):not(.tabs):not(.tab-bar) {
    flex-wrap: wrap !important;
  }
}
