/* ============================================================================
   MOBILE UNIFIED — Consolidation Sprint / Day 11-12
   Merge of 6 page-scoped mobile_*.css files loaded via <link media=768px>.
   Source order preserved (gantt → tables → meetings → dashboard → projects
   → tasks). Each file's original content is wrapped in a section-comment so
   grep for 'MOBILE_GANTT' etc. still lands in the right place.
   Internal @media queries (~8 of them) are kept as-is; they run inside this
   file's outer 768px gate at HTML-link time.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   MOBILE_GANTT — ported verbatim from static/css/v3/mobile_gantt.css
   ══════════════════════════════════════════════════════════════════════════ */

/* ============================================================================
 * MOBILE GANTT — Wave 7 / Agent A5
 * Loaded with media="(max-width: 768px)" from <head>.
 * Targets .tg-* selectors from static/css/v2/tree-gantt.css.
 * No JS; CSS-only behaviour. Container queries used where supported (Safari
 * iOS 16+ / Chrome 105+). Class fallback path documented at bottom of file.
 * ==========================================================================*/


/* ── 1. Stop hiding the right column on mobile ──────────────────────────────
 * Legacy tree-gantt.css hides .tg-right at <760px. We override: keep the
 * timeline visible but force horizontal scroll + sticky left task names. */
.tg-wrap {
  flex-direction: row;            /* override stack-mode from legacy */
  max-height: calc(100vh - 180px);
  min-height: 320px;
  position: relative;
  /* Establish a containment context so we can address children with
   * container queries (progressive enhancement; ignored when unsupported). */
  container-type: inline-size;
  container-name: tg;
}

.tg-left {
  /* Narrower fixed-width "task name" rail on mobile */
  flex: 0 0 160px;
  min-width: 140px;
  max-width: 180px;
  /* Hard-stick to the left edge with shadow indicator */
  position: sticky;
  left: 0;
  z-index: 4;
  background: var(--surface, var(--surface));
  /* Right-edge shadow indicates more content to the right (scroll affordance) */
  box-shadow: 6px 0 8px -6px rgba(15, 15, 30, 0.18);
  border-right: 1px solid var(--border, var(--border));
}

.tg-right {
  display: block;                 /* override legacy 'display:none' */
  overflow-x: auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}


/* ── 2. Sticky header on mobile (project / timeline label rails) ──────────── */
.tg-header,
.tg-timeline-header {
  height: 36px;
  font-size: 10px;
}

.tg-month {
  /* Slight tap-friendly padding so user can scroll-grab between months */
  padding: 0 6px;
}


/* ── 3. Tap-friendly rows + bars ──────────────────────────────────────────── */
.tg-row {
  /* Match bar-row height for alignment */
  height: 40px;
  font-size: 12.5px;
  padding: 0 8px;
  gap: 4px;
}

.tg-row[data-level="epic"]    { padding-left: 20px; }
.tg-row[data-level="task"]    { padding-left: 32px; font-size: 12px; }
.tg-row[data-level="subtask"] { padding-left: 44px; font-size: 11.5px; }

.tg-row .tg-meta { display: none; }   /* hide secondary date column at <=768 */

.tg-bar-row {
  height: 40px;
}

/* Bars: taller (24px) and pinch-friendly. */
.tg-bar {
  height: 24px;
  top: 8px;
  font-size: 11px;
  padding: 0 8px;
  /* Minimum 44px wide so even short tasks remain tappable */
  min-width: 44px;
  border-radius: 6px;
}
.tg-bar[data-level="project"] {
  height: 28px;
  top: 6px;
}
.tg-bar[data-level="epic"] {
  height: 22px;
  top: 9px;
}


/* ── 4. Today line — stronger on mobile so it's never missed ─────────────── */
.tg-today-line {
  width: 3px;
  opacity: 0.9;
  box-shadow: 0 0 0 1px rgba(220, 38, 38, 0.18);
}
.tg-today-line::before {
  font-size: 10px;
  padding: 2px 7px;
  top: -18px;
  font-weight: 800;
}


/* ── 5. Density / readability when chevrons & icons are present ──────────── */
.tg-row .tg-chevron,
.tg-row .tg-icon {
  width: 12px;
  height: 12px;
}


/* ── 6. Container-query scale-down (progressive enhancement) ───────────────
 * If the gantt wrap is itself in a narrow container (e.g. side-panel split
 * on tablet portrait), tighten further. Browsers without @container support
 * silently skip this block; the @media rules above still apply. */
@container tg (max-width: 520px) {
  .tg-left { flex: 0 0 132px; min-width: 120px; }
  .tg-bar { font-size: 10.5px; padding: 0 6px; min-width: 40px; }
}


/* ── 7. Tap-target floor (WCAG 2.5.5) ─────────────────────────────────────── */
.tg-row,
.tg-bar {
  /* The visual height is set above; this guarantees the *hit region*
   * via a pseudo-element overlay even when bars are visually shorter. */
  position: relative;
}
.tg-bar::before {
  content: "";
  position: absolute;
  inset: -10px 0;            /* extend hit box vertically only */
  pointer-events: auto;
}


/* ── 8. Horizontal-scroll edge shadow hint on .tg-right ─────────────────────
 * Tells the user "more content to the right" when content overflows.
 * Using a sticky pseudo on the timeline. */
.tg-right::before {
  /* Right-edge gradient stays put while content scrolls underneath. */
  content: "";
  position: sticky;
  top: 0;
  right: 0;
  float: right;
  width: 18px;
  height: 100%;
  pointer-events: none;
  background: linear-gradient(
    to left,
    rgba(15, 15, 30, 0.14) 0%,
    rgba(15, 15, 30, 0) 100%
  );
  z-index: 3;
}


/* ── 9. FALLBACK INSTRUCTIONS (no JS toggle available) ─────────────────────
 * Gantt scale (day-pixel-width) is set inline by static/js/app.js via the
 * --tg-day-width custom property; CSS cannot reliably re-scale the
 * pre-rendered bars at the @media boundary. Recommendation for future
 * Wave 8 follow-up: have app.js read window.matchMedia('(max-width:768px)')
 * once at render time and emit a coarser month-scale (4px/day) layout. The
 * sticky-left rail + horizontal scroll below makes the current
 * week/day-scale layout usable on phones until then.
 * ────────────────────────────────────────────────────────────────────────── */


/* ── 10. Sub-tab toolbar for Gantt page — iOS-zoom guards only ──────────────
   Wave 17 / Agent 7 (A): #page-gantt .toolbar { flex-wrap:wrap; gap:8px }
   removed — mobile.css ≤600px lines 405-408 provides generic .toolbar
   wrap. We keep only the page-scoped tap-target + iOS-zoom-prevention
   refinement below (mobile.css's pointer:coarse block sets 16px on
   inputs but not specifically on filter-select / search-input here). */
#page-gantt .filter-select,
#page-gantt .search-input {
  min-height: 44px;            /* WCAG SC 2.5.5 */
  font-size: 16px;             /* prevent iOS zoom on focus */
}


/* ── 11. Dark-mode parity for sticky shadow ───────────────────────────────── */
[data-theme="dark"] .tg-left {
  box-shadow: 6px 0 8px -6px rgba(0, 0, 0, 0.55);
}
[data-theme="dark"] .tg-right::before {
  background: linear-gradient(
    to left,
    rgba(0, 0, 0, 0.45) 0%,
    rgba(0, 0, 0, 0) 100%
  );
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE_TABLES — ported verbatim from static/css/v3/mobile_tables.css
   ══════════════════════════════════════════════════════════════════════════ */

/* ============================================================================
 * MOBILE TABLES — Wave 7 / Agent A5
 * Loaded with media="(max-width: 768px)" from <head>.
 * Targets every table enhanced by static/js/modules/table_superpowers.js
 * (it adds the .tw-sortable class to all <table>s in .table-wrap).
 *
 * Strategy: wide data tables on phones cannot fit 5+ columns; we
 *   (a) hide columns 4+ visually with display:none,
 *   (b) keep cols 1-3 sticky-left so identity stays anchored,
 *   (c) provide a horizontal scroll affordance with edge shadow,
 *   (d) prepend an inline hint "Tap row to see all fields" above each
 *       sortable table via ::before on .table-wrap (no JS required).
 *
 * Wave 17 / Agent 7 (A): Dead-rule audit vs canonical mobile.css.
 * Removed the generic .table-wrap { overflow-x:auto } block — mobile.css
 * ≤900px already provides that. We still add a sticky-edge ::after shadow
 * here (surface-specific affordance for the sortable variant).
 * Also removed the generic table.tw-sortable width/min-width — covered by
 * mobile.css's `.table-wrap > table { width:max-content; min-width:100% }`.
 * ==========================================================================*/


/* ── 1. Card-mode hint banner above every .tw-sortable container ──────────── */
.table-wrap:has(table.tw-sortable)::before {
  content: "Tap row to see all fields  ›  Scroll sideways for more columns";
  display: block;
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--muted, #6B6B70);
  background: var(--bg, #FAFAF7);
  border-bottom: 1px solid var(--border, var(--border));
  letter-spacing: 0.01em;
}

/* Browsers without :has() (Firefox < 121 ESR) silently skip the banner.
 * The functional behaviour (hidden columns, sticky cols, scroll) still
 * applies via the rules below. */


/* ── 2. Right-edge shadow hint = "more columns this way" ──────────────────
   SURFACE-SPECIFIC: the .table-wrap horizontal-scroll behaviour itself
   lives in mobile.css ≤900px lines 227-238. We only add the gradient
   shadow indicator here. position:relative is required as the anchor
   for the sticky ::after pseudo. */
.table-wrap {
  position: relative;
}
.table-wrap::after {
  content: "";
  position: sticky;
  right: 0;
  top: 0;
  float: right;
  width: 14px;
  height: 100%;
  margin-left: -14px;
  pointer-events: none;
  background: linear-gradient(
    to left,
    rgba(15, 15, 30, 0.14) 0%,
    rgba(15, 15, 30, 0) 100%
  );
  z-index: 2;
}


/* ── 3. Table base: separate borders required for sticky-cell bg paint ────
   border-collapse is the only rule here that survives the audit: mobile.css
   gives `width:max-content; min-width:100%` to .table-wrap > table already,
   which covers .tw-sortable. We need `border-collapse: separate` so the
   sticky-left columns below can paint their own backgrounds (collapsed
   borders share cell bg-paint with neighbours and break sticky offsets). */
.table-wrap table.tw-sortable {
  border-collapse: separate;
  border-spacing: 0;
}


/* ── 4. Hide low-priority columns (col 4 onwards) on mobile ───────────────── */
.table-wrap table.tw-sortable thead th:nth-child(n+4),
.table-wrap table.tw-sortable tbody td:nth-child(n+4) {
  display: none;
}

/* Escape hatch: opt a table out with class="tw-no-mobile-collapse" */
.table-wrap table.tw-sortable.tw-no-mobile-collapse thead th,
.table-wrap table.tw-sortable.tw-no-mobile-collapse tbody td {
  display: table-cell;
}


/* ── 5. Sticky-left columns (1, 2, 3) so identity is always visible ───────── */
.table-wrap table.tw-sortable thead th:nth-child(1),
.table-wrap table.tw-sortable tbody td:nth-child(1) {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface, var(--surface));
  /* Right-edge shadow so user sees the boundary while scrolling */
  box-shadow: 4px 0 6px -4px rgba(15, 15, 30, 0.15);
}

.table-wrap table.tw-sortable thead th:nth-child(2),
.table-wrap table.tw-sortable tbody td:nth-child(2) {
  position: sticky;
  left: 96px;                    /* approx width of col 1 on mobile */
  z-index: 2;
  background: var(--surface, var(--surface));
}

.table-wrap table.tw-sortable thead th:nth-child(3),
.table-wrap table.tw-sortable tbody td:nth-child(3) {
  position: sticky;
  left: 188px;                   /* col 1 (~96) + col 2 (~92) */
  z-index: 2;
  background: var(--surface, var(--surface));
  box-shadow: 4px 0 6px -4px rgba(15, 15, 30, 0.15);
}

/* Header cells need a slightly different sticky-top so they stack atop body */
.table-wrap table.tw-sortable thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--surface-soft, var(--border-soft));
}
.table-wrap table.tw-sortable thead th:nth-child(1) { z-index: 4; left: 0; }
.table-wrap table.tw-sortable thead th:nth-child(2) { z-index: 4; left: 96px; }
.table-wrap table.tw-sortable thead th:nth-child(3) { z-index: 4; left: 188px; }


/* ── 6. Hover-row background must respect sticky bg ───────────────────────── */
.table-wrap table.tw-sortable tbody tr:hover td:nth-child(-n+3) {
  background: var(--bg-hover, #F0EDE5);
}


/* ── 7. Tap-target floor (WCAG SC 2.5.5) — .tw-sortable-specific ───────────
   mobile.css ≤900px line 239-243 sets generic .table-wrap thead th/tbody td
   to padding:10px 12px / font-size:12.5px. We *intentionally* override here
   with 12px 10px to give ~44px row height for the sortable variant — kept
   as a surface-specific refinement, not a duplicate. */
.table-wrap table.tw-sortable tbody td {
  padding: 12px 10px;
  font-size: 13px;
  line-height: 1.35;
}
.table-wrap table.tw-sortable thead th {
  padding: 10px 10px;
  font-size: 11.5px;
}

/* Force any action buttons inside data tables to be ≥ 30x30 visually, but
 * extend their hit area to 44x44 via a transparent pseudo. */
.table-wrap table.tw-sortable td .btn,
.table-wrap table.tw-sortable td .iconbtn,
.table-wrap table.tw-sortable td .mtg-icon-btn {
  min-width: 30px;
  min-height: 30px;
  position: relative;
}
.table-wrap table.tw-sortable td .btn::after,
.table-wrap table.tw-sortable td .iconbtn::after,
.table-wrap table.tw-sortable td .mtg-icon-btn::after {
  content: "";
  position: absolute;
  inset: -7px;                   /* 30 + 7*2 = 44 hit-target */
  pointer-events: auto;
}


/* ── 8. Action-cell wrapper (used in meetings + tables) ───────────────────── */
.action-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
}
.action-cell .btn,
.action-cell .iconbtn,
.action-cell .mtg-icon-btn {
  min-width: 30px;
  min-height: 30px;
}


/* ── 9. Dark-mode sticky-column backgrounds ───────────────────────────────── */
[data-theme="dark"] .table-wrap table.tw-sortable thead th,
[data-theme="dark"] .table-wrap table.tw-sortable tbody td:nth-child(-n+3) {
  background: var(--surface, var(--border-soft));
}
[data-theme="dark"] .table-wrap table.tw-sortable thead th {
  background: var(--surface-soft, var(--text));
}
[data-theme="dark"] .table-wrap::after {
  background: linear-gradient(
    to left,
    rgba(0, 0, 0, 0.45) 0%,
    rgba(0, 0, 0, 0) 100%
  );
}
[data-theme="dark"] .table-wrap table.tw-sortable tbody tr:hover td:nth-child(-n+3) {
  background: var(--bg-hover, #2A2A2F);
}


/* ── 10. Sort-arrow row in <thead> needs taller hit area on mobile ────────── */
.table-wrap table.tw-sortable thead th {
  min-height: 44px;
}


/* ── 11. Tighter pagination + result count placement ──────────────────────── */
.table-wrap + #dashRiskPagination,
.table-wrap + #dashOverduePagination,
.table-wrap + .pagination {
  padding: 8px 12px;
  font-size: 12px;
}

/* Removed (Wave 17, Agent 7 A — duplicates of mobile.css):
 *   - .table-wrap { overflow-x:auto; overflow-y:visible;
 *                   -webkit-overflow-scrolling:touch; }
 *     → mobile.css ≤900px lines 228-233 already provides
 *       `overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch;
 *        max-width:100%`. We keep only `position:relative` for ::after anchor.
 *   - .table-wrap table.tw-sortable { width:max-content; min-width:100% }
 *     → mobile.css ≤900px lines 234-238 covers it for `.table-wrap > table`,
 *       which matches `.tw-sortable` (it IS a > table descendant).
 *   - [id$="Pagination"] flex-wrap → mobile.css ≤900px lines 246-250.
 */

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE_MEETINGS — ported verbatim from static/css/v3/mobile_meetings.css
   ══════════════════════════════════════════════════════════════════════════ */

/* ============================================================================
 * MOBILE MEETINGS + CHART-CARD GRID — Wave 7 / Agent A5
 * Loaded with media="(max-width: 768px)" from <head>.
 *
 * Covers:
 *   - .chart-card variant used as meeting card (#meetingsList children)
 *   - Meeting action buttons (.mtg-icon-btn) — 30x30 visual / 44x44 hit
 *   - The meeting detail expansion (mtgDetail_*) action-cells
 *
 * Wave 17 / Agent 7 (A): Dead-rule audit vs canonical mobile.css.
 * Removed:
 *   - generic .dash-grid-* 1-col stack (mobile.css ≤900px handles it)
 *   - generic .chart-card padding/header — overlapped with mobile.css ≤900px
 *     .chart-card padding rule; kept only meetings-scoped variants.
 *   - generic .kpi-grid / .summary-strip rules (mobile.css ≤600px handles)
 *   - generic .charts-grid / [class*="chart-cards"] (covered by ≤900px
 *     .dash-grid stack — and we no longer want a duplicate generic rule)
 *   - generic toolbar wrap (mobile.css ≤600px provides .toolbar wrap +
 *     full-width search). Page-scoped #page-meetings rules retained where
 *     they tune iOS zoom-prevention / min-height for tap targets.
 * ==========================================================================*/


/* ── 1. Meeting list card (uses .chart-card class) — single-column body ─────
   SURFACE-SPECIFIC: #meetingsList chart-cards are individual meeting cards,
   not the generic chart-card chrome. Tighter margin + padding here is
   meetings-only and does not duplicate mobile.css's generic .chart-card. */
#meetingsList .chart-card {
  margin-bottom: 10px;
  padding: 12px;
}

/* The meeting card header is a flex row with title + action-cell.
 * On mobile the action-cell wraps below the title for breathing room. */
#meetingsList .chart-card > div:first-child {
  flex-wrap: wrap;
  gap: 10px;
}

#meetingsList .chart-card > div:first-child > div:first-child {
  flex: 1 1 100%;
  min-width: 0;
}

#meetingsList .chart-card .action-cell {
  flex: 0 0 auto;
  margin-left: auto;
}


/* ── 2. Meeting card action buttons — 30x30 visual, 44x44 hit-target ──────── */
.mtg-icon-btn,
#meetingsList .chart-card .btn-sm,
#meetingsList .chart-card .btn {
  min-width: 30px;
  min-height: 30px;
  padding: 6px 8px;
  position: relative;
}

.mtg-icon-btn::after,
#meetingsList .chart-card .btn-sm::after {
  content: "";
  position: absolute;
  inset: -7px;                   /* 30 + 14 = 44 hit-target — WCAG SC 2.5.5 */
  pointer-events: auto;
}


/* ── 3. Meeting detail (expanded) — action item rows ──────────────────────── */
#meetingsList [id^="mtgDetail_"] {
  font-size: 12.5px;
}

#meetingsList [id^="mtgDetail_"] .action-cell {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Action items inside expanded detail are horizontally cramped on mobile;
 * relax them into a 2-row layout: text + meta on top, controls below */
#meetingsList [id^="mtgActions_"] > div {
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 6px 10px;
}
#meetingsList [id^="mtgActions_"] > div > span:nth-child(2) {
  flex: 1 1 100%;
  order: 2;
}
#meetingsList [id^="mtgActions_"] > div > .action-cell {
  order: 3;
  margin-left: auto;
}


/* ── 4. Meetings toolbar — page-scoped iOS-zoom guards ──────────────────────
   mobile.css ≤600px already gives `.toolbar { flex-wrap:wrap; gap:8px }`
   and full-width search. We keep these page-scoped rules ONLY for the
   min-height:44px / font-size:16px tap-target + iOS zoom-prevention
   tuning that mobile.css's pointer:coarse block does at a different
   specificity — kept here to win cascade on this page. */
#page-meetings .search-input {
  min-height: 44px;
  font-size: 16px;               /* prevent iOS Safari zoom-on-focus */
}
#page-meetings #btnAddMeeting {
  min-height: 44px;
}


/* ── 5. Dark-mode shadow parity ───────────────────────────────────────────── */
[data-theme="dark"] .chart-card {
  background: var(--surface, var(--border-soft));
}

/* Removed (Wave 17, Agent 7 A — duplicates of mobile.css):
 *   - .dash-grid-70-30 / .dash-grid-2 / .dash-grid-3 / .dash-grid-2col
 *     1-col stack  → see mobile.css ≤900px lines 120-125.
 *   - generic .chart-card padding/header/title typography
 *     → mobile.css ≤900px line 219-225 covers .chart-card padding.
 *   - canvas height-cap [style*="height:NNNpx"] — kept locally in
 *     mobile_dashboard.css since it is dashboard-only.
 *   - .kpi-grid repeat(2,1fr) + .summary-strip 1fr
 *     → mobile.css ≤900px lines 127-135 (KPI 2-col / strip 2-col) and
 *       mobile.css ≤600px lines 268-278 (KPI/strip 1-col).
 *   - .charts-grid / .chart-grid / [class*="chart-cards"] generic stack
 *     → fall back to mobile.css ≤900px dash-grid behaviour.
 *   - #page-meetings .toolbar wrap + .search-box full-width
 *     → mobile.css ≤600px lines 405-414.
 */

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE_DASHBOARD — ported verbatim from static/css/v3/mobile_dashboard.css
   ══════════════════════════════════════════════════════════════════════════ */

/* ============================================================
   mobile_dashboard.css — Wave 7 Agent A4
   Scope: #page-dashboard at ≤768px (loaded via media gate in <link>)
   Goal:  1-col KPI stack, charts snap-scroll horizontally,
          AI Summary / strip moves below KPIs, no inner horizontal
          overflow at 375×812 portrait or 812×375 landscape.
   Notes: All rules are scoped to #page-dashboard to avoid bleeding
          into other pages. We rely on existing v2 dashboard tokens
          (--space-*, --surface, --border, --radius-*).

   Wave 17 / Agent 7 (A): Dead-rule audit vs canonical mobile.css.
   Removed generic-grid duplicates (.kpi-grid 1-col stack, .summary-strip
   single-col, modal full-screen) that mobile.css now handles at ≤600px.
   Kept #page-dashboard-scoped rules that carry surface-specific behaviour
   (chart-card snap carousel, KPI typography, summary-strip card chrome).
   ============================================================ */

/* ── KPI grid (page-scoped) ──
   mobile.css ≤600px already collapses .kpi-grid to 1fr globally. We
   keep the page-scoped override only for the comfortable touch-card
   heights & kpi-value typography below — the grid-template repeat lives
   in mobile.css. */
#page-dashboard .kpi-card{
  padding:14px 16px;
  min-height:88px;
}

/* Tighten huge KPI numbers so single-col cards stay readable */
#page-dashboard .kpi-card .kpi-value,
#page-dashboard .kpi-card .value{
  font-size:30px;
  line-height:1.05;
}
#page-dashboard .kpi-card .kpi-label,
#page-dashboard .kpi-card .label{
  font-size:11px;
  letter-spacing:.06em;
}

/* ── Summary strip (AI Summary slot) — page-scoped card chrome ──
   mobile.css ≤600px collapses .summary-strip grid to 1fr globally;
   what's page-specific here is the card-chrome treatment (surface bg,
   border, radius, padding). Grid-template removed (duplicate). */
#page-dashboard .summary-strip{
  order:1; /* keep below KPIs even when parents become flex */
  margin:0 0 16px 0;
  padding:0;
}
#page-dashboard .summary-strip > *{
  background:var(--surface,var(--surface));
  border:1px solid var(--border,#e5e7eb);
  border-radius:12px;
  padding:12px 14px;
}

/* ── Chart cards: horizontal snap-scroll carousel ──
   This is SURFACE-SPECIFIC: dashboard charts become a swipeable strip
   on this page only (other pages with .dash-grid-* should stack — and
   mobile.css ≤900px stacks them). We override that stack here for the
   dashboard to give a carousel UX, so this rule is NOT a duplicate. */
#page-dashboard .dash-grid-70-30,
#page-dashboard .dash-grid-2,
#page-dashboard .dash-grid-3{
  display:flex;
  grid-template-columns:none;
  gap:12px;
  overflow-x:auto;
  overflow-y:hidden;
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  padding:2px 0 12px;
  margin:0 -12px 14px; /* bleed into content padding for edge snap */
  padding-left:12px;
  padding-right:12px;
  scrollbar-width:none;
}
#page-dashboard .dash-grid-70-30::-webkit-scrollbar,
#page-dashboard .dash-grid-2::-webkit-scrollbar,
#page-dashboard .dash-grid-3::-webkit-scrollbar{display:none;}

#page-dashboard .dash-grid-70-30 > *,
#page-dashboard .dash-grid-2 > *,
#page-dashboard .dash-grid-3 > *{
  flex:0 0 88vw;
  max-width:88vw;
  scroll-snap-align:start;
  min-width:0;
}

/* Make chart canvases honor the narrowed parent */
#page-dashboard .chart-card{
  padding:14px;
  border-radius:12px;
}
#page-dashboard .chart-card .chart-header{
  flex-wrap:wrap;
  gap:8px;
  margin-bottom:8px;
}
#page-dashboard .chart-card .chart-title{
  font-size:14px;
  margin-bottom:2px;
}
#page-dashboard .chart-card .chart-subtitle{
  font-size:11px;
  color:var(--muted,#6b7280);
}
#page-dashboard .chart-card canvas{
  max-width:100%;
  height:auto;
}
/* Cap the fixed inline heights some chart wrappers carry */
#page-dashboard .chart-card > div[style*="height:220px"],
#page-dashboard .chart-card > div[style*="height:200px"],
#page-dashboard .chart-card > div[style*="height:190px"],
#page-dashboard .chart-card > div[style*="height:180px"]{
  height:200px;
}

/* ── Tables inside dashboard: keep the horizontal-scroll wrap
       affordance with a fade indicator on the right edge so users
       know there's more content sideways. ── */
#page-dashboard .table-wrap{
  position:relative;
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity;
  border-radius:10px;
}
#page-dashboard .table-wrap::after{
  content:"";
  position:sticky;
  top:0;
  right:0;
  display:block;
  width:24px;
  margin-left:-24px;
  height:100%;
  background:linear-gradient(to right, transparent, var(--surface,var(--surface)));
  pointer-events:none;
}
/* (Agent A5's mobile_tables.css already injects a "Tap row to see all
   fields" banner via .table-wrap:has(table.tw-sortable)::before — we
   defer to that rather than double-stacking our own hint here.) */

/* ── Section title spacing inside the dashboard mobile flow ── */
#page-dashboard .section-title{
  font-size:14px;
  margin:4px 0 8px;
  letter-spacing:.02em;
}

/* ── Landscape phone (812×375): allow 2-up KPIs since width is wide ── */
@media (orientation:landscape) and (max-height:480px){
  #page-dashboard .kpi-grid{
    grid-template-columns:repeat(2,1fr);
  }
  /* Chart strip cards: narrow them so two fit in landscape */
  #page-dashboard .dash-grid-70-30 > *,
  #page-dashboard .dash-grid-2 > *,
  #page-dashboard .dash-grid-3 > *{
    flex:0 0 60vw;
    max-width:60vw;
  }
}

/* ── prefers-reduced-motion: kill snap-scroll animation hints ── */
@media (prefers-reduced-motion:reduce){
  #page-dashboard .dash-grid-70-30,
  #page-dashboard .dash-grid-2,
  #page-dashboard .dash-grid-3{
    scroll-snap-type:none;
    scroll-behavior:auto;
  }
}

/* Modal full-screen rules removed — Wave 17 / Agent 7 (A):
   mobile.css ≤600px already provides full-screen modal with 100dvh,
   safe-area-inset-bottom, sticky header/footer. Duplicate block here
   (.modal-overlay padding 0, .modal border-radius 0 / 100dvh) deleted.
   See mobile.css:365-402 for canonical. */

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE_PROJECTS — ported verbatim from static/css/v3/mobile_projects.css
   ══════════════════════════════════════════════════════════════════════════ */

/* ============================================================
   mobile_projects.css — Wave 7 Agent A4
   Scope: #page-projects at ≤768px (loaded via media gate).
   Goal:  Transform the desktop <table> into a card-style list,
          full-width search, stacked filter controls.
   NOTE:  This file loads AFTER mobile_tables.css (Agent A5) and
          must therefore override its sticky-column/hide-cols rules
          for THIS page only. Selectors below are scoped to
          #page-projects #projectTableFull (or its .table-wrap)
          with higher specificity so they reliably win cascade.
   ============================================================ */

/* ── Toolbar: full-width search, stacked controls ── */
#page-projects .toolbar{
  display:flex;
  flex-direction:column;
  gap:8px;
  align-items:stretch;
  padding:8px 0;
}
#page-projects .toolbar .search-box{
  width:100%;
  max-width:none;
  flex:1 1 100%;
  order:1;
}
#page-projects .toolbar > .filter-select{
  width:100%;
  flex:1 1 100%;
  min-height:44px;
  order:2;
}
#page-projects .toolbar > .result-count{
  order:3;
  font-size:12px;
  padding:4px 0;
  color:var(--muted,#6b7280);
}
#page-projects .toolbar > button{
  order:4;
  width:100%;
  justify-content:center;
  min-height:44px;
}

/* ── Kill the "Tap row to see all fields" banner from A5's
       mobile_tables.css (we're using cards, no horizontal scroll). ── */
#page-projects .table-wrap:has(table.tw-sortable)::before,
#page-projects .table-wrap::before{
  display:none;
  content:none;
}
#page-projects .table-wrap::after{
  display:none;
}

/* ── Reset wrap/table to non-scrolling block ── */
#page-projects .table-wrap{
  overflow:visible;
  background:transparent;
  border:none;
  padding:0;
}

#page-projects #projectTableFull,
#page-projects #projectTableFull.tw-sortable{
  width:100%;
  min-width:0;
  border-collapse:separate;
  border-spacing:0 10px;
  background:transparent;
  display:block;
}

#page-projects #projectTableFull thead{
  display:none;
}

#page-projects #projectTableFull tbody{
  display:block;
  width:100%;
}

/* ── Each row becomes a card ──
   Column order at runtime (table_superpowers.js prepends a checkbox):
     1: tw-bulk-cell (checkbox)
     2: # (idx)
     3: Project (name + description)
     4: PM
     5: PMO
     6: Status
     7: Priority
     8: Progress
     9: Start
    10: End
    11: Actions
   ============================================================ */
#page-projects #projectTableFull tbody tr{
  display:grid;
  grid-template-columns:32px 1fr auto;
  grid-template-areas:
    "check  name    actions"
    "check  idx     idx"
    "status priority priority"
    "progress progress progress"
    "pm     pm       pm"
    "pmo    pmo      pmo"
    "dates  dates    dates";
  gap:6px 10px;
  background:var(--surface,var(--surface));
  border:1px solid var(--border,#e5e7eb);
  border-radius:12px;
  padding:12px 14px;
  margin-bottom:10px;
  box-shadow:0 1px 2px rgba(0,0,0,.03);
  align-items:center;
}

#page-projects #projectTableFull tbody tr.empty-row{
  display:block;
  text-align:center;
  padding:20px;
  color:var(--muted,#6b7280);
}
#page-projects #projectTableFull tbody tr.empty-row td{
  display:block;
  border:none;
  padding:0;
}

/* Override A5 hide-from-col-4 rule for THIS table */
#page-projects #projectTableFull tbody td,
#page-projects #projectTableFull.tw-sortable tbody td{
  display:block;
  border:none;
  padding:0;
  white-space:normal;
  font-size:13px;
  line-height:1.35;
  position:static; /* override sticky from A5 */
  left:auto;
  box-shadow:none;
  background:transparent;
  min-width:0;
}

/* Place cells into grid areas */
#page-projects #projectTableFull tbody td.tw-bulk-cell,
#page-projects #projectTableFull tbody td:nth-child(1){
  grid-area:check;
  display:flex;
  align-items:center;
}
#page-projects #projectTableFull tbody td.tw-bulk-cell input,
#page-projects #projectTableFull tbody td:nth-child(1) input{
  width:18px;
  height:18px;
}

#page-projects #projectTableFull tbody td:nth-child(2){
  grid-area:idx;
  font-family:var(--mono);
  font-size:10px;
  color:var(--muted,#6b7280);
  padding-left:0;
}

#page-projects #projectTableFull tbody td:nth-child(3){
  grid-area:name;
  font-size:15px;
  font-weight:600;
}
#page-projects #projectTableFull tbody td:nth-child(3) > div:first-child{
  font-size:15px;
  font-weight:600;
}
#page-projects #projectTableFull tbody td:nth-child(3) > div:last-child{
  font-size:11px;
  color:var(--muted,#6b7280);
  font-weight:400;
  margin-top:2px;
}

#page-projects #projectTableFull tbody td:nth-child(4){
  grid-area:pm;
  font-size:12px;
}
#page-projects #projectTableFull tbody td:nth-child(4)::before{
  content:"PM: ";
  color:var(--muted,#6b7280);
  font-weight:500;
}

#page-projects #projectTableFull tbody td:nth-child(5){
  grid-area:pmo;
  font-size:12px;
}
#page-projects #projectTableFull tbody td:nth-child(5)::before{
  content:"PMO: ";
  color:var(--muted,#6b7280);
  font-weight:500;
}

#page-projects #projectTableFull tbody td:nth-child(6){
  grid-area:status;
}
#page-projects #projectTableFull tbody td:nth-child(7){
  grid-area:priority;
  justify-self:end;
}

#page-projects #projectTableFull tbody td:nth-child(8){
  grid-area:progress;
  min-width:0;
}

#page-projects #projectTableFull tbody td:nth-child(9),
#page-projects #projectTableFull tbody td:nth-child(10){
  grid-area:dates;
  display:inline-block;
  font-size:11px;
  font-family:var(--mono);
  color:var(--muted,#6b7280);
}
#page-projects #projectTableFull tbody td:nth-child(9)::before{
  content:"Start ";
  color:var(--muted,#6b7280);
  font-family:var(--font-body, system-ui);
  text-transform:uppercase;
  letter-spacing:.04em;
  font-size:10px;
}
#page-projects #projectTableFull tbody td:nth-child(10){
  margin-left:14px;
}
#page-projects #projectTableFull tbody td:nth-child(10)::before{
  content:"End ";
  color:var(--muted,#6b7280);
  font-family:var(--font-body, system-ui);
  text-transform:uppercase;
  letter-spacing:.04em;
  font-size:10px;
}

#page-projects #projectTableFull tbody td:nth-child(11){
  grid-area:actions;
  justify-self:end;
}
#page-projects #projectTableFull tbody td:nth-child(11) .action-cell{
  display:flex;
  gap:6px;
}
#page-projects #projectTableFull tbody td:nth-child(11) .btn{
  min-height:36px;
  min-width:36px;
  padding:6px 8px;
}

/* Hide the desktop sticky-col background for THIS table — we already
   reset td position:static above but make absolutely sure thead is
   gone and no left:N stragglers paint anything. */
#page-projects #projectTableFull.tw-sortable thead th{
  display:none;
  position:static;
}

/* Pagination on mobile: page-scoped centering + padding only.
   Wave 17 / Agent 7 (A): flex-wrap, gap, font-size removed — mobile.css
   ≤900px lines 246-250 provides [id$="Pagination"] { flex-wrap:wrap;
   gap:6px; font-size:12px } generically. We add center+padding here. */
#page-projects #projTablePagination{
  display:flex;
  justify-content:center;
  padding:8px 0;
}

/* ── Landscape (812×375): 2-column card grid ── */
@media (orientation:landscape) and (max-height:480px){
  #page-projects #projectTableFull tbody{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:10px;
  }
  #page-projects #projectTableFull tbody tr{
    margin-bottom:0;
  }
}

/* ── prefers-reduced-motion: no row transition flicker ── */
@media (prefers-reduced-motion:reduce){
  #page-projects #projectTableFull tbody tr{
    transition:none;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE_TASKS — ported verbatim from static/css/v3/mobile_tasks.css
   ══════════════════════════════════════════════════════════════════════════ */

/* ============================================================
   mobile_tasks.css — Wave 7 Agent A4
   Scope: #page-tasks at ≤768px (loaded via media gate).
   Goal:  Kanban becomes a horizontal snap-scroll carousel of
          full-width columns. Drag-drop is preserved (we only
          touch layout, not pointer-events). Visible scroll
          indicator (sticky shadow + column dots stub).

   Wave 17 / Agent 7 (A): Dead-rule audit vs canonical mobile.css.
   Removed the generic .kanban-cols / .kanban-col carousel rules
   (display:flex, overflow-x:auto, scroll-snap, min-width:85vw) —
   mobile.css ≤600px lines 327-341 already provides them globally.
   Kept the #page-tasks-scoped overrides that ONLY apply here
   (gradient mask, viewport bleed margins, taller min-height for
   drag-drop targets, swipe-hint pseudo on the project-block).
   ============================================================ */

/* ── Toolbar above kanban: collapse vertically, full-width search ──
   SURFACE-SPECIFIC: this is a 4-row vertical reorder (search → filter →
   count → button), which mobile.css's generic ≤600px toolbar wrap does
   NOT do (it only allows wrap). The `order:N` cells and column flex
   are page-specific and kept. */
#page-tasks .toolbar{
  display:flex;
  flex-direction:column;
  gap:8px;
  align-items:stretch;
  padding:8px 0;
}
#page-tasks .toolbar .search-box{
  width:100%;
  max-width:none;
  flex:1 1 100%;
  order:1;
}
#page-tasks .toolbar > .filter-select{
  width:100%;
  min-height:44px;
  order:2;
}
#page-tasks .toolbar > .result-count{
  order:3;
  font-size:12px;
  color:var(--muted,#6b7280);
}
#page-tasks .toolbar > button{
  order:4;
  width:100%;
  justify-content:center;
  min-height:44px;
}

/* ── Project block header card: tighter padding on mobile ── */
#page-tasks .kanban-project-card{
  padding:12px 14px;
  gap:10px;
  flex-direction:column;
  align-items:stretch;
}
#page-tasks .kanban-project-card-title{
  font-size:14px;
  flex-wrap:wrap;
  gap:6px;
}
#page-tasks .kanban-project-card-meta{
  font-size:11px;
  gap:8px 12px;
}
#page-tasks .kanban-project-progress{
  flex-direction:row;
  align-items:center;
  gap:10px;
  width:100%;
}
#page-tasks .kanban-project-progress > div:first-child{
  font-size:16px;
  flex:0 0 auto;
}
#page-tasks .kanban-progress-bar{
  flex:1 1 auto;
  height:6px;
}

/* ── Kanban column strip: visual indicator only ──
   SURFACE-SPECIFIC: the underlying carousel mechanics
   (display:flex, overflow-x:auto, scroll-snap-type:x mandatory,
   gap:10px) live in mobile.css ≤600px (lines 327-341). What is
   page-scoped here is the gradient mask-image (fade right edge as
   a scroll affordance) and the negative-margin bleed so the
   first/last column snap aligns with the viewport edge. */
#page-tasks .kanban-cols{
  padding:12px;
  margin:0 -12px;     /* bleed to viewport edge so snap aligns nicely */
  scrollbar-width:none;
  /* Visual indicator: gradient fade on the right edge to hint scroll */
  -webkit-mask-image:linear-gradient(to right, #000 0, #000 calc(100% - 22px), transparent 100%);
          mask-image:linear-gradient(to right, #000 0, #000 calc(100% - 22px), transparent 100%);
}
#page-tasks .kanban-cols::-webkit-scrollbar{display:none;}

/* SURFACE-SPECIFIC: mobile.css gives `.kanban-col { min-width:85vw }`
   but our column needs `flex:0 0 85vw` + `max-width:85vw` to lock
   the basis (mobile.css doesn't set flex-basis explicitly), and
   tighter internal padding override. */
#page-tasks .kanban-col{
  flex:0 0 85vw;
  max-width:85vw;
  padding:12px;
}

/* Task cards full-width inside the column */
#page-tasks .kanban-col .task-card{
  width:100%;
  margin:0 0 8px 0;
  padding:10px 12px;
}
#page-tasks .kanban-col .task-card .task-title,
#page-tasks .kanban-col .task-card .title{
  font-size:13.5px;
  line-height:1.35;
}

/* ── Column "dots" indicator under the strip ──
   We can't add new DOM, but we can use a sticky pseudo-positioned
   gradient cue on .kanban-project-block bottom. A simple persistent
   text affordance suffices for accessibility. */
#page-tasks .kanban-project-block{
  position:relative;
  margin-bottom:20px;
}
#page-tasks .kanban-project-block::after{
  content:"← swipe sideways to see To Do / In Progress / Done →";
  display:block;
  text-align:center;
  font-size:10.5px;
  color:var(--muted,#6b7280);
  padding:4px 8px 8px;
  letter-spacing:.02em;
}

/* ── Drag affordance: bigger touch target on task cards ── */
#page-tasks .kanban-col .task-card{
  min-height:60px;
  -webkit-tap-highlight-color:transparent;
}

/* ── Landscape (812×375): 2-up columns visible at once ── */
@media (orientation:landscape) and (max-height:480px){
  #page-tasks .kanban-col{
    flex:0 0 55vw;
    min-width:55vw;
    max-width:55vw;
  }
  #page-tasks .kanban-project-card{
    flex-direction:row;
    align-items:flex-start;
  }
  #page-tasks .kanban-project-progress{
    width:auto;
    flex-direction:column;
    align-items:flex-end;
  }
}

/* ── prefers-reduced-motion: disable snap animation ── */
@media (prefers-reduced-motion:reduce){
  #page-tasks .kanban-cols{
    scroll-snap-type:none;
    scroll-behavior:auto;
  }
}

/* ── Empty state inside kanban ── */
#page-tasks .kanban-col .empty-state,
#page-tasks #kanbanBoard > .empty-state{
  padding:20px 12px;
  text-align:center;
}

/* Removed (Wave 17, Agent 7 A — duplicates of mobile.css):
 *   - #page-tasks .kanban-cols { display:flex; grid-template-columns:none;
 *       gap:10px; overflow-x:auto; overflow-y:visible;
 *       scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch }
 *     → mobile.css ≤600px lines 328-336 (.kanban-cols rules).
 *     We kept page-scoped padding/margin/mask only.
 *   - #page-tasks .kanban-col { min-width:85vw; scroll-snap-align:start;
 *       flex-shrink:0 }
 *     → mobile.css ≤600px lines 337-341 covers this. We kept
 *       `flex: 0 0 85vw` + max-width as a flex-basis pin.
 */
