/* mobile-ergonomics.css — CDS mobile input ergonomics (Ben, 2026-07-23).
   Phone-width surfaces get thumb-sized, readable inputs. Any text-entry control at
   <16px font makes iOS Safari/WKWebView auto-zoom the viewport on focus, which is
   the "design doesn't work / jumpy zoom" defect in the iPhone shell — so every
   focusable text control is >=16px here. Scoped entirely to <=760px: desktop
   density is untouched. Loaded after app-extensions.css so its later rules win
   inside the same specificity. */

/* === Cross-platform (ALL widths) =========================================
   Ben 2026-07-25: "use the same changes for YB main app, i like them" — the
   composer geometry from the phone pass is the product-wide look now, so it
   lives OUTSIDE the media query and applies on web, desktop and mobile alike.
   Touch-target sizing and the 16px no-zoom floor stay phone-only below: they
   are device ergonomics, not design, and desktop density must not bloat. */
.box {
  padding: 6px 6px 6px 12px;
  gap: 6px;
  border-radius: 14px;
}
.box textarea {
  line-height: 1.4;
  padding: 8px 0;
  min-height: 20px;        /* single-line rest state; grows with content */
  max-height: 220px;
  border: 0;               /* the .box carries the border */
  border-radius: 0;
}

@media (max-width: 760px) {

  /* --- Text entry: readable and comfortable everywhere ------------------- */
  input:not([type=checkbox]):not([type=radio]):not([type=range]),
  select,
  textarea,
  .form-field,
  .form-textarea {
    font-size: 16px;
    min-height: 48px;
    padding: 12px 14px;
    border-radius: 10px;
  }
  textarea,
  .form-textarea {
    min-height: 96px;
    line-height: 1.5;
  }

  /* --- Chat composer: the primary input, largest of all ------------------
     ITEM F (2026-07-24): the pill read oversized at rest — less rounding (was the full
     var(--r-pill), ~40px+ given the box's own height; capped at 14px here) and a slimmer
     rest-state height (padding + textarea padding both cut). Font stays AT the 16px iOS
     no-zoom floor — never lower, that rule is non-negotiable — the slimming comes from
     padding/line-height, not from shrinking text under 16px. */
  /* Geometry now lives in the cross-platform block above; phone width only has
     to hold the 16px iOS no-zoom floor. */
  .box textarea { font-size: 16px; }
  .send {
    width: 46px;
    height: 46px;
  }
  .send svg { width: 22px; height: 22px; }
  .clip {
    width: 44px;
    height: 44px;
  }

  /* --- Buttons: 44pt minimum tap targets --------------------------------- */
  .btn {
    font-size: 15px;
    padding: 12px 18px;
    min-height: 44px;
  }
  .icbtn {
    width: 44px;
    height: 44px;
  }
  .seg button,
  .seg .seg-item {
    min-height: 44px;
    font-size: 15px;
  }

  /* --- Auth / login card -------------------------------------------------- */
  .authc { padding: 26px 20px; }
  .gbtn {
    font-size: 16px;
    padding: 15px;
    min-height: 52px;
  }
  .auth-waitlist-button {
    font-size: 15px;
    min-height: 44px;
    padding: 12px 16px;
  }

  /* --- App header: one clean row, never a wrapped orphan cluster ---------- */
  /* _ds_bundle.css lets .top wrap at phone widths, which strands the nav
     icon buttons on a floating second row. Native-app pattern instead:
     logo mark only (wordmark hidden), all controls right-aligned in ONE row. */
  /* No overflow-x:auto here: since the 36px icon compaction the row FITS (YUM-516), and
     any overflow value except visible turns .top into a clip box that beheads the chat
     menu panel anchored inside it (only a sliver rendered below the bar). */
  .top {
    flex-wrap: nowrap;
    gap: 4px;
    padding: 10px 6px 10px 10px;
    align-items: center;
    overflow: visible;
    max-width: 100%;
    /* The bundle centres the bar with `margin: 0 auto`. Inside a flex COLUMN an auto margin
       on the cross axis cancels the stretch, so the bar collapsed to its padding — 16px wide,
       with the navigation spilling out of it. Full width, no auto margin. */
    width: 100%;
    margin-left: 0;
    margin-right: 0;
  }
  .top .word { display: none; }
  .top .icbtn {
    width: 36px;
    height: 36px;
    flex: 0 0 auto;
  }
  .top .model-toggle-wrap { gap: 8px; flex: 0 0 auto; }
  /* YUM-516 ("the navigation items are still cut off"): with the document controls and
     the Projects icon the row measured 486px on a 412px screen — Settings clipped off
     the edge. Two moves make it fit (~400px): the document open/minimize controls hide
     on a phone (documents stay reachable through file and chat cards), and the icon
     buttons compact from 40 to 36px with tighter gaps. */
  .top .nav-doc-btn { display: none; }

  /* YUM-517 (Ben 2026-08-03): a phone's top row is chat / projects / settings, nothing
     more. Files fold into the composer's attach menu and the Projects Files tab; the
     standalone deep-thinking toggle duplicates the model pill's bulb above and the
     composer's bulb below. */
  .top .nav-files-btn { display: none; }
  .top .think-toggle-btn { display: none; }

  /* YUM-517: the red fragments under the top icons were coach-mark tip bubbles (and
     their "i" badges) drawing clipped at phone widths. A 400px-wide working row has no
     room for floating tutorial chrome — tips are desktop-only. */
  .tip-bubble { display: none; }
  .tip-info { display: none; }

  /* YUM-517: the composer belongs on the bottom edge, thumb-reachable — not floating
     mid-screen under the prompt chips. The canvas mobile block above forces the shell
     to display:block/height:auto (its panes are position:fixed and don't care); restore
     the app column here so the last row really is the bottom of the screen. */
  .yarnball-app.yarnball-shell,
  .yarnball-shell.dock-rail {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    overflow: hidden;
  }
  .yarnball-main { flex: 1 1 auto; min-height: 0; }
  .compwrap { margin-top: auto; }

  /* YUM-517: the corporate footer costs a full row of a small screen. */
  .app-footer { display: none; }

  /* YUM-517: the file drawer kept its desktop rail width (min(22vw,280px) ≈ a 90-200px
     strip) inside the now full-screen open dock — icons without names. On a phone the
     drawer IS the screen. !important: canvas.css sizes the panels through 3- and 4-class
     variants (.is-open.is-files-only, .is-files-mid.is-open.is-files-only, …) that a
     sane phone selector cannot outrank one by one. */
  .right-dock.is-open .right-dock-panels {
    width: 100% !important;
  }
  .right-dock.is-open .right-dock-panels > .files-drawer {
    flex: 1 1 auto;
    width: 100% !important;
    max-width: none;
    border-left: 0;
    border-right: 0;
  }

  /* --- Settings & generic form surfaces ---------------------------------- */
  .form-field.is-surface { padding: 13px 15px; }
  .field-stack { gap: 12px; }
  .action-row { gap: 12px; }
}


/* === Phone document surface, portrait AND landscape (YUM-517, Ben 2026-08-04) ===========
   Scoped by width OR height on purpose. A phone turned sideways is ~914 CSS px wide, which
   sails past a max-width:760px phone rule — so before this the document sheet fell back to
   the desktop dock and sat on top of the app's own navigation, clipping the icons in half.
   Height is what still says "phone" when the device is rotated: no phone is 520 px tall in
   landscape. Same one-panel-at-a-time design either way round. */
@media (max-width: 760px), (max-height: 520px) {
/* === Phone document surface (YUM-517, Ben 2026-08-03) ==========================
   canvas.css's phone block sizes the dock and the document pane with hard pixel
   arithmetic — `height:calc(100dvh - 151px)` for a 44px switch plus a 107px composer.
   Those numbers are wrong the moment anything moves: the composer is a different
   height once it wraps, and on rotation the pane keeps a portrait-shaped box, so the
   document ran under the composer and off the screen. Replaced here (this sheet loads
   after canvas.css) with a plain column that measures itself: dock top to bottom of the
   screen, the pane as the flexible row inside it. Nothing overlaps because nothing is
   positioned over anything — landscape included. */
/* The document does NOT cover the app. Ben, 2026-08-04: "the whole navbar on top
   disappeared" — it did, because this used to be a position:fixed sheet anchored at top:0,
   which lays over the top bar and leaves no way out of the document. It is now an ordinary
   row of the app's own column: the top bar keeps its place above it and the document takes
   exactly the space that is left. Nothing is positioned over anything, so nothing can be
   covered. */
/* THE one that broke the document view. canvas.css reserves a right-hand gutter the width
   of the desktop viewer so the dock can sit beside the page:
     .yarnball-shell.dock-open:has(.right-dock.is-doc-only .viewer-compact)
       { padding-right: calc(var(--viewer-side) + var(--dock-rail)) }
   canvas.js sets --viewer-side inline (520px). On a phone that gutter is the entire screen:
   the shell's content box measured 0px wide and every child collapsed with it — the top bar
   to 16px, the dock and the document to nothing. A phone has no side to dock to, so there is
   no width to reserve. !important because canvas.css pins this through five :has() variants
   that outrank any plain selector; naming them all here would rot the moment a sixth lands. */
.yarnball-shell,
.yarnball-shell.dock-open,
.yarnball-shell.dock-rail,
.yarnball-shell.tree-open {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

/* Every state canvas.css pins with position:fixed has to be named here, or the one it names
   most specifically wins and the sheet floats over the app again. .is-doc-only (3 classes)
   and its :has(.viewer-compact) variant (4) both outrank a plain .right-dock.is-open — that
   is precisely why the first attempt at this fix changed nothing on screen. */
.right-dock.is-open,
.right-dock.is-open.is-doc-only,
.right-dock.is-open.is-files-only,
.right-dock.is-open.is-split,
.right-dock.is-open.is-files-tab-only,
.right-dock.is-open.is-doc-only:has(.viewer-compact) {
  position: relative;
  top: auto;
  left: auto;
  right: auto;
  bottom: auto;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
  z-index: auto;
}
/* A phone shows one thing at a time: while a document is open the chat list and its
   composer step aside rather than fighting it for the same column. The top bar's chat
   button is how you come back. */
.yarnball-shell:has(.right-dock.is-open) > .yarnball-main,
.yarnball-shell:has(.right-dock.is-open) > .compwrap {
  display: none;
}
/* The document's own toolbar wraps instead of running its controls off the right edge. */
.right-dock.is-open .dock-pane-actions,
.right-dock.is-open .canvas-head,
.right-dock.is-open .canvas-rich-toolbar {
  flex-wrap: wrap;
  row-gap: 6px;
}
/* wrap alone was not enough: the actions row is flex:0 0 auto, so it kept its 455px content
   width on a 412px screen and its buttons had no reason to wrap. Bounded to the parent, it
   wraps and every control stays on screen. */
.right-dock.is-open .dock-pane-actions {
  flex: 1 1 100%;
  max-width: 100%;
  min-width: 0;
}
.right-dock.is-open .right-dock-panels {
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
}
.right-dock.is-open .canvas-pane {
  position: relative;
  top: auto;
  left: auto;
  right: auto;
  bottom: auto;
  width: 100%;
  max-width: 100%;
  height: auto;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.right-dock.is-open .canvas-body,
.right-dock.is-open .canvas-onlyoffice-wrap,
.right-dock.is-open .canvas-onlyoffice-host,
.right-dock.is-open .canvas-onlyoffice-mount,
.right-dock.is-open .docpv,
.right-dock.is-open .docpv-body {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
  overflow: auto;
}
/* The switch belongs IN the column, not fixed over it. */
.right-dock.is-open .canvas-mobile-switch {
  position: relative;
  top: auto;
  left: auto;
  width: 100%;
  max-width: 100%;
  flex: 0 0 auto;
}
/* The last-chat-line overlay was pinned by the same broken arithmetic; on a phone the
   document owns the screen and the chat is one tap away. */
.right-dock.is-open .canvas-mobile-recent { display: none; }

/* While the document list IS open on a phone it is the screen, not a 300px slab parked over
   the document with the toolbar poking out behind it (Ben 2026-08-04: "the canvas keeps
   crashing the screen"). It sits above the dock so it is never half-covered, and its own
   content scrolls instead of running off the bottom. Picking a document closes it — see
   canvas.js. */
.canvas-tree.tree-drawer {
  width: 100vw;
  max-width: 100vw;
  z-index: 70;
  border-right: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
}
.canvas-tree.tree-drawer.collapsing { width: 0; padding-left: 0; padding-right: 0; }
/* The header wraps instead of pushing Close off the edge. */
.canvas-tree-head { flex-wrap: wrap; gap: 6px; row-gap: 8px; }

/* The short pull-out tab a collapsed file browser leaves behind: a thumb-sized handle on
   the edge, not a full-height rail. */
.right-dock.is-open .dock-files-tab {
  position: absolute;
  /* Mid-edge, not the top corner: at the top it landed on the document's own toolbar
     (theme picker, zoom) and read as part of it. Half way down the left edge it reads as
     what it is — a handle to pull the file list back out — and collides with nothing. */
  /* A true earmark: a slim edge grip. As a 72px labelled tab it lay across the document's
     text — icon only, hugging the edge, reachable without covering what you are reading. */
  top: 50%;
  transform: translateY(-50%);
  left: 0;
  z-index: 69;
  width: 26px;
  min-width: 26px;
  min-height: 46px;
  padding: 0;
  justify-content: center;
  font-size: 0;
  opacity: .9;
  writing-mode: horizontal-tb;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  box-shadow: var(--shadow);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

/* A modal must never be wider than the phone it is on. The CDS floors a dialog at
   320px, and a `wide` dialog at 480px, so a desktop modal cannot collapse into a
   narrow column. In CSS min-width beats max-width, so on a 402pt iPhone that 480px
   floor won the cascade outright: every wide modal rendered ~40px past each screen
   edge, clipping its own title and close button. On the Security panel that meant
   the "S" of "Security", the close X, and every green check badge were cut off
   (found in the iOS build 11 pass, 2026-08-18). Keep the floor as the intent it is,
   and let the viewport win whenever the viewport is the smaller of the two. */
.mcard { min-width: min(320px, 100%); }
.mcard.wide { min-width: min(480px, 100%); }
}

/* YUM-1472 (SB chose Design A, 2026-09-29): the phone tab bar (main.js MobileTabBar).
   It is the last in-flow flex child of the shell, never position:fixed, so the composer sits
   directly on top of it. The bar owns the gesture-bar gap; nothing else adds one. */
@media (max-width: 600px) {
  .mobile-tabbar {
    display: flex;
    flex: none;
    order: 99;
    min-height: calc(56px + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    box-sizing: border-box;
    background: var(--surface);
    border-top: 1px solid var(--line);
    position: relative;
    z-index: 41;
  }
  .mobile-tab {
    flex: 1 1 0;
    min-width: 0;
    min-height: 56px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 6px 2px 4px;
    border: 0;
    background: none;
    color: var(--mute);
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .mobile-tab-icon { display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 28px; border-radius: 999px; }
  .mobile-tab-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mobile-tab.active { color: var(--accent); }
  .mobile-tab.active .mobile-tab-icon { background: var(--accent-soft); }
  .mobile-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }

  /* B4: the bar steps aside, in CSS only, while an item is open in Work (its back bar is the
     way out), while the keyboard is up, and while a modal or document covers the screen.
     The keyboard test is html.kb-open (set from the real keyboard in main.js), NOT "a box
     has focus": on iOS, dismissing the keyboard leaves the caret behind and the bar stayed
     gone until the next tap (Ben's iPhone, 2026-10-19). */
  .yarnball-shell:has(.mail-pane-hidden) .mobile-tabbar,
  html.kb-open .mobile-tabbar,
  .yarnball-shell:has(.modal.on, .doc-overlay, .canvas-popup-backdrop) .mobile-tabbar { display: none; }

  /* Settings covers the phone screen (layouts.css). With the bar present it stops at the bar,
     so the other three places stay one tap away. */
  .yarnball-shell:has(.mobile-tabbar) .yb-winlayer { bottom: calc(56px + env(safe-area-inset-bottom)); }
  .yarnball-shell:has(.mobile-tabbar) .yb-winlayer .yb-win { width: 100%; height: 100%; max-width: none; max-height: none; min-width: 0; resize: none; }
}

/* YUM-1472 B5 (frame A2): at phone width Work's rail is one chip row of sources, then one
   row of the open mailbox's folders, then the list. The column tree took a third of the
   screen before the first message. Desktop keeps the icon rail (the name is hidden there). */
@media (max-width: 600px) {
  /* The rail row is only as tall as its chips; the list or the open message takes the rest. */
  .mail-shell:has(> .mail-rail) { grid-template-rows: auto minmax(0, 1fr); }
  .mail-rail.has-tree { flex-direction: row; flex-wrap: nowrap; align-items: flex-start; gap: 6px; max-height: none; overflow: visible; padding: 8px 10px; }
  .mail-rail.has-tree .mail-rail-label { display: none; }
  /* Sources on one sideways-scrolling row (frame A2); the open source's folders, which the
     rail nests after its chip, drop to a second row under it. */
  .mail-rail .work-sources { flex: 1 1 0; min-width: 0; display: grid; grid-auto-flow: column; grid-auto-columns: max-content; grid-template-rows: auto; column-gap: 6px; row-gap: 4px; padding: 0; margin: 0; border: 0; overflow-x: auto; scrollbar-width: none; }
  .mail-rail .work-sources > .work-source { grid-row: 1; }
  .mail-rail .work-source,
  [data-theme] .mail-rail .work-source { width: auto; flex: none; min-height: 32px; padding: 4px 12px; border: 1px solid var(--line); border-radius: 999px; box-shadow: none; }
  .mail-rail .work-source.active,
  .mail-rail:has(.mail-folder.active, .ds-tree-node.active, .todo-rail-item.is-active) .work-source.active { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); box-shadow: none; }
  /* More icons, less text (SB 2026-10-01): each source is an icon chip, and only the open
     source also shows its name, so all six fit one row without scrolling. */
  .mail-rail .work-source,
  [data-theme] .mail-rail .work-source { min-width: 40px; min-height: 36px; padding: 4px 10px; justify-content: center; gap: 6px; }
  .mail-rail .work-source svg { display: block; flex: none; width: 18px; height: 18px; }
  .mail-rail .work-source .work-source-name { display: none; }
  .mail-rail .work-source.active .work-source-name { display: inline; flex: none; }
  .mail-rail .work-sources > :not(.work-source) { grid-row: 2; grid-column: 1 / span 12; contain: inline-size; }
  .mail-nav-folders-tree { display: flex; flex-direction: row; overflow-x: auto; gap: 4px; padding: 2px 0 0; margin: 0; border: 0; scrollbar-width: none; }
  .mail-nav-folders-tree .mail-boxes-label,
  .mail-nav-folders-tree .mail-box-head,
  .mail-nav-folders-tree .mail-rail-newfolder { display: none; }
  .mail-nav-folders-tree .mail-box-root { display: contents; }
  .mail-nav-folders-tree .ds-tree { flex: none; display: flex; flex-direction: row; gap: 4px; margin: 0; padding: 0; border: 0; }
  .mail-nav-folders-tree .ds-tree-branch { flex: none; }
  .mail-nav-folders-tree .ds-tree-row { white-space: nowrap; padding: 2px 8px; }
  .mail-nav-folders-tree .mail-rail-more { flex: none; width: auto; white-space: nowrap; }
  /* One column: the reader only takes room once a message is open. */
  .mail-list-pane:not(.mail-pane-hidden) ~ .mail-reader { display: none; }
  /* Frame A3: an open item has the whole column; its back bar leads out. */
  .mail-shell:has(> .mail-pane-hidden) > .mail-rail { display: none; }
  /* The desktop rule spans the calendar over columns 2 to 4 (app-extensions.css). The phone
     shell has one column, so the calendar fell into 0px implicit columns and the chip row
     stretched to fill the screen. To do already has the same override. */
  .mail-shell > .work-split.is-calendar { grid-column: auto; }

  /* Files and Teams use the two-column frame, which pins the reader to column 2. On a phone
     that put the rail and the reader side by side in 0px and 200px columns. Stack them like
     every other source: chips on top, the source's view below. */
  .work-frame[data-reading-pane] .mail-shell.is-two-column { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .work-frame[data-reading-pane] .mail-shell.is-two-column .mail-reader { grid-column: auto; grid-row: 2; }

  /* Every source keeps the chip row on top. What the source adds to the rail (Files places,
     Teams, the Teams messages filter, To do's Outlook sync) wraps under it as a second row
     of chips. Before, these sat beside the chips and crushed them into one narrow column. */
  .mail-rail, .mail-rail.has-tree {
    flex-direction: row; flex-wrap: wrap; align-items: center; gap: 6px; max-height: none;
    overflow: visible; padding: 8px 10px; border-right: 0; border-bottom: 1px solid var(--line-soft);
  }
  .mail-rail > .work-sources { flex: 0 0 100%; }
  .mail-rail > .work-rail-group { display: contents; }
  .mail-rail > .work-rail-group > .work-rail-group-head,
  .mail-rail > .work-rail-group .work-rail-group-chevron { display: none; }
  .mail-rail > .work-rail-group > * { flex: none; width: auto; }
  /* Files: the Recent files group repeats what the file list below already shows, and on a
     phone it took six rows before the list began. Places stay as chips. */
  .mail-rail > .work-rail-group[data-group="recent"] { display: none; }
  .mail-rail > .todo-sync { flex: 1 1 100%; margin: 0; padding: 2px 2px 0; border-top: 0; }
  .mail-rail > .todo-sync .btn { min-height: 32px; }

  /* The floating button writes a new mail, so it shows on Mail only. Calendar has New event
     in its own bar, and To do has Add a task. */
  .work-frame:not([data-source="mail"]) .mail-rail .new-menu-split { display: none; }

  /* To do's lists (Tasks, Important, New list) become a chip row under the sources, like the
     mail folders, so the rail no longer takes 140px above the tasks. */
  .mail-rail .work-sources > .todo-lists { display: flex; flex-direction: row; gap: 4px; padding: 2px 0 0; margin: 0; border: 0; overflow-x: auto; scrollbar-width: none; }
  .mail-rail .todo-lists > .todo-rail-item,
  .mail-rail .todo-lists > .todo-rail-newlist { flex: none; width: auto; min-height: 32px; padding: 4px 10px; border-radius: 999px; box-shadow: none; }
  .mail-rail .todo-lists > .todo-rail-item.is-active { background: var(--accent-soft); color: var(--accent); }
  .mail-rail .todo-lists .todo-rail-item::before { display: none; }

  /* YUM-1472 Calendar at phone width, after Outlook's phone agenda: one row per day with the
     date as a sticky header, each meeting a full-width row with its times in a left column,
     and an empty day says so. Controls are 40px touch targets; New event is an icon. */
  .work-cal-bar { gap: 6px; padding: 6px 8px; min-height: 52px; }
  .work-cal-bar .work-cal-btn { height: 40px; min-width: 40px; padding: 0 12px; font-size: 13px; }
  .work-cal-bar .work-cal-arrow { width: 40px; padding: 0; font-size: 18px; }
  .work-cal-bar .work-cal-period { flex: 1 1 auto; min-width: 0; justify-content: center; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .work-cal-bar .work-cal-refresh.icbtn { display: none; }
  .work-cal-bar .work-cal-new { width: 40px; padding: 0; justify-content: center; margin-left: 0; background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
  .work-cal-bar .work-cal-new svg { width: 16px; height: 16px; }
  .work-cal-new-label { display: none; }
  .work-cal-view-icons { gap: 6px; padding: 0; }
  .work-cal-view-icon { width: 44px; height: 36px; }
  .work-cal-view-icon svg { width: 18px; height: 18px; }
  .work-tg-colhead { height: 34px; align-items: center; gap: 8px; padding: 0 12px; }
  .work-tg-dayname { font-size: 11px; }
  .work-tg-daynum { font-size: 15px; font-weight: 600; color: var(--ink); }
  .work-tg-col.is-today .work-tg-dayname, .work-tg-col.is-today .work-tg-daynum { color: var(--accent); }
  .work-tg-col { padding-bottom: 4px; }
  .work-tg-ev,
  .work-tg-col-allday .work-cal-chip {
    display: grid; grid-template-columns: 52px minmax(0, 1fr); column-gap: 10px; align-items: start;
    box-sizing: border-box; width: calc(100% - 20px); min-height: 48px; margin: 4px 10px; padding: 7px 10px;
    border: 1px solid var(--line-soft); border-left: 3px solid var(--accent); border-radius: var(--r-xs);
  }
  .work-tg-col-allday { padding: 0; gap: 0; }
  .work-tg-ev .work-tg-ev-time { grid-column: 1; grid-row: 1 / span 2; font-size: 11px; line-height: 1.5; white-space: normal; }
  .work-tg-ev .work-tg-ev-title { grid-column: 2; grid-row: 1; font-size: 14px; }
  .work-tg-ev .work-tg-ev-where { grid-column: 2; grid-row: 2; font-size: 12px; }
  .work-cal-chip-when { grid-column: 1; font-family: var(--mono); font-size: 11px; color: var(--work-dim); }
  .work-cal-chip .work-cal-chip-title { grid-column: 2; font-size: 14px; }
  /* Files at phone width: the folder path takes the first row with Refresh and New (an icon),
     the second row is Search with the view switch. Filter is the same job as Search inside
     one folder, so the phone keeps Search only. */
  .fm-one-row { flex-wrap: wrap; row-gap: 8px; }
  .fm-one-row > .fm-path { flex: 1 1 0; order: 0; }
  .fm-one-row > .fm-filter { display: none; }
  .fm-one-row > .icbtn, .fm-one-row > .fm-new { order: 1; width: 40px; height: 40px; min-width: 40px; padding: 0; justify-content: center; }
  .fm-one-row > .fm-new .fm-new-label { display: none; }
  .fm-one-row > .fm-new svg { width: 16px; height: 16px; }
  .fm-one-row > .fm-search { order: 2; flex: 1 1 60%; min-width: 0; height: 40px; }
  .fm-one-row > .fm-views { order: 3; }

  /* Month: each meeting is a mark under the date, and a tap on the day opens it. */
  .work-cal-month .work-cal-col { cursor: pointer; }
  .work-cal-month .work-cal-col-head { justify-content: center; }
  .work-cal-month .work-cal-col-body { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 3px; min-height: 40px; padding: 4px 2px; pointer-events: none; }
  .work-cal-month .work-cal-chip { width: 6px; height: 6px; min-height: 0; padding: 0; border: 0; border-radius: 50%; background: var(--accent); }
  .work-cal-month .work-cal-chip > * { display: none; }
  .work-tg-col:not(:has(.work-tg-ev, .work-cal-chip)) .work-tg-canvas::after { content: 'No events'; display: block; padding: 6px 12px 8px 74px; font-size: 13px; color: var(--work-mute); }
}

/* Ben 2026-09-30: "make the email more similar to how gmail or outlook does it for phones".
   Outlook's phone app is the model, because Work already follows Outlook on the desktop
   (Focused/Other, the same verbs in the same order). Gmail's app shares the same pattern:
   roomy rows, a floating compose button, a reader with a top bar of verbs and replies at
   the bottom. */
@media (max-width: 600px) {
  /* List rows: a 40px avatar, the sender with the time beside it, subject, one preview line. */
  :root .mail-item { padding: 10px 14px 10px 11px; gap: 12px; }
  :root .mail-avatar.is-row { width: 40px; height: 40px; font-size: 15px; margin-top: 0; }
  :root .mail-item-top, :root .mail-item-subject-line { height: auto; }
  :root .mail-item-from { font-size: 15px; line-height: 21px; }
  :root .mail-item-subject { font-size: 14px; line-height: 20px; }
  :root .mail-item-preview { font-size: 13.5px; line-height: 19px; }
  /* Touch has no hover, and the row's hover verbs covered the time on a tap. */
  .mail-item-hover { display: none !important; }

  /* New mail is a floating button over the list, above the tab bar, like Outlook's and
     Gmail's. The caret's other "new" choices stay on the desktop rail. */
  .mail-rail .new-menu-split:not(.is-caret-only) {
    position: fixed; right: 16px; bottom: calc(56px + 16px + env(safe-area-inset-bottom)); z-index: 40;
    width: auto; margin: 0; border-radius: 16px; box-shadow: 0 4px 14px rgba(0, 0, 0, .22); overflow: hidden;
  }
  .mail-rail .new-menu-split:not(.is-caret-only) .new-menu-caret { display: none; }
  .mail-rail .new-menu-split:not(.is-caret-only) .new-menu-main { width: 56px; height: 56px; padding: 0; justify-content: center; border-radius: 16px; }
  .mail-rail .new-menu-split:not(.is-caret-only) .new-menu-main svg { width: 22px; height: 22px; }

  /* An open mail: Back and the verbs in a top bar, the subject in full, replies at the bottom.
     The old "Back to list" button and the up/down arrows give way to the bar. */
  .mail-reader:has(.mail-phone-bar) > .mail-back-bar,
  .mail-reader:has(.mail-phone-bar) > .mail-reader-nav { display: none; }
  .mail-phone-bar {
    position: sticky; top: 0; z-index: 3; display: flex; align-items: center; gap: 4px;
    min-height: 52px; padding: 4px 8px; background: var(--surface); border-bottom: 1px solid var(--line-soft);
  }
  .mail-phone-bar .icbtn { width: 44px; height: 44px; }
  .mail-phone-bar .icbtn svg { width: 22px; height: 22px; }
  .mail-phone-bar-gap { flex: 1; }
  .mail-reader:has(.mail-phone-bar) .mail-reader-head { padding: 14px 16px 8px; padding-right: 16px; flex-wrap: wrap; }
  .mail-reader:has(.mail-phone-bar) .mail-reader-subject {
    order: -1; flex: 1 0 100%; margin-bottom: 10px; font-size: 20px; line-height: 1.3;
    white-space: normal; overflow: visible; text-overflow: clip;
  }
  .mail-reader:has(.mail-phone-bar) .mail-reader-head-text { display: contents; }
  .mail-reader:has(.mail-phone-bar) .mail-reader-meta { flex: 1; min-width: 0; font-size: 13.5px; }
  .mail-reader:has(.mail-phone-bar) .mail-reader-from-addr { display: none; }
  .mail-reader:has(.mail-phone-bar) .mail-reader-date { margin-left: 8px; font-size: 12.5px; }
  /* The verbs moved to the bars; what stays in this row is Yarnball's own proposals. */
  .mail-actionbar.is-phone > .icbtn { display: none; }
  .mail-actionbar.is-phone { flex-wrap: wrap; padding: 4px 16px 8px; gap: 6px; }
  .mail-actionbar.is-phone:not(:has(> :not(.icbtn):not(.attach-menu-backdrop))) { display: none; }
  /* The tab bar steps aside while a mail is open, so the reply bar takes the screen's foot. */
  .mail-reader:has(.mail-phone-replybar) { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
  .mail-phone-replybar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 42; display: flex; gap: 8px;
    padding: 8px 12px calc(8px + env(safe-area-inset-bottom)); background: var(--surface); border-top: 1px solid var(--line-soft);
  }
  .mail-phone-reply {
    flex: 1 1 0; min-width: 0; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink);
    font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .mail-phone-reply:active { background: var(--accent-soft); }
}

/* YUM-1472 home (agreed with the coordinator 2026-10-01): on a phone the empty chat reads
   from the thumb up. The greeting sits just above the composer, and the composer box takes the
   theme line token, not ink, with 12px side margins. Populated chats already fill the height. */
@media (max-width: 600px) {
  .yarnball-main-compact { justify-content: flex-end; }
  /* Greeting placement (proxy pick D, made by Phone questions for Ben on 2026-10-01; Ben may
     overrule it): the greeting is the empty screen's hero, centred in its upper third; the starters stay on the composer. The 1fr and 2fr
     rows put the greeting a third of the way down whatever height is left, so the keyboard
     shrinks the space above it instead of pushing it off the screen. */
  .yarnball-main-compact > .card {
    flex: 1 1 auto; min-height: 0; padding-bottom: 4px;
    display: grid; grid-template-rows: 1fr auto 2fr auto; grid-template-columns: minmax(0, 1fr);
  }
  .yarnball-main-compact .chat-hello { grid-row: 2; margin: 0; padding: 0 8px; text-align: center; }
  .yarnball-main-compact .chat-hello-line { font-size: 27px; line-height: 1.25; }
  .compwrap { padding-left: 12px; padding-right: 12px; }
  /* Ben, 2026-10-06: the Ask Yarnball field has no frame on a phone; the tab bar rule below it
     already separates it from the bar. */
  .yarnball-app .box, .yarnball-app[data-theme="letterpress"] .box { border: 0; box-shadow: none; }
  .yarnball-app .box, .yarnball-app[data-theme="letterpress"] .box { background: transparent; border-radius: 0; }
  .yarnball-app .box:focus-within, .yarnball-app[data-theme="letterpress"] .box:focus-within { box-shadow: none; }
  .yarnball-app .box textarea { max-height: calc(5 * 1.4em + 16px); }
}

/* YUM-1478 phone: the calendar toolbar holds Today, the arrows, the period, New event and four view
   buttons. At 44px touch targets that is wider than a phone, so it is a 4-column grid on two rows:
   row one is navigation, the period (which may ellipsize) and New event; row two is the four views,
   one equal column each. */
@media (max-width: 900px) {
  .work-cal-bar { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-flow: row; row-gap: 4px; column-gap: 4px; }
  .work-cal-bar > .work-cal-nav { grid-row: 1; grid-column: 1 / 3; justify-self: start; }
  .work-cal-bar > .work-cal-period { grid-row: 1; grid-column: 3; min-width: 0; display: block; text-align: left; padding-left: 4px; padding-right: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .work-cal-bar > .work-cal-period .work-cal-period-caret { display: none; }
  .work-cal-bar > .work-cal-new { grid-row: 1; grid-column: 4; justify-self: end; }
  .work-cal-bar > .work-cal-view-icon { grid-row: 2; width: auto; min-width: 0; }
}

/* Ben, 2026-10-06: no logo row on a phone. main.js renders the top bar on the Chat page only,
   without the logo, and here it stops being a bar: its controls (chats list, security lock,
   plan) float in the top right corner over the conversation, which keeps the full height. */
@media (max-width: 600px) {
  .yarnball-shell:has(> .top) { position: relative; }
  html .yarnball-shell > .top {
    position: absolute; top: 0; right: 0; left: auto; z-index: 6;
    width: auto; max-width: none; margin: 0; padding: 8px 10px; gap: 6px;
    background: transparent; border: 0; box-shadow: none;
  }
  html .yarnball-shell > .top .sp { display: none; }
  html .yarnball-shell > .top .icbtn,
  html .yarnball-shell > .top .topnav-chat,
  html .yarnball-shell > .top .model-lock-standalone {
    width: 44px; height: 44px; padding: 0; justify-content: center;
    border-radius: 50%; background: var(--surface); box-shadow: var(--shadow-sm);
  }
  /* Settings started under the 64px logo row (app-extensions.css); with no row it starts at
     the top. */
  html .yarnball-shell .yb-winlayer { top: 0; }
  /* The first message starts below the floating controls; later ones scroll under them. */
  .yarnball-shell:has(> .top) > .yarnball-main { padding-top: 60px; }
}

/* YUM-1141 — the phone composer's own controls. The compact composer form (box-compact, which
   chat.js renders at phone width) shrank the attach, mic and Send controls to 26 to 30px, and
   the "remove frames from all buttons" rule shrank them again for every .box under 720px, so
   the three controls a reader taps most were the smallest things on the screen. At phone width
   they are 44px now, which is the same floor the header icons and the buttons already carry,
   and the glyphs inside them are not enlarged. The html prefix is what outranks the compact
   rules in app-extensions.css, whose .box-compact .clip.clip--sm weighs three classes.
   The pill grows with them, which is what a thumb wants.
   The 600px bound is the app's phone width, not a round number: settings.js useIsMobile(), every
   phone path in work.js and chat.js's own compact-composer gate all read (max-width: 600px), and
   chat.js renders box-compact at that same width. So this floor covers phone width and the
   601 to 720 band keeps the compact sizing the wider composer has always had. If that band is ever
   treated as a phone, this query has to grow with it, or the controls there stay 26 to 30px. */
@media (max-width: 600px) {
  /* Scoped through .compwrap, the composer wrapper the app and the design system both render,
     so the rule is about the composer and not about every element that happens to carry .box.
     The gap change stays on the compact form alone, which only the phone composer adds. */
  html .compwrap .box .clip,
  html .compwrap .box-compact .clip,
  html .compwrap .box .clip.clip--sm,
  html .compwrap .box-compact .clip.clip--sm,
  /* The compact form carries both classes today, but each control is listed under both so a
     future composer that renders the compact class alone cannot fall back to the small size. */
  html .compwrap .box .composer-plus-prominent,
  html .compwrap .box-compact .composer-plus-prominent { width: 44px; height: 44px; }
  html .compwrap .box .send,
  html .compwrap .box-compact .send { width: 46px; height: 46px; }
  html .compwrap .box-compact { gap: 6px; }
  /* YUM-1141, the header half: the ticket asks for at least 44x44 on the phone header and menu
     controls as well as the composer's. The 760px block above compacts .top .icbtn to 36px for
     YUM-516, and that rule outranks the generic 44px floor in the Buttons section, so the chat
     header buttons stayed 36px. They are 44px here, inside the same phone block as the composer,
     and only their boxes change: the glyph sizes are left alone. The three selectors are the
     same three the phone top cluster carries. */
  html .top .icbtn,
  html .top .topnav-chat,
  html .top .model-lock-standalone { width: 44px; height: 44px; }
}
