/* =============================================================================
   responsive.css — enterprise responsive layer for the Phantasm card-based UI
   -----------------------------------------------------------------------------
   Loaded AFTER styles.css + gradient.css so it refines the existing system
   (it reuses the same --tokens; it never redefines colours/themes).

   Design goals
     • One UI that never breaks: mobile → tablet → laptop → desktop →
       ultra-wide → smart-TV.
     • Cards auto-resize, wrap, and stay equally spaced — dynamic data never
       distorts the grid.
     • Wide content (tables, code) SCROLLS inside its card instead of pushing
       the whole page wider (which is what made grids mis-compute columns and
       text shatter letter-by-letter).
     • Long words/URLs/codes wrap gracefully; headings never break per-letter.

   Breakpoints (mobile-first; min-width scales UP)
     base   ≤640   phones        ·  md  ≥769  tablets   ·  lg ≥1025 laptops
     xl ≥1440 desktops · 2xl ≥1920 ultra-wide · tv ≥2560 4K / smart-TV
   ========================================================================== */

/* ---- 1. Cross-browser foundation ----------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  scroll-behavior: smooth;
}

/* Graceful word wrapping. `break-word` (NOT `anywhere`) is deliberate: it
   breaks an over-long word only as a last resort and KEEPS the longest word
   as the min-content size, so flex/grid cards never collapse to a sliver and
   shatter text into one-letter-per-line. Normal text still breaks at spaces. */
body, p, span, div, td, th, li, a, label, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
  word-break: normal;
}

/* ---- 2. No-overflow structural guards ------------------------------------ */
/* Let the content column shrink instead of forcing a page-wide scrollbar. */
.app-shell > * { min-width: 0; }
.app-content  { min-width: 0; max-width: 100%; }

/* Responsive media — never overflow their container, keep aspect ratio. */
img, svg, video, canvas, iframe, embed, object { max-width: 100%; height: auto; }
img, video { display: block; }

/* ---- 3. Tables: scroll inside their card, never widen the page ----------- */
/* The #1 layout-breaker on mobile was a wide multi-column table with no
   horizontal scroll: it stretched the page, so every grid mis-computed its
   columns. Make table containers scroll and keep headers on one line. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-wrap > table { min-width: max-content; }

/* Standalone tables that aren't in a .table-wrap (e.g. the Testing dashboard)
   get a scrollable shell via .scroll-x (added in markup) — and as a safety
   net any bare .data / .tdash-table keeps its header cells on one line so
   they scroll rather than shatter. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.scroll-x > table { min-width: max-content; }
.data thead th, .tdash-table thead th { white-space: nowrap; }

/* Many tables sit directly in a .panel with no scroll wrapper, so a wide
   table (e.g. Teams) pushed its last column out of the card. On smaller
   screens let any panel that directly contains a table scroll horizontally.
   :has() is scoped so panels without tables are unaffected (no clipping). */
@media (max-width: 1024px) {
  .panel:has(> table),
  .panel:has(> .data),
  .panel:has(> .table-wrap) { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .panel > table.data { min-width: max-content; }
}

/* ---- 4. Card grids: auto-fit, equal spacing, dynamic-data safe ----------- */
/* Any card grid fluidly fits as many equal columns as the width allows and
   wraps the rest — no fixed column counts to break. (.kpi-grid / .pt-grid
   already do this; this reinforces it and adds graceful phone fallback.) */
.kpi-grid { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

/* ---- 5. Top bar: title truncates, never wraps per-letter ----------------- */
.topbar { min-width: 0; flex-wrap: nowrap; }
.topbar .crumbs { min-width: 0; flex: 1 1 auto; overflow: hidden; }
.topbar .crumbs strong {
  display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Actions stay on ONE row (never wrap the avatar below). The title truncates
   instead, so the bar height is always consistent. */
.topbar .topbar-actions { min-width: 0; flex: 0 0 auto; flex-wrap: nowrap; justify-content: flex-end; }

/* ---- 6. Touch-friendly inputs (coarse pointers: phones, tablets, TV) ------ */
@media (pointer: coarse) {
  .btn, button, [role="button"], .sb-link, .mt-pg, .tab, .mt-tabs a { min-height: 44px; }
  input:not([type="checkbox"]):not([type="radio"]), select, textarea { min-height: 44px; }
  input, select, textarea { font-size: 16px; } /* stop iOS focus-zoom */
}

/* ---- 7. Fluid typography (display headings only — body stays in px) ------- */
.page-title { font-size: clamp(20px, 2.4vw, 30px); line-height: 1.15; }

/* ---- 8. Phones (≤ 640px) ------------------------------------------------- */
@media (max-width: 640px) {
  .app-content { padding: 16px 14px; }

  /* Multi-column content grids collapse to a single clean column. */
  .pt-grid,
  .kpi-grid,
  .tc-page-grid,
  .bu-grid,
  .tc-stats-grid,
  .tc-row-2,
  .ot-hero { grid-template-columns: 1fr !important; }

  /* Kanban "live" hero: stack title + metric tiles into a 2-up grid so the
     "Phantasm" title and counts never get crushed into a sliver. */
  .ot-hero { gap: 10px; }
  .ot-hero .ot-kpi { padding: 8px 10px; }

  /* Page header stacks; primary action goes full width and easy to tap. */
  .page-head { flex-direction: column; align-items: stretch; gap: 12px; }
  .page-actions { display: flex; }
  .page-actions .btn { flex: 1; justify-content: center; }

  /* Modals become near-full-screen sheets so nothing is clipped. */
  .modal, .modal-card, .tc-modal { width: 100% !important; max-width: 100% !important; }
}

/* ---- 8b. Filter toolbars — the big fix ----------------------------------
   Every page has its OWN filter-bar class and most use Select2 (which writes
   an inline pixel width that beat earlier rules). Below ~860px we stack every
   filter bar into one clean full-width column so search / dropdowns / dates /
   buttons all line up edge-to-edge instead of floating as tiny centred pills.
   The container list intentionally enumerates each page's class. */
@media (max-width: 860px) {
  .toolbar, .mt-toolbar, .lvq-filter, .exq-filter, .dept-toolbar, .al-toolbar,
  .att-filter-bar, .sh-toolbar, .au-toolbar, .ml-filters, .rt-toolbar,
  .rx-toolbar, .rh-filters, .tb-filters, .wf-toolbar, .ma-filters, .lr-filter,
  .lr-toolbar, .ts-toolbar {
    display: flex !important;
    flex-direction: column !important;
    flex-wrap: nowrap !important;
    align-items: stretch !important;
    gap: 10px !important;
  }

  /* Direct children each take a full row. */
  .toolbar > *, .mt-toolbar > *, .lvq-filter > *, .exq-filter > *,
  .dept-toolbar > *, .al-toolbar > *, .att-filter-bar > *, .sh-toolbar > *,
  .au-toolbar > *, .ml-filters > *, .rt-toolbar > *, .rx-toolbar > *,
  .rh-filters > *, .tb-filters > *, .wf-toolbar > *, .ma-filters > *,
  .lr-filter > *, .lr-toolbar > *, .ts-toolbar > * {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    margin: 0 !important;
    flex: 0 0 auto !important;
  }

  /* Native controls fill the row. */
  .toolbar input, .toolbar select, .toolbar textarea,
  .mt-toolbar input, .mt-toolbar select, .mt-toolbar textarea,
  .lvq-filter input, .lvq-filter select, .lvq-filter textarea,
  .exq-filter input, .exq-filter select, .exq-filter textarea,
  .dept-toolbar input, .dept-toolbar select, .dept-toolbar textarea,
  .al-toolbar input, .al-toolbar select, .al-toolbar textarea,
  .att-filter-bar input, .att-filter-bar select, .att-filter-bar textarea,
  .sh-toolbar input, .sh-toolbar select, .sh-toolbar textarea,
  .au-toolbar input, .au-toolbar select, .au-toolbar textarea,
  .f-search, .f-select, .f-date {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
  }

  /* Select2 widgets carry an inline pixel width, and some pages re-declare
     `.x .select2-container { width:auto !important }` in a <style> block that
     loads AFTER this file. Prefixing with .app-content + an attribute match
     raises specificity (0,3,0) so full-width reliably wins on mobile, plus it
     covers every toolbar/filter container class in one rule. */
  .app-content [class*="toolbar"] .select2-container,
  .app-content [class*="filter"] .select2-container,
  .app-content [class*="-bar"] .select2-container {
    width: 100% !important;
  }

  /* Date field: label ABOVE the input (was inline → "FRO M" / "T O" breaking). */
  .f-date-wrap {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 4px !important;
  }
  .f-date-wrap label { white-space: nowrap; }

  /* Apply / Clear buttons go full width and touch-friendly. */
  .toolbar .btn, .mt-toolbar .btn, .lvq-filter .btn, .exq-filter .btn,
  .dept-toolbar .btn, .al-toolbar .btn, .att-filter-bar .btn,
  .sh-toolbar .btn, .au-toolbar .btn { width: 100% !important; justify-content: center; }

  /* Tab strips (status filters) keep their row but wrap instead of overflowing. */
  .filter-tabs, .mt-tabs { flex-wrap: wrap !important; }
}

/* ---- 9. Small phones (≤ 380px): pack the metric cards 1-up --------------- */
@media (max-width: 380px) {
  .kpi-grid { grid-template-columns: 1fr; }
}

/* ---- 10. Tablets (641px – 1024px) ---------------------------------------- */
@media (min-width: 641px) and (max-width: 1024px) {
  .app-content { padding: 22px 20px; }
  .tc-page-grid, .bu-grid { grid-template-columns: 1fr; }
}

/* ---- 11. Desktops (≥ 1440px) --------------------------------------------- */
@media (min-width: 1440px) {
  .app-content { padding: 32px 40px; }
}

/* ---- 12. Ultra-wide monitors (≥ 1920px) ---------------------------------- */
/* Cap readable width + centre so cards/lines don't stretch edge-to-edge. */
@media (min-width: 1920px) {
  .app-content { max-width: 1780px; margin-inline: auto; padding: 36px 56px; }
  .kpi-grid { gap: 20px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
}

/* ---- 13. Smart TV / 4K (≥ 2560px) ---------------------------------------- */
/* 10-foot "lean-back" sizing: bigger type, roomier spacing, wider rail. */
@media (min-width: 2560px) {
  .app-content { max-width: 2400px; padding: 56px 80px; }
  .app-shell { grid-template-columns: 320px 1fr; }
  body { font-size: 19px; }
  .page-title { font-size: clamp(34px, 2.2vw, 48px); }
  .kpi-value { font-size: 40px; }
  .kpi-label { font-size: 14px; }
  .data th, .data td { padding: 18px 22px; font-size: 16px; }
  .btn { font-size: 16px; padding: 12px 22px; }
  .sb-link { font-size: 17px; }
  .card, .panel { border-radius: 14px; }
  .kpi-grid { gap: 26px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
}

/* ---- 14. Motion & accessibility ------------------------------------------ */
.btn, .card, .panel, .sb-link, .mt-pg, .tab, a {
  transition: background-color .15s ease, border-color .15s ease,
              color .15s ease, transform .12s ease, box-shadow .15s ease;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ---- 15. Landscape phones: reclaim vertical space ------------------------ */
@media (max-height: 480px) and (orientation: landscape) {
  .app-content { padding-top: 12px; padding-bottom: 12px; }
}

/* ---- 16. Per-page mobile polish (dashboard / approvals / status / roles) -- */
@media (max-width: 860px) {
  /* Dashboard — tighten the oversized hero spacing and let rows wrap. */
  .pt-top { margin-bottom: 24px !important; flex-wrap: wrap; gap: 12px; }
  .pt-hero { padding: 20px 18px !important; }
  .pt-hero-roles { flex-wrap: wrap; }
  .pt-section-title { margin-top: 22px; }

  /* Roles & permissions — the 2-column "roles | permissions" grid stacks. */
  .roles-grid { grid-template-columns: 1fr !important; }

  /* Approvals — each row stacks: identity on top, action buttons full-width
     below (they were getting cut off / squeezing the name on phones). */
  .appr-row { flex-direction: column !important; align-items: stretch !important; gap: 12px !important; }
  .appr-actions { width: 100% !important; min-width: 0 !important; flex-wrap: wrap !important; }
  .appr-actions form { flex: 1 1 auto; display: flex; }
  .appr-actions .btn, .appr-actions form .btn { flex: 1 1 auto; justify-content: center; }

  /* Status page — fewer uptime bars so each stays tappable, rows stack. */
  .st-comp-row { flex-direction: column; align-items: stretch !important; gap: 8px; }
  .st-banner { flex-direction: column; align-items: flex-start !important; gap: 8px; }
}
@media (max-width: 480px) {
  .st-bars { grid-template-columns: repeat(30, 1fr) !important; }
}

/* ---- 17. Subtle entrance animation --------------------------------------- */
/* Cards/panels gently fade-and-rise on load for a premium feel. Plays once,
   GPU-friendly (opacity + transform), and is disabled under reduced-motion
   (section 14 already neutralises animations there). */
@keyframes resp-fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.app-content .panel,
.app-content .pt-card,
.app-content .st-panel,
.app-content .kpi-grid,
.app-content > .card,
.appr-row {
  animation: resp-fade-up .34s cubic-bezier(.22,.61,.36,1) both;
}
/* Tap/press feedback on interactive cards & buttons (touch-friendly). */
.pt-card:active, .card:active, .btn:active { transform: translateY(1px); }
