/* ============================================================
   Yesh — Responsive System  (load LAST, after app.css)
   ------------------------------------------------------------
   One central, reusable responsive layer. Desktop is the
   baseline and is left untouched (≥1025px). Everything below
   adapts the existing markup to tablet and phone without
   changing any product logic, IDs, routes or data.

   BREAKPOINTS (see yesh.css :root for the token block)
     Desktop  ≥ 1025px   baseline — spacious, unchanged
     Tablet   ≤ 1024px   hybrid / 2-col · sidebar → drawer
     Phone    ≤ 767px    single column · scroll-tabs · table→cards · sheet modals
     Small    ≤ 380px    tightened spacing & type

   REUSABLE PRIMITIVES (the "components" this pass introduces)
     .rsp-grid       ResponsiveGrid   — auto-fit grid, no media query needed
     .rsp-actionbar  ActionBar        — action group that wraps→stacks on phone
     .rsp-tabs       ResponsiveTabs   — horizontally scrollable pill/tab strip
     .rsp-sheet      MobileDrawer     — modal that becomes a bottom sheet
     .rsp-section    ResponsiveSection— vertical rhythm wrapper
     .rsp-stack      stacks its children to one column on phone
     .rsp-hide-phone / .rsp-only-phone / .rsp-hide-tablet  visibility helpers
   These are applied to the existing app via the grouped rules
   further down, so the current screens benefit immediately and
   new markup can opt in by class.
   ============================================================ */

/* ============================================================
   0 · REUSABLE PRIMITIVES
   ============================================================ */
.rsp-grid {
  display: grid;
  gap: var(--grid-gap);
  grid-template-columns: repeat(auto-fit, minmax(var(--rsp-min, 240px), 1fr));
}
.rsp-actionbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.rsp-tabs { display: flex; gap: 4px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.rsp-tabs::-webkit-scrollbar { display: none; }
.rsp-tabs > * { flex: 0 0 auto; white-space: nowrap; }
.rsp-section { display: flex; flex-direction: column; gap: clamp(14px, 2.4vw, 22px); }
@media (max-width: 767px) {
  .rsp-stack { display: flex !important; flex-direction: column !important; }
  .rsp-stack > * { width: 100% !important; }
  .rsp-actionbar > .btn { flex: 1 1 auto; }
}
.rsp-hide-phone { }
.rsp-only-phone { display: none; }
@media (max-width: 767px) {
  .rsp-hide-phone { display: none !important; }
  .rsp-only-phone { display: revert; }
}
@media (max-width: 1024px) { .rsp-hide-tablet { display: none !important; } }

/* ============================================================
   1 · GLOBAL GUARDS — viewport, safe-area, overflow root causes
   ============================================================ */
/* Real mobile viewport height (avoids iOS URL-bar clipping). */
.shell { height: 100dvh; }

/* The scroll surface clips stray horizontal overflow at the page
   level (intentional scroll containers inside still scroll, since
   they form their own overflow context). */
.view { overflow-x: clip; }

/* Long unbroken strings (URLs, emails, IDs) must wrap, not push width. */
.fc-ai-insight span, .ge-nba-text, .alert, .set-secnote, .fc-ii-meta,
.pd-sub, .panel-body p, .empty-cta p, .access-lock p, .badge { overflow-wrap: anywhere; }

/* Media never exceeds its container. */
img, svg, video, canvas, table { max-width: 100%; }

/* Safe-area: give the chrome breathing room on notched devices. */
@media (max-width: 1024px) {
  .topbar { padding-left: max(16px, var(--safe-l)); padding-right: max(16px, var(--safe-r)); }
}

/* ============================================================
   2 · APP SHELL + SIDEBAR DRAWER  (PageShell / ResponsiveHeader)
   Tablet & phone: sidebar collapses to an off-canvas drawer so
   content gets the full width. A tap-scrim closes it.
   ============================================================ */
@media (max-width: 1024px) {
  .shell { grid-template-columns: 1fr; }
  .side {
    position: fixed; z-index: 90; top: 0; bottom: 0; left: 0;
    width: min(280px, 84vw);
    padding-top: var(--safe-t); padding-left: var(--safe-l);
    transform: translateX(-100%); transition: transform .24s cubic-bezier(.2,.7,.3,1);
    box-shadow: var(--sh-3);
  }
  .side.open { transform: none; }
  .side-toggle { display: grid; }
}

/* Drawer scrim (element injected by responsive.js). */
.side-scrim {
  position: fixed; inset: 0; z-index: 89;
  background: rgba(20,18,12,.45); backdrop-filter: blur(1px);
  opacity: 0; visibility: hidden; transition: opacity .2s ease;
}
.side-scrim.show { opacity: 1; visibility: visible; }
@media (min-width: 1025px) { .side-scrim { display: none !important; } }

/* ---- Topbar: keep it usable as width shrinks ---- */
@media (max-width: 1024px) {
  .topbar { gap: 10px; }
  .topbar-search { max-width: 300px; }
}
@media (max-width: 767px) {
  .topbar { height: 56px; padding: 0 max(12px, var(--safe-l)) 0 max(8px, var(--safe-l)); gap: 6px; }
  .topbar-title {
    font-size: 1rem; flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .topbar-search { display: none; }          /* search lives in-page on phone */
  .topbar-right { gap: 4px; margin-left: auto; }
  /* Workspace switcher must not dominate — show only the status dot + caret. */
  .ws-switch { padding: 6px 8px; gap: 4px; }
  .ws-switch #wsActiveName { display: none; }
  .icon-btn, .ws-switch, .avatar { flex: none; }
}
@media (max-width: 600px) {
  /* Skin switcher is also reachable from Brand Kit / Settings — drop it here
     to keep primary chrome (menu · title · notifications · workspace · avatar). */
  #themeBtn { display: none; }
}

/* ============================================================
   3 · RESPONSIVE TABS  (ResponsiveTabs)
   Every tab family becomes a horizontally scrollable pill strip
   on tablet/phone — never clipped, never hidden, active state and
   badge counts preserved. A right-edge fade hints there's more.
   ============================================================ */
@media (max-width: 1024px) {
  .pd-tabs, .gf-tabs, .ge-tabs, .ob-tabs, .fin-tabs, .ib-tabs,
  .np-src-tabs, .seg, .fc-nav, .set-nav {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
  }
  .pd-tabs::-webkit-scrollbar, .gf-tabs::-webkit-scrollbar, .ge-tabs::-webkit-scrollbar,
  .ob-tabs::-webkit-scrollbar, .fin-tabs::-webkit-scrollbar, .ib-tabs::-webkit-scrollbar,
  .np-src-tabs::-webkit-scrollbar, .seg::-webkit-scrollbar { display: none; }

  /* Tabs keep their size and never shrink into each other. */
  .pd-tab, .gf-tab, .ge-tab, .ob-tab, .fin-tab, .ib-tab, .np-src-tab {
    flex: 0 0 auto; white-space: nowrap;
  }
}
@media (max-width: 767px) {
  /* Tighter padding so more tabs are visible before scrolling. */
  .gf-tab, .ge-tab, .ob-tab, .fin-tab, .pd-tab, .ib-tab { padding: 10px 13px; font-size: .82rem; }
  /* Pull tab strips to the screen edge so the scroll affordance is obvious. */
  .gf-tabs, .ge-tabs, .ob-tabs { padding-left: 16px; padding-right: 16px; }
}

/* Scrollable strips that hold horizontal content (lifecycle stepper, etc.) */
@media (max-width: 767px) {
  .lc-track, .views-bar, .seg-bar, .gf-prov-row, .fin-type-checks { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ============================================================
   4 · RESPONSIVE GRIDS  (ResponsiveGrid)
   Collapse the many bespoke grid families on a consistent scale.
   IMPORTANT: every collapsed track uses minmax(0, 1fr) — a plain
   `1fr` track keeps its content's min-content as a floor, which on
   narrow screens blows the grid (and its ancestors) wider than the
   viewport. minmax(0,…) lets tracks shrink so nothing overflows.
   ============================================================ */
/* Layout containers must be allowed to shrink below their content. */
.fc-console, .set-console, .main, .view > * { min-width: 0; }
.fc-main, .fc-side, .set-main, .set-side { min-width: 0; }

/* --- Tablet: dense stat grids → 2-3 cols; wide 2-col layouts → 1 col --- */
@media (max-width: 1024px) {
  .fc-stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .kpis, .stat-row, .fin-summary, .ge-stats-grid, .gf-scores, .ob-stat-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .grid-2, .grid-2b, .client-grid, .project-grid, .seq-grid2, .fc-two-col,
  .gf-info-grid, .ge-breakdown-grid, .pro-grid, .rc-pd-grid, .svc-media-row,
  .gf-icp-body, .fin-reports-row, .td-seg, .agent-gal, .ai-grid, .proc-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .fin-reimb-board { grid-template-columns: minmax(0, 1fr); }
  .fc-sup-grid, .tmpl-grid, .send-grid, .people-grid, .fin-pkg-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Dashboard bento: stat tiles go 2-up across the tablet band so the big
   spotlight number ($112,800) is never squeezed/clipped in a 4-up row.
   Scoped above 560px so the ≤560 single-column rule still wins on phones. */
@media (min-width: 561px) and (max-width: 1024px) {
  .b-spot, .b-stat { grid-column: span 6; }
}
@media (max-width: 1024px) {
  .statc.spot .sc-num { font-size: clamp(2rem, 4.2vw, 2.9rem); }
}

/* --- Phone: single column almost everywhere; stat cards stay 2-up --- */
@media (max-width: 767px) {
  .kpis, .stat-row, .fin-summary, .fc-stat-grid, .ge-stats-grid, .gf-scores,
  .ob-stat-strip, .kv-stats, .fc-sup-stats, .cc-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .grid, .grid-2, .grid-2b, .quick-grid, .b-quick .quick-grid, .people-grid,
  .agent-gal, .ai-grid, .proc-grid, .tmpl-grid, .send-grid, .pro-grid,
  .client-grid, .project-grid, .seq-grid2, .seq-figs, .task-cols, .type-row,
  .portal-meta, .vis-grid, .perm-grid, .pv-grid, .gm-grid2, .pc-montage,
  .inv-summary, .pipe-summary, .nba-list, .fc-two-col, .fc-sup-grid,
  .gf-info-grid, .gf-icp-body, .gf-territory-goals, .ge-breakdown-grid,
  .rc-pd-grid, .svc-media-row, .fin-reports-row, .fin-pkg-grid,
  .fin-reimb-board, .set-snap-3, .set-member-extra, .td-seg, .td-props,
  .td-time-stats, .skin-sw, .logo-slots, .form-row, .form-row.three,
  .fin-exp-form .fin-ef-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- Small phone: collapse the last 2-up stat grids to 1 --- */
@media (max-width: 380px) {
  .kpis, .stat-row, .fin-summary, .fc-stat-grid, .ge-stats-grid,
  .gf-scores, .ob-stat-strip, .fc-sup-stats { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   5 · CARDS & SECTIONS  (ResponsiveCard / ResponsiveSection)
   Responsive inner padding; cards never overflow their parent.
   ============================================================ */
@media (max-width: 1024px) {
  :root { --view-px: 24px; --view-py: 22px; --card-px: 16px; --grid-gap: 16px; }
  .view { padding: var(--view-py) var(--view-px) 56px; }
}
@media (max-width: 767px) {
  :root { --view-px: 16px; --view-py: 16px; --card-px: 14px; --grid-gap: 14px; }
  .view { padding: var(--view-py) var(--view-px) calc(48px + var(--safe-b)); }

  .card, .panel-body, .panel-pad { padding: var(--card-px); }
  .panel-head { padding: 14px var(--card-px); }
  .fc-panel-head, .fc-panel-body { padding-left: var(--card-px); padding-right: var(--card-px); }
  .gf-header, .ge-header { padding: 18px 16px 0; }
  .gf-body, .ge-body, .ob-body { padding: 18px 16px 26px; }
  .hero-card, .client-hero, .project-hero, .seq-hero { padding: 18px 16px; }

  /* No card may exceed the viewport. */
  .card, .panel, .fc-panel, .gf-card, .ge-card, .ob-card,
  .statc, .fc-sup-card, .fc-int-card { max-width: 100%; }
}

/* ============================================================
   6 · ACTION BARS & PAGE HEADERS  (ActionBar)
   Headers stack; action groups wrap, then go full-width on phone.
   ============================================================ */
@media (max-width: 767px) {
  .page-head, .fc-sec-head, .fc-toolbar, .gf-title-row, .ge-title-row,
  .seq-hero, .client-hero, .project-hero, .panel-head, .fc-panel-head,
  .gf-section-head {
    flex-direction: column; align-items: stretch; gap: 12px;
  }
  .page-head { align-items: flex-start; }
  .page-actions, .ph-actions, .ch-actions, .fc-toolbar > .row, .gf-actions,
  .seq-hero .ch-actions {
    display: flex; flex-wrap: wrap; gap: 8px; width: 100%;
  }
  /* Primary + secondary actions share the row, wrapping as needed. */
  .page-actions > .btn, .ph-actions > .btn, .ch-actions > .btn,
  .fc-toolbar .btn { flex: 1 1 auto; min-width: 0; }
  .page-actions > .btn-primary, .ph-actions > .btn-primary { order: -1; }

  /* Panel-head action that was pinned right (e.g. "View all") drops below. */
  .panel-head .btn, .fc-panel-head .btn { margin-left: 0 !important; }
}

/* Touch targets: every control comfortably tappable on touch screens. */
@media (max-width: 1024px) {
  .btn, .btn-sm, .icon-btn, .pd-icon-btn, .x-btn, .fc-nav-item,
  .nav-i, .gf-tab, .ge-tab, .ob-tab, .fin-tab, .pd-tab, .set-nav-i {
    min-height: var(--touch);
  }
  .btn-sm { padding-top: 9px; padding-bottom: 9px; }
  .icon-btn { width: var(--touch); height: var(--touch); }
}

/* ============================================================
   7 · TABLES → MOBILE CARDS  (MobileTableCard)
   On phone, generic .tbl tables restructure into stacked cards.
   responsive.js stamps each <td> with data-label from its <th>;
   the label renders to the left of the value. Wide editor tables
   (line-items etc.) keep their own scroll container instead.
   ============================================================ */
/* Wide data tables get an intentional horizontal scroll on tablet. */
@media (max-width: 1024px) {
  .panel-body, .fc-panel-body, .fc-main, .ob-table-wrap, .inv-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

@media (max-width: 767px) {
  table.tbl, table.tbl thead, table.tbl tbody, table.tbl tr,
  table.tbl td, table.tbl tbody th {
    display: block !important;
  }
  table.tbl { min-width: 0 !important; width: 100%; }
  /* Header row is removed — each cell carries its own data-label (set by
     responsive.js), so the column titles render inline beside the values. */
  table.tbl thead { display: none !important; }
  table.tbl tbody tr {
    border: 1px solid var(--line) !important; border-radius: var(--r) !important;
    margin-bottom: 10px; background: var(--surface) !important;
    box-shadow: var(--sh-soft, var(--sh-1)); overflow: hidden;
  }
  table.tbl tbody tr:hover { background: var(--surface) !important; }
  table.tbl td, table.tbl tbody th {
    display: flex !important; justify-content: space-between; align-items: center; gap: 14px;
    padding: 9px 13px !important; text-align: right !important;
    border: 0 !important; border-bottom: 1px solid var(--line-2) !important;
    font-size: .88rem; font-weight: 400; white-space: normal !important;
    width: auto !important; max-width: 100% !important;
  }
  table.tbl tbody tr td:last-child, table.tbl tbody tr th:last-child { border-bottom: 0 !important; }
  table.tbl td::before, table.tbl tbody th::before {
    content: attr(data-label); flex: 0 0 40%; text-align: left;
    font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    color: var(--ink-mute); align-self: center;
  }
  /* Action / unlabeled cells: no label, content right-aligned & wrappable. */
  table.tbl td[data-label=""]::before, table.tbl td:not([data-label])::before { content: ""; flex: 0; }
  table.tbl td[data-label=""], table.tbl td:not([data-label]) { justify-content: flex-end; flex-wrap: wrap; gap: 6px; }
  /* Reset min-widths that would otherwise force overflow. */
  .inv-tbl, .fin-exp-tbl, .fin-po-tbl, .fc-exp-tbl, .pipe-tbl { min-width: 0 !important; }
  /* Right-aligned money cells stay right; that's already the value side. */
  table.tbl td.row-num { font-weight: 700; color: var(--ink); }

  /* Tables that are genuinely matrices (mapping/line-item editors) keep
     a scroll container rather than cardifying. */
  .set-notif-table, .li-table, .pn-items, .ho-items, .co-table { display: table !important; }
  .set-notif-wrap, .li-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ============================================================
   8 · MODALS · SHEETS · FORMS  (MobileDrawer/Sheet · FormLayout)
   Phone: centred dialogs become bottom sheets with a sticky
   footer and single-column forms.
   ============================================================ */
@media (max-width: 767px) {
  .modal, .modal.wide {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; max-width: 100%; max-height: 94dvh;
    transform: none;
    border-radius: var(--sheet-radius) var(--sheet-radius) 0 0;
    animation: rspSheetUp .26s cubic-bezier(.2,.7,.3,1);
    padding-bottom: var(--safe-b);
  }
  /* Grab-handle affordance. */
  .modal-head { position: sticky; top: 0; z-index: 3; background: var(--surface); padding-top: 20px; }
  .modal-head::before {
    content: ""; position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
    width: 38px; height: 4px; border-radius: var(--pill); background: var(--line);
  }
  .modal-foot {
    position: sticky; bottom: 0; z-index: 3; background: var(--surface);
    flex-wrap: wrap; padding-bottom: calc(16px + var(--safe-b));
    box-shadow: 0 -6px 18px rgba(20,18,12,.06);
  }
  .modal-foot .btn { flex: 1 1 auto; }
  .modal-body { padding: 16px; }
  .form-row, .form-row.three { grid-template-columns: 1fr; }
  .input, .select, .textarea { font-size: 16px; }   /* prevents iOS zoom-on-focus */
}
@keyframes rspSheetUp { from { transform: translateY(100%); } to { transform: none; } }

/* Opt-in sheet utility for any future overlay. */
@media (max-width: 767px) {
  .rsp-sheet { border-radius: var(--sheet-radius) var(--sheet-radius) 0 0 !important; }
}

/* ============================================================
   9 · TYPOGRAPHY SCALE
   Consistent hierarchy; no giant headings on phone, no tiny labels.
   ============================================================ */
@media (max-width: 1024px) {
  .page-title { font-size: 1.4rem; }
}
@media (max-width: 767px) {
  .page-title { font-size: 1.25rem; }
  .page-sub { font-size: .9rem; }
  .fc-sec-head h2, .gf-title-row h1, .ge-title-row h1 { font-size: 1.18rem; }
  .ph-name, .client-hero h1, .project-hero h1 { font-size: 1.3rem; }
  h1 { font-size: clamp(1.7rem, 7vw, 2.2rem); }
  h2 { font-size: clamp(1.4rem, 5.5vw, 1.8rem); }
  h3 { font-size: 1.12rem; }
  /* Big numeric stats: readable, not oversized. */
  .sc-num, .statc .sc-num, .stat-num, .kpi-num { font-size: clamp(1.3rem, 6vw, 1.6rem) !important; }
}

/* ============================================================
   10 · BADGES · CHIPS · ALERTS · EMPTY STATES · AI INSIGHTS
   Wrap cleanly, never warp, never overflow the right edge.
   ============================================================ */
/* Pills/badges keep their shape — never stretched by flex. */
.badge, .count-pill, .ob-tab-count, .gf-score-badge, .health-pill,
.set-chip, .badge.pos, .badge.neg, .badge.warn, .badge.gray, .badge.gold {
  flex: 0 0 auto; width: auto; white-space: nowrap;
}
.count-pill, .ob-tab-count { display: inline-flex; align-items: center; justify-content: center; }

@media (max-width: 767px) {
  /* Chip/badge rows wrap instead of clipping. */
  .pd-sub, .gf-chiprow, .gf-signal-row, .meta-row, .proj-meta,
  .ph-meta, .badge-row, .fc-alert-row, .fin-type-checks {
    flex-wrap: wrap;
  }
  /* AI insight rows: icon stays, text wraps, nothing hits the right edge. */
  .fc-ai-insight, .gf-insight, .ge-rec-row, .ge-nba, .alert {
    flex-wrap: wrap; align-items: flex-start;
  }
  .fc-ai-insight span, .ge-nba-text { flex: 1 1 100%; min-width: 0; }

  /* Empty states centre and stack. */
  .empty-cta, .empty-state, .access-lock {
    margin: 28px auto; padding: 28px 18px; text-align: center;
  }
  .empty-cta-actions, .access-lock-actions { flex-wrap: wrap; justify-content: center; }
  .empty-cta-actions .btn { flex: 1 1 auto; }
}

/* ============================================================
   11 · MODULE-SPECIFIC POLISH
   Targeted fixes for the screens called out in the brief.
   ============================================================ */

/* ---- Finance console: left rail → top scroll-nav on phone ---- */
@media (max-width: 767px) {
  .fc-console { grid-template-columns: minmax(0, 1fr); border-radius: var(--r); }
  .fc-side { border-right: 0; border-bottom: 1px solid var(--line); padding: 8px; position: sticky; top: 0; z-index: 5; background: var(--surface-2); }
  .fc-nav { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; gap: 4px; }
  .fc-nav::-webkit-scrollbar { display: none; }
  .fc-nav-sect { display: none; }                       /* section labels collapse on the strip */
  .fc-nav-item { flex: 0 0 auto; width: auto; white-space: nowrap; border-radius: var(--pill); padding: 8px 13px; gap: 7px; }
  .fc-nav-item .fc-nav-lbl { display: inline; }
  .fc-nav-item.on::before { display: none; }
  .fc-main { padding: 16px 14px 26px; }
  /* "Upload Receipt" / "Add Expense" toolbar buttons stack/compress. */
  .fc-toolbar { gap: 8px; }
  .fc-toolbar .btn { flex: 1 1 auto; }
  /* Status badges keep their pill shape (no stretch). */
  .fc-exp-tbl .badge, .fin-exp-tbl .badge { white-space: nowrap; }
}

/* ---- Settings console: rail → wrapped chips (already 900); refine touch ---- */
@media (max-width: 900px) {
  .set-search input, .set-search .input { width: 100%; }
  .set-nav-i { padding: 9px 12px; }
}
@media (max-width: 767px) {
  .set-main { padding: 0; }
  .set-panel { padding: 16px; }
  .set-row { flex-direction: column; align-items: flex-start; gap: 8px; }
  .set-row .switch, .set-row .select, .set-row .input { align-self: stretch; }
  .set-grid, .set-cards { grid-template-columns: 1fr; }
}
@media (min-width: 481px) and (max-width: 767px) {
  /* Two-up settings categories where width allows. */
  .set-grid, .set-cards { grid-template-columns: repeat(2, 1fr); }
}

/* ---- Project detail: hero stacks, metadata wraps, progress scales ---- */
@media (max-width: 1024px) { .project-grid { grid-template-columns: 1fr; } }
@media (max-width: 767px) {
  .project-hero { flex-direction: column; align-items: stretch; }
  .ph-actions { width: 100%; }
  .ph-actions .btn { flex: 1 1 auto; }
  .ph-meta, .proj-meta, .ph-facts { flex-wrap: wrap; gap: 8px 14px; }
  .ph-progress, .progress, .progress-bar { width: 100%; }
  .proj-actions { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 380px) { .proj-actions { grid-template-columns: 1fr; } }

/* ---- Proofing review drawer: stack stage over rail on tablet/phone ---- */
@media (max-width: 1024px) {
  .pd-main { flex-direction: column; }
  .pd-stage { min-height: 48dvh; }
  .pd-side, .pd-rail, .pd-panel { width: 100% !important; flex: none !important; border-left: 0 !important; border-top: 1px solid var(--line-2); }
}
@media (max-width: 767px) {
  .pd-head { flex-wrap: wrap; gap: 8px; }
  .pd-head-actions { width: 100%; justify-content: flex-end; }
  .pd-clientbar { flex-wrap: wrap; }
}

/* ---- Pipeline board: horizontal scroll lanes on phone ---- */
@media (max-width: 767px) {
  .pipe-board, .kanban, .kanban-cols { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .pipe-board > *, .kanban-col { flex: 0 0 86%; }
}

/* ---- Outbound / Growth cards ---- */
@media (max-width: 767px) {
  .ob-card-grid, .gf-list, .gf-results { grid-template-columns: 1fr; }
  .gf-prov-row { flex-wrap: nowrap; }
}

/* ---- Brand Kit ---- */
@media (max-width: 767px) {
  .logo-slots, .palette-grid, .font-grid, .typo-grid { grid-template-columns: 1fr; }
  .swatch-grid { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }
}

/* ============================================================
   12 · SMALL-PHONE TIGHTENING  (≤380px)
   ============================================================ */
@media (max-width: 380px) {
  :root { --view-px: 12px; --card-px: 12px; }
  .topbar { gap: 4px; }
  .btn { padding-left: 12px; padding-right: 12px; }
  table.tbl td::before { flex-basis: 46%; }
}
