/* ============================================================
   PatchWork — Mobile canvas chrome.

   Everything here hangs off `body.pw-mobile`, which js/mobile-mode.js adds
   on a touch device with a small viewport and removes on rotate/resize. The
   layout is deliberately the SAME layout as desktop — same toolbar, same
   canvas, same node panels — with the chrome that does not survive a 390px
   screen hidden and every remaining target grown to a thumb-sized 44px.

   Touch behaviour (pan / pinch / long-press menu) lives in
   js/mobile-mode.js, not here.
   ============================================================ */

/* ---------------------------------------------------------------
   iOS safe area.

   viewport-fit=cover (plus apple-mobile-web-app-status-bar-style:
   black-translucent) deliberately extends the page under the status
   bar, the notch / Dynamic Island and the home indicator — so every
   piece of chrome anchored to an edge has to inset itself back out
   again, or it sits underneath them.

   Indirected through custom properties rather than calling env()
   at each site: env() cannot be overridden, so a test has no way to
   simulate a notch. These can be set to a fake inset to prove the
   layout responds. Real devices still get the real env() values.
   --------------------------------------------------------------- */
:root {
    --pw-safe-top: env(safe-area-inset-top, 0px);
    --pw-safe-bottom: env(safe-area-inset-bottom, 0px);
    --pw-safe-left: env(safe-area-inset-left, 0px);
    --pw-safe-right: env(safe-area-inset-right, 0px);
}

/* Mobile browser chrome makes 100vh taller than the visible viewport, which
   pushed the run controls under the address bar. */
body.pw-mobile #app {
    height: 100dvh;
}

/* The canvas toolbar is the topmost chrome on a phone — without a top inset
   its tab strip and icon row sit under the status bar / Dynamic Island. The
   rule itself lives with the rest of the toolbar padding further down, so a
   shorthand there cannot quietly undo it. */

/* Landscape puts the notch on a side, over the node rail and the canvas. */
body.pw-mobile #palette {
    padding-left: calc(5px + var(--pw-safe-left));
}

body.pw-mobile .edge-show-tab-left {
    margin-left: var(--pw-safe-left);
}

body.pw-mobile .edge-show-tab-right {
    margin-right: var(--pw-safe-right);
}

/* Stop the rubber-band overscroll from dragging the whole page while a
   gesture is running on the canvas. */
body.pw-mobile {
    overscroll-behavior: none;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* Never let a double-tap zoom the document; the canvas does its own zoom. */
body.pw-mobile #canvas-container,
body.pw-mobile #graph-canvas,
body.pw-mobile #drawing-canvas {
    touch-action: none;
}

/* ---------------------------------------------------------------
   Home screen — the first thing a phone sees, and the only route to
   a canvas. Its 240px vertical rail eats 60% of a 390px screen, so
   the whole shell flips to a column with the rail as a horizontally
   scrolling tab strip.
   --------------------------------------------------------------- */
body.pw-mobile .home-screen {
    flex-direction: column;
}

body.pw-mobile .home-sidebar {
    width: 100%;
    flex-shrink: 0;
    flex-direction: row;
    align-items: center;
    border-right: none;
    border-bottom: 1px solid var(--sl-line);
    padding-top: var(--pw-safe-top);
    overflow: visible;
}

/* The wordmark is a whole row of vertical space for zero function. */
body.pw-mobile .home-sidebar-brand,
body.pw-mobile .home-sidebar-spacer,
body.pw-mobile .home-sidebar-version,
body.pw-mobile .home-sidebar-byline {
    display: none !important;
}

body.pw-mobile .home-sidebar-nav {
    flex-direction: row;
    align-items: center;
    gap: 2px;
    padding: 6px 8px;
    /* Without min-width:0 the flex item refuses to shrink below its content
       and the strip spills out under the account pill instead of scrolling. */
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
}

body.pw-mobile .home-sidebar-nav::-webkit-scrollbar {
    display: none;
}

/* Icon-only tabs. Labelled tabs needed ~700px and turned the strip into a
   horizontal scroller whose off-screen half nobody found; seven 42px icons
   plus the account fit 390px outright, so every destination stays visible.
   (.sl-navitem is width:100% for the vertical rail — that made the first tab
   swallow the whole row.) */
body.pw-mobile .home-sidebar-tab {
    flex: 0 0 auto;
    width: auto;
    justify-content: center;
    gap: 0;
    padding: 11px;
    white-space: nowrap;
}

body.pw-mobile .home-sidebar-tab > span:not(.sl-navicon) {
    display: none;
}

/* Account: avatar-sized, label and sign-out live behind the tap. */
body.pw-mobile .home-sidebar-footer {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    margin-left: auto;
    border-top: none;
    padding: 0 8px 0 4px;
}

body.pw-mobile .pw-auth-mount {
    min-width: 0;
}

body.pw-mobile .pw-auth-pill {
    width: auto;
    padding: 9px;
    gap: 0;
}

body.pw-mobile .pw-auth-pill-label {
    display: none;
}

body.pw-mobile .pw-auth-pill-logout {
    padding: 8px 0 8px 8px;
    font-size: 12px;
}

body.pw-mobile .home-main-area {
    flex: 1;
    min-height: 0;
}

body.pw-mobile .home-content,
body.pw-mobile .home-dash,
body.pw-mobile #home-tab-projects .home-content {
    padding: 18px 14px 32px;
    max-width: 100%;
}

/* The greeting is a display face at 26px+ — it wrapped to four lines. */
body.pw-mobile .sl-h1 {
    font-size: 21px;
}

/* Header rows that put a title and its actions side by side stack instead
   of crushing both. */
body.pw-mobile .home-dash-head,
body.pw-mobile .home-dash-sechead,
body.pw-mobile .home-projects-head {
    flex-wrap: wrap;
    gap: 10px;
}

body.pw-mobile #home-new-project {
    width: 100%;
    justify-content: center;
    padding: 13px 16px;
}

body.pw-mobile .home-dash-searchbox {
    flex: 1 1 100%;
    min-width: 0;
}

body.pw-mobile .home-dash-grid {
    grid-template-columns: 1fr;
}

/* ---------------------------------------------------------------
   Project list — a desktop table (name · gen · modified · 5 actions)
   whose fixed columns totalled ~340px, so on a 390px screen the name
   column was squeezed to nothing and every row read "Unknown".
   Each row becomes a two-line card instead, with the poster spanning
   both lines and the name finally getting the leftover width.
   --------------------------------------------------------------- */
/* .home-projects-page sits INSIDE .home-content, so both were applying the
   14px gutter and everything started 28px in. The wrapper keeps it. */
body.pw-mobile .home-projects-page {
    padding: 0 0 32px;
    max-width: 100%;
}

/* Import / From template / New Project: a non-wrapping flex row whose
   min-content width (377px) overflowed its own 334px parent. */
body.pw-mobile .home-actions {
    flex-wrap: wrap;
    min-width: 0;
    gap: 8px;
    margin-bottom: 20px;
}

body.pw-mobile .home-actions > button {
    flex: 1 1 auto;
    min-width: 0;
}

/* Five columns so the NAME can span the two that the action cluster needs.
   With the name confined to a single 1fr column the five 32px actions below
   it forced that column down to 72px and every title ellipsised again. */
body.pw-mobile .home-project-row {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto auto;
    grid-template-areas:
        "check poster name     name    ring"
        "check poster modified actions actions";
    column-gap: 10px;
    row-gap: 4px;
    align-items: center;
    padding: 10px 12px;
}

body.pw-mobile .home-project-check { grid-area: check; }
body.pw-mobile .home-project-poster { grid-area: poster; align-self: center; }
body.pw-mobile .home-col-name { grid-area: name; min-width: 0; }
body.pw-mobile .home-project-ring { grid-area: ring; width: auto; }

/* The fixed 92px right-aligned "modified" cell moves under the name. */
body.pw-mobile .home-col-modified,
body.pw-mobile .home-col-modified.home-project-detail {
    grid-area: modified;
    width: auto;
    text-align: left;
    font-size: 11.5px;
}

body.pw-mobile .home-col-actions {
    grid-area: actions;
    width: auto;
    justify-content: flex-end;
    gap: 2px;
}

/* ---- hover-revealed controls do not exist on a touchscreen ----
   A whole class of affordance is opacity:0 / visibility:hidden until the
   row is hovered. With no hover, favourite / move-to-folder / duplicate /
   export / delete were simply unreachable on a phone — the row looked like
   it had no actions at all. They are always visible here.
   (Video-editor equivalents are deliberately left alone — the editor is a
   separate pass.) */
body.pw-mobile .home-col-actions,
body.pw-mobile .home-project-row .home-col-actions,
body.pw-mobile .home-project-delete,
body.pw-mobile .home-project-pin,
body.pw-mobile .home-project-folder,
body.pw-mobile .home-project-duplicate,
body.pw-mobile .home-project-export,
body.pw-mobile .asset-list-actions,
body.pw-mobile .asset-thumb-actions,
body.pw-mobile .home-asset-fav,
body.pw-mobile .sb-tab-close,
body.pw-mobile .sb-clip-delete {
    opacity: 1;
}

body.pw-mobile .home-project-desc.home-desc-placeholder {
    visibility: visible;
}

/* Row actions were 26px squares. */
body.pw-mobile .home-col-actions > button {
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

body.pw-mobile .home-project-check {
    width: 24px;
    height: 24px;
    flex: none;
}

/* "July16 Fan-out Batch" ellipsised to "July16 F..." in the narrow column.
   A phone has vertical room it does not have horizontal, so names wrap to
   two lines rather than truncate. */
body.pw-mobile .home-project-name {
    white-space: normal;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    font-size: 14px;
    line-height: 1.25;
}

body.pw-mobile .home-project-poster {
    width: 34px;
    height: 44px;
}

body.pw-mobile .home-project-ring {
    width: 38px;
}

/* Folder chips take the full first line so the list/grid toggle wraps under
   them instead of overlapping the last chip. */
body.pw-mobile .home-folder-bar {
    flex: 1 1 100%;
}

/* Sort bar: the same fixed columns, and 12px-tall buttons. Becomes a plain
   row of chips — it is a control row now, not a table header. */
body.pw-mobile .home-sort-bar {
    display: flex;
    gap: 6px;
    height: auto;
    padding: 6px 2px;
    max-width: 100%;
}

body.pw-mobile .home-sort-bar .home-col-check,
body.pw-mobile .home-sort-bar .home-col-actions {
    display: none;
}

body.pw-mobile .home-sort-btn {
    width: auto;
    flex: 0 0 auto;
    text-align: left;
    padding: 9px 11px;
    border-radius: 8px;
    background: oklch(1 0 0 / 0.04);
}

/* Grid view cards: one per row is too sparse on a phone, two fit fine. */
body.pw-mobile .home-projects-grid,
body.pw-mobile .home-dash-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

/* Page header: title + Import / From template / New Project stacked cleanly
   instead of three half-width buttons breaking mid-word. */
body.pw-mobile .home-projects-head {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
}

body.pw-mobile .home-projects-head .sl-btn-primary,
body.pw-mobile .home-projects-head button {
    justify-content: center;
    padding: 12px 14px;
    white-space: nowrap;
}

/* Filter chips + list/grid toggle */
body.pw-mobile .home-projects-toolbar {
    flex-wrap: wrap;
    gap: 8px;
}

body.pw-mobile .home-folder-bar {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
}

body.pw-mobile .home-folder-bar::-webkit-scrollbar { display: none; }

body.pw-mobile .home-folder-chip,
body.pw-mobile .sl-chip,
body.pw-mobile .home-ws-chip,
body.pw-mobile #projects-ws-chip,
body.pw-mobile #assets-ws-chip {
    padding: 9px 12px;
    flex: 0 0 auto;
}

body.pw-mobile .sl-seg-btn {
    padding: 9px 14px;
}

/* The ⌘K hint is meaningless without a keyboard. */
body.pw-mobile .sl-kbd {
    display: none;
}

body.pw-mobile .sl-search input,
body.pw-mobile .home-projects-search input {
    padding-top: 11px;
    padding-bottom: 11px;
}

/* Bulk-select bar */
body.pw-mobile .home-projects-bulkbar {
    flex-wrap: wrap;
    gap: 6px;
}

/* ---------------------------------------------------------------
   Assets tab — a side-by-side split (asset grid | scene builder) with
   a 240px minimum on the right pane, which pushed 78px off screen.
   Stacks instead, and the scene builder keeps its own height.
   --------------------------------------------------------------- */
body.pw-mobile .assets-split {
    flex-direction: column;
    gap: 12px;
}

body.pw-mobile .assets-split-left,
body.pw-mobile .assets-split-right {
    min-width: 0;
    width: 100%;
}

body.pw-mobile .assets-split-right {
    flex: 0 0 auto;
    min-height: 220px;
}

body.pw-mobile .home-asset-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 10px;
}

/* Scene-builder header buttons were 22px squares. */
body.pw-mobile .sb-header-btn {
    padding: 8px;
    min-width: 34px;
    min-height: 34px;
}

body.pw-mobile .sb-tab-add,
body.pw-mobile .sb-play-btn {
    min-width: 34px;
    min-height: 34px;
}

body.pw-mobile #sb-collapse-tab {
    min-height: 26px;
}

/* ---------------------------------------------------------------
   Remaining sub-thumb controls across the home surfaces.
   --------------------------------------------------------------- */
body.pw-mobile #home-dash-viewall,
body.pw-mobile #home-asset-search-clear,
body.pw-mobile .pw-account-refresh,
body.pw-mobile .btn-close,
body.pw-mobile #settings-close,
body.pw-mobile .btn-small,
body.pw-mobile .home-bulk-clear {
    min-width: 36px;
    min-height: 36px;
    padding: 8px 10px;
}

body.pw-mobile .sl-seg-btn,
body.pw-mobile .home-sort-btn {
    min-height: 36px;
}

/* ---------------------------------------------------------------
   Toolbar — keep it to one compact row of the things people
   actually reach for: tabs, Assets, Settings, Editor, Share, account.
   --------------------------------------------------------------- */
/* The top inset lives in this shorthand rather than a separate rule — a
   later `padding:` shorthand silently reset it and the toolbar went back
   under the status bar. */
body.pw-mobile #toolbar {
    padding: calc(2px + var(--pw-safe-top)) 8px 0;
    padding-left: max(8px, var(--pw-safe-left));
    padding-right: max(8px, var(--pw-safe-right));
}

body.pw-mobile #toolbar .toolbar-row-top,
body.pw-mobile #toolbar.toolbar-row-top {
    height: 46px;
    min-height: 46px;
}

body.pw-mobile .toolbar-left {
    gap: 6px;
}

body.pw-mobile .toolbar-right {
    gap: 4px;
}

/* The logo is the ONLY way back to the home screen / project list
   (main.js binds showHomeScreen to it). Hiding it stranded phone users
   inside a project with no exit. It stays, as a real tap target. */
body.pw-mobile .logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 9px;
    flex: none;
    cursor: pointer;
    background: oklch(1 0 0 / 0.05);
}

body.pw-mobile .logo:active {
    background: oklch(1 0 0 / 0.11);
}

body.pw-mobile .logo-icon {
    width: 20px;
    height: 20px;
}

/* The project name is flex-shrink:0 and collided with the right-hand
   buttons. The active tab already names where you are, and the home
   screen names the project — so it goes. (Scoped through #toolbar to
   outrank `#toolbar .project-name{display:inline-flex}` in style.css.) */
body.pw-mobile #toolbar .project-name {
    display: none;
}

/* Tabs stay — they are how you move between workflows — but scroll
   horizontally instead of squeezing the toolbar. */
body.pw-mobile #tabs-container {
    overflow-x: auto;
    scrollbar-width: none;
}

/* Workflow tabs are the second navigation axis (Home button is the first).
   28px rows and a 2px-padded close button are not thumb targets.
   The close stays active-tab-only, as on desktop: showing an ✕ on every
   tab in a scrolling strip is a fat-finger workflow deletion waiting to
   happen. */
body.pw-mobile .tab-item {
    padding: 9px 12px;
    max-width: 160px;
}

body.pw-mobile .tab-item .tab-name {
    max-width: 108px;
}

body.pw-mobile .tab-item.active .tab-close {
    padding: 6px;
    margin-right: -4px;
    font-size: 1rem;
}

body.pw-mobile #btn-new-tab {
    padding: 9px 13px;
    flex-shrink: 0;
}

body.pw-mobile #tabs-container::-webkit-scrollbar {
    display: none;
}

/* Hidden icons: GPU pods, Scene Builder, the save timestamp, collaborator
   presence and the keyboard-shortcuts button have no place on a phone. */
body.pw-mobile #btn-gpu-chip,
body.pw-mobile #btn-scene-builder,
body.pw-mobile #last-saved,
body.pw-mobile #collab-presence,
body.pw-mobile .slc-shortcuts-btn,
body.pw-mobile #status {
    display: none !important;
}

/* Kept icons, grown to a real tap target. */
body.pw-mobile .toolbar-icon-btn {
    width: 38px;
    height: 38px;
}

body.pw-mobile .toolbar-icon-btn svg {
    width: 19px;
    height: 19px;
}

/* Editor and Share drop their labels — five text pills do not fit in a
   390px row, and both icons are already the desktop ones. */
body.pw-mobile .topbar-editor-pill {
    padding: 9px;
    gap: 0;
    font-size: 0;
}

body.pw-mobile .topbar-editor-pill svg {
    width: 18px;
    height: 18px;
}

/* #btn-share.btn-share in style.css sets the padding/gap — match its
   specificity or the label-less button keeps its label-sized box. */
body.pw-mobile #btn-share.btn-share {
    padding: 9px;
    gap: 0;
}

body.pw-mobile .btn-share span {
    display: none;
}

body.pw-mobile .btn-share svg {
    width: 18px;
    height: 18px;
}

body.pw-mobile .topbar-avatar {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
}

/* The "+" must stay reachable after the tab strip scrolls. (No overflow
   clipping on .toolbar-left — tab dropdowns have to escape the bar.) */
body.pw-mobile #btn-new-tab {
    flex-shrink: 0;
}

/* Menu row: File / View / Workflow stay (they hold Save, Reset View,
   Organize, Wipe…) but get thumb-sized hit areas. The desktop 42px indent
   aligns the menubar past the logo — on a phone the logo is in the row
   above, so it is just 42px of a 390px screen spent on nothing. */
body.pw-mobile .toolbar-row-menus,
body.pw-mobile #toolbar-menus {
    height: 40px;
    min-height: 40px;
    overflow-x: auto;
    scrollbar-width: none;
}

body.pw-mobile .toolbar-menus {
    margin-left: 8px;
}

body.pw-mobile #toolbar-menus::-webkit-scrollbar {
    display: none;
}

body.pw-mobile .toolbar-menu-btn {
    padding: 10px 14px !important;
    font-size: 13px !important;
    white-space: nowrap;
}

/* Dropdowns become full-width sheets so the items are reachable.
   `position: fixed` is load-bearing, not styling. The rule above makes the
   menu row a horizontal scroller, and `overflow-x: auto` computes
   `overflow-y` to `auto` too — so an ABSOLUTELY positioned dropdown is
   clipped to that 40px box. The menu opened, painted nothing at all, and
   every item reported the canvas under it: tapping File / View / Workflow
   looked like the menus were simply dead. Fixed descendants escape ancestor
   overflow, which is the only thing that gets the sheet out of the bar.
   `top` is set per-open by _setupToolbarMenus — see the note there on why it
   cannot be written here. */
body.pw-mobile .toolbar-menu-dropdown {
    position: fixed;
    left: 8px;
    right: 8px;
    width: auto;
    min-width: 0;
    max-height: min(60vh, calc(100vh - 150px));
    overflow-y: auto;
}

body.pw-mobile .tools-dropdown-item {
    padding: 13px 14px !important;
    font-size: 13.5px !important;
}

/* Keyboard hints mean nothing without a keyboard. */
body.pw-mobile .tools-shortcut {
    display: none !important;
}

/* ---------------------------------------------------------------
   Left node rail — the primary way to add a node by tapping.
   Drawing tools are hidden: they need a precise pointer and a
   long-press already covers the add-node menu.
   --------------------------------------------------------------- */
body.pw-mobile #palette {
    width: 54px;
    padding: 8px 5px;
}

body.pw-mobile #palette.palette-expanded {
    width: 168px;
}

body.pw-mobile .palette-item,
body.pw-mobile .drawing-item {
    padding: 13px 8px;
    border-radius: 11px;
}

body.pw-mobile .palette-icon {
    width: 19px;
    height: 19px;
}

body.pw-mobile .drawing-item,
body.pw-mobile .drawing-color-picker,
body.pw-mobile .palette-divider {
    display: none !important;
}

/* Hover tooltips fire on touch and then stick; kill them. */
body.pw-mobile #palette:not(.palette-expanded) .palette-item:hover::after,
body.pw-mobile #palette:not(.palette-expanded) .drawing-item:hover::after {
    display: none !important;
}

body.pw-mobile .palette-footer-btn {
    width: 40px;
    height: 40px;
}

/* ---------------------------------------------------------------
   Right tools rail — a duplicate of the toolbar menus, and the
   single biggest waste of width on a phone. Hidden outright,
   along with its edge tab, so nothing can bring it back by accident.
   --------------------------------------------------------------- */
body.pw-mobile #tools-sidebar,
body.pw-mobile #tools-show-tab {
    display: none !important;
}

/* ---------------------------------------------------------------
   Canvas overlays
   --------------------------------------------------------------- */

/* The minimap is a 150x96 block on a 390px screen and pans by mouse-drag
   only — no loss. */
body.pw-mobile .slc-minimap {
    display: none !important;
}

/* Zoom control keeps its place bottom-right (the rail it used to clear is
   gone) and grows to tappable buttons — pinch works, but a precise 100%
   reset does not. */
body.pw-mobile .slc-zoom {
    right: max(10px, var(--pw-safe-right));
    bottom: calc(12px + var(--pw-safe-bottom));
    padding: 5px;
    gap: 2px;
}

body.pw-mobile .slc-zoom-btn {
    padding: 11px;
}

body.pw-mobile .slc-zoom-btn svg {
    width: 17px;
    height: 17px;
}

body.pw-mobile .slc-zoom-label {
    font-size: 11.5px;
    min-width: 38px;
}

/* Run / Stop — the most-used control on the canvas. Sits above the home
   indicator and left of the zoom cluster. */
body.pw-mobile .control-buttons {
    bottom: calc(14px + var(--pw-safe-bottom));
    left: max(60px, calc(var(--pw-safe-left) + 60px));
    transform: none;
    padding: 5px;
    border-radius: 18px;
}

body.pw-mobile #control-buttons.controls-hidden {
    transform: translateY(140px);
}

body.pw-mobile .control-btn {
    width: 52px;
    height: 52px;
}

body.pw-mobile .control-btn svg {
    width: 23px;
    height: 23px;
}

body.pw-mobile .control-hide-btn {
    width: 26px;
    height: 52px;
}

/* Edge tab for the collapsed node rail — the one piece of chrome that must
   stay findable with a thumb. */
body.pw-mobile .edge-show-tab {
    width: 30px;
    height: 62px;
}

/* ---------------------------------------------------------------
   LiteGraph context menus (long-press) — 12px rows are unhittable.
   --------------------------------------------------------------- */
body.pw-mobile .litecontextmenu {
    min-width: 200px;
    max-height: 70vh;
    overflow-y: auto;
}

body.pw-mobile .litemenu-entry {
    padding: 13px 14px !important;
    font-size: 13.5px !important;
}

/* ---------------------------------------------------------------
   Node DOM panels — the .pwc-a controls inside a node. The panel is
   scaled with the canvas, so a node at 100% zoom already gives ~34px
   buttons; this just stops iOS from surfacing the callout/selection
   UI when a finger rests on one.
   --------------------------------------------------------------- */
body.pw-mobile .pwc-panel {
    -webkit-touch-callout: none;
}

body.pw-mobile .pwc-a {
    -webkit-tap-highlight-color: transparent;
}

/* Panels must never block a canvas gesture that started on the node body. */
body.pw-mobile .pwc-panel {
    touch-action: none;
}

/* Text fields keep their own gestures (caret drag, scroll). Their font size
   is deliberately left alone — the panel is transform-scaled with the canvas,
   so forcing 16px would wreck the node's typography. The iOS focus-zoom that
   small fonts trigger is blocked at the viewport meta instead
   (MobileMode._applyViewport). */
body.pw-mobile .pwc-panel textarea,
body.pw-mobile .pwc-panel input {
    touch-action: auto;
}

/* ---------------------------------------------------------------
   Modals — full-screen sheets on a phone instead of centred desktop
   cards. The 720px settings modal was fitting a 170px nav rail and a
   179px content pane into 390px, which left every control clipped.
   --------------------------------------------------------------- */
body.pw-mobile .modal {
    width: 100%;
    max-width: 100%;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
    border-left: none;
    border-right: none;
}

body.pw-mobile .modal-header {
    padding: 12px 14px;
    padding-top: max(12px, var(--pw-safe-top));
}

/* Nav rail → scrolling tab strip above the content. */
body.pw-mobile .modal-layout {
    flex-direction: column;
    min-height: 0;
}

body.pw-mobile .settings-nav {
    flex-direction: row;
    width: auto;
    min-width: 0;
    border-right: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    overflow-x: auto;
    overflow-y: hidden;
    padding: 6px 8px;
    scrollbar-width: none;
    flex: 0 0 auto;
}

body.pw-mobile .settings-nav::-webkit-scrollbar { display: none; }

body.pw-mobile .settings-nav-item {
    flex: 0 0 auto;
    white-space: nowrap;
    padding: 10px 12px;
    font-size: 0.82rem;
}

body.pw-mobile .settings-content,
body.pw-mobile .modal-body {
    padding: 16px 14px;
    min-height: 0;
}

body.pw-mobile .modal-footer {
    padding: 12px 14px;
    padding-bottom: max(12px, var(--pw-safe-bottom));
    gap: 8px;
}

body.pw-mobile .modal-footer button {
    flex: 1 1 0;
    padding: 13px 16px;
}

/* Controls: full width and thumb-height. Inputs stay >=16px so the
   viewport lock is not the only thing preventing iOS focus-zoom. */
body.pw-mobile .setting-group input[type="text"],
body.pw-mobile .setting-group input[type="password"],
body.pw-mobile .setting-group input[type="number"],
body.pw-mobile .setting-group select,
body.pw-mobile .setting-group textarea,
body.pw-mobile .settings-content select,
body.pw-mobile .settings-content input[type="text"],
body.pw-mobile .settings-content input[type="password"] {
    width: 100%;
    min-height: 42px;
    font-size: 16px;
    box-sizing: border-box;
}

body.pw-mobile .setting-input-row {
    flex-wrap: wrap;
}

body.pw-mobile .setting-input-row > button {
    flex: 1 1 auto;
    min-height: 42px;
}

/* 13px checkboxes are not tappable. */
body.pw-mobile .setting-group input[type="checkbox"],
body.pw-mobile .settings-content input[type="checkbox"] {
    width: 20px;
    height: 20px;
    flex: none;
}

body.pw-mobile .checkbox-label {
    gap: 10px;
    padding: 6px 0;
}

/* Popovers that are not the big modal still need a ceiling. */
body.pw-mobile .sl-modal,
body.pw-mobile .modal-content {
    max-width: calc(100vw - 20px);
    max-height: calc(100dvh - 80px);
    overflow-y: auto;
}

/* ===============================================================
   PART 2 — the surfaces the first pass deferred.

   Everything above this line covers the home screen, the toolbar,
   the node canvas and the settings modal. What follows covers the
   rest of the app: the video editor, the GPU panel, workspaces,
   labeling, and the floating panels/popovers that were still laid
   out for a 1440px window.

   Touch BEHAVIOUR for drag handles is not here — it is the shared
   bridge in js/touch-drag.js, wired at each drag site.
   =============================================================== */

/* ---------------------------------------------------------------
   Global touch affordances.
   --------------------------------------------------------------- */

/* `manipulation` drops the ~300ms double-tap-zoom wait that makes
   every button feel laggy, without giving up scrolling the way
   `none` would. `.pwc-a` is excluded deliberately: those live on
   transform-scaled node panels whose parent sets touch-action:none
   so a gesture on the node body reaches the canvas, and relaxing it
   per-button would punch a hole in that. */
body.pw-mobile button:not(.pwc-a),
body.pw-mobile [role="button"],
body.pw-mobile select,
body.pw-mobile summary,
body.pw-mobile .sl-navitem,
body.pw-mobile .sl-chip,
body.pw-mobile .tab-item {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

/* With the tap highlight suppressed a button needs to say something
   itself, or a tap that is still waiting on the network reads as a
   dead control. :active is the only press state a touchscreen has. */
body.pw-mobile button:not(.pwc-a):active,
body.pw-mobile [role="button"]:active {
    filter: brightness(1.25);
}

/* ---- the last hover-only affordances ----
   The first pass fixed the home-screen and scene-builder ones. These
   four are the remainder: with no hover they are unreachable, and the
   row simply looks like it has no delete/clear at all. */
body.pw-mobile .lbl-thumb,
body.pw-mobile .veditor-picker-item-delete,
body.pw-mobile .veditor-projects-row-delete,
body.pw-mobile .home-asset-search-clear {
    opacity: 1;
}

/* ---------------------------------------------------------------
   Video editor.

   Desktop is three side-by-side panes (media | preview | properties)
   over a toolbar+timeline row — about 1100px of hard minimum width.
   On a phone the preview and the timeline stay on screen, because
   they are what you are actually looking at, and the two side panes
   become bottom sheets raised from a fixed tab bar
   (.veditor-mobile-bar, built in VideoEditor._buildMobilePaneBar).
   --------------------------------------------------------------- */

/* Built into every editor and shown only here — see the note on
   _buildMobilePaneBar for why it is not gated in JS. */
.veditor-mobile-bar,
.veditor-sheet-scrim {
    display: none;
}

/* The editor is a HOME TAB, not a page of its own — it opens below the
   ~53px home header. Its desktop height is `calc(100vh - 0px)`, which
   inside that tab overhangs the viewport by exactly the header. Filling
   the container instead is what keeps the timeline on screen; the chain
   above it has to carry a height for `100%` to resolve against. */
body.pw-mobile #home-tab-editor,
body.pw-mobile .veditor-fullscreen-container,
body.pw-mobile .veditor-root {
    height: 100%;
    max-height: 100%;
    min-height: 0;
}

/* Room for the fixed tab bar, so the timeline never hides under it. */
body.pw-mobile .veditor-root {
    padding-bottom: calc(54px + var(--pw-safe-bottom));
    overflow: hidden;
}

/* AI review mode replaces both side panes with its own rail and hides
   them outright (.veditor-root.ai-mode in style.css), so the bar would
   be two buttons that open nothing. */
body.pw-mobile .veditor-root.ai-mode .veditor-mobile-bar {
    display: none;
}

body.pw-mobile .veditor-root.ai-mode {
    padding-bottom: var(--pw-safe-bottom);
}

body.pw-mobile .veditor-mobile-bar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 62;
    gap: 6px;
    padding: 6px max(8px, var(--pw-safe-left))
             calc(6px + var(--pw-safe-bottom)) max(8px, var(--pw-safe-right));
    background: var(--ved-surface-1, #14161c);
    border-top: 1px solid var(--ved-border-soft, rgba(154, 177, 214, 0.12));
}

body.pw-mobile .veditor-mobile-tab {
    flex: 1 1 0;
    min-height: 40px;
    border-radius: 10px;
    border: 1px solid var(--ved-border-soft, rgba(154, 177, 214, 0.12));
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-primary, #f4f4f5);
    font-size: 13px;
    font-weight: 500;
}

body.pw-mobile .veditor-mobile-tab-active {
    background: var(--ved-accent-soft, rgba(91, 164, 207, 0.14));
    border-color: var(--ved-accent-strong, rgba(91, 164, 207, 0.28));
}

/* ---- the two side panes, as sheets ----
   width/max-width carry !important because the editor writes both as
   INLINE styles (the persisted _assetWidth / props width from the
   desktop resizers), and an inline width beats any selector. */
body.pw-mobile .veditor-assets,
body.pw-mobile .veditor-properties {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(54px + var(--pw-safe-bottom));
    width: auto !important;
    min-width: 0 !important;
    max-width: none !important;
    height: min(60dvh, 540px);
    z-index: 61;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -18px 44px rgba(0, 0, 0, 0.55);
    /* The sheet is anchored ABOVE the tab bar, so translating by its own
       height alone leaves exactly the bar's height peeking at the bottom
       edge. The offset has to clear the bar as well, plus 2px for the
       border and the shadow's first pixel. */
    transform: translateY(calc(100% + 54px + var(--pw-safe-bottom) + 2px));
    transition: transform 0.22s ease;
}

body.pw-mobile .veditor-assets.veditor-sheet-open,
body.pw-mobile .veditor-properties.veditor-sheet-open {
    transform: translateY(0);
}

body.pw-mobile .veditor-sheet-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(0, 0, 0, 0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

body.pw-mobile .veditor-sheet-scrim.veditor-sheet-open {
    opacity: 1;
    pointer-events: auto;
}

/* Nothing left to resize once the panes are sheets, and an 8px
   invisible col-resize strip is only a way to lose a tap. */
body.pw-mobile .veditor-resize-h,
body.pw-mobile .veditor-resize-v,
body.pw-mobile .veditor-properties-resizer {
    display: none !important;
}

/* .veditor-top is now the preview alone. */
body.pw-mobile .veditor-top {
    padding: 4px 4px 0;
    gap: 0;
}

/* `flex: 1` already gives it the row; an explicit width:100% would be
   100% of the PADDING box and overhang .veditor-top's own 4px gutters. */
body.pw-mobile .veditor-preview {
    min-width: 0;
}

/* Toolbar was a 156px vertical rail beside the timeline; on a phone
   it lies down into a row above it. */
body.pw-mobile .veditor-timeline-section {
    flex-direction: column;
    gap: 2px;
    /* Inline height, written by _startResizeV and restored from
       localStorage on open — a desktop value here would eat the whole
       phone screen. */
    height: 38dvh !important;
    min-height: 0;
}

body.pw-mobile .veditor-toolbar {
    /* The desktop rail pins width: 84px !important; on a phone the row must span the screen. */
    width: auto !important;
    min-width: 0 !important;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    padding: 4px 6px;
    border-radius: 8px 8px 0 0;
    overflow-x: auto;
    scrollbar-width: none;
}

body.pw-mobile .veditor-toolbar::-webkit-scrollbar { display: none; }

body.pw-mobile .veditor-toolbar-main {
    /* The compact-chrome block lays the tools out as the desktop rail's grid
       (!important); on a phone that stack ate the timeline. A scrolling row. */
    display: flex !important;
    flex-direction: row !important;
    flex: 0 0 auto;
    gap: 4px;
}

/* The compact-chrome block pins these at `width: 100% !important;
   min-width: 0 !important; height: 30px !important` — sized for the
   3-column grid of the vertical rail. In a row that collapses each
   button to its 16px icon, so every declaration has to be answered. */
body.pw-mobile .veditor-tool-btn {
    width: auto !important;
    min-width: 40px !important;
    height: 38px !important;
    flex: 0 0 auto;
}

body.pw-mobile .veditor-zoom-control {
    width: auto;
    flex: 0 0 auto;
    margin-top: 0;
}

body.pw-mobile .veditor-zoom-control .veditor-tool-btn {
    width: 36px !important;
    min-width: 36px !important;
    height: 36px !important;
    flex: 0 0 36px;
}

body.pw-mobile .veditor-timeline-wrapper {
    flex: 1;
    min-height: 0;
}

/* The scrollbar doubles as the range trimmer, so it has to be big
   enough to grab by its 6px-wide edge handles. */
body.pw-mobile .veditor-timeline-scrollbar {
    height: 26px;
}

/* Timeline header and project bar hold more buttons than fit; both
   scroll rather than crush. */
body.pw-mobile .veditor-timeline-header,
body.pw-mobile .veditor-project-bar,
body.pw-mobile .veditor-tab-bar {
    overflow-x: auto;
    scrollbar-width: none;
    flex-wrap: nowrap;
}

body.pw-mobile .veditor-timeline-header::-webkit-scrollbar,
body.pw-mobile .veditor-project-bar::-webkit-scrollbar,
body.pw-mobile .veditor-tab-bar::-webkit-scrollbar { display: none; }

body.pw-mobile .veditor-project-bar {
    padding-top: max(4px, var(--pw-safe-top));
}

body.pw-mobile .veditor-project-name-wrap {
    flex: 0 0 auto;
    max-width: 34vw;
}

body.pw-mobile .veditor-project-actions {
    flex: 0 0 auto;
}

/* !important is not decoration here: the editor's compact-chrome block
   pins these at `min-height: 30px !important`, which nothing without it
   can outrank. */
body.pw-mobile .veditor-project-btn,
body.pw-mobile .veditor-header-btn,
body.pw-mobile .veditor-ctrl-btn,
body.pw-mobile .veditor-selbar-btn {
    min-height: 36px !important;
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Icon-only buttons are square at 30px; height alone leaves them 30 wide. */
body.pw-mobile .veditor-header-btn {
    min-width: 36px;
}

body.pw-mobile .veditor-ctrl-play {
    min-width: 46px;
}

/* 150px of monospace timecode next to the transport buttons pushed
   play off the row. */
body.pw-mobile .veditor-time-display {
    min-width: 0;
    font-size: 11px;
}

/* 13px corner handles are a third of a fingertip. */
body.pw-mobile .veditor-transform-handle {
    width: 22px;
    height: 22px;
}

/* Range input thumbs default to ~14px. */
body.pw-mobile .veditor-prop-slider {
    height: 22px;
}

body.pw-mobile .veditor-prop-slider::-webkit-slider-thumb {
    width: 22px;
    height: 22px;
}

body.pw-mobile .veditor-prop-slider::-moz-range-thumb {
    width: 22px;
    height: 22px;
}

/* The floating multi-select bar sat where the sheet tab bar now is. */
body.pw-mobile .veditor-selection-bar {
    left: 6px;
    right: 6px;
    transform: none;
    flex-wrap: wrap;
    gap: 4px;
}

/* Editor's own modals/overlays become full-bleed like the app's. */
body.pw-mobile .veditor-export-content,
body.pw-mobile .veditor-projects-panel,
body.pw-mobile .veditor-picker-panel {
    width: min(100%, calc(100vw - 20px));
    max-width: calc(100vw - 20px);
    max-height: calc(100dvh - 90px);
    overflow-y: auto;
}

/* ---- AI review mode: a 300px rail alongside the preview ----
   `flex` rather than `width: 100%`, for the same reason as the preview:
   100% of .veditor-top's padding box overhangs its 4px gutters. */
body.pw-mobile .aim-rail {
    width: auto;
    min-width: 0;
    flex: 1 1 auto;
    max-height: 46dvh;
}

body.pw-mobile .aim-railtab,
body.pw-mobile .aim-tool,
body.pw-mobile .aim-chip {
    min-height: 36px;
}

body.pw-mobile .aim-sb-split {
    flex-direction: column;
}

/* ---------------------------------------------------------------
   GPU / RunPod panel — a 520px docked rail. Full-screen on a phone;
   there is no width left to dock it beside.
   --------------------------------------------------------------- */
body.pw-mobile .runpod-panel {
    position: fixed;
    inset: 0;
    width: 100% !important;
    min-width: 0;
    max-width: 100%;
    z-index: 320;
    border-left: none;
    padding-top: var(--pw-safe-top);
    padding-bottom: var(--pw-safe-bottom);
}

body.pw-mobile .rp-resize-handle,
body.pw-mobile .runpod-panel .rp-resize {
    display: none !important;
}

/* Three- and two-up stat grids at 390px gave every value ~110px and
   the numbers wrapped mid-digit-group. */
body.pw-mobile .rp-cards,
body.pw-mobile .rp-ovs,
body.pw-mobile .rp-pair {
    grid-template-columns: 1fr 1fr;
}

body.pw-mobile .rp-stats {
    grid-template-columns: 1fr;
}

body.pw-mobile .rp-gpu-n {
    min-width: 0;
}

body.pw-mobile .rp-head {
    padding-top: max(12px, var(--pw-safe-top));
}

body.pw-mobile .rp-seg-b,
body.pw-mobile .rp-btn,
body.pw-mobile .rp-opt,
body.pw-mobile .rp-tab {
    min-height: 38px;
}

/* ---------------------------------------------------------------
   Workspaces — a 280px card column beside a 340px-minimum detail
   pane, then a 380px-minimum auto-fit grid inside it.
   --------------------------------------------------------------- */
body.pw-mobile .ws-page {
    padding: 18px 14px 32px;
}

body.pw-mobile .ws-shell {
    flex-direction: column;
    gap: 14px;
}

body.pw-mobile .ws-left,
body.pw-mobile .ws-right {
    width: 100%;
    min-width: 0;
}

body.pw-mobile .ws-right {
    padding: 16px 14px;
}

body.pw-mobile .ws-cols,
body.pw-mobile .ws-tilegrid {
    grid-template-columns: 1fr;
    gap: 0;
}

body.pw-mobile .ws-member {
    padding: 12px 4px;
}

body.pw-mobile .pws-modal-overlay {
    padding: 16px 12px;
    align-items: flex-end;
}

body.pw-mobile .pws-tpl-grid {
    grid-template-columns: 1fr 1fr;
}

body.pw-mobile .pws-invite-code {
    max-width: 100%;
}

/* ---------------------------------------------------------------
   Labeling mode — a 340px scoring rail beside the image stage.
   --------------------------------------------------------------- */
body.pw-mobile .lbl-main {
    flex-direction: column;
}

body.pw-mobile .lbl-side {
    width: 100%;
    border-left: none;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    padding: 14px;
}

body.pw-mobile .lbl-stage {
    min-height: 42dvh;
}

body.pw-mobile .lbl-modal,
body.pw-mobile .lbl-modal-wide {
    width: 100%;
    max-width: calc(100vw - 20px);
    max-height: calc(100dvh - 60px);
    overflow-y: auto;
}

body.pw-mobile .lbl-an-grid {
    grid-template-columns: 1fr;
    gap: 12px;
}

body.pw-mobile .lbl-tax-name {
    width: auto;
    flex: 1 1 100%;
}

body.pw-mobile .lbl-btn,
body.pw-mobile .lbl-chip,
body.pw-mobile .lbl-cat-pill {
    min-height: 36px;
}

body.pw-mobile .lbl-topbar {
    flex-wrap: wrap;
    gap: 8px;
    padding-top: max(8px, var(--pw-safe-top));
}

/* ---------------------------------------------------------------
   Floating panels and popovers — all sized for a desktop window and
   positioned from JS-written inline left/top, so a popover opened
   near the right edge hung off a 390px screen entirely. Each is
   pinned to both gutters instead; !important is what beats the
   inline coordinates.
   --------------------------------------------------------------- */
body.pw-mobile .tutorial-card {
    left: 8px !important;
    right: 8px !important;
    width: auto !important;
    max-width: none;
    bottom: calc(12px + var(--pw-safe-bottom)) !important;
    top: auto !important;
    max-height: 62dvh;
    overflow-y: auto;
}

body.pw-mobile .tutorial-card-minimized {
    min-width: 0;
    left: auto !important;
    right: 8px !important;
    width: auto !important;
}

body.pw-mobile .tutorial-card-btn {
    min-width: 34px;
    min-height: 34px;
}

body.pw-mobile .history-panel {
    left: 10px;
    right: 10px;
    width: auto;
    bottom: calc(30px + var(--pw-safe-bottom));
    max-height: 40dvh;
}

body.pw-mobile #output-panel {
    left: 8px !important;
    right: 8px !important;
    width: auto !important;
    min-width: 0;
    max-height: 52dvh;
}

body.pw-mobile .collab-dropdown {
    left: 8px !important;
    right: 8px !important;
    width: auto !important;
    max-height: 60dvh;
    overflow-y: auto;
}

body.pw-mobile .comment-popup {
    width: auto;
    max-width: calc(100vw - 24px);
}

/* Group settings (.pwgs) and the organize menu (.pwog) inject their
   own <style> at runtime, which lands after this file in the cascade
   — the extra `body` in the selector is what wins the tie. */
body.pw-mobile .pwgs {
    left: 8px !important;
    right: 8px !important;
    width: auto !important;
    max-height: 68dvh;
    overflow-y: auto;
}

body.pw-mobile .pwog {
    left: 8px !important;
    right: 8px !important;
    min-width: 0 !important;
    max-height: 60dvh;
    overflow-y: auto;
}

/* ---- dialogs that were centred desktop cards ---- */
body.pw-mobile .share-dialog-modal {
    width: 100%;
    max-width: 100%;
    max-height: 88dvh;
    border-radius: 16px 16px 0 0;
    margin-top: auto;
}

body.pw-mobile .share-dialog-overlay,
body.pw-mobile .drive-browser-overlay {
    align-items: flex-end;
    padding: 0;
}

body.pw-mobile .share-dialog-link-row,
body.pw-mobile .share-dialog-invite-row {
    flex-wrap: wrap;
}

body.pw-mobile .share-dialog-url-input,
body.pw-mobile .share-dialog-email-input {
    flex: 1 1 100%;
    min-height: 42px;
    font-size: 16px;
}

body.pw-mobile .share-dialog-btn {
    min-height: 40px;
}

body.pw-mobile .drive-browser-modal {
    width: 100%;
    height: 92dvh;
    max-width: 100%;
    border-radius: 16px 16px 0 0;
}

body.pw-mobile .drive-browser-grid {
    grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
}

body.pw-mobile .drive-browser-close,
body.pw-mobile .drive-browser-import-btn {
    min-width: 38px;
    min-height: 38px;
}

/* The sort bar is a row of `flex: 0 0 auto` chips whose total exceeds
   390px, and nothing clipped it — so the last chip hung 8px past the
   right edge and the whole document scrolled sideways with it. It is a
   chip strip like the folder bar, so it scrolls like one. */
body.pw-mobile .home-sort-bar {
    overflow-x: auto;
    scrollbar-width: none;
}

body.pw-mobile .home-sort-bar::-webkit-scrollbar { display: none; }

/* Workflow defaults: a two-column settings grid. */
body.pw-mobile .wfd-grid {
    grid-template-columns: 1fr;
}

/* Emoji picker: 36px cells are fine, the chrome around them was not. */
body.pw-mobile .emoji-picker-search input {
    min-height: 40px;
    font-size: 16px;
}

body.pw-mobile .emoji-picker-categories {
    overflow-x: auto;
    scrollbar-width: none;
}

body.pw-mobile .emoji-picker-categories::-webkit-scrollbar { display: none; }
