/* phone-app.css: the phone pass (Ben, 2026-10-14: "go through all of it ... make good and
   proper UI ... designed well according to the prod website").

   One stylesheet for the phone, loaded last so it settles the cascade on purpose rather than
   by accident. Everything sits inside the 600px phone query, so the website and the desktop
   app are untouched. The look is the production site's: white (or the phone's dark) surface,
   the serif for headings, the system sans for reading, the madder red as the one accent,
   hairline rules instead of boxes, and 44px or larger targets everywhere.

   Sections:
     1. Voice first: the composer microphone and the voice sheet
     2. Screen frame: every phone screen starts at the top, scrolls in one column
     3. Headings, tabs and pills
     4. Dialogs become bottom sheets
     5. Chat: floating controls, chats sheet, messages, composer
     6. Work: source chips, lists, reader, compose, calendar, To do, Teams, meetings, files
     7. Chief of staff
     8. Settings */

@keyframes yb-voice-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  70% { box-shadow: 0 0 0 18px color-mix(in srgb, var(--accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); }
}
@keyframes yb-sheet-in {
  from { transform: translateY(24px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

@media (max-width: 600px) {

  /* === 1. Voice first ==================================================== */

  /* The empty composer's primary action: one large, filled microphone where Send sits. */
  .composer-voice {
    flex: none; width: 52px; height: 52px; margin-left: 2px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%; padding: 0; cursor: pointer;
    background: var(--accent); color: var(--on-accent);
    box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 35%, transparent);
    -webkit-tap-highlight-color: transparent; touch-action: none;
    transition: transform .12s ease;
  }
  .composer-voice:active { transform: scale(.94); }
  .composer-voice:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

  .voice-sheet-layer { position: fixed; inset: 0; z-index: 80; display: flex; flex-direction: column; justify-content: flex-end; }
  .voice-sheet-backdrop { position: absolute; inset: 0; background: color-mix(in srgb, #000 45%, transparent); }
  .voice-sheet {
    position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 18px;
    padding: 10px 20px calc(22px + env(safe-area-inset-bottom));
    background: var(--surface); color: var(--ink);
    border-radius: 22px 22px 0 0; box-shadow: 0 -12px 40px rgba(0, 0, 0, .25);
    min-height: 58vh; max-height: 88vh;
    animation: yb-sheet-in .2s ease-out;
  }
  .voice-sheet-grip { align-self: center; width: 40px; height: 4px; border-radius: 2px; background: var(--line); }
  .voice-sheet-state {
    margin: 4px 0 0; text-align: center;
    font: 600 12px/1.2 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--accent);
  }
  /* A problem is a sentence to read and act on, not a status label. */
  .voice-sheet-state.is-error {
    padding: 10px 14px; border-radius: var(--r-sm); background: var(--accent-soft);
    font: 500 15px/1.4 var(--ui); letter-spacing: 0; text-transform: none; text-align: left;
  }
  .voice-sheet-text {
    flex: 1 1 auto; min-height: 120px; overflow-y: auto;
    font-family: var(--display); font-size: 24px; line-height: 1.35; color: var(--ink);
    text-wrap: pretty; overscroll-behavior: contain;
  }
  .voice-sheet-text.is-empty { color: var(--faint); font-size: 20px; }
  .voice-meter { display: flex; align-items: center; justify-content: center; gap: 4px; height: 56px; }
  /* The bar is full height and scaled from the middle: a transform moves on the compositor,
     where animating height re-laid out the sheet every frame of speech. */
  .voice-meter-bar {
    flex: 0 0 5px; height: 100%; border-radius: 3px; background: var(--line);
    transform: scaleY(.06); transition: transform .09s linear, background-color .2s;
  }
  .voice-meter.is-live .voice-meter-bar { background: var(--accent); }
  .voice-meter-bar[data-level="1"] { transform: scaleY(.12); }
  .voice-meter-bar[data-level="2"] { transform: scaleY(.2); }
  .voice-meter-bar[data-level="3"] { transform: scaleY(.3); }
  .voice-meter-bar[data-level="4"] { transform: scaleY(.4); }
  .voice-meter-bar[data-level="5"] { transform: scaleY(.5); }
  .voice-meter-bar[data-level="6"] { transform: scaleY(.6); }
  .voice-meter-bar[data-level="7"] { transform: scaleY(.7); }
  .voice-meter-bar[data-level="8"] { transform: scaleY(.8); }
  .voice-meter-bar[data-level="9"] { transform: scaleY(.9); }
  .voice-meter-bar[data-level="10"] { transform: scaleY(1); }
  .voice-sheet-actions { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; justify-items: center; }
  .voice-sheet-side {
    display: inline-flex; flex-direction: column; align-items: center; gap: 4px;
    min-width: 72px; min-height: 64px; padding: 8px; border: 0; background: none; color: var(--mute);
    font: 600 12px var(--ui); cursor: pointer; border-radius: 14px;
  }
  .voice-sheet-side:active { background: var(--line-soft); }
  .voice-sheet-mic {
    width: 84px; height: 84px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--ink); color: var(--bg);
  }
  .voice-sheet-mic.is-live { background: var(--accent); color: var(--on-accent); animation: yb-voice-pulse 1.6s ease-out infinite; }
  .voice-sheet-mic:disabled { opacity: .5; }
  .voice-sheet-send {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 52px; border: 0; border-radius: 14px; cursor: pointer;
    background: var(--ink); color: var(--bg); font: 650 16px var(--ui);
  }
  .voice-sheet-send:disabled { background: var(--line-soft); color: var(--faint); }

  /* (The Chief of staff block that lived here described the old board. The screen is
     the simple decision cards now, styled in app-extensions.css COS-DECISIONS for every
     width, so it needs no phone block.) */
}

/* === LANE work ==========================================================
   The Work sources on a phone (Mail, WhatsApp, Calendar, To do, Teams chats, Teams
   channels, Meetings, My OneDrive). Every rule here sits inside the 600px phone query,
   so the website and the desktop app are untouched. New classes introduced by this
   block: work-seg, work-seg-item, work-cal-fab, work-compose-layer, work-compose-head,
   work-compose-title, voice-relay-box, todo-head-btn-label. */
@media (max-width: 600px) {

  /* --- 1. The source strip: one sideways row of named area pills -----------------
     Before this the strip was icon-only except for the open source, so eight areas were
     eight anonymous glyphs. Every area now keeps its name at a fixed 40px height. */
  html [data-theme] .mail-rail .work-source,
  html .mail-rail .work-source {
    flex: none;
    width: auto;
    min-width: 0;
    height: 44px;
    min-height: 44px;
    padding: 0 14px;
    gap: 7px;
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--ink-2);
    font-size: 14px;
    font-weight: 600;
    box-shadow: none;
  }
  html [data-theme] .mail-rail .work-source .work-source-name,
  html .mail-rail .work-source .work-source-name {
    display: inline;
    flex: none;
    overflow: visible;
    font-size: 14px;
  }
  html .mail-rail .work-source svg { width: 16px; height: 16px; }
  html [data-theme] .mail-rail .work-source.active,
  html .mail-rail .work-source.active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 650;
  }
  html .mail-rail .work-source:disabled { opacity: .45; }
  /* The strip itself: a hairline row that scrolls sideways with the names showing. */
  html .mail-rail > .work-sources {
    column-gap: 8px;
    row-gap: 8px;
    padding-bottom: 2px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  html .mail-rail > .work-sources::-webkit-scrollbar { display: none; }
  /* The open source's own rows (To do's lists) are pills of the same height. */
  html .mail-rail .todo-lists > .todo-rail-item,
  html .mail-rail .todo-lists > .todo-rail-newlist {
    min-height: 44px;
    height: 44px;
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface);
    font-size: 14px;
  }
  html .mail-rail .todo-lists > .todo-rail-item.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
  }

  /* --- 2. Mail: the list head --------------------------------------------------- */
  html .mail-list-head.is-mail {
    padding: 8px 12px 6px;
    row-gap: 8px;
  }
  html .mail-list-head.is-mail > .mail-search { height: 44px; }
  html .mail-list-tools,
  html .mail-list-head.is-mail .mail-bulk-bar {
    height: auto;
    min-height: 44px;
    gap: 4px;
  }
  html .mail-list-head .icbtn.mail-tool {
    width: 44px;
    height: 44px;
    min-width: 44px;
  }
  html .mail-list-head .icbtn.mail-tool svg { width: 20px; height: 20px; }
  html .mail-list-head.is-mail .mail-focus-tab {
    min-height: 44px;
    padding: 0 12px;
    font-size: 15px;
  }
  html .mail-list-head.is-mail .mail-list-tools-gap { display: none; }
  /* The date strips a person scrolls past: a full-height row with the count on the right. */
  html .mail-list-group {
    min-height: 44px;
    padding: 0 12px;
    border-bottom: 1px solid var(--line-soft);
    font-size: 14px;
    font-weight: 600;
  }

  /* --- 3. Mail: the reader ------------------------------------------------------ */
  html .mail-phone-bar { min-height: 56px; padding: 4px 6px; }
  html .mail-phone-reply { min-height: 48px; font-size: 14.5px; }
  html .mail-attachment-actions .icbtn { width: 44px; height: 44px; }
  html .mail-reader:has(.mail-phone-bar) .mail-reader-head { padding: 12px 14px 8px; }

  /* Every menu inside Work opens as a sheet from the bottom of the screen, with a grab
     handle, instead of a small popover pinned to the button that opened it. The position
     comes from the design system's popover as an inline offset, so it is overridden with
     importance on purpose: on a phone the sheet owns the foot of the screen. */
  html .work-frame .link-context-menu {
    left: 10px !important;
    right: 10px !important;
    top: auto !important;
    bottom: calc(10px + env(safe-area-inset-bottom)) !important;
    width: auto !important;
    max-height: 72vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 6px 6px 10px;
    border-radius: 20px;
    box-shadow: 0 -10px 40px rgba(0, 0, 0, .28);
  }
  html .work-frame .link-context-menu::before {
    content: "";
    display: block;
    width: 40px;
    height: 4px;
    margin: 2px auto 8px;
    border-radius: 2px;
    background: var(--line);
  }
  html .work-frame .link-context-menu .link-context-menu-item,
  html .work-frame .todo-menu .todo-menu-item {
    min-height: 48px;
    padding: 0 14px;
    border-radius: 14px;
    font-size: 16px;
  }
  html .work-frame .work-cal-popover { padding: 10px 12px 14px; }

  /* --- 4. Mail: the phone compose ----------------------------------------------
     A full screen of its own, no desktop card. The To row keeps its chips, Cc and Bcc
     stay folded behind one word, the body takes the room, and the Send row sticks to
     the foot with the big microphone beside it. */
  .work-compose-layer {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    flex-direction: column;
    background: var(--bg);
  }
  .work-compose-head {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 56px;
    padding: 6px 8px 6px 12px;
    background: var(--surface);
    border-bottom: 1px solid var(--line-soft);
  }
  .work-compose-title {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--display);
    font-size: 19px;
    font-weight: 600;
    color: var(--ink);
  }
  .work-compose-layer .work-compose.is-phone {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 10px 14px 12px;
  }
  .work-compose.is-phone .work-compose-row { min-height: 48px; }
  .work-compose.is-phone .work-compose-label {
    flex: 0 0 62px;
    font-size: 13.5px;
    color: var(--mute);
  }
  .work-compose.is-phone .mail-compose-field {
    min-height: 48px;
    font-size: 16px;
  }
  .work-compose.is-phone .rte,
  .work-compose.is-phone .rich-text { min-height: 44vh; font-size: 16px; }
  .work-compose.is-phone .work-compose-ask { align-items: stretch; }
  /* The sticky foot: microphone and Send first, the rest of the row wraps under them. */
  .work-compose.is-phone .mail-compose-actions {
    position: sticky;
    bottom: -12px;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 12px -14px -12px;
    padding: 10px 14px calc(12px + env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--line-soft);
  }
  .work-compose.is-phone .mail-compose-actions .send-split,
  .work-compose.is-phone .mail-compose-actions .btn.solid { order: 1; min-height: 52px; }
  .work-compose.is-phone .mail-compose-actions > .composer-voice { order: 0; }
  .work-compose.is-phone .mail-compose-actions > .icbtn { order: 2; }
  .work-compose.is-phone .mail-compose-actions > .mail-sig-select,
  .work-compose.is-phone .mail-compose-actions > .mail-options-row,
  .work-compose.is-phone .mail-compose-actions > .mail-draft-status,
  .work-compose.is-phone .mail-compose-actions > .work-compose-translate { order: 3; }
  .work-compose.is-phone .mail-options-row { flex: 1 1 100%; }
  .work-compose.is-phone .work-compose-translate { flex: 1 1 100%; }
  /* The relay box the voice sheet writes into while the body is the rich editor. */
  .voice-relay-box {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    opacity: 0;
    pointer-events: none;
  }

  /* --- 5. WhatsApp ------------------------------------------------------------- */
  html .wa-chip {
    min-height: 44px;
    padding: 0 14px;
    font-size: 14px;
  }
  html .wa-composer .mail-compose-actions { gap: 8px; }
  html .wa-list-head .icbtn { width: 44px; height: 44px; }

  /* --- 6. Shared small controls: segmented control, sheet title, floating action ---
     work-seg is the phone's Day/Week/Month switch and the Meetings status switch. */
  .work-seg {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    gap: 3px;
    padding: 3px;
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface-2);
  }
  .work-seg-item {
    flex: 1 1 0;
    min-width: 0;
    min-height: 38px;
    padding: 0 10px;
    border: 0;
    border-radius: var(--r-pill);
    background: transparent;
    color: var(--ink-2);
    font-family: var(--ui);
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
  }
  .work-seg-item.is-on {
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-sm);
  }
  .work-seg-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* --- 7. Calendar: an agenda --------------------------------------------------- */
  html .work-cal-bar {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 8px;
    column-gap: 8px;
    padding: 8px 12px;
    min-height: 0;
  }
  html .work-cal-bar > .work-cal-nav { grid-row: 1; grid-column: 1; }
  html .work-cal-bar > .work-cal-period { grid-row: 1; grid-column: 2; text-align: right; padding-right: 4px; }
  html .work-cal-bar > .work-cal-view-icon { display: none; }
  html .work-cal-bar > .work-cal-new { display: none; }
  html .work-cal-bar > .work-cal-seg { grid-row: 2; grid-column: 1 / -1; }
  html .work-cal-bar .work-cal-btn { height: 44px; min-width: 44px; }
  html .work-cal-bar .work-cal-arrow { width: 44px; }
  /* The floating way to add a meeting, above the tab bar and out of the way of the list. */
  .work-cal-fab {
    position: fixed;
    right: 16px;
    bottom: calc(56px + 16px + env(safe-area-inset-bottom));
    z-index: 40;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    padding: 0;
    border: 0;
    border-radius: 18px;
    background: var(--accent);
    color: var(--on-accent);
    box-shadow: 0 6px 20px color-mix(in srgb, var(--accent) 38%, transparent);
    cursor: pointer;
  }
  .work-cal-fab:active { transform: scale(.96); }
  .work-cal-fab:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
  .work-cal-fab-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  /* One day of the agenda: its date stays put while its meetings scroll past, and a day
     with nothing on it is one short quiet line instead of a screenful. */
  html .work-tg-col-head { min-height: 40px; padding: 8px 12px 4px; background: var(--surface); }
  html .work-tg-col:not(:has(.work-tg-ev, .work-cal-chip)) .work-tg-canvas { min-height: 0; }
  html .work-tg-col:not(:has(.work-tg-ev, .work-cal-chip)) .work-tg-canvas::after {
    padding: 0 12px 6px 16px;
    line-height: 28px;
    font: 400 14px/28px var(--ui);
    color: var(--mute);
  }
  html .work-tg-ev { min-height: 56px; padding: 9px 10px; }
  html .work-tg-ev .work-tg-ev-title { font-size: 15px; }
  html .work-tg-ev .work-tg-ev-time { font-size: 12px; }
  html .work-cal-month .work-cal-col-body { min-height: 48px; }

  /* --- 8. To do ----------------------------------------------------------------- */
  html .todo-head {
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px 12px;
  }
  html .todo-head-title,
  html .todo-head-modes { display: none; }
  html .todo-head-search {
    flex: 1 1 140px;
    order: 1;
    min-height: 44px;
  }
  html .todo-search { height: 44px; font-size: 16px; }
  html .todo-head-right { order: 2; gap: 4px; margin-left: 0; }
  html .todo-head-btn { width: 44px; height: 44px; padding: 0; justify-content: center; }
  .todo-head-btn-label { display: none; }
  html .todo-add { gap: 8px; padding: 8px 12px; }
  html .todo-add-input { min-height: 44px; font-size: 16px; }
  html .todo-tool { width: 44px; height: 44px; }
  html .todo-tick,
  html .todo-star,
  html .todo-row-menu,
  html .todo-row-expand,
  html .todo-due {
    width: 44px;
    height: 44px;
    min-width: 44px;
  }
  html .todo-row { min-height: 64px; padding: 8px 12px; gap: 8px; }
  html .todo-row-title,
  html .todo-card-title { font-size: 16px; line-height: 1.35; }
  html .todo-row-notes { font-size: 13.5px; line-height: 1.4; }
  html .todo-card { padding: 12px; }
  html .todo-chip { font-size: 13px; min-height: 28px; padding: 0 10px; }
  html .todo-lists > .todo-rail-item { min-height: 44px; }
  html .todo-sync .btn { min-height: 44px; }

  /* --- 9. Teams channels and Teams chats --------------------------------------- */
  /* One list of channels, then the thread. The channel rows are list rows, not a rail. */
  html .work-frame .mail-list-pane > .work-filters { padding: 8px 12px; }
  html .work-frame .mail-list-pane > .work-filters .work-pill {
    min-height: 44px;
    padding: 0 14px;
    font-size: 14px;
  }
  html .mail-list-pane .mail-item .mail-item-subject { font-size: 16px; }
  html .tc-filters { display: flex; flex-wrap: wrap; gap: 8px; padding: 8px 12px; }
  html .tc-filters .work-pill { min-height: 44px; padding: 0 14px; font-size: 14px; }
  /* A chat row a thumb can hit: the name over the last line, the time quiet at the right. */
  html .mail-item.tc-row { min-height: 64px; padding: 10px 16px 10px 12px; gap: 12px; }
  html .tc-row-title { font-size: 16px; }
  html .tc-row-preview { font-size: 14px; color: var(--mute); }
  html .tc-row-time { font: 400 13px var(--ui); color: var(--mute); }
  /* "3 loaded" is a count for a wide screen's status line; a phone list just ends. */
  html .tc-list-note { display: none; }
  /* An open chat fills the screen: the thread grows, the reply box sits on the bottom edge,
     and the way back is a quiet text link at the top left. */
  html .mail-shell:has(> .mail-pane-hidden) { grid-template-rows: minmax(0, 1fr); }
  html .mail-reader:has(> .tc-thread) { display: flex; flex-direction: column; height: 100%; min-height: 0; }
  html .mail-reader:has(> .tc-thread) > .tc-thread { flex: 1 1 auto; }
  html .mail-reader:has(> .tc-thread) > .mail-back-bar { padding: 4px 8px; border-bottom: 0; }
  html .mail-reader:has(> .tc-thread) > .mail-back-bar .btn {
    min-height: 44px; padding: 0 8px; border: 0; background: none; box-shadow: none;
    font: 500 16px var(--ui); color: var(--accent);
  }
  html .mail-reader:has(> .tc-thread) > .mail-back-bar .btn::before { content: '\2039'; margin-right: 6px; font-size: 22px; line-height: 1; }
  html .tc-head { padding: 4px 16px 10px; border-bottom: 1px solid var(--line-soft); }
  html .tc-compose { padding: 8px 12px calc(8px + env(safe-area-inset-bottom)); }
  html .tc-compose-text { min-height: 44px; font-size: 16px; }
  html .tc-head { padding: 8px 12px; }
  html .tc-compose-row .btn { min-height: 44px; }

  /* --- 10. Meetings ------------------------------------------------------------ */
  html .mail-list-head > .work-seg { flex: 1 1 auto; }
  html .mail-item-flags { gap: 6px; }
  html .mail-item-flags .mail-flag { font-size: 12px; min-height: 26px; padding: 0 8px; }

  /* --- 11. My OneDrive and every place rail ------------------------------------ */
  /* The places are pills, not a column of small rows. */
  html .mail-rail .fm-place {
    flex: none;
    width: auto;
    min-height: 40px;
    height: 40px;
    padding: 0 13px;
    gap: 7px;
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface);
    font-size: 14px;
  }
  html .mail-rail .fm-place.active,
  html .mail-rail .fm-place.is-on {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
  }
  html .mail-rail .fm-place .mail-folder-name { font-size: 14px; }
  html .mail-rail > .work-rail-group > * { margin: 0; }
  /* The file browser: fat rows a thumb can hit, and a bar with 44px controls. */
  html .fm-one-row > .icbtn,
  html .fm-one-row > .fm-new { width: 44px; height: 44px; min-width: 44px; }
  html .fm-one-row > .fm-search { height: 44px; }
  html .fm-one-row > .fm-views { gap: 2px; }
  html .fm-view-btn { width: 44px; height: 44px; }
  html .fm-crumb { min-height: 44px; }
  html .fm-item-compact { min-height: 52px; padding: 0 12px; font-size: 16px; }
  html .fm-item-details { min-height: 52px; padding: 0 12px; font-size: 15px; grid-template-columns: minmax(0, 1fr) auto; }
  html .fm-item-details .fm-cell-size,
  html .fm-item-details .fm-cell-kind,
  html .fm-item-details .fm-cell-modified,
  html .fm-details-head { display: none; }
  html .fm-item-icons { padding: 12px 8px; }
  html .fm-item-icons .fm-name { font-size: 13.5px; }
  html .fm-body { padding: 4px 8px 16px; }
  html .fm-status { font-size: 13px; padding: 8px 12px calc(8px + env(safe-area-inset-bottom)); }

  /* The places sit as one block of pills under the source strip. */
  html .mail-rail .work-rail-group:has(.fm-place) { flex-direction: row; flex-wrap: wrap; gap: 8px; padding: 4px 0; }

  /* My OneDrive's tree: one 52px row per file or folder, the name over a quiet size and
     date line, and the row menu a full 44px target. The mono desktop columns ran off the
     right edge of the screen. */
  html .file-tree-row,
  html .file-tree-folder {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "icon name menu" "icon meta menu";
    align-items: center;
    column-gap: 12px;
    min-height: 56px;
    padding: 6px 4px 6px 12px;
    border-bottom: 1px solid var(--line-soft);
    font: 400 16px/1.3 var(--ui);
    text-align: left;
  }
  html .file-tree-folder { grid-template-columns: auto auto minmax(0, 1fr) auto; grid-template-areas: "chev icon name count"; }
  html .file-tree-folder .file-tree-chevron { grid-area: chev; width: 14px; height: 14px; }
  html .file-tree-row .file-tree-icon,
  html .file-tree-folder .file-tree-icon { grid-area: icon; width: 28px; height: 28px; }
  html .file-tree-name { grid-area: name; font-size: 16px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  html .file-tree-row .file-tree-meta { grid-area: meta; font: 400 13px/1.3 var(--ui); color: var(--mute); }
  html .file-tree-row .file-tree-size { display: none; }
  html .file-tree-folder .file-tree-count { grid-area: count; font: 400 13px var(--ui); color: var(--mute); padding-right: 12px; }
  html .file-tree-kebab { grid-area: menu; width: 44px; height: 44px; font-size: 20px; color: var(--mute); }
  /* Phone files are for reading: no new folders from here. */
  html .work-frame .fm-new-folder,
  html .work-frame button[title="New folder"] { display: none; }
}

/* === LANE settings ======================================================
   The Settings window at phone width (Ben, 2026-10-14: every Settings view reads as a phone
   page). Every rule is inside the 600px query and scoped to .yb-win, the class only main.js's
   SettingsWindow renders, so the desktop dialog is untouched. New class introduced by this
   block: yb-set-modal (a marker on <html>, set by settings.js while a Settings dialog is
   open). The four defects it fixes:

     1. Every view starts at the TOP. mobile-ergonomics.css pins .yarnball-main-compact to
        justify-content: flex-end for the chat empty state, and Settings renders through the
        same class, so every Settings page was packed against the bottom edge.
     2. The root list reads as a phone list: 44px icon squares, hairline separators, section
        headings in the serif, Appearance and Text size as real segmented controls.
     3. Sub-views read as phone pages: a header with Back and the page title, body text at
        reading size instead of 8.5 to 12px mono capitals, 44px targets, and no tables.
     4. The dialogs Settings opens (Telepathy, Automations, Feedback, and the three
        settings.js renders itself) become full-height pages. They carry the html marker, so
        the generic .modal and .mcard rules the chat lane owns are left alone. */
@media (max-width: 600px) {

  /* --- 1. The frame: one column, from the top ------------------------------------- */
  :root .yb-win .yarnball-main-compact { justify-content: flex-start; }
  :root .yb-win .yarnball-main { padding: 0; }
  :root .yb-win .settings-wrap,
  :root .yb-win .settings-wrap-wide {
    max-width: none;
    padding: 0 16px calc(24px + env(safe-area-inset-bottom));
  }

  /* The page header. main.js's own window bar is display:none below 760px, so this is the
     only chrome a Settings page has: Back on the left, then the title in the serif. */
  :root .yb-win .mhead {
    display: flex; align-items: center; gap: 10px;
    min-height: 60px; margin: 0; padding: 4px 12px 4px 10px;
    background: var(--surface); border-bottom: 1px solid var(--line-soft);
  }
  :root .yb-win .mhead .mh-t {
    flex: 1 1 auto; min-width: 0; text-align: left;
    font-family: var(--display); font-size: 27px; font-weight: 600;
    letter-spacing: -.02em; line-height: 1.15; color: var(--ink);
    text-transform: none;
  }
  :root .yb-win .mhead .icbtn { width: 44px; height: 44px; flex: none; }
  /* The root view has no Back, so its title sits on the page's own left edge. */
  :root .yb-win .mhead > .mh-sp:first-child { width: 0; }

  /* --- 2. The root list ------------------------------------------------------------ */
  :root .yb-win .settings-wrap .setgh {
    margin: 26px 0 8px; font-family: var(--display); font-size: 16px; font-weight: 600;
    letter-spacing: 0; text-transform: none; color: var(--ink);
  }
  :root .yb-win .settings-wrap > :first-child .setgh,
  :root .yb-win .settings-wrap > div:first-child .setgh { margin-top: 14px; }
  :root .yb-win .settings-wrap .setgroup {
    margin: 0; border: 0; border-top: 1px solid var(--line-soft);
    border-radius: 0; background: transparent; box-shadow: none;
  }
  :root .yb-win .settings-wrap > :first-child .setgroup { border-top: 0; }
  :root .yb-win .settings-wrap .setlink,
  :root .yb-win .settings-wrap .setrow {
    min-height: 68px; padding: 10px 0; gap: 14px; border: 0;
    border-bottom: 1px solid var(--line-soft); align-items: center;
  }
  :root .yb-win .settings-wrap .setgroup > :last-child { border-bottom: 0; }
  :root .yb-win .settings-wrap .setlink .sl-ic {
    display: inline-grid; place-items: center;
    width: 44px; height: 44px; flex: 0 0 44px;
    border: 1px solid var(--line-soft); border-radius: var(--r);
    background: var(--surface-2); color: var(--ink-2);
  }
  :root .yb-win .settings-wrap .setlink .sl-ic svg { width: 22px; height: 22px; }
  /* The icon colour above covers every row, so the two rows whose icon colour carries meaning
     name theirs again: the security lock stays trust green, the destructive row stays red. */
  :root .yb-win .settings-wrap .sec-lock-row .sl-ic { color: var(--trust-green); }
  :root .yb-win .settings-wrap .setlink-danger .setlink .sl-ic { color: var(--danger, #d32f2f); }
  :root .yb-win .settings-wrap .setlink .sl-l {
    font-family: var(--display); font-size: 17px; font-weight: 600; line-height: 1.25;
  }
  :root .yb-win .settings-wrap .setlink .sl-v,
  :root .yb-win .settings-wrap .setrow .sl-v {
    margin-top: 3px; font-family: var(--ui); font-size: 14px; line-height: 1.45;
    letter-spacing: normal; text-transform: none; color: var(--mute);
  }
  :root .yb-win .settings-wrap .setlink .sl-ch { flex: none; width: 24px; justify-content: flex-end; }
  :root .yb-win .settings-wrap .setlink .sl-ch svg { width: 18px; height: 18px; }

  /* The rows that carry actions (a project's verbs, a chat's remove) put them on their own
     full-width line, so five verbs are five thumb-sized targets instead of five 11px links
     squeezed beside the name. */
  :root .yb-win .settings-wrap .setlink { flex-wrap: wrap; row-gap: 2px; }
  :root .yb-win .settings-wrap .row-actions-tight {
    flex: 1 1 100%; flex-wrap: wrap; gap: 0 18px; align-items: center;
  }
  :root .yb-win .settings-wrap .x {
    display: inline-flex; align-items: center; min-height: 44px;
    font-family: var(--ui); font-size: 13.5px; font-weight: 600; letter-spacing: normal;
  }

  /* --- 3. Segmented controls ------------------------------------------------------- */
  /* Appearance and Text size, and every Off/On switch on a sub-page. The active segment keeps
     the app's own accent fill, which the design system already pins with !important. */
  :root .yb-win .settings-wrap .fontscale-row {
    display: flex; width: 100%; min-width: 0; margin: 0;
    padding: 3px; gap: 3px;
    border: 1px solid var(--line); border-radius: var(--r); background: var(--surface-2);
  }
  :root .yb-win .settings-wrap .fontscale-btn {
    flex: 1 1 0; min-width: 0; min-height: 44px; padding: 0 8px;
    border: 1px solid transparent; border-radius: calc(var(--r) - 2px);
    background: transparent; color: var(--ink-2);
    font-family: var(--ui); font-size: 15px; font-weight: 600;
  }
  :root .yb-win .settings-wrap .fontscale-btn.is-on {
    background: var(--accent); border-color: var(--accent); color: var(--on-accent);
  }
  :root .yb-win .settings-wrap .setrow { flex-wrap: wrap; row-gap: 12px; justify-content: flex-start; }
  :root .yb-win .settings-wrap .settings-display .setrow { flex-direction: column; align-items: stretch; gap: 10px; }
  :root .yb-win .settings-wrap .setrow > label { flex: 1 1 100%; font-family: var(--display); font-size: 16px; font-weight: 600; color: var(--ink); }
  :root .yb-win .settings-wrap .setrow > .atabs { flex: 1 1 100%; margin: 0; padding: 3px; border-radius: var(--r); }
  :root .yb-win .settings-wrap .setrow > .btn { flex: 1 1 100%; }
  :root .yb-win .settings-wrap .setrow .atab {
    display: flex; align-items: center; justify-content: center;
    min-height: 44px; padding: 0 10px; border-radius: calc(var(--r) - 2px); font-size: 15px;
  }

  /* --- 4. Sub-view text: sentences at reading size --------------------------------- */
  /* The desk compresses Settings hard; a phone cannot read 8.5px mono capitals, and
     letterpress sets .hint exactly that way. Captions become sentence case in the UI face. */
  :root .yb-win .hint,
  :root .yb-win .s,
  :root .yb-win .muted,
  :root .yb-win .seth,
  :root .yb-win .ds-notice,
  :root .yb-win .sec-claim-line,
  :root .yb-win .storage-usage-text,
  :root .yb-win .conn-cap-item,
  :root .yb-win .conn-cap-item-note,
  :root .yb-win .conn-cap-group-title,
  :root .yb-win .conn-cap-reconnect-link,
  :root .yb-win .conn-row-account,
  :root .yb-win .conn-row-status,
  :root .yb-win .conn-memory-row,
  :root .yb-win .mcp-symbol-note,
  :root .yb-win .usage-hero-sub,
  :root .yb-win .usage-stat,
  :root .yb-win .plan-row-desc,
  :root .yb-win .plan-row-price,
  :root .yb-win .plan-row-cta,
  :root .yb-win .custom-skill-desc,
  :root .yb-win .wizard-step-desc,
  :root .yb-win .wizard-step-done-label,
  :root .yb-win .wizard-optional-heading,
  :root .yb-win .onboarding-step-optional,
  :root .yb-win .mail-automation-state,
  :root .yb-win .profile-field-helper,
  :root .yb-win .speed-test-row,
  :root .yb-win .speed-test-result {
    font-family: var(--ui); font-size: 14px; line-height: 1.5;
    letter-spacing: normal; text-transform: none;
  }
  :root .yb-win .ds-notice,
  :root .yb-win .sec-claim-line,
  :root .yb-win .wizard-step-desc,
  :root .yb-win .custom-skill-desc,
  :root .yb-win .plan-row-desc,
  :root .yb-win .muted { font-size: 14.5px; }
  :root .yb-win .seth { font-size: 16px; font-weight: 600; color: var(--ink); margin: 18px 0 8px; }
  :root .yb-win .sec-claim-title,
  :root .yb-win .wizard-step-title,
  :root .yb-win .custom-skill-name,
  :root .yb-win .profile-field-label { font-size: 16px; }
  :root .yb-win .plan-row-name { font-size: 17px; }
  :root .yb-win .usage-hero-plan { font-size: 26px; }
  :root .yb-win .sl-v b,
  :root .yb-win .sec-claim-line b { font-weight: 600; color: var(--ink); }

  /* --- 5. Targets, and the rows that were desktop tables ---------------------------- */
  :root .yb-win button,
  :root .yb-win [role="button"],
  :root .yb-win .gs-action,
  :root .yb-win .conn-icon-btn,
  :root .yb-win .conn-sync-btn,
  :root .yb-win .conn-text-btn,
  :root .yb-win .scheduled-task-delete-btn,
  :root .yb-win .mail-automation-toggle,
  :root .yb-win .sec-claim { min-height: 44px; }
  :root .yb-win .btn { min-height: 48px; font-size: 15px; }
  :root .yb-win .btn-compact { min-height: 44px; }
  :root .yb-win .gs-action { padding: 0 14px; font-size: 14px; border-radius: var(--r-pill); }
  :root .yb-win .wizard-step-row > .tlink.gs-action {
    min-height: 44px; padding: 0 14px; font-size: 14px; border-radius: var(--r-pill);
  }
  :root .yb-win .conn-icon-btn,
  :root .yb-win .scheduled-task-delete-btn { width: 44px; height: 44px; }
  :root .yb-win .conn-icon-btn.conn-text-btn { width: auto; padding: 0 14px; font-size: 13.5px; }
  :root .yb-win .conn-provider-glyph { width: 40px; height: 40px; border-radius: var(--r); }
  :root .yb-win .conn-row-head { flex-wrap: wrap; gap: 8px; }
  :root .yb-win .conn-row-actions { margin-left: 0; width: 100%; gap: 10px; }
  :root .yb-win .conn-cap-list { columns: 1; padding-left: 0; }
  :root .yb-win .conn-cap-item { gap: 8px; }
  :root .yb-win .conn-switch { min-height: 44px; }
  :root .yb-win .conn-switch-track { width: 46px; height: 28px; }
  :root .yb-win .conn-switch-knob { width: 22px; height: 22px; }
  :root .yb-win .conn-switch-input:checked + .conn-switch-track .conn-switch-knob { transform: translateX(20px); }
  :root .yb-win .conn-switch-label,
  :root .yb-win .conn-switch .s { font-size: 14px; }
  :root .yb-win .mail-automation-toggle { padding: 10px 0; font-size: 15px; }
  :root .yb-win .mail-automation-name { white-space: normal; overflow: visible; }

  /* Full-width actions, stacked. A phone has no room for two verbs side by side. */
  :root .yb-win .action-row { flex-direction: column; align-items: stretch; gap: 10px; }
  :root .yb-win .action-row .btn,
  :root .yb-win .action-row button { width: 100%; justify-content: center; padding: 0 14px; font-size: 15px; }
  :root .yb-win .chip-row { flex-direction: column; align-items: stretch; gap: 10px; }
  :root .yb-win .chip-row > * { flex: 1 1 auto; width: 100%; min-width: 0; }
  :root .yb-win .inline-edit-row,
  :root .yb-win .instructions-row { flex-wrap: wrap; gap: 10px; }
  :root .yb-win .inline-edit-row > .btn,
  :root .yb-win .instructions-row > .btn { flex: 1 1 100%; }

  /* One-column cards where the desk shows a grid or a table. */
  :root .yb-win .mcp-directory-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  :root .yb-win .mcp-symbol-card { min-height: 76px; padding: 10px 6px; border-radius: var(--r); }
  :root .yb-win .mcp-symbol-name { font-size: 13px; }
  :root .yb-win .speed-test-row {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px;
    padding: 12px 0; border-bottom: 1px solid var(--line-soft);
  }
  :root .yb-win .speed-test-row.is-head { display: none; }
  :root .yb-win .speed-test-model { white-space: normal; font-size: 15px; }
  :root .yb-win .speed-test-result { grid-column: 1 / -1; }
  :root .yb-win .plan-row { flex-wrap: wrap; gap: 8px; margin: 0; padding: 16px 0; border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0; background: transparent; }
  :root .yb-win .plan-row-side { width: 100%; justify-content: space-between; }
  :root .yb-win .usage-hero { flex-direction: column; align-items: flex-start; gap: 10px; }
  :root .yb-win .usage-stat-strip { flex-wrap: wrap; gap: 6px 20px; }
  :root .yb-win .usage-stat-sep { display: none; }
  :root .yb-win .storage-usage-line { flex-wrap: wrap; gap: 10px; }
  :root .yb-win .storage-usage-text { white-space: normal; }
  :root .yb-win .storage-usage-meter { flex: 1 1 100%; }
  :root .yb-win .storage-usage-line .btn { flex: 1 1 100%; }
  :root .yb-win .custom-skill-card { padding: 14px 0; border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0; background: transparent; margin: 0; }
  :root .yb-win .custom-skill-header { gap: 12px; }
  :root .yb-win .sec-claim { padding: 14px 0; gap: 12px; }
  :root .yb-win .sec-claim-lock svg { width: 20px; height: 20px; }
  :root .yb-win .sec-claim-more svg { width: 18px; height: 18px; }
  :root .yb-win .wizard-step-row { gap: 12px; align-items: flex-start; }
  :root .yb-win .wizard-step-glyph { width: 22px; height: 22px; margin-top: 2px; }
  :root .yb-win .wizard-step-glyph.is-done::after { left: 6px; top: 2.5px; }
  :root .yb-win .wizard-step-row > .tlink.gs-action { align-self: center; }

  /* Mail: the reading language, the reading pane and the signatures were a label with its
     control beside it on one desktop line. On a phone each control takes its own line. */
  :root .yb-win .settings-wrap .mail-lang-select-row,
  :root .yb-win .settings-wrap .mail-sig-head { flex-direction: column; align-items: stretch; gap: 10px; padding: 12px 0; }
  :root .yb-win .settings-wrap .mail-lang-select { max-width: none; width: 100%; }
  :root .yb-win .settings-wrap .mail-sig-row { padding: 14px; }
  :root .yb-win .settings-wrap .mail-sig-name { flex: 1 1 auto; min-width: 0; }
  :root .yb-win .settings-wrap .mail-sig-default { min-height: 44px; font-size: 14px; white-space: normal; }
  :root .yb-win .settings-wrap .mail-sig-head .btn,
  :root .yb-win .settings-wrap .mail-sig-actions .btn { width: 100%; }
  :root .yb-win .settings-wrap .mail-sig-actions { flex-direction: column; align-items: stretch; gap: 10px; }

  /* Inputs: 16px and 48px, whatever the desk's own class asked for. app-extensions.css settles
     a few of these through .settings-wrap, so they are named the same way here. */
  :root .yb-win .settings-wrap .settings-row-pad { padding: 12px 0; }
  :root .yb-win .settings-wrap .usage-stat { font-size: 14px; }
  :root .yb-win .settings-wrap .plan-row-desc { font-size: 14.5px; line-height: 1.5; }
  /* A row's own text action (a chat's remove) gets its own full-width line, like the verb
     rows above it. In a project row the verbs sit in .row-actions-tight and stay inline. */
  :root .yb-win .settings-wrap .setlink > .x { flex: 1 1 100%; }
  :root .yb-win input:not([type=checkbox]):not([type=radio]),
  :root .yb-win select,
  :root .yb-win textarea,
  :root .yb-win .select-native,
  :root .yb-win .profile-select,
  :root .yb-win .onboarding-profile-field,
  :root .yb-win .mail-lang-select,
  :root .yb-win .automation-select {
    font-size: 16px; min-height: 48px; padding: 12px 14px; border-radius: var(--r-sm);
  }
  :root .yb-win textarea { min-height: 120px; line-height: 1.5; }

  /* --- 6. The dialogs Settings opens become full-height pages ----------------------- */
  /* Telepathy, Automations and Feedback come from the shared modal layer, and the three
     dialogs settings.js renders itself (the custom skill form, a security claim, the model
     speed test) come from the design system's own modal. All six are marked by yb-set-modal
     on <html>, set by settings.js only while one of them is open, so no generic .modal rule
     is restated here and nothing outside Settings changes. */
  :root.yb-set-modal .modal { align-items: stretch; justify-content: stretch; padding: 0; }
  :root.yb-set-modal .modal > .mcard,
  :root.yb-set-modal .modal > .mcard.wide {
    box-sizing: border-box;
    width: 100%; min-width: 0; max-width: none;
    height: 100dvh; min-height: 0; max-height: 100dvh;
    margin: 0; padding: 10px 16px calc(20px + env(safe-area-inset-bottom));
    border: 0; border-radius: 0; box-shadow: none;
    overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  }
  /* The letterpress theme pads the card's children rather than the card, so the children's
     own side padding is dropped here and the card's 16px inset is the only one. */
  :root.yb-set-modal .modal .mcard > *:not(h3):not(p.s) { padding-left: 0; padding-right: 0; }
  :root.yb-set-modal .modal .modal-close-btn,
  :root.yb-set-modal .modal .mclosebtn {
    top: 10px; right: 8px; width: 44px; height: 44px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%; background: transparent; color: var(--mute);
    font-size: 22px; line-height: 1;
  }
  :root.yb-set-modal .modal .modal-close-btn svg { width: 20px; height: 20px; }
  :root.yb-set-modal .modal .mcard > h3 {
    font-family: var(--display); font-size: 26px; font-weight: 600; letter-spacing: -.015em;
    margin: 0; padding: 2px 56px 10px 0; line-height: 1.2;
    border-bottom: 1px solid var(--line-soft);
  }
  :root.yb-set-modal .modal .mcard > p.s {
    font-family: var(--ui); font-size: 14.5px; line-height: 1.5;
    letter-spacing: normal; text-transform: none; color: var(--mute);
    margin: 0; padding: 10px 0 0;
  }
  :root.yb-set-modal .modal .btn { min-height: 48px; font-size: 15px; }
  :root.yb-set-modal .modal .action-row { flex-direction: column; align-items: stretch; gap: 10px; }
  :root.yb-set-modal .modal .action-row .btn { width: 100%; justify-content: center; }
  :root.yb-set-modal .modal .hint,
  :root.yb-set-modal .modal .s,
  :root.yb-set-modal .modal .muted,
  :root.yb-set-modal .modal .feedback-status,
  :root.yb-set-modal .modal .feedback-kicker,
  :root.yb-set-modal .modal .feedback-preview-line,
  :root.yb-set-modal .modal .feedback-empty-note,
  :root.yb-set-modal .modal .feedback-consent-row {
    font-family: var(--ui); font-size: 14px; line-height: 1.5;
    letter-spacing: normal; text-transform: none;
  }
  :root.yb-set-modal .modal .feedback-kicker { font-size: 13px; font-weight: 600; color: var(--ink-2); }
  :root.yb-set-modal .modal .feedback-console-tail { font-size: 12.5px; line-height: 1.5; }
  :root.yb-set-modal .modal .feedback-preview-box { max-height: 34vh; }
  :root.yb-set-modal .modal .feedback-consent-checkbox { width: 22px; height: 22px; flex: none; }
  :root.yb-set-modal .modal input:not([type=checkbox]):not([type=radio]),
  :root.yb-set-modal .modal select,
  :root.yb-set-modal .modal textarea,
  :root.yb-set-modal .modal .automation-select { font-size: 16px; min-height: 48px; padding: 12px 14px; }
  :root.yb-set-modal .modal textarea { min-height: 120px; }

  /* Telepathy: the three views are one segmented row, and every field is a phone field. */
  :root.yb-set-modal .telepathy-modal-body { gap: 16px; }
  :root.yb-set-modal .telepathy-modal-body > nav.telepathy-meta-row {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 0;
  }
  :root.yb-set-modal .telepathy-modal-body > nav.telepathy-meta-row .btn {
    min-height: 44px; justify-content: center; padding: 0 6px; font-size: 14px;
  }
  :root.yb-set-modal .telepathy-input { font-size: 16px; min-height: 48px; padding: 12px 14px; border-radius: var(--r-sm); }
  :root.yb-set-modal .telepathy-group-title {
    font-family: var(--ui); font-size: 14px; font-weight: 600; letter-spacing: normal;
    text-transform: none; color: var(--ink);
  }
  :root.yb-set-modal .telepathy-preview-title {
    font-family: var(--ui); font-size: 13px; font-weight: 600; letter-spacing: normal;
    text-transform: none; color: var(--mute);
  }
  :root.yb-set-modal .telepathy-preview-body,
  :root.yb-set-modal .memory-space-body { font-family: var(--ui); font-size: 15px; line-height: 1.55; }
  :root.yb-set-modal .telepathy-preview { padding: 14px; border-radius: var(--r); background: transparent; }
  :root.yb-set-modal .telepathy-actions { flex-direction: column; align-items: stretch; gap: 10px; }
  :root.yb-set-modal .telepathy-actions .btn { width: 100%; justify-content: center; }
  :root.yb-set-modal .telepathy-meta-row { font-family: var(--ui); font-size: 13.5px; gap: 8px 14px; letter-spacing: normal; text-transform: none; }
  :root.yb-set-modal .telepathy-badge,
  :root.yb-set-modal .telepathy-person-flag {
    font-family: var(--ui); font-size: 12.5px; letter-spacing: normal; text-transform: none;
  }
  :root.yb-set-modal .telepathy-result { font-size: 14.5px; line-height: 1.5; }
  :root.yb-set-modal .telepathy-controls { grid-template-columns: minmax(0, 1fr); }
  :root.yb-set-modal .automation-form-card { padding: 14px; border-radius: var(--r); }

  /* Body copy reads in the theme's own reading face at a readable size, and field labels
     are quiet sentence case, not 11px mono capitals (Ben's phone, 2026-10-19). */
  html .yb-win .settings-wrap .ds-notice,
  html .yb-win .settings-wrap .ds-notice p {
    font-family: var(--ui); font-size: 15px; line-height: 1.55; letter-spacing: 0; text-transform: none;
  }
  html .yb-win .settings-wrap .fld > label {
    font: 500 13px/1.4 var(--ui); letter-spacing: 0; text-transform: none; color: var(--mute);
  }
}

/* === LANE chat ================================================================
   The chat lane's phone surfaces: the chats panel, the two controls that float over
   the conversation, the composer's "+" sheet, every dialog in the app (this lane owns
   the generic .modal .mcard rule), the Projects page, the Projects & Files dialog and
   the security sheet. Ben, 2026-10-14: a row on a phone is a row of a list, not a
   desktop toolbar, and every dialog is a sheet that rises from the bottom edge. */

@media (max-width: 600px) {

  /* --- 1. The chats panel is a bottom sheet ---------------------------------
     It was a 320px dropdown under the Chat button with four 22px icons on every row.
     On a phone it is a full-width sheet: 56px rows (title, time, one 44px more
     button), a 48px search field, New chat as a filled first row, and the four
     actions behind the more button.
     The panel renders inside .top, which is its own stacking context at z-index 6,
     so the whole row is lifted while the sheet is open. Without that the sheet
     would paint under the phone's tab bar (z-index 41). */
  .yarnball-shell > .top:has(.chat-nav-panel) { z-index: 60; }

  .chat-nav-backdrop {
    background: color-mix(in srgb, #000 45%, transparent);
    z-index: 60;
  }

  .yarnball-shell .top .chat-nav-panel {
    position: fixed;
    top: auto; right: 0; bottom: 0; left: 0;
    width: 100%;
    max-width: none;
    max-height: 92vh;
    gap: 0;
    padding: 10px 14px calc(16px + env(safe-area-inset-bottom));
    border: 0;
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -12px 40px rgba(0, 0, 0, .32);
    z-index: 61;
    overscroll-behavior: contain;
    animation: yb-sheet-in .2s ease-out;
  }
  /* The grab handle. A pseudo-element, so the sheet needs no extra markup. */
  .yarnball-shell .top .chat-nav-panel::before {
    content: '';
    display: block;
    flex: none;
    width: 40px;
    height: 4px;
    margin: 2px auto 10px;
    border-radius: 999px;
    background: var(--line);
  }

  /* The sheet's own title and its way out, so a long list is not a trap. */
  .chat-nav-head {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 48px;
    padding: 0 0 2px;
  }
  .chat-nav-head-title {
    flex: 1;
    min-width: 0;
    font-family: var(--display);
    font-size: 20px;
    font-weight: 650;
    color: var(--ink);
  }
  .chat-nav-head-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--mute);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .chat-nav-head-close:active { background: var(--line-soft); color: var(--ink); }

  /* One row of the list: the title and the time on one line, the project under the
     title, and one 44px menu button spanning both lines. */
  .yarnball-shell .top .chat-nav-panel-item {
    min-height: 56px;
    padding: 6px 6px 6px 12px;
    margin: 0;
    gap: 8px;
    border: 0;
    border-bottom: 1px solid var(--line-soft);
    border-radius: 0;
    color: var(--ink);
    font-size: 16px;
  }
  .yarnball-shell .top .chat-nav-panel-item:has(.chat-nav-panel-item-time) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto 44px;
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: 8px;
    row-gap: 1px;
  }
  .yarnball-shell .top .chat-nav-panel-item-title {
    grid-column: 1;
    grid-row: 1;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.25;
  }
  .yarnball-shell .top .chat-nav-panel-item-time {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    font-family: var(--ui);
    font-size: 13px;
    color: var(--mute);
  }
  .yarnball-shell .top .chat-nav-panel-item-project {
    grid-column: 1 / span 2;
    grid-row: 2;
    justify-self: start;
    font-size: 12px;
    color: var(--accent);
  }
  /* The four desktop icons step aside for the one menu button below. */
  .yarnball-shell .top .chat-nav-panel-item .yb-chats-pin,
  .yarnball-shell .top .chat-nav-panel-item .chat-nav-panel-item-archive { display: none; }

  .chat-nav-more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    min-height: 44px;
    padding: 0;
    border-radius: 12px;
    color: var(--mute);
    -webkit-tap-highlight-color: transparent;
  }
  .chat-nav-more:active { background: var(--line-soft); color: var(--ink); }
  .yarnball-shell .top .chat-nav-more {
    grid-column: 3;
    grid-row: 1 / span 2;
    justify-self: end;
  }

  /* The row's own menu, open under it: four labelled 56px actions. */
  .chat-nav-actions {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
    padding: 8px 4px 10px;
    border-bottom: 1px solid var(--line-soft);
  }
  .chat-nav-action {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 56px;
    padding: 6px 2px;
    border: 1px solid var(--line-soft);
    border-radius: 14px;
    background: var(--surface);
    color: var(--ink);
    font-family: var(--ui);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .chat-nav-action:active { background: var(--accent-soft); color: var(--accent); }
  .chat-nav-action-danger { color: var(--accent); }

  /* New chat: the sheet's one filled action, always the first row. */
  .yarnball-shell .top .chat-nav-panel-item.chat-nav-panel-new {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 56px;
    margin: 0 0 4px;
    padding: 8px 14px;
    border: 0;
    border-radius: 14px;
    background: var(--accent);
    color: var(--on-accent);
    font-size: 16px;
    font-weight: 650;
  }
  .yarnball-shell .top .chat-nav-panel-item.chat-nav-panel-new .chat-nav-panel-icon { color: var(--on-accent); }

  .yarnball-shell .top .chat-nav-panel-label {
    padding: 16px 4px 6px;
    border-bottom: 0;
    font-family: var(--ui);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mute);
  }
  .yarnball-shell .top .chat-nav-search {
    min-height: 48px;
    margin: 0 0 4px;
    padding: 12px 14px;
    border-radius: 12px;
    font-size: 16px;
  }
  .yarnball-shell .top .chat-nav-panel-empty { padding: 16px 6px; font-size: 15px; color: var(--mute); }

  /* --- 2. The two controls that float over the conversation -----------------
     44px each, on a surface, so they stay legible over a message that scrolls under
     them. Same size and language as every other target on the screen. */
  html .yarnball-shell > .top .topnav-chat,
  html .yarnball-shell > .top .icbtn,
  html .yarnball-shell > .top .model-lock-standalone {
    border: 1px solid var(--line-soft);
    background: var(--surface);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
  }

  /* --- 3. The composer's "+" menu is a bottom action sheet ------------------- */
  .yarnball-app .attach-menu,
  .yarnball-shell .attach-menu {
    position: fixed;
    top: auto; right: 0; bottom: 0; left: 0;
    width: 100%;
    min-width: 0;
    padding: 10px 14px calc(18px + env(safe-area-inset-bottom));
    border: 0;
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -12px 40px rgba(0, 0, 0, .32);
    z-index: 61;
    animation: yb-sheet-in .2s ease-out;
  }
  .yarnball-app .attach-menu::before,
  .yarnball-shell .attach-menu::before {
    content: '';
    display: block;
    width: 40px;
    height: 4px;
    margin: 2px auto 12px;
    border-radius: 999px;
    background: var(--line);
  }
  .attach-menu-backdrop {
    background: color-mix(in srgb, #000 45%, transparent);
    z-index: 60;
  }
  .yarnball-app .attach-menu-item,
  .yarnball-shell .attach-menu-item {
    min-height: 56px;
    gap: 14px;
    padding: 0 12px;
    border-bottom: 1px solid var(--line-soft);
    border-radius: 12px;
    font-size: 16px;
    color: var(--ink);
  }
  .yarnball-app .attach-menu-item:last-child,
  .yarnball-shell .attach-menu-item:last-child { border-bottom: 0; }
  .attach-menu-item:active { background: var(--surface-2); }
  .attach-menu-icon { width: 22px; height: 22px; }

  /* --- 4. Every dialog is a bottom sheet -------------------------------------
     One rule for all of them, this lane's alone: a centred card with the title and a
     28px × in the same corner is a desktop shape. The card sits on the bottom edge,
     full width, with a grab handle, a 44px close button that clears the title, and a
     body that scrolls.
     The letterpress theme draws its card with 0 padding and pads the children
     instead, so the card keeps that inset and only the vertical padding is set here. */
  html:not(.yb-set-modal) .modal,
  :root[data-theme]:not(.yb-set-modal) .modal {
    align-items: flex-end;
    padding: 0;
    background: color-mix(in srgb, #000 45%, transparent);
  }
  html:not(.yb-set-modal) .modal .mcard,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard {
    width: 100%;
    min-width: 0;
    min-height: 0;
    max-width: 100%;
    max-height: 92vh;
    margin: 0;
    padding: 10px 24px calc(18px + env(safe-area-inset-bottom));
    border: 0;
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -14px 44px rgba(0, 0, 0, .34);
    overscroll-behavior: contain;
    animation: yb-sheet-in .2s ease-out;
  }
  :root[data-theme]:not(.yb-set-modal) .modal .mcard {
    padding-left: 0;
    padding-right: 0;
  }
  html:not(.yb-set-modal) .modal .mcard.is-maximized,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard.is-maximized { height: 92vh; }
  html:not(.yb-set-modal) .modal .mcard::before,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard::before {
    content: '';
    display: block;
    width: 40px;
    height: 4px;
    margin: 0 auto 12px;
    border-radius: 999px;
    background: var(--line);
  }
  /* The title stops before the close button instead of running under it. */
  html:not(.yb-set-modal) .modal .mcard > h3,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard > h3 {
    padding-top: 6px;
    padding-bottom: 8px;
    padding-right: 56px;
    border-bottom: 1px solid var(--line-soft);
    font-size: 20px;
    line-height: 1.25;
  }
  html:not(.yb-set-modal) .modal .mcard > p.s,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard > p.s {
    padding-top: 8px;
    padding-bottom: 0;
    border-bottom: 0;
  }
  /* Both modal shells' close buttons: 44px, round, in the corner. */
  html:not(.yb-set-modal) .modal .mcard > .modal-close-btn,
  html:not(.yb-set-modal) .modal .mcard > .mclosebtn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard > .modal-close-btn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard > .mclosebtn {
    top: 12px;
    right: 12px;
    width: 44px;
    height: 44px;
    min-width: 44px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--mute);
  }
  html:not(.yb-set-modal) .modal .mcard > .modal-close-btn svg,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard > .modal-close-btn svg { width: 20px; height: 20px; }
  html:not(.yb-set-modal) .modal .mcard > .mclosebtn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard > .mclosebtn { font-size: 22px; }
  html:not(.yb-set-modal) .modal .mcard > .modal-maximize-btn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard > .modal-maximize-btn {
    top: 12px;
    right: 62px;
    width: 44px;
    height: 44px;
    min-width: 44px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--mute);
  }
  /* The card scrolls; the panes inside it must not trap the scroll. */
  html:not(.yb-set-modal) .modal .mcard .attachment-modal-content,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attachment-modal-content {
    max-height: none;
    overflow: visible;
    padding: 0;
  }
  /* The security sheet is the same card: 560px and a 500px floor do not fit a phone. */
  html:not(.yb-set-modal) .modal .mcard:has(.sec-panel),
  html:not(.yb-set-modal) .modal .mcard:has(.secfact-detail),
  :root[data-theme]:not(.yb-set-modal) .modal .mcard:has(.sec-panel),
  :root[data-theme]:not(.yb-set-modal) .modal .mcard:has(.secfact-detail) {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    border-radius: 22px 22px 0 0;
    /* auto, not the theme's hidden: the sheet scrolls its own content. */
    overflow-x: hidden;
    overflow-y: auto;
  }
  html:not(.yb-set-modal) .modal .mcard .sec-panel,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-panel { min-height: 0; padding: 0 22px 4px; }
  /* app-extensions.css floors .sec-diagram at 660px below 720px wide (it was written for
     the marketing figure). Inside a phone sheet that is 250px of the path off the edge. */
  html:not(.yb-set-modal) .modal .mcard .sec-diagram,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-diagram { min-width: 0; width: 100%; }
  html:not(.yb-set-modal) .modal .mcard .secfact-detail,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .secfact-detail { min-height: 0; max-height: none; padding-right: 22px; padding-left: 22px; }
  html:not(.yb-set-modal) .modal .mcard .sec-diagram-row,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-diagram-row {
    grid-template-columns: 34px minmax(0, 1fr) 26px;
    column-gap: 10px;
    min-height: 62px;
    padding: 8px 4px;
  }
  html:not(.yb-set-modal) .modal .mcard .sec-diagram-link,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-diagram-link { margin-left: 21px; }
  html:not(.yb-set-modal) .modal .mcard .sec-diagram-label,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-diagram-label { font-size: 15px; }
  html:not(.yb-set-modal) .modal .mcard .sec-diagram-sub,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-diagram-sub { font-size: 12.5px; }
  html:not(.yb-set-modal) .modal .mcard .sec-e2e-only-row,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-e2e-only-row { margin-top: 12px; padding: 12px 14px; }
  html:not(.yb-set-modal) .modal .mcard .sec-e2e-only-check,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-e2e-only-check { width: 20px; height: 20px; }
  html:not(.yb-set-modal) .modal .mcard .sec-e2e-only-text,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-e2e-only-text { font-size: 13.5px; }
  html:not(.yb-set-modal) .modal .mcard .sec-actions,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    margin-top: 12px;
  }
  html:not(.yb-set-modal) .modal .mcard .sec-actions .sec-privacy-link-btn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-actions .sec-privacy-link-btn { min-height: 52px; }
  html:not(.yb-set-modal) .modal .mcard .sec-actions .btn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .sec-actions .btn { width: 100%; min-height: 52px; }

  /* --- 5. The Projects page ---------------------------------------------------
     It was bottom-anchored (the chat empty state's flex-end rule) with a 22px title.
     It starts at the top, in the serif, with the one action the page exists for. */
  .projects-screen { justify-content: flex-start; }
  .projects-screen .settings-wrap { padding-top: 4px; }
  .projects-screen .ptitle { margin-top: 0; padding-bottom: 12px; }
  .projects-screen .ptitle h2 { font-size: 28px; line-height: 1.15; }
  .projects-screen .action-row.is-end .btn {
    width: 100%;
    min-height: 52px;
    justify-content: center;
    font-size: 16px;
  }
  /* The empty state and the loading line were 11px mono caps, pinned at 13px by the generic
     settings rule (html .settings-wrap .hint), which outranks a two-class selector. */
  .projects-screen .settings-wrap .hint {
    margin-top: 4px;
    padding: 14px 2px;
    font-family: var(--ui);
    font-size: 15px;
    line-height: 1.5;
    letter-spacing: normal;
    text-transform: none;
    text-align: left;
    color: var(--ink-2);
  }

  /* --- 6. Projects & Files ----------------------------------------------------
     It was a grid of emoji buttons over a two-pane browser. The actions are one clean
     list of 52px rows; the active folder row takes the theme's own surface, which in
     dark mode is what stops "All files" reading as a white block. */
  html:not(.yb-set-modal) .modal .mcard .attachment-modal-header-actions,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attachment-modal-header-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 12px 0 4px;
  }
  /* flex: 1 in app-extensions makes the field stretch down the column; here it is a row. */
  html:not(.yb-set-modal) .modal .mcard .attachment-search-input,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attachment-search-input {
    flex: none;
    min-height: 48px;
    margin-bottom: 8px;
    border-radius: 12px;
  }
  html:not(.yb-set-modal) .modal .mcard .attach-upload-btn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attach-upload-btn {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    width: 100%;
    min-height: 52px;
    gap: 10px;
    padding: 0 6px;
    border: 0;
    border-bottom: 1px solid var(--line-soft);
    border-radius: 0;
    background: transparent;
    color: var(--ink);
    font-family: var(--ui);
    font-size: 15.5px;
    font-weight: 500;
    text-align: left;
    white-space: normal;
  }
  html:not(.yb-set-modal) .modal .mcard .attach-upload-btn:first-of-type,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attach-upload-btn:first-of-type { border-top: 1px solid var(--line-soft); }
  html:not(.yb-set-modal) .modal .mcard .attach-create-btn,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attach-create-btn { color: var(--accent); font-weight: 600; }
  html:not(.yb-set-modal) .modal .mcard .attach-upload-btn:active,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attach-upload-btn:active { background: var(--surface-2); }
  html:not(.yb-set-modal) .modal .mcard .attachment-browser-folder,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attachment-browser-folder {
    min-height: 44px;
    padding: 8px 12px;
    font-size: 14.5px;
  }
  html:not(.yb-set-modal) .modal .mcard .attachment-browser-folder.is-active,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attachment-browser-folder.is-active {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 700;
  }
  html:not(.yb-set-modal) .modal .mcard .attachment-browser-folders,
  :root[data-theme]:not(.yb-set-modal) .modal .mcard .attachment-browser-folders {
    max-height: none;
    padding: 0 0 6px;
  }
}

/* === LANE work (continued) ==============================================
   The rest of the Work phone pass: sizes and shapes the first block could not reach
   because they belong to the mail editor, to a pill inside a bar, or to a switch that
   needed its own class. */
@media (max-width: 600px) {
  /* The rich editor is where a mail is written on a phone, so it gets real room, and its
     formatting bar scrolls sideways instead of wrapping into the writing. */
  .work-compose.is-phone .work-rte-body {
    min-height: 42vh;
    font-size: 16px;
    line-height: 1.5;
  }
  .work-compose.is-phone .work-rte-bar { flex-wrap: nowrap; overflow-x: auto; gap: 2px; }
  html .work-compose.is-phone .work-rte-btn { min-width: 44px; height: 44px; }
  html .work-compose.is-phone .work-rte-colour { width: 44px; height: 44px; }

  /* The calendar's Day / Week / Month switch takes the whole second row of the bar. */
  .work-cal-seg { flex: 1 1 100%; }

  /* A pill inside a bar of its own: the channel switch in the reader's bar. */
  html .mail-phone-bar .work-pill {
    min-height: 40px;
    padding: 0 14px;
    font-size: 14px;
  }

  /* The big microphone inside WhatsApp's round message bar. */
  html .wa-pill > .composer-voice {
    width: 46px;
    height: 46px;
    margin: 0 0 0 2px;
  }

  /* To do's menus: a sheet of full rows. */
  html .work-frame .todo-menu .todo-menu-item,
  html .work-frame .todo-menu .todo-menu-header { min-height: 44px; }
  html .work-frame .todo-menu { left: 10px; right: 10px; }
}

/* === 0. One rule for every screen =================================================
   A long address, id or link must wrap, never push the page wider than the screen.
   On Ben's iPhone at the 125% text size (Settings -> Text size, which is CSS zoom) the
   Chief of staff page grew wider than the window: the mail address on a card could not
   break, the page scrolled sideways and the fourth tab fell off the edge (2026-10-19).
   "anywhere" (unlike break-word) also shrinks the min-content width, so a layout can
   never be wider than its longest word again. */
@media (max-width: 600px) {
  html :where(*) { overflow-wrap: anywhere; }
  html :where(pre, code) { overflow-wrap: normal; word-break: normal; }
}

/* === 9. Document viewer (main agent) ======================================
   Files open read-only on a phone, in the full-screen viewer. Its desktop head put the
   title in 13.5px type and pushed Translate, Print, Download and zoom into one 736px strip
   that scrolled sideways. On a phone the title leads in the serif, the close sits at the
   thumb's top right, and the tools wrap into two short rows. Print and maximise mean
   nothing on a phone and are left out. */
@media (max-width: 600px) {
  html .dv-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "title window" "meta meta" "tools tools";
    gap: 4px 8px;
    min-height: 0;
    padding: calc(8px + env(safe-area-inset-top)) 8px 10px 16px;
    border-bottom: 1px solid var(--line-soft);
  }
  html .dv-head > .dv-title {
    grid-area: title;
    align-self: center;
    font: 600 20px/1.25 var(--display);
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  html .dv-head > .dv-meta { grid-area: meta; display: block; font: 400 13px var(--ui); color: var(--mute); }
  html .dv-head > .dv-window { grid-area: window; padding-left: 0; border-left: 0; }
  html .dv-head > .dv-window > .icbtn:not(.dv-close) { display: none; }
  html .dv-head > .tx-toolbar {
    grid-area: tools;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 6px 0 0;
    overflow: visible;
  }
  html .dv-head > .tx-toolbar .tx-group { flex-wrap: wrap; gap: 8px; }
  html .dv-head > .tx-toolbar .tx-from { font: 400 14px var(--ui); color: var(--mute); }
  html .dv-head > .tx-toolbar .tx-lang-button { min-height: 44px; font-size: 15px; }
  html .dv-head > .tx-toolbar button.btn { min-height: 44px; font-size: 15px; }
  html .dv-head > .tx-toolbar .tx-group:has(> .modal) > .btn:first-child { display: none; }
  html .dv-head > .tx-toolbar .tx-group,
  html .dv-head > .tx-toolbar .dv-zoom { padding-left: 0; border-left: 0; margin-left: 0; }
  html .dv-head > .tx-toolbar .dv-zoom { margin-left: auto; }
  html .dv-canvas { padding: 12px 8px; }
  html .dv-canvas .docpv-stack,
  html .dv-canvas .work-preview-doc { min-width: 0; width: 100%; padding: 0; }
  html .dv-canvas .docpv-page { max-width: 100%; }

  /* A meeting invite in the mail reader: Accept, Tentative, Decline and More share the row
     equally and never push the reader wider than the screen. */
  html .invite-card-row:has(> .invite-actions) { flex-wrap: wrap; }
  html .invite-actions { display: flex; width: 100%; margin-left: 0; gap: 6px; }
  html .invite-actions > .btn { flex: 1 1 0; min-width: 0; height: 44px; padding: 0 8px; }
  html .invite-actions > .btn:last-child:not(.is-primary):not(.is-danger) { flex: 0 0 44px; }

  /* A reply on a phone is the whole page. The message folds to its one-line strip, so the
     header, the action chips and an invite card step aside while the reply is open. */
  html .mail-reader:has(> .mail-compose.is-full) > .mail-reader-head,
  html .mail-reader:has(> .mail-compose.is-full) > .mail-actionbar,
  html .mail-reader:has(> .mail-compose.is-full) > .invite-card { display: none; }
  html .mail-reader-folded {
    display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 4px 0 16px;
    border-bottom: 1px solid var(--line-soft); font: 400 14px var(--ui); color: var(--mute);
  }
  html .mail-reader-folded-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  html .mail-reader-folded .work-compose-link { min-height: 44px; padding: 0 12px; font-size: 15px; }
  /* The bar: Send and Discard on one line, the message options under it, the aids at the end. */
  html .mail-compose.is-full { padding: 0 16px; }
  html .mail-compose.is-full > .mail-compose-actions.is-top {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 0;
  }
  html .mail-compose-actions .btn { min-height: 44px; }
  html .mail-compose-actions .mail-compose-actions-end { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; flex: 1 1 100%; }
  html .mail-compose-actions .mail-compose-actions-end .icbtn { width: 44px; height: 44px; }
  html .mail-compose-actions select { min-height: 44px; font-size: 15px; }
  html .mail-compose-actions label { min-height: 40px; display: inline-flex; align-items: center; gap: 6px; font-size: 14px; }
  /* Recipients: the label is a quiet word, the chips take the width, Cc and Bcc are 44px. */
  html .mail-compose .work-compose-row { gap: 8px; align-items: flex-start; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
  html .mail-compose .work-compose-links { display: inline-flex; gap: 2px; }
  html .mail-compose .work-compose-link { min-width: 44px; min-height: 44px; font-size: 15px; }
  html .mail-compose .work-compose-label {
    flex: none; width: 36px; min-height: 44px; display: inline-flex; align-items: center;
    padding: 0; border: 0; background: none; font: 400 15px var(--ui); color: var(--mute);
  }
  html .mail-compose .work-people-wrap { flex: 1 1 auto; min-width: 0; }
  html .mail-compose .mail-recipient-field { min-height: 44px; border: 0; padding: 0; background: none; box-shadow: none; }
  html .mail-compose .mail-recipient-input { min-height: 44px; font-size: 16px; border: 0; }
  html .mail-compose .mail-recipient-chip { max-width: calc(100% - 48px); min-height: 32px; font-size: 14px; }
  html .mail-compose .mail-recipient-chip > span:not(.mail-avatar) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  html .mail-compose .mail-recipient-chip .mail-attach-remove { min-width: 32px; min-height: 32px; }
  /* The quoted original sits in the body already; the read-only history under it repeats
     it, which on a phone is a second copy of the same message to scroll past. */
  html .mail-compose.is-full > .mail-history-row { display: none; }
  html .mail-compose .mail-compose-subject-row { padding: 10px 0; }
  html .mail-compose .mail-compose-subject { font: 600 17px/1.3 var(--display); color: var(--ink); }
  html .mail-compose .mail-compose-rte { min-height: 40vh; font-size: 16px; }
  html .mail-compose .mail-recipient-field { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
  html .mail-compose .mail-recipient-field .mail-recipient-input { flex: 1 1 120px; min-width: 120px; }
  html .mail-compose .mail-recipient-field:has(.mail-recipient-chip) .mail-recipient-input { flex-basis: 40px; min-width: 40px; min-height: 36px; }
  html .mail-compose .mail-compose-toolbar-wrap {
    display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; height: auto;
    overflow-x: auto; scrollbar-width: none; padding: 4px 0;
  }
  html .mail-compose .mail-compose-toolbar-wrap > .mail-compose-toolbar { flex: none; }
  html .mail-compose .mail-compose-toolbar-wrap > .mail-sig-select { flex: none; width: auto; min-height: 40px; font-size: 15px; }
  html .mail-compose .mail-compose-toolbar-wrap button { min-width: 40px; height: 40px; }
}
