/* ═══ Mobile layer — phones ≤ 767px (2026-09-25) ═════════════════════════════
   The same dashboard, reflowed for 320–430px screens. Loaded after lv2.css and
   devbiz-polish.css, so an equal-specificity rule here wins; every rule is
   inside a max-width media query (or a hover:none one), so desktop and the
   ≤900px tablet drawer are untouched. Colours, type, radii and shadows are the
   desktop's own tokens; nothing is restyled, only re-laid.

   Sections: 1 shell (header, bottom bar, sheets) · 2 page frame · 3 KPI and
   card grids · 4 tables · 5 overlays · 6 controls and touch · 7 motion. */

/* One theme, declared: keeps Chrome's Android auto-dark off (see the meta tag in index.html). */
:root{color-scheme:light only}

/* ── 1. Shell ──────────────────────────────────────────────────────────────── */
@media (max-width: 767px){
  html.mb-phone .app-main .topbar{display:none}
  html.mb-phone #dash .app-shell{min-height:100dvh}
  html.mb-phone .app-main{padding:0 0 calc(74px + env(safe-area-inset-bottom, 0px))}

  #mb-header{position:sticky;top:0;z-index:60;display:flex;align-items:center;gap:10px;
    min-height:56px;padding:calc(6px + env(safe-area-inset-top, 0px)) 12px 6px;background:#fff;
    border-bottom:1px solid #EDEFF3}
  #mb-header .mb-logo{height:30px;width:34px;object-fit:contain;flex:none}
  /* "MKT Dashboard ▾" with the unit beneath it — one trigger, one tap target */
  #mb-header .mb-unit{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:1px;
    min-height:44px;padding:4px 8px;margin-left:-4px;border:0;border-radius:10px;background:transparent;
    font:inherit;color:#0F172A;text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent}
  #mb-header .mb-unit:active{background:#F8FAFC}
  #mb-header .mb-unit:focus-visible{outline:2px solid #2563EB;outline-offset:2px}
  #mb-header .mb-unit-t{display:inline-flex;align-items:center;gap:4px;font-size:13px;font-weight:800;letter-spacing:-.2px;line-height:1.2}
  #mb-header .mb-unit-t svg{color:#64748B;flex:none}
  #mb-header .mb-unit-sub{font-size:10.5px;font-weight:700;color:#2563EB;line-height:1.2;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #mb-header .mb-unit.mb-unit-static{cursor:default}
  #mb-header .mb-unit.mb-unit-static .mb-unit-t svg{display:none}
  #mb-header .mb-unit.mb-unit-static .mb-unit-sub{color:#64748B}
  .mb-avatar{flex:none;width:34px;height:34px;border-radius:50%;border:0;background:#EFF4FF;color:#2563EB;
    font:700 11px/1 'Plus Jakarta Sans','Inter',sans-serif;letter-spacing:.3px;display:grid;place-items:center;cursor:pointer;
    -webkit-tap-highlight-color:transparent}
  .mb-avatar:focus-visible{outline:2px solid #2563EB;outline-offset:2px}
  .mb-avatar-lg{width:44px;height:44px;font-size:14px}

  #mb-nav{position:fixed;left:0;right:0;bottom:0;z-index:150;display:grid;grid-template-columns:repeat(var(--mb-cols,4),minmax(0,1fr));
    gap:2px;padding:4px 6px calc(6px + env(safe-area-inset-bottom, 0px));background:#fff;border-top:1px solid #EDEFF3;
    box-shadow:0 -6px 18px rgba(15,23,42,.05)}
  #mb-nav .mb-tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-height:52px;
    border:0;border-radius:10px;background:transparent;color:#64748B;font:600 10px/1 'Plus Jakarta Sans','Inter',sans-serif;
    cursor:pointer;-webkit-tap-highlight-color:transparent;padding:4px 2px}
  #mb-nav .mb-tab-ic{width:36px;height:26px;display:grid;place-items:center;border-radius:8px}
  #mb-nav .mb-tab-t{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #mb-nav .mb-tab.on{color:#2563EB;font-weight:700}
  #mb-nav .mb-tab.on .mb-tab-ic{background:#EFF4FF}
  #mb-nav .mb-tab:focus-visible{outline:2px solid #2563EB;outline-offset:-2px}

  /* the desktop drawer stays wired but is unreachable here (the ☰ lives in the hidden topbar) */
  html.mb-phone .side-open-btn{display:none}

  /* bottom sheets */
  /* [hidden] must win over display:flex, or the closed host is an invisible
     full-screen layer that swallows every tap (found by Satriya, 2026-09-25 —
     JS .click() in the headless checks went straight through it). */
  #mb-sheet-host{position:fixed;inset:0;z-index:1100;display:flex;align-items:flex-end}
  #mb-sheet-host[hidden]{display:none !important}
  #mb-sheet-host .mb-backdrop{position:absolute;inset:0;background:rgba(15,23,42,.34);opacity:0;transition:opacity .18s ease}
  #mb-sheet-host .mb-sheet{position:relative;width:100%;max-height:min(88dvh, 88vh);display:flex;flex-direction:column;background:#fff;
    border-radius:22px 22px 0 0;box-shadow:0 -8px 28px rgba(15,23,42,.09);transform:translateY(100%);transition:transform .22s cubic-bezier(.2,.8,.2,1);
    padding-bottom:env(safe-area-inset-bottom, 0px);outline:0}
  #mb-sheet-host.is-open .mb-backdrop{opacity:1}
  #mb-sheet-host.is-open .mb-sheet{transform:none}
  .mb-sheet-handle{width:36px;height:4px;border-radius:5px;background:#CBD5E1;margin:8px auto 10px;flex:none}
  .mb-sheet-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 16px 10px;flex:none}
  .mb-sheet-head h2{margin:0;font-size:17px;font-weight:800;letter-spacing:-.3px;color:#0F172A}
  .mb-iconbtn{width:36px;height:36px;display:grid;place-items:center;border:0;border-radius:9px;background:#F8FAFC;color:#0F172A;cursor:pointer}
  .mb-iconbtn:focus-visible{outline:2px solid #2563EB;outline-offset:2px}
  .mb-sheet-body{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;padding:0 12px 14px}
  .mb-group{font-size:10.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:#64748B;padding:12px 8px 6px}
  .mb-row{display:flex;align-items:center;gap:12px;width:100%;min-height:50px;padding:8px 10px;border:1px solid transparent;border-radius:12px;
    background:transparent;color:#0F172A;font:inherit;text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent}
  .mb-row:active{background:#F8FAFC}
  .mb-row:focus-visible{outline:2px solid #2563EB;outline-offset:-2px}
  .mb-row.on,.mb-row.selected{background:#EFF4FF;border-color:#DBEAFE}
  .mb-row-ic{flex:none;width:34px;height:34px;border-radius:9px;background:#EFF4FF;color:#2563EB;display:grid;place-items:center}
  .mb-row-ic svg{width:18px;height:18px}
  .mb-row-t{flex:1;min-width:0}
  .mb-row-t b{display:block;font-size:13px;font-weight:700;line-height:1.3}
  .mb-row-t small{display:block;font-size:10.5px;color:#64748B;line-height:1.35;margin-top:2px}
  .mb-row-x{flex:none;color:#94A3B8;display:grid;place-items:center}
  .mb-row.on .mb-row-x,.mb-row.selected .mb-row-x{color:#2563EB}
  .mb-account{display:flex;align-items:center;gap:12px;padding:6px 10px 14px;border-bottom:1px solid #EDEFF3;margin-bottom:6px}
  .mb-account-t{min-width:0}
  .mb-account-t b{display:block;font-size:13px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mb-account-t small{display:block;font-size:10.5px;color:#64748B;margin-top:2px}
  body.mb-sheet-open{overflow:hidden}
}

/* ── 2. Page frame ─────────────────────────────────────────────────────────── */
@media (max-width: 767px){
  html.mb-phone .page,
  html.mb-phone #overview .page,
  html.mb-phone #project-detail .page,
  html.mb-phone #listing-gcc.lv2 .page,
  html.mb-phone .lv2-surface .page,html.mb-phone #mt-dvz .page{padding:0 12px 24px}
  html.mb-phone .home-stickyhead,html.mb-phone .detail-stickyhead{padding-top:10px}
  html.mb-phone .alert{font-size:11px;line-height:1.55;padding:9px 12px}
  html.mb-phone .card-header{flex-wrap:wrap;gap:8px 12px;padding-left:14px;padding-right:14px}
  html.mb-phone .card-body{padding-left:14px;padding-right:14px}
  html.mb-phone .card{min-width:0}
  html.mb-phone :root{--card-pad-x:14px}
  /* every page title at the mockup's phone size */
  html.mb-phone .ui-page-t,html.mb-phone #lgc-title,html.mb-phone .detail-title,html.mb-phone h1.page-title{font-size:22px;letter-spacing:-.6px}
  /* nothing may push the document wider than the phone */
  html.mb-phone,html.mb-phone body{overflow-x:hidden;-webkit-text-size-adjust:100%}
  html.mb-phone .app-main{overflow-x:clip}
  html.mb-phone img,html.mb-phone canvas,html.mb-phone svg{max-width:100%}
  html.mb-phone .chart-card canvas{height:240px !important}
  /* Explanations are for a first read on a desktop. Someone opening the phone
     app already knows the page (Satriya, 2026-09-26) — the how-to lines under
     titles go, the ones that carry a number (#pi-count, #br-count, .tg-sub) stay. */
  html.mb-phone .chart-card-sub,html.mb-phone .card-sub:empty,html.mb-phone .card-sub:not(#pi-count):not(#br-count),
  html.mb-phone .cw-sub,html.mb-phone .md-detail-sub,html.mb-phone #kpi-scope-note,
  html.mb-phone .lv2-panel__s,html.mb-phone .lv2-panel__foot,html.mb-phone .lv2-hint,html.mb-phone .lv2-ctlbar-note,
  html.mb-phone .lgc-note,html.mb-phone .lgc-fn-sub,html.mb-phone .lgc-md-note,html.mb-phone .md-sub,html.mb-phone .ui-page-s,html.mb-phone #lgc-subtitle{display:none !important}
  /* Project Detail hero: controls stack under the title; the Basis switch wraps
     into a pill group instead of running off the right edge */
  html.mb-phone .project-hero{padding:14px 14px 12px}
  html.mb-phone .project-hero > div{min-width:0;max-width:100%}
  html.mb-phone .project-hero-title{font-size:19px}
  /* page head, 2026-09-27: the desktop head (assets/devbiz-polish.css) is
     id-scoped, so the phone sizes restate the id. Hero padding stays what the
     phone had — the Basis strip beside the chip picker sits just past the
     right edge and a 20px shift left brought it on screen. */
  html.mb-phone #project-detail .project-hero,html.mb-phone #mt-dvz .project-hero{padding:12px 22px}
  html.mb-phone #project-detail .project-hero-title,html.mb-phone #mt-dvz .project-hero-title{font-size:19px}
  html.mb-phone #project-detail .project-hero-sub,html.mb-phone #mt-dvz .project-hero-sub{font-size:12px}
  html.mb-phone .dvz-title{font-size:20px}
  html.mb-phone .dvz-sub{font-size:12px}
  html.mb-phone .dvz-ds{flex-wrap:nowrap;max-width:100%;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  html.mb-phone .dvz-ds::-webkit-scrollbar{display:none}
  html.mb-phone .home-stickyhead.dvz-pagehead,html.mb-phone #project-detail .detail-stickyhead,html.mb-phone #mt-dvz .detail-stickyhead{--dvz-gutter:12px}
  /* The head's own control (Home's Showing, Detail's Basis) is a picker like
     every other one on a phone: full content width. The row was sized to its
     content, so the box stopped at ~170px and a long value ellipsed to one
     letter (2026-10-03, "cuman initial awal doang (A)"). */
  html.mb-phone .dvz-ctlrow{justify-content:flex-start;flex:1 1 100%;width:100%;min-width:0}
  html.mb-phone .dvz-ctls{justify-content:flex-start;flex:1 1 100%;width:100%;min-width:0;gap:10px}
  html.mb-phone .src-pill,html.mb-phone .md-period-btn{clip-path:none}
  html.mb-phone .project-hero > div:last-child{width:100%}
  html.mb-phone .mchild-pick{max-width:100%;flex-wrap:wrap}
  html.mb-phone .mchild-pick select{flex:1 1 160px;min-width:0;max-width:100%}
  html.mb-phone #cpb-switch{flex-wrap:wrap;max-width:100%}
  html.mb-phone #cpb-switch .cpb-btn{flex:1 1 auto}
}

/* ── 2a. Control tokens on a phone: compact, the values every picker and
   input read (assets/lv2.css defines the desktop ones) ───────────────────── */
@media (max-width: 767px){
  html.mb-phone{--ctl-h:30px;--ctl-font:12px;--ctl-radius:8px}
  /* the phone keeps the compact segment the desktop had before 2026-09-27 */
  html.mb-phone{--ctl-seg-h:var(--ctl-h);--ctl-seg-cell:calc(var(--ctl-h) - 8px);--ctl-seg-border:var(--ctl-border);--ctl-seg-shadow:none;--ctl-seg-shadow-run:none}
}

/* ── 2b. Login ─────────────────────────────────────────────────────────────── */
@media (max-width: 767px){
  /* no card on a phone: the form sits on a white page (Satriya, 2026-09-26 —
     the white box on the tinted canvas read as a desktop dialog) */
  html.mb-phone #login-screen{background:#fff;align-items:flex-start;min-height:100dvh;padding:max(56px,12vh) 24px 32px;box-sizing:border-box}
  html.mb-phone .login-card{background:transparent;border:0;box-shadow:none;border-radius:0;padding:0;max-width:100%}
}

/* ── 3. KPI and card grids ─────────────────────────────────────────────────── */
@media (max-width: 767px){
  html.mb-phone .kpi-strip,html.mb-phone .kpi-strip.mg-strip,html.mb-phone .detail-kpi-row{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  html.mb-phone .detail-kpi{min-width:0}
  html.mb-phone .kpi-mini{padding:14px 13px 12px}
  html.mb-phone .detail-kpi{padding:13px 13px 12px}
  html.mb-phone .kpi-mini-val,html.mb-phone .det-val{font-size:24px}
  html.mb-phone .charts-grid{grid-template-columns:1fr;gap:12px}
  html.mb-phone .tsp-sum{grid-template-columns:repeat(2,minmax(0,1fr))}
  html.mb-phone .perf-strip{grid-template-columns:repeat(2,minmax(0,1fr))}
  html.mb-phone .md-card-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  html.mb-phone .md-summary,html.mb-phone .md-detail,html.mb-phone .pmkt-dgrid,html.mb-phone .mapping-layout{grid-template-columns:1fr}
  html.mb-phone .lv2-kpis,html.mb-phone .lv2-kpis--5,html.mb-phone .lv2-kpis--7,html.mb-phone .lv2-kpis--8{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  html.mb-phone .lv2-bento>*{grid-column:span 12}
  /* inline column counts in the renderers (3–4 across) become two, or one for forms */
  html.mb-phone .lv2-pair,html.mb-phone .lgc-g5,html.mb-phone .lgc-g4,html.mb-phone .lv2-dual,html.mb-phone .lv2-feat,html.mb-phone .mka-trio,html.mb-phone .mka-stats,html.mb-phone .lv2-mtdisc,html.mb-phone .lv2-ffdet{grid-template-columns:repeat(2,minmax(0,1fr)) !important}
  html.mb-phone .lv2-fgrid,html.mb-phone .lv2-fgrid--3,html.mb-phone .mka-ev,html.mb-phone .lgc-g2,html.mb-phone .lgc-g3,html.mb-phone .lv2-geo{grid-template-columns:1fr !important}
  html.mb-phone .lv2-fgrid .span2{grid-column:span 1}
  html.mb-phone .mka-team{grid-template-columns:repeat(2,minmax(0,1fr))}
  html.mb-phone .mka-row{grid-template-columns:1fr}
  html.mb-phone .lv2-surface .mb-hist-list{grid-template-columns:1fr}
  html.mb-phone .lv2-kpi__val{font-size:24px}
  /* an odd card count leaves a hole at the bottom-right of a two-column grid:
     the last card takes the whole row instead (Satriya, 2026-09-26) — every
     two-column grid above, one rule */
  html.mb-phone .kpi-strip > :last-child:nth-child(odd),html.mb-phone .detail-kpi-row > :last-child:nth-child(odd),
  html.mb-phone .tsp-sum > :last-child:nth-child(odd),html.mb-phone .perf-strip > :last-child:nth-child(odd),
  html.mb-phone .md-card-grid > :last-child:nth-child(odd),html.mb-phone .lv2-kpis > :last-child:nth-child(odd),
  html.mb-phone .lv2-pair > :last-child:nth-child(odd),html.mb-phone .lgc-g5 > :last-child:nth-child(odd),html.mb-phone .lgc-g4 > :last-child:nth-child(odd),
  html.mb-phone .lv2-dual > :last-child:nth-child(odd),html.mb-phone .lv2-feat > :last-child:nth-child(odd),html.mb-phone .mka-trio > :last-child:nth-child(odd),
  html.mb-phone .mka-stats > :last-child:nth-child(odd),html.mb-phone .lv2-mtdisc > :last-child:nth-child(odd),html.mb-phone .lv2-ffdet > :last-child:nth-child(odd),
  html.mb-phone .mka-team > :last-child:nth-child(odd){grid-column:1 / -1}
  /* …and mobile.js marks the odd last item of any other two-across container */
  html.mb-phone .mb-span{grid-column:1 / -1 !important}
  html.mb-phone .mb-fill{flex:1 1 0 !important;max-width:none !important;min-width:0 !important}
  /* a 170px card cannot keep a 54px badge slot beside its title: the source
     badge moves above the title instead of truncating "Bookings" to "Bookin" */
  html.mb-phone .lv2-kpi{padding:13px 13px 12px}
  html.mb-phone .lv2-kpi__head{padding-right:0;flex-wrap:wrap}
  html.mb-phone .lv2-kpi__src{position:static;order:-1;flex:none;width:100%;margin-bottom:6px;display:flex}
  html.mb-phone #integrations-view [style*="grid-template-columns"],html.mb-phone #members-view [style*="grid-template-columns"]{grid-template-columns:1fr !important}
  html.mb-phone #mb-agency{grid-template-columns:1fr !important}
}
@media (max-width: 359px){
  html.mb-phone .lv2-pair,html.mb-phone .lgc-g5,html.mb-phone .lgc-g4,html.mb-phone .mka-team{grid-template-columns:1fr !important}
}

/* ── 4. Tables ─────────────────────────────────────────────────────────────── */
@media (max-width: 767px){
  /* every table scrolls sideways inside its own box; the page never does */
  html.mb-phone .tbl-wrap,html.mb-phone .lgc-scroll,html.mb-phone .ui-scroll,html.mb-phone .pig-wrap,html.mb-phone .cw-tbl-wrap,
  html.mb-phone .pmkt-dtbl-wrap,html.mb-phone .modal-tbl-wrap,html.mb-phone .lv2-scroll{overflow:auto;-webkit-overflow-scrolling:touch;max-width:100%}
  html.mb-phone .tbl-wrap{max-height:none}
  /* tables index.html leaves without a wrapper */
  html.mb-phone #tsp-body,html.mb-phone #meta-platform-table,html.mb-phone .md-table-wrap,html.mb-phone .rl,
  html.mb-phone .bg-tbl-wrap,html.mb-phone .alog-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  html.mb-phone .rl-hd,html.mb-phone .rl-r{min-width:max-content}
  html.mb-phone table.bg-tbl{display:block;overflow-x:auto;max-width:100%;min-width:0}   /* .lgc-tbl's min-width:760px would beat max-width */
  html.mb-phone .mb-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}   /* mobile.js wraps the bare wide tables in this */
  /* a tab strip inside a flex row must be allowed to shrink, or it runs off the screen instead of scrolling */
  html.mb-phone .lv2-tabrow,html.mb-phone .lv2-tabrow > div{max-width:100%;min-width:0}
  html.mb-phone .lv2-tabs{flex:0 1 auto;min-width:0}
  /* Campaign Naming: a field spanning two grid columns forces a second column into a one-column phone grid */
  html.mb-phone .mb-f[style*="grid-column"]{grid-column:auto !important}
  /* Home's project table keeps ONE frozen column on a phone — two pinned 350px */
  html.mb-phone #overview-table thead th:first-child,
  html.mb-phone #overview-table tbody tr.proj-row td:first-child,
  html.mb-phone #overview-table tbody tr.tr-sub td:first-child{min-width:120px;max-width:120px;width:120px}
  html.mb-phone #overview-table thead th:nth-child(2),
  html.mb-phone #overview-table tbody tr.proj-row td:nth-child(2),
  html.mb-phone #overview-table tbody tr.tr-sub td:nth-child(2){position:static;box-shadow:none;min-width:110px;max-width:none;width:auto}
  html.mb-phone #overview-table thead th:first-child,html.mb-phone #overview-table tbody td:first-child{box-shadow:2px 0 5px -2px rgba(15,23,42,.10)}
  html.mb-phone #overview-table .rl-n,html.mb-phone #overview-table td:first-child{white-space:normal}
  html.mb-phone .tbl-grid .tbl-lead,html.mb-phone .pig td,html.mb-phone .pig th{max-width:170px}
  html.mb-phone :root{--grid-lead-min:150px;--grid-lead-max:170px}
  html.mb-phone .lgc-tbl{min-width:640px}
  /* Frozen columns on a phone: a 290px context column pinned inside a 366px
     scroller leaves 76px that moves — the table reads as stuck. The breakdown
     and Calibration columns unfreeze; the tables that pin an identity column
     keep it, capped at 120px so two thirds of the width still scrolls. */
  /* Breakdown tables: the context cell (period + the four panel pills) is
     290px wide on desktop and hid every data column on a phone. It becomes a
     132px block — period on top, pills wrapped beneath — and stays frozen at
     that width, so the numbers scroll and the month never leaves the screen. */
  /* table-layout:fixed — the shared <colgroup> (MAIN_COLS in index.html) is the
     authority on width, so the column is narrowed there, not on the cells. */
  html.mb-phone #monthly-table col:first-child,html.mb-phone #weekly-table col:first-child{width:132px !important}
  html.mb-phone #monthly-table thead tr:first-child th:first-child,html.mb-phone #weekly-table thead tr:first-child th:first-child,
  html.mb-phone #monthly-table tbody td:first-child,html.mb-phone #weekly-table tbody td:first-child{padding-left:8px;padding-right:6px}
  html.mb-phone .brk-ctx,html.mb-phone .brk-ctx.brk-ctx-g{display:flex;flex-wrap:wrap;align-items:center;gap:3px 2px;white-space:normal;max-width:118px}
  html.mb-phone .brk-ctx > :first-child{flex:none}
  html.mb-phone .brk-ctx-period{flex:1 1 60px;font-size:11px}
  html.mb-phone .brk-ctx-slot{flex:none;justify-content:flex-start}
  html.mb-phone .brk-ctx .mp-btn{font-size:8.5px;padding:2px 6px;line-height:1.3}
  html.mb-phone .brk-ctx-wide{white-space:normal;padding-left:0;font-size:10.5px}
  html.mb-phone .chan-table th:first-child,html.mb-phone .chan-table td:first-child{position:static;box-shadow:none}
  html.mb-phone #calib-table th,html.mb-phone #calib-table td{position:static !important;left:auto !important}
  html.mb-phone .tbl-wrap thead th{position:sticky}
  html.mb-phone .lex-tbl th.is-pin,html.mb-phone .lex-tbl td.is-pin{position:static}
  html.mb-phone .lex-tbl th:first-child.is-pin,html.mb-phone .lex-tbl td:first-child.is-pin{position:sticky;left:0 !important;width:120px !important;min-width:120px !important;max-width:120px !important}
  html.mb-phone .pig .pig-fz{min-width:120px;max-width:120px}
  /* the sticky first cell keeps one line; a long name truncates with an
     ellipsis instead of running under the next column (a wrap here breaks the
     name letter by letter, because the table gives the cell its minimum width) */
  /* Project hero on a phone: one row — status chip (Active · Ending soon …)
     where the BASIS label was, then the Basis picker filling the rest. The
     label went and the chip took its seat (Satriya, 2026-09-26). */
  html.mb-phone .project-hero > div:last-child{display:flex !important;flex-direction:row;flex-wrap:wrap;align-items:center;gap:8px}
  html.mb-phone .project-hero > div:last-child > #detail-status-badge{order:-1;flex:none;width:auto !important;margin:0}
  html.mb-phone .project-hero > div:last-child > #detail-status-badge:empty{display:none}
  html.mb-phone .project-hero > div:last-child > div:has(> #cpb-switch){display:flex !important;flex:1 1 0 !important;width:auto !important;min-width:0}
  html.mb-phone .project-hero > div:last-child > .mchild-pick{flex:1 1 100%}
  html.mb-phone [data-mb-for="cpb-switch"] > .mb-chipsel__k{display:none}
  html.mb-phone .lv2-tbl td:first-child,html.mb-phone .lv2-tbl th:first-child{max-width:190px}
  html.mb-phone .lv2-tbl .who{max-width:100%}
  html.mb-phone .lv2-tbl .who > span:last-child{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:118px;display:inline-block;vertical-align:middle}
  html.mb-phone .mb-tbl td:first-child,html.mb-phone .mb-tbl th:first-child{white-space:nowrap}
}

/* ── 5. Overlays ───────────────────────────────────────────────────────────── */
@media (max-width: 767px){
  html.mb-phone .modal-overlay{padding:0;align-items:stretch}
  html.mb-phone .modal{width:100%;max-width:none;max-height:none;height:100%;border-radius:0}
  /* small dialogs stay dialogs: centred cards, not full screens */
  html.mb-phone .modal-overlay:has(> .pig-dlg),html.mb-phone #unq-overlay,html.mb-phone #adpv-overlay{padding:12px;align-items:center}
  html.mb-phone .modal.pig-dlg,html.mb-phone #unq-modal,html.mb-phone .adpv-modal{width:100%;height:auto;max-height:calc(100dvh - 24px);border-radius:16px}
  html.mb-phone .adpv-stage{width:100%;max-width:335px;margin:0 auto}
  html.mb-phone .adpv-body{min-height:0}
  html.mb-phone #lex-overlay{padding:0}
  html.mb-phone .lex-modal{border-radius:0;height:100dvh}
  html.mb-phone .modal-header{padding:12px 12px 10px;gap:8px;flex-wrap:wrap;padding-top:calc(12px + env(safe-area-inset-top, 0px))}
  html.mb-phone .modal-body{padding:12px}
  /* Lead Detail: a full-width pane over the table, back button in its own head */
  html.mb-phone .lex-split.is-open .lex-pane{width:100%;max-width:none;left:0;z-index:8;box-shadow:none}
  /* the Explorer's header: ✕ pinned top-right, the view / customize / export
     buttons wrap under the title instead of pushing ✕ off screen */
  html.mb-phone .lex-modal .modal-header{position:relative;padding-right:56px}
  html.mb-phone .lex-modal .modal-header > div:last-child{flex:1 1 100% !important;flex-wrap:wrap;gap:6px}
  html.mb-phone .lex-modal .modal-close{position:absolute;top:calc(10px + env(safe-area-inset-top, 0px));right:10px}
  html.mb-phone .lex-modal .modal-title{font-size:15px;line-height:1.3}
  html.mb-phone .lex-bar{flex-wrap:wrap;gap:6px;padding:8px 10px}
  html.mb-phone .lex-search{min-width:0;flex:1 1 100%}
  html.mb-phone .lex-menu{max-width:calc(100vw - 16px)}
  html.mb-phone .lex-cust{width:100vw;height:100dvh;max-height:none;border-radius:0}
  html.mb-phone .lv2-drawer__p{width:100vw}
  html.mb-phone .tgt-pop{max-width:calc(100vw - 16px)}
  html.mb-phone .lv2-toast,html.mb-phone .toast{bottom:calc(80px + env(safe-area-inset-bottom, 0px));max-width:calc(100vw - 24px)}
  html.mb-phone .pres-pop{width:min(300px,calc(100vw - 24px))}
}

/* ── 5b. Segmented controls → chip rows ────────────────────────────────────── */
/* Outside the phone query the wrapper span is invisible to layout. */
.mb-chiprow{display:contents}
@media (max-width: 767px){
  html.mb-phone .src-toggle,html.mb-phone #tsp-range{display:flex;flex-direction:column;align-items:stretch;gap:8px;margin-bottom:12px}
  html.mb-phone .mb-chiprow{display:flex;flex-wrap:nowrap;align-items:center;gap:6px;overflow-x:auto;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;margin:0;padding:2px 0;max-width:100%;scroll-snap-type:x proximity}
  html.mb-phone .mb-chiprow::-webkit-scrollbar{display:none}
  html.mb-phone .mb-chiprow > *{flex:none;scroll-snap-align:start}
  /* left-aligned, always: the desktop pushes the VIEW group to the right edge
     with margin-left:auto, which on a phone reads as a stray row */
  html.mb-phone .mb-chiprow,html.mb-phone .src-toggle > .mb-chiprow{margin-left:0 !important;justify-content:flex-start}
  html.mb-phone .mb-chiprow > span[style*="margin-left"]{margin-left:0 !important}
  html.mb-phone .card-header,html.mb-phone .cw-head-row,html.mb-phone .cw-controls{justify-content:flex-start}
  /* Home's project table: once the explanation line under the title is gone
     the search group no longer wraps onto its own full row, so it hugged the
     title (2026-09-27). It takes the whole second row now — count left, the
     search box filling the rest, flush right like the desktop. */
  html.mb-phone #overview .card-header > div:last-child{flex:1 1 100% !important;display:flex;justify-content:space-between;min-width:0}   /* the markup says flex:none inline */
  html.mb-phone #overview .search-wrap{flex:1 1 auto;width:auto;min-width:0;max-width:260px}
  html.mb-phone .card-header > [style*="margin-left:auto"],html.mb-phone .card-header > [style*="margin-left: auto"],
  html.mb-phone .cw-head-row > [style*="margin-left:auto"],html.mb-phone .chart-card > [style*="margin-left:auto"]{margin-left:0 !important}
  html.mb-phone .src-pill{min-height:32px;padding:6px 13px;font-size:11.5px;font-weight:700;white-space:nowrap}
  /* 5c. Every toolbar control is ONE picker on a phone — label on the left,
     a white box with the value and a chevron filling the rest of the row —
     over the real control: a segmented group's buttons (mobile.js clicks the
     matching one) or the toolbar's own <select> (moved inside, transparent).
     Sizes are the --ctl-* tokens in assets/lv2.css, the same ones the desktop
     controls read, so the two never drift (Satriya, 2026-09-26: "once 1
     ganti semua ikut ganti"). One control per row — the Listing layout he
     preferred — and a 16px font on the hidden <select> is no longer needed
     for iOS, because the viewport carries maximum-scale=1. */
  html.mb-phone .mb-chiprow--sel,html.mb-phone .mb-chiplbl--sel{display:none !important}
  /* the Basis strip is also styled by id in lv2.css (#cpb-switch, display:inline-flex
     !important — the shared segment rule of 2026-09-26), and an id beats the rule
     above, so the strip stayed on screen beside its own picker and pushed the page
     sideways. Restate it by id. */
  html.mb-phone #cpb-switch.mb-chiprow--sel{display:none !important}
  html.mb-phone .mb-chipsel{position:relative;display:flex;align-items:center;gap:8px;width:100%;max-width:100%;min-width:0;flex:1 1 100%}
  html.mb-phone .mb-chipsel__k{flex:0 0 84px;font-size:var(--ctl-lbl-font);font-weight:var(--ctl-lbl-weight);color:var(--ctl-lbl-color);letter-spacing:var(--ctl-lbl-ls);text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  html.mb-phone .mb-chipsel__k:empty{display:none}
  html.mb-phone .mb-chipsel__b{flex:1 1 auto;display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0;box-sizing:border-box;height:var(--ctl-h);padding:0 var(--ctl-px);border:1px solid var(--ctl-border);border-radius:var(--ctl-radius);background:var(--ctl-bg);color:var(--ctl-text);font-size:var(--ctl-font);font-weight:var(--ctl-weight)}
  html.mb-phone .mb-chipsel__v{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  html.mb-phone .mb-chipsel svg{color:var(--ctl-muted);flex:none;margin-right:2px}
  html.mb-phone .mb-chipsel select{position:absolute;inset:0;width:100% !important;height:100% !important;min-width:0 !important;opacity:0;margin:0;padding:0;border:0;appearance:none;-webkit-appearance:none}
  html.mb-phone .mb-chipsel:focus-within .mb-chipsel__b{border-color:var(--ctl-on-bg);box-shadow:0 0 0 2px rgba(37,99,235,.15)}
  /* the containers stack their pickers, one per row */
  html.mb-phone .src-toggle,html.mb-phone .lgc-ctl:not(#lgc-range-ctl),html.mb-phone .bg-ctl,html.mb-phone .mg-ctl,
  html.mb-phone #activity-log-section .card-header > div:last-child,html.mb-phone .ui-ctl:not(#ae-head .ui-ctl){display:flex;flex-direction:column;align-items:stretch;gap:6px;width:100%;min-width:0;margin-left:0 !important}
  html.mb-phone .ui-ctl:not(#ae-head .ui-ctl) > .ui-btn,html.mb-phone .ui-ctl:not(#ae-head .ui-ctl) > .ui-inp{width:100%;box-sizing:border-box}
  html.mb-phone .ui-ctl > .pif-vbtn{max-width:none;width:100%;box-sizing:border-box}   /* Project Index view picker, as wide as its siblings */
  /* 5d. Toolbars: a change applies itself (mobile.js), so Apply goes; presets,
     Export CSV and the "Last 7 Days (default)" hint go with it. The date pair
     is one row — from · to · to — with no RANGE label (the calendar icons say
     it, and "27/08/2026" needs the width); the pickers stack under it. */
  html.mb-phone .cw-controls > button.ui-btn,html.mb-phone #tsp-range > button.ui-btn,html.mb-phone .lgc-ctl > button.lgc-btn,
  html.mb-phone #ae-head .ui-ctl > button.ui-btn,html.mb-phone #lgc-presets,html.mb-phone #cw-limit,html.mb-phone #cw-range-label,html.mb-phone .tsp-cur{display:none !important}
  html.mb-phone .cw-controls > span:first-child,html.mb-phone #tsp-range > .tsp-lbl,html.mb-phone #lgc-range-ctl > .lgc-ctl-lbl,html.mb-phone #ae-head .ui-ctl > .ui-ctl-lbl:first-child{display:none !important}
  html.mb-phone .cw-controls,html.mb-phone #tsp-range,html.mb-phone #lgc-range-ctl,html.mb-phone #ae-head .ui-ctl{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:6px;align-items:center;width:100%;min-width:0}
  html.mb-phone .cw-controls > .mb-chipsel,html.mb-phone .cw-controls > #cw-search,html.mb-phone #tsp-range > .mb-chipsel{grid-column:1 / -1}
  html.mb-phone .cw-controls input[type=date],html.mb-phone #tsp-range input[type=date],html.mb-phone .lgc-ctl input[type=date],html.mb-phone #ae-head .ui-ctl input[type=date],html.mb-phone #cw-search{width:100%;min-width:0 !important;box-sizing:border-box}
  html.mb-phone input[type=date].ui-inp,html.mb-phone input[type=date].lgc-inp{font-size:13px;height:var(--ctl-h);min-height:0;padding:0 8px}
  /* Creative Breakdown: date pair · platform · search (his order), Google views under the platform */
  html.mb-phone .cw-controls > [data-mb-for="cw-plat-toggle"]{order:2}
  html.mb-phone .cw-controls > [data-mb-for="cw-gsub"]{order:3}
  html.mb-phone .cw-controls > #cw-search{order:4}
  html.mb-phone .cw-controls > .cw-view-wrap{grid-column:1 / -1;order:-1;margin:0}   /* Creative | Landing Page picker, full width above the dates */
  html.mb-phone .cw-toolbar{padding:10px 14px 0;gap:6px}   /* Creative's own tools, one full-width row each */
  html.mb-phone .cw-toolbar-l,html.mb-phone .cw-toolbar-r{width:100%;gap:6px}
  html.mb-phone .cw-toolbar-l > .mb-chipsel,html.mb-phone .cw-toolbar-r > #cw-search{flex:1 1 100%;min-width:0 !important}
  html.mb-phone #cw-search{font-size:13px;min-height:0;height:var(--ctl-h)}
  html.mb-phone .lgc-ctl{flex:1 1 100%}
  html.mb-phone .md-mini-note:not(:only-child){display:none !important}   /* footnotes under a table go; a lone "Loading…" / empty state stays */
  /* 5d2. A badge strip (SOURCES · Meta live · Google live …) is one line that
     swipes; wrapped to two it read as a paragraph. */
  html.mb-phone .lgc-ds,html.mb-phone .lv2-legend,html.mb-phone .lv2-seg-lg,
  html.mb-phone .lv2-strip,html.mb-phone .lv2-chsum{display:flex;flex-wrap:nowrap;align-items:center;overflow-x:auto;max-width:100%;scrollbar-width:none;-webkit-overflow-scrolling:touch;white-space:nowrap}
  html.mb-phone .lgc-ds::-webkit-scrollbar,html.mb-phone .lv2-legend::-webkit-scrollbar,html.mb-phone .lv2-seg-lg::-webkit-scrollbar,
  html.mb-phone .lv2-strip::-webkit-scrollbar,html.mb-phone .lv2-chsum::-webkit-scrollbar{display:none}
  html.mb-phone .lgc-ds > *,html.mb-phone .lv2-legend > *,html.mb-phone .lv2-seg-lg > *,html.mb-phone .lv2-strip > *,html.mb-phone .lv2-chsum > *{flex:none}
  /* a figure strip (RAW · SUBMIT · APPROVED · AKAD) keeps its full-width box;
     the figures inside are the one line that swipes (Satriya, 2026-09-26) */
  html.mb-phone .lv2-strip{align-items:flex-start;width:100%;box-sizing:border-box;gap:22px}
  /* 5e. A v2 panel head never wraps its title word by word: the badges drop
     under the title when they do not fit beside it. */
  html.mb-phone .lv2-panel__head{flex-wrap:wrap;align-items:center}
  html.mb-phone .lv2-panel__titles{flex:1 1 150px}
  html.mb-phone .lv2-panel__act{flex:0 1 auto}
  html.mb-phone #tsp-range .tsp-gap{display:none}
  html.mb-phone #tsp-range .tsp-lbl,html.mb-phone .src-toggle > span:not(.mb-chiprow){flex:none}
  /* Basis (cpb) and the lgc segments: one scrolling pill strip, no wrapping */
  html.mb-phone .project-hero > div:last-child > div{display:flex;align-items:center;gap:8px;width:100%;min-width:0}
  html.mb-phone #cpb-switch{display:flex;flex-wrap:nowrap;flex:1;min-width:0;overflow-x:auto;scrollbar-width:none;border-radius:999px}
  html.mb-phone #cpb-switch::-webkit-scrollbar{display:none}
  html.mb-phone #cpb-switch .cpb-btn{flex:none;min-height:34px;padding:7px 14px;white-space:nowrap}
  html.mb-phone .lgc-seg,html.mb-phone .lgc-tabs,html.mb-phone .lv2-tabs,html.mb-phone #cw-plat-toggle,html.mb-phone #alog-plat-toggle{display:flex;flex-wrap:nowrap;max-width:100%;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  html.mb-phone .lgc-seg::-webkit-scrollbar,html.mb-phone .lgc-tabs::-webkit-scrollbar,html.mb-phone .lv2-tabs::-webkit-scrollbar{display:none}
  html.mb-phone .lgc-seg button,html.mb-phone .lgc-tabs > *,html.mb-phone .lv2-tabs > *{flex:none;white-space:nowrap;min-height:34px}
  /* a short tab strip (All · Active · Ended) fills the row, each tab an equal
     share; four or more tabs keep the swipe strip (Satriya, 2026-09-26) */
  html.mb-phone .lv2-tabs:not(:has(> :nth-child(4))),html.mb-phone .lgc-tabs:not(:has(> :nth-child(4))){display:flex;width:100%;flex:1 1 100%;overflow:visible}
  html.mb-phone .lv2-tabs:not(:has(> :nth-child(4))) > *,html.mb-phone .lgc-tabs:not(:has(> :nth-child(4))) > *{flex:1 1 0;justify-content:center;min-width:0}
  html.mb-phone .lv2-tabrow > div:has(> .lv2-tabs){flex:1 1 100%;min-width:0}
  html.mb-phone .cw-controls{gap:6px 8px}
}

/* ── 6. Controls and touch ─────────────────────────────────────────────────── */
@media (max-width: 767px){
  /* 16px stops iOS Safari zooming into a field; the labels keep their own size */
  html.mb-phone textarea,html.mb-phone input[type=text]:not(.ui-inp):not(.lgc-inp):not(.search-input),html.mb-phone input[type=search],html.mb-phone input[type=email],html.mb-phone input[type=password]{font-size:16px}
  html.mb-phone .ui-inp,html.mb-phone .ui-sel,html.mb-phone .lgc-inp,html.mb-phone .lgc-sel,html.mb-phone .lex-search input{min-height:40px}
  html.mb-phone .ui-btn,html.mb-phone .tbtn,html.mb-phone .lgc-btn,html.mb-phone .lv2-btn,html.mb-phone .cpb-btn,html.mb-phone .btn{min-height:38px}
  html.mb-phone .cpb-switch{flex-wrap:wrap}
  html.mb-phone [data-tip],html.mb-phone [title]{-webkit-touch-callout:none}
}
@media (hover: none){
  /* hover-revealed controls are always visible on a touch screen */
  .ic-act{color:#64748B !important}
  .lex-th__m{opacity:1 !important}
  .pig-c:focus-within{outline:2px solid #2563EB}
}

/* ── 7. Motion ─────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce){
  #mb-sheet-host .mb-backdrop,#mb-sheet-host .mb-sheet{transition:none}
}
