/* The Auctioneer on a phone (D1, 13 October 2026). Every rule here is under html.phone, which the head of
   app/index.html sets before the first paint, only on a phone with the switch on (/app/?phone=on) or once a view is
   live (phone.js decide(); the same test keeps the class in step at run time). Without the class nothing here
   applies: from 700px up the app is exactly as before, and a phone without the switch keeps R64's notice. Loaded after
   app.css and onboarding.css, so a rule of the same weight wins on order. One block per view, so each view's owner
   finds theirs; this first one is the shell's. The numbers are F's spec of 13 October (phone-spec-2026-10-13.md,
   section 3). The tokens are app.css's :root ones, plus the phone's below. */

/* ── The shell (D1) ───────────────────────────────────────────────────────────────────────────────────────── */
html.phone { --tap: 44px; --bar: 56px; --top: 52px; --gutter: 16px; --panel-max: 85%; }

/* R64's desk rule, undone: under its query the notice is all the desk shows. With the phone layout on, the frame,
   the gate and the line (toast) show as from 700px up; the tour, its Guide pill and Search everything (the palette)
   stay off on a phone (decision 8). Each of these outweighs R64's `.desk > :not(.notice)`. */
html.phone .notice { display: none; }
html.phone .desk > .frame { display: grid; }
html.phone .desk > .gate:not([hidden]) { display: flex; }
html.phone .desk > #toast:not([hidden]) { display: block; }
html.phone .desk > .guide, html.phone .desk > .guide-open, html.phone .desk > #palette { display: none; }

/* The frame edge to edge, one column: no desk padding, border, rounding or shadow, no rail, no Runs handle (Search's
   Threads opens the tray as a panel in D3). Its sides keep clear of the notch on a phone held sideways. The desk's
   height is the visible height while the keyboard is up on an iPhone (--ph-vh, phone.js), and ends above the cookie
   banner while it shows, as from 700px up. */
html.phone .desk { padding: 0; height: calc(var(--ph-vh, 100dvh) - var(--ac-consent-h, 0px)); }
html.phone .frame { grid-template-columns: minmax(0, 1fr); padding: 0 env(safe-area-inset-right, 0px) 0 env(safe-area-inset-left, 0px); border: 0; border-radius: 0; box-shadow: none; }
html.phone .rail, html.phone .tray-dock { display: none; }

/* The top bar: 52px under the top inset. The view's name (Search's thread title once Search is open), the Sample
   marker when it shows, the view's own actions, and the person's mark, 32px in a 44px button, with R65's ring in the
   team's colour on a light ground, opening the account panel. The crumb and the desktop tabs do not come over. */
html.phone .hdr { height: calc(var(--top) + env(safe-area-inset-top, 0px)); padding: env(safe-area-inset-top, 0px) 4px 0 var(--gutter); gap: 8px; }
html.phone .hdr .crumb, html.phone .hdr .tabs { display: none; }
html.phone .ph-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 16px/1.25 var(--sans); color: var(--ink); }
html.phone .hdr .sample { font-size: 11px; }
html.phone .ph-acts { flex: none; display: flex; align-items: center; gap: 2px; }
html.phone .ph-me { flex: none; display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: 50%; background: none; -webkit-tap-highlight-color: transparent; }
html.phone .ph-me:focus-visible { outline-offset: -2px; }
html.phone .ph-disc { display: block; width: 32px; height: 32px; border-radius: 50%; background: #0c0c0e; }
html.phone .ph-disc[data-team] { box-shadow: 0 0 0 1.5px var(--team); }
html.phone .ph-disc auc-mark { width: 32px; height: 32px; }

/* The tab bar, the last of .main, so it sits in the flow and nothing scrolls under it: 56px of tabs over the bottom
   inset (8px at least). Four equal tabs, an icon over its word; the one open is marked (aria-current). The Watchlist's
   count at 11px, Search's live dot while a search runs. Hidden while a text field has focus, so the field sits on the
   keyboard. */
html.phone .ph-tabs { flex: none; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); height: calc(var(--bar) + max(8px, env(safe-area-inset-bottom, 0px))); padding-bottom: max(8px, env(safe-area-inset-bottom, 0px)); background: #fff; box-shadow: inset 0 1px 0 rgba(32,30,29,.1); }
html.phone .ph-tab { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-width: 0; padding: 0 4px; border: 0; background: none; color: var(--muted); font: 600 11.5px/1 var(--sans); -webkit-tap-highlight-color: transparent; }
html.phone .ph-ico { display: grid; place-items: center; width: 56px; height: 28px; border-radius: 999px; transition: background .16s, color .16s; }
html.phone .ph-word { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.phone .ph-tab[aria-current="page"] { color: var(--ink); }
html.phone .ph-tab[aria-current="page"] .ph-ico { background: rgba(32,30,29,.09); }
html.phone .ph-tab .count { position: absolute; top: 3px; left: calc(50% + 9px); min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: var(--blue); color: #fff; font: 600 11px/18px var(--sans); font-style: normal; text-align: center; animation: popIn .3s var(--ease); }
html.phone .ph-tab .live { position: absolute; top: 6px; left: calc(50% + 14px); width: 7px; height: 7px; border-radius: 50%; background: var(--blue); animation: pulseDot 1.5s infinite; }
html.phone .ph-tab:focus-visible { outline-offset: -3px; }
html.phone.phone-typing .ph-tabs { display: none; }

/* A view not open on a phone: its notice in the content area, in R64's card, the top bar naming the view and the
   tab bar still there. Centred while it fits; scrolled when a phone held sideways leaves it less room. */
html.phone .ph-notice { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: auto; padding: 20px var(--gutter); background: var(--desk); }
html.phone .ph-notice .gate-card { flex: none; margin: auto; }
html.phone .ph-notice h2 { margin: 14px 0 0; font: 400 26px/1.1 var(--serif); letter-spacing: -.015em; color: var(--ink); }

/* Fields at 16px (F's spec, 3.10), so a phone does not zoom into one as it takes focus: every field in the app, size
   only, each keeping its own face and weight. The onboarding (#onboarding) is outside the desk and keeps its own. */
html.phone .desk input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=button]):not([type=submit]), html.phone .desk select, html.phone .desk textarea { font-size: 16px; }

/* Lines (toasts) above the tab bar and its inset; the gate's buttons and the cookie banner's at 44px, the banner
   clear of the home indicator (consent.js reads its bottom when it keeps its room). */
html.phone .toast { bottom: calc(var(--bar) + max(8px, env(safe-area-inset-bottom, 0px)) + 12px); }
html.phone.phone-typing .toast { bottom: 12px; }
html.phone .gate-card .btn-34 { height: var(--tap); padding: 0 18px; }
html.phone .ac-consent { bottom: max(12px, env(safe-area-inset-bottom, 0px)); }
html.phone .ac-consent-btn { height: var(--tap); }

/* Panels from the foot of the screen (phone.js openPanel): up to 85% of the visible height, a grabber, a body that
   scrolls inside the panel, and a 44px Close that stays in view below it (a phone held sideways leaves the account
   panel less than its height); the rest dimmed (and inert, phone.js). */
html.phone .ph-sheets { position: absolute; inset: 0; z-index: 11; display: flex; flex-direction: column; justify-content: flex-end; }
html.phone .ph-scrim { position: absolute; inset: 0; background: rgba(32,30,29,.38); animation: phFade .2s var(--ease) both; }
html.phone .ph-sheet { position: relative; display: flex; flex-direction: column; max-height: var(--panel-max); overflow: hidden; padding: 0 0 max(12px, env(safe-area-inset-bottom, 0px)); border-radius: 14px 14px 0 0; background: #fff; box-shadow: 0 -16px 48px rgba(32,30,29,.2); animation: phRise .26s var(--ease) both; }
html.phone .ph-sheet:focus { outline: none; }
html.phone .ph-grab { flex: none; width: 36px; height: 5px; margin: 8px auto 4px; border-radius: 3px; background: rgba(32,30,29,.22); }
html.phone .ph-sheet-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; overscroll-behavior: contain; padding: 0 var(--gutter); -webkit-mask-image: linear-gradient(#000 calc(100% - 12px), transparent); mask-image: linear-gradient(#000 calc(100% - 12px), transparent); }
html.phone .ph-sheet-body::after { content: ""; flex: none; height: 12px; } /* E2-2 (D3): the body's last 12px fade, so a line cut by the panel's height reads as more below; the spacer lets the last line scroll clear of the fade */
html.phone .ph-sheet-title { flex: none; margin: 8px 0 10px; font: 400 26px/1.1 var(--serif); letter-spacing: -.015em; color: var(--ink); }
html.phone .ph-close { flex: none; height: var(--tap); margin: 0 var(--gutter); border: 0; border-radius: 0; background: var(--blue); color: #fff; font: 600 15px/1 var(--sans); }
html.phone .ph-close:hover { background: var(--blue-hover); }
@keyframes phRise { from { transform: translateY(100%); } to { transform: none; } }
@keyframes phFade { from { opacity: 0; } to { opacity: 1; } }

/* The account panel: who is signed in, the plan in planLabel's words, Sign out (the app's own act, as the gate's), and
   what opens on a larger screen. Carl's account menu on the position page is its pattern, without Access code. */
html.phone .ph-acct { flex: none; display: flex; flex-direction: column; gap: 4px; padding: 12px 0; border-top: 1px solid rgba(32,30,29,.1); }
html.phone .ph-acct-k { font: 600 11px/1.2 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--faint); }
html.phone .ph-acct-v { font: 600 16px/1.35 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
html.phone .ph-acct-sub { font: 400 14px/1.4 var(--sans); color: var(--muted); overflow-wrap: anywhere; }
html.phone .ph-signout { flex: none; width: 100%; height: var(--tap); margin-top: 8px; border: 1px solid color-mix(in oklch, var(--ink) 28%, transparent); border-radius: 0; background: transparent; font: 500 15px/1 var(--sans); color: var(--ink); }
html.phone .ph-signout:hover { border-color: var(--ink); background: color-mix(in oklch, var(--ink) 6%, transparent); }
html.phone .ph-acct-line { flex: none; margin: 14px 0 0; font: 400 13.5px/1.5 var(--sans); color: var(--muted); }
/* D7 (F6-3): opened from See plans or Execute (Business), the panel leads with what that press asked (phone.js accountLead). */
html.phone .ph-acct-lead { flex: none; margin: 0 0 14px; font: 400 15px/1.45 var(--sans); color: var(--ink); }

/* ── Search (D3) ────────────────────────────────────────────────────────────────────────────────────────────
   Search on a phone, as F's spec of 13 October sets it (section 4) and the plan's Search section: the conversation at
   12px sides; the first screen in one column; the composer one row (the field at 16px and Send), with a slim row above
   it for the Search/Assistant switch and the usage chip, and no tool chips or set-up line (decision 10); rows as a
   column of cards; an opened card at the screen's width. Every figure keeps its words: the table's header row is not
   shown on a phone, so each figure carries its own label, in the header's words. Rules only, under html.phone: the
   views draw the same markup at every width. */
html.phone .chat .thread { padding: 12px 12px 8px; gap: 14px; }
html.phone .chat .msg-user { max-width: 85%; }

/* The first screen: the mark, the heading, and the four suggestions in one column, each a 52px row whose words have
   the row's width (cut at 62px of text in two columns before). */
html.phone .first-run, html.phone .as-empty { flex: 1 0 auto; } /* taller than the view (a phone held sideways), it scrolls from its top rather than being centred off it */
html.phone .first-run h1 { font-size: 24px; }
html.phone .first-run .starters { grid-template-columns: minmax(0, 1fr); max-width: none; margin-top: 14px; }
html.phone .first-run .starter { min-height: 52px; padding: 9px 14px; }
html.phone .first-run .starter span { font-size: 14px; }

/* The composer: the slim row (the switch, the usage chip) over one row holding the field and Send. The tool chips
   change nothing in a search and the set-up line points at Settings, which a phone does not open: neither is shown
   (decision 10). It sits at the foot of the view, so with the tab bar hidden while typing (the shell) it rests on the
   keyboard. */
html.phone .chat .composer-wrap { padding: 6px 12px 8px; }
html.phone .chat .composer-wrap .su-line-bar, html.phone .chat .composer .tool-chips, html.phone .chat .composer .explainer { display: none; }
html.phone .chat .composer, html.phone .as-composer { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
html.phone .chat .composer:hover, html.phone .chat .composer:focus-within, html.phone .as-composer:hover, html.phone .as-composer:focus-within { border-color: transparent; box-shadow: none; }
html.phone .composer-top { flex: 1 1 auto; gap: 6px 8px; margin: 0; }
html.phone .chat .composer-row, html.phone .as-field { flex: 999 1 360px; min-width: 0; } /* under the slim row on a phone held upright; beside it from about 700px of line (a phone held sideways), where the conversation needs the height */
html.phone .composer-top .mode-switch { flex: none; }
html.phone .composer-top .mode-opt { height: var(--tap); padding: 0 14px; font-size: 13px; }
html.phone .composer-top .uc { min-width: 0; }
html.phone .composer-top .uc-chip { height: var(--tap); max-width: 100%; padding: 0 12px; font-size: 12px; }
html.phone .uc-eyebrow { font-size: 11px; } /* the usage chip's popover, in both composers: its eyebrows at 11px, See usage a 44px target */
html.phone .uc-more { display: inline-flex; align-items: center; min-height: var(--tap); margin-top: 4px; }
/* D7 (E5-2): the popover in a panel from the foot (phone.js usagePanel), at the panel's width and inside the screen at
   every size: usage-chip.js's own markup, without its place over the chip, its card or its rise. */
html.phone #ph-usage .uc { position: static; flex: none; margin: 0; }
html.phone #ph-usage .uc-pop { position: static; width: auto; max-width: none; padding: 2px 0 6px; border: 0; border-radius: 0; background: none; box-shadow: none; animation: none; }
html.phone .chat .composer-row { gap: 6px; height: 50px; padding: 0 2px 0 14px; border: 1.5px solid rgba(32,30,29,.16); border-radius: 12px; background: #fff; transition: border-color .18s, box-shadow .18s; }
html.phone .chat .composer-row:focus-within { border-color: rgba(65,105,225,.6); box-shadow: 0 6px 20px rgba(65,105,225,.09); }
html.phone .chat .composer-row input { height: 100%; line-height: 1.25; text-overflow: ellipsis; } /* a placeholder longer than the field ends in an ellipsis rather than mid-word */
html.phone .chat .composer-row .send { width: var(--tap); height: var(--tap); border-radius: 10px; }

/* The conversation's lines: the question's own paragraph and the summary at a phone's reading size, the search card's
   Cancel and the summary's Refine as 44px targets. */
html.phone .chat .rc-cancel { height: var(--tap); padding: 0 16px; }
html.phone .chat .summary .rf-open { display: inline-flex; align-items: center; min-height: var(--tap); margin: 6px 0 0; padding: 0 16px; font-size: 13px; }
html.phone .chat .refine .rf-acts .btn-30 { height: var(--tap); padding: 0 16px; }
html.phone .chat .refine label.rf input, html.phone .chat .refine label.rf select { min-height: var(--tap); }
html.phone .chat .nearcard .btn-30 { height: var(--tap); padding: 0 16px; }

/* Rows as cards. The table and the line under it take the conversation's whole width, out from under the agent's mark
   (26px and its 11px gap); the summary above stays beside it. One card per lot: the photo (64px) beside the title, up
   to three lines in the list and whole once opened, the badges under it, the meta line, then one row of three
   labelled figures, the Estimate's third a little wider for a range. The rank goes: the order is the cards'. */
html.phone .chat .msg-body > .table, html.phone .chat .msg-body > #next-real { margin-left: -37px; }
html.phone .chat .table { border: 0; border-radius: 0; background: none; overflow: visible; }
html.phone .chat .table > .thead { display: none; }
html.phone .chat .trow { margin-top: 8px; border: 1px solid rgba(32,30,29,.14); border-radius: 11px; background: #fff; overflow: hidden; }
html.phone .chat .table > .thead + .trow { margin-top: 0; }
html.phone .chat .trow.watched { background: rgba(65,105,225,.05); }
html.phone .chat .trow-main, html.phone .chat #results-real .trow-main { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.25fr); grid-template-areas: "lot lot lot" "bid closes est"; gap: 12px 10px; align-items: start; padding: 12px; }
html.phone .chat .trow-main:hover { background: none; }
html.phone .chat .trow.closed .trow-main { background: var(--subtle); }
html.phone .chat .trow-main > .rank { display: none; }
html.phone .chat .trow-main > .lot { grid-area: lot; align-items: flex-start; gap: 12px; }
html.phone .chat .trow .lot .thumb { width: 64px !important; height: 64px !important; border-radius: 8px !important; } /* the view draws it 48px in an inline style */
html.phone .chat .trow .lot-title-row { gap: 6px; }
html.phone .chat .trow .lot-title { flex-basis: 100%; font-size: 16px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
html.phone .chat .trow-main[aria-expanded="true"] .lot-title { display: block; -webkit-line-clamp: unset; line-clamp: none; }
html.phone .chat .trow .lot-meta { margin-top: 5px; }

/* The three figures, each with its label in the header row's words (Bid, Closes, Estimate) and everything the cell
   holds on the desktop: the figure, its source tag, "opening price", "No bid yet", "not available". The Estimate,
   which the desktop drops under 900px, comes back: on a phone it has its own third of the row. */
html.phone .chat .trow-main > .bid { grid-area: bid; }
html.phone .chat .trow-main > .bid + .est { grid-area: closes; }
html.phone .chat .trow-main > .est + .est, html.phone .chat #results-real .trow-main > .est:last-child { grid-area: est; display: block; }
html.phone .chat .trow-main > .bid, html.phone .chat .trow-main > .est { min-width: 0; text-align: left; white-space: normal; line-height: 1.3; overflow-wrap: break-word; }
html.phone .chat .trow-main > .bid::before, html.phone .chat .trow-main > .est::before { display: block; margin-bottom: 5px; font: 600 11px/1.2 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--head); }
html.phone .chat .trow-main > .bid::before { content: "Bid"; }
html.phone .chat .trow-main > .bid + .est::before { content: "Closes"; }
html.phone .chat .trow-main > .est + .est::before { content: "Estimate"; }
html.phone .chat .trow-main > .bid.na, html.phone .chat .trow-main > .est.na { font-size: 12.5px; line-height: 1.3; }

/* An opened card at the screen's width: no 99px indent. The figure lines one to a row, Why and Checks, the photos as a
   row of 88px tiles that scrolls sideways, then the actions as a two-column grid of 44px buttons (Watch this lot, Set
   an alert, Execute in whichever of its states the API gives, Open source page), and Wrong label? under them. */
html.phone .chat .expand { padding: 0 12px 14px; gap: 8px; }
html.phone .chat .expand-top { gap: 8px 12px; }
html.phone .chat .expand-top > .comp { flex-basis: 100%; }
html.phone .chat .expand p { font-size: 13px; line-height: 1.5; }
html.phone .chat .expand .gallery { flex-wrap: nowrap; gap: 8px; margin: 6px -12px 2px; padding: 0 12px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none; }
html.phone .chat .expand .gallery::-webkit-scrollbar { display: none; }
html.phone .chat .expand .gallery .shot { flex: none; width: 88px; height: 88px; scroll-snap-align: start; }
html.phone .chat .expand-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 6px; }
html.phone .chat .expand-actions > * { justify-content: center; min-width: 0; height: auto; min-height: var(--tap); padding: 8px 10px; line-height: 1.25; text-align: center; white-space: normal; }
html.phone .chat .expand .lr-open { display: inline-flex; align-items: center; min-height: var(--tap); font-size: 13px; }
html.phone .chat .expand .lr-chip { height: var(--tap); padding: 0 14px; }
html.phone .chat .expand .lr .c-btn { height: var(--tap); padding: 0 16px; font-size: 13px; }

/* Set a maximum (R89) at the card's width: its amount field full width at 16px (the shell's rule; inputmode stays
   decimal), its buttons 44px, and the API's words in full. */
html.phone .chat .ex-panel { max-width: none; }
html.phone .chat .ex-field { max-width: none; }
html.phone .chat .ex-field input { height: var(--tap); }
html.phone .chat .ex-btns .c-btn { height: var(--tap); padding: 0 16px; font-size: 13px; }

/* Set an alert (the shared panel) inside the card: one item to a line at the card's width, its fields and buttons
   44px. D7 (L-03): one column that does not wrap, so each line is the form's width and its words wrap inside it (a
   wrapping column is as wide as its widest line, which left the form's box at 360). */
html.phone .chat .alert-form { flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 8px; padding: 12px; }
html.phone .chat .alert-form label { min-height: var(--tap); }
html.phone .chat .alert-form .amt { flex: 1; min-width: 0; }
html.phone .chat .alert-form input[type="number"] { flex: 1; min-width: 0; width: auto; height: var(--tap); }
html.phone .chat .alert-form .chk input { -webkit-appearance: none; appearance: none; flex: none; width: var(--tap); height: var(--tap); margin: -10px -6px -10px -11px; border: 0; border-radius: 50%; background: radial-gradient(circle, #fff 0 8px, var(--alert-solid) 8.5px 10px, transparent 10.5px); } /* each time choice a 44px target, drawn as the 20px radio it was */
html.phone .chat .alert-form .chk input:checked { background: radial-gradient(circle, var(--alert-solid) 0 5px, #fff 5.5px 8px, var(--alert-solid) 8.5px 10px, transparent 10.5px); }
html.phone .chat .alert-form .chk input:focus-visible { outline: 2px solid var(--blue); outline-offset: -9px; }
html.phone .chat .alert-form .acts { margin-left: 0; }
html.phone .chat .alert-form .btn-30 { height: var(--tap); padding: 0 16px; }

/* R83's line under the lots: its three actions as 44px targets that wrap, their words as they are. */
html.phone .nx { align-items: center; gap: 0 6px; margin: 10px 2px 0; font-size: 13px; line-height: 1.4; }
html.phone .nx-lead { flex-basis: 100%; }
html.phone .nx-act { display: inline-flex; align-items: center; min-height: var(--tap); text-align: left; }

/* Small controls inside a card, kept as they look and given a 44px target: the lot's code (it copies the lot's link),
   the long-time flag while it watches the lot on a press, and a platform's terms link inside a line of words. Each is
   44px tall with the room it adds given back by negative margins, so a card's lines stay where they were; the code's
   and the flag's pills are drawn behind the words at their own size. Their words at 11px (10.5px in the views' inline
   styles, hence !important). */
html.phone .chat .tag-chip { position: relative; z-index: 0; min-height: var(--tap); margin: -11px 0; border-color: transparent !important; background: transparent !important; font-size: 11px !important; }
html.phone .chat .tag-chip::before { content: ""; position: absolute; left: 0; right: 0; top: calc(50% - 11px); height: 22px; z-index: -1; border: 1px solid rgba(32,30,29,.18); border-radius: 5px; background: #fff; }
html.phone .chat .long-pill, html.phone .chat .marg-pill { font-size: 11px !important; }
html.phone .chat .long-pill[role="button"] { position: relative; z-index: 0; min-height: var(--tap); margin: -11px 0; background: transparent !important; }
html.phone .chat .long-pill[role="button"]::before { content: ""; position: absolute; left: 0; right: 0; top: calc(50% - 11px); height: 22px; z-index: -1; border-radius: 999px; background: rgba(91,52,176,.12); }
html.phone .chat .terms-link { padding: 15px 0; }
html.phone .chat .expand > .ex-slot:empty { display: none; }

/* A source tag ("i") on a phone: the same 16px ring and its letter at 11px, inside a 44px target whose extra room is
   given back by negative margins, so the figure beside it keeps its line. A tap shows its words in a bubble (phone.js
   tipFor): the words a hover shows on the desktop, which a phone has no other way to reach. Every view open on a
   phone gets this; the views draw the tag the same way everywhere (api.js sourceTag). */
html.phone .src { width: var(--tap); height: var(--tap); margin: -14px -13px -14px -8px; border: 0; border-radius: 50%; background: radial-gradient(circle, #fff 0 7px, rgba(32,30,29,.3) 7.5px 8.5px, transparent 9px); font-size: 11px; vertical-align: middle; -webkit-tap-highlight-color: transparent; }
html.phone .src.ph-on { background: radial-gradient(circle, var(--ink) 0 8.5px, transparent 9px); color: #fff; }
html.phone .ph-tip { position: fixed; z-index: 45; max-width: min(300px, calc(100vw - 2 * var(--gutter))); padding: 9px 12px; border-radius: 9px; background: var(--ink); color: var(--paper); font: 400 13px/1.45 var(--sans); box-shadow: 0 10px 28px rgba(32,30,29,.28); overflow-wrap: anywhere; pointer-events: none; animation: phFade .14s var(--ease) both; }

/* The top bar's actions, between the view's name and the person's mark, 44px each: on Search, Threads (its word, with
   the live dot while a search runs); on the Assistant, Options; on both, New search (+). */
html.phone .ph-act { position: relative; display: inline-grid; place-items: center; min-width: var(--tap); height: var(--tap); padding: 0 8px; border: 0; border-radius: 10px; background: none; color: var(--ink); font: 600 14px/1 var(--sans); -webkit-tap-highlight-color: transparent; }
html.phone .ph-act:active { background: rgba(32,30,29,.07); }
html.phone .ph-act:focus-visible { outline-offset: -2px; }
html.phone .ph-act .live { position: absolute; top: 9px; right: 3px; width: 7px; height: 7px; border-radius: 50%; background: var(--blue); animation: pulseDot 1.5s infinite; }

/* The Threads panel: the tray's run card and threads (tray.js draws them as on the desktop), at the panel's width;
   each thread a 44px row, the eyebrows at 11px. */
html.phone #ph-threads .tray-run { padding: 4px 0 14px; border-bottom: 1px solid rgba(32,30,29,.1); }
html.phone #ph-threads .tray-history { flex: none; overflow: visible; padding: 14px 0 4px; }
html.phone #ph-threads .eyebrow, html.phone #ph-threads .hist-eyebrow { font-size: 11px; }
html.phone #ph-threads .run-card .name, html.phone #ph-threads .run-card .line, html.phone #ph-threads .run-idle { font-size: 13px; }
html.phone #ph-threads .hist-item { min-height: var(--tap); margin-top: 6px; padding: 10px 12px; border: 1px solid rgba(32,30,29,.1); border-radius: 10px; }
html.phone #ph-threads .hist-item.cur { border-color: rgba(65,105,225,.45); box-shadow: none; }
html.phone #ph-threads .hist-item .t { font-size: 15px; }
html.phone #ph-threads .hist-item .s { font-size: 12.5px; }
html.phone #ph-threads .hist-note { margin: 10px 0 0; font-size: 13px; }

/* The photo viewer on a phone, upright or sideways: app.css's own layout under 640px (close at the top right, previous
   and next at the foot, where a thumb is), sized by the visible height (dvh) where app.css uses vh, which on an iPhone
   counts the room under Safari's bars (not measurable here). A swipe moves between the photos (phone.js). */
html.phone .pv { padding: 64px 16px 80px; }
html.phone .pv-fig img, html.phone .pv-fig.failed .sp-fail-big { width: calc(100vw - 32px); height: calc(100dvh - 170px); }
html.phone .pv-btn { top: auto; bottom: 16px; transform: none; }

/* ── The Assistant (D3) ─────────────────────────────────────────────────────────────────────────────────────
   Search's second mode on a phone: the same composer pattern (the slim row with the switch and the usage chip, over
   one row holding the field at 16px and Send), its model and Deep research in the Options panel from the top bar
   (phone.js), New conversation as the top bar's New search (R62). Its answers keep R57's lots and R83's line, at the
   phone's sizes. app.css's own rules under 640px still apply. */
html.phone .as-thread { padding: 12px 12px 14px; }
html.phone .as-composer-wrap { padding: 6px 12px 8px; }
html.phone .as-composer .as-model { display: none; }
html.phone .as-field { align-items: flex-end; gap: 6px; min-height: 50px; padding: 2px 2px 2px 14px; border: 1.5px solid rgba(32,30,29,.16); border-radius: 12px; background: #fff; transition: border-color .18s, box-shadow .18s; }
html.phone .as-field:focus-within { border-color: rgba(65,105,225,.6); box-shadow: 0 6px 20px rgba(65,105,225,.09); }
html.phone .as-field .as-input { align-self: center; min-height: var(--tap); padding: 11px 2px; line-height: 1.35; }
html.phone .as-field .as-send { width: var(--tap); height: var(--tap); border-radius: 10px; }
html.phone .as-field .as-stop { height: var(--tap); }
html.phone .as-row { display: contents; } /* its count alone stays, on a line of its own once there is one (from 1,800 characters) */
html.phone .as-row > :not(.as-count) { display: none; }
html.phone .as-row .as-count { flex: 1 1 100%; margin: 0 4px; text-align: right; font-size: 12px; }

/* The Options panel: Model (a 16px select, 44px tall) and Deep research (a 44px switch) with its hint. */
html.phone .ph-opt { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 12px 0; border-top: 1px solid rgba(32,30,29,.1); }
html.phone .ph-opt select { height: var(--tap); padding: 0 12px; border: 1px solid rgba(32,30,29,.22); border-radius: 10px; background: #fff; font: 600 16px/1 var(--sans); color: var(--ink); }
html.phone .ph-deep { align-self: flex-start; display: inline-flex; align-items: center; gap: 10px; height: var(--tap); padding: 0 16px 0 12px; border: 1px solid rgba(32,30,29,.22); border-radius: 999px; background: #fff; font: 600 15px/1 var(--sans); color: var(--muted); -webkit-tap-highlight-color: transparent; }
html.phone .ph-deep[aria-pressed="true"] { border-color: var(--blue); background: var(--tint); color: var(--blue-hover); }
html.phone .ph-deep[aria-pressed="true"] .as-switch { background: var(--blue); }
html.phone .ph-deep[aria-pressed="true"] .as-switch::after { transform: translateX(10px); }
html.phone .ph-opt-hint { margin: 0; font: 400 13.5px/1.45 var(--sans); color: var(--muted); }

/* An answer at a phone's sizes: the lots' labels, the citation numerals, the sources' numbers and "In the answer" at
   11px; the answer's own buttons at 44px; its links (a lot's title and listing, a code in the text, a citation, a
   source) 44px tall targets whose extra height is padding that moves no line. R57's table keeps app.css's own
   rules under 640px (the close and the estimate written under the bid). */
html.phone .as-lot-figs dt, html.phone .as-cite, html.phone .as-cite a, html.phone .as-cite span, html.phone .as-n, html.phone .as-f-in, html.phone .as-found-table caption.eyebrow { font-size: 11px; }
html.phone .as-work-toggle, html.phone .as-card .btn-34, html.phone .as-found-fold { min-height: var(--tap); }
html.phone .as-verify-go { min-height: var(--tap); }
html.phone .as-lot-title, html.phone .as-f-title { min-height: var(--tap); font-size: 14px; line-height: 22px; } /* two lines are the 44px target exactly, so the clamp shows no part of a third */
html.phone .as-lot-links a, html.phone .as-res a, html.phone .as-src a { padding-top: 14px; padding-bottom: 14px; }
html.phone .as-chip, html.phone .as-cite a { position: relative; z-index: 0; padding-top: 14px; padding-bottom: 14px; margin-top: -14px; margin-bottom: -14px; border-color: transparent; background: transparent; } /* their pills drawn behind at their own size */
html.phone .as-chip::before, html.phone .as-cite a::before { content: ""; position: absolute; left: 0; right: 0; top: 14px; bottom: 14px; z-index: -1; border-radius: 5px; }
html.phone .as-chip::before { border: 1px solid rgba(32,30,29,.18); background: #fff; }
html.phone .as-cite a::before { border-radius: 4px; background: var(--tint); }
html.phone .as-starter { min-height: 52px; }
html.phone .as-turn .as-lots, html.phone .as-turn .as-found { margin-left: -37px; } /* the answer's lots take the conversation's whole width, out from under the agent's mark, as Search's cards do */

/* ── Discover (G4) ──────────────────────────────────────────────────────────────────────────────────────────
   Discover on a phone, as F's spec of 13 October sets it (section 5) and the plan's Discover section: the deck as it
   is, a swipe that can start anywhere on the card (views/discover.js bindDrag), every control 44px (Pass and Watch
   48), the photo at least half the card, the filter lists in a panel from the foot (phone.js), and a compact deck for
   a phone held sideways (html.phone-side, which phone.js reads from the screen's orientation, never a height). The
   view's name and Refresh are the top bar's, so its view head does not show. Every figure keeps its words: nothing on
   the card is hidden, and a strip with more than half the card's height of them scrolls inside itself. */
html.phone #discover { padding: 0; }
html.phone #discover .view-head { display: none; }

/* The filter bar: one row that scrolls sideways at every phone size, its controls 44px. */
html.phone .g-bar { padding: 6px var(--gutter); overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: none; }
html.phone .g-bar::-webkit-scrollbar { display: none; }
html.phone .g-ctl { height: var(--tap); padding: 0 14px; font-size: 13px; }

/* The stage and the card. A press anywhere on the card is a tap until it moves, then a swipe: no text selection, no
   photo or link dragged out of it. */
html.phone .g-stage { gap: 8px; padding: 10px var(--gutter) 0; }
html.phone .g-stack { width: 100%; }
html.phone .g-card { -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
html.phone .g-card img, html.phone .g-card a { -webkit-user-drag: none; }
html.phone .g-mosaic.hero3 { grid-template-rows: 1fr 72px; }
/* Held upright, the strip lies over the photo's lower half, so a photo shown whole (contained) sits at the top of its
   tile rather than its middle, where the strip's edge would cross the watch; and two upright photos sit side by side
   rather than one over the other, where the lower would lie wholly under the strip. Sideways nothing covers them. */
html.phone:not(.phone-side) .g-tile img, html.phone:not(.phone-side) .g-one img { object-position: 50% 0; }
html.phone:not(.phone-side) .g-mosaic.stack2 { grid-template-rows: none; grid-template-columns: 1fr 1fr; grid-template-areas: "a1 a2"; }

/* The photo keeps at least half the card: the strip of figures over its foot is held to the lower half, tighter than
   on the desktop, and scrolls inside itself when a lot has more to say than fits (a platform's cost sentence under
   the Margin is often four lines on a phone). Its lines wrap as a row, so the house's line and the watch's (brand,
   reference, year) share one line when both fit, a gap between them (and none when the watch's wraps under). Open the
   listing comes first, beside the closing time when there is room and under it at the right when not, so it is never
   below the fold: a pill like the time's and the tag's, inside a 44px target whose extra height is given back. */
html.phone .g-strip { max-height: 50%; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; touch-action: pan-y; flex-flow: row wrap; align-content: flex-start; gap: 2px 12px; padding: 16px 14px 12px; } /* touch-action: a scroller does not take the card's, so it says it again: upright moves scroll the strip, sideways ones are the swipe's */
html.phone .g-strip::-webkit-scrollbar { display: none; }
html.phone .g-strip > * { flex: 0 0 100%; min-width: 0; order: 2; } /* a line each, none squeezed away (the title's clamp would let it shrink to nothing): held to half the card, the strip scrolls instead */
html.phone .g-strip > .g-strip-top { flex: 1 0 auto; order: 0; }
html.phone .g-strip > .g-meta { flex: 0 1 auto; }
html.phone .g-title { font-size: 16px; line-height: 1.2; }
html.phone .g-meta, html.phone .g-bid span, html.phone .g-est span, html.phone .g-value span, html.phone .g-margin span { line-height: 1.3; }
html.phone .g-figures { margin-top: 0; }
html.phone .g-comp { padding: 4px 8px; }
html.phone .g-comp > .g-margin { margin-left: auto; } /* at the right when it wraps under the value, as when beside it */
html.phone .g-strip > .g-open { position: relative; z-index: 0; flex: 0 0 auto; order: 1; display: inline-flex; align-items: center; min-height: var(--tap); margin: -13px 0 -13px auto; padding: 0 9px; color: var(--ink); }
html.phone .g-strip > .g-open::before { content: ""; position: absolute; left: 0; right: 0; top: calc(50% - 9px); height: 18px; z-index: -1; border-radius: 999px; background: rgba(243,242,242,.92); }
html.phone .g-strip > .g-open:hover { color: var(--ink); }

/* The photo enlarged: All n a 44px target. The Watch and Pass hints, unseen until a drag, take no press: they sit over
   the photo's top corners and over All n, which a tap there reaches now. */
html.phone .g-back { top: 6px; left: 6px; height: var(--tap); padding: 0 16px; font-size: 13px; }
html.phone .g-hint { pointer-events: none; }

/* The actions: Pass and Watch 48px, Rewind 44 x 44 with its count at 11px. The three reasons after a pass, 44px and
   on one line at 360, sit between the card and the actions, so the actions never move under the thumb: the card gives
   up the room (from 700px up they come under the actions, which rise, and a second quick press where Pass was lands
   on a reason). So no room is held for them after a rewind either. Decisions still on their way, said over the top
   of the card, as the stage's corners hold the actions here. */
html.phone .g-acts { order: 2; gap: 12px; padding: 0 0 8px; }
html.phone .g-act { height: 48px; padding: 0 24px; font-size: 14px; }
html.phone .g-act.undo { width: var(--tap); height: var(--tap); padding: 0; }
html.phone .g-rew-n { top: -6px; right: -6px; min-width: 20px; height: 20px; padding: 0 5px; font-size: 11px; line-height: 20px; }
html.phone .g-reasons { order: 1; flex-wrap: wrap; gap: 5px; padding: 0; font-size: 12px; }
html.phone .g-reason { height: var(--tap); padding: 0 10px; font-size: 12.5px; }
html.phone .g-reasons.held { display: none; }
html.phone .g-saving { top: 18px; bottom: auto; left: 50%; z-index: 6; max-width: calc(100% - 2 * var(--gutter)); padding: 5px 11px; border-radius: 999px; background: rgba(32,30,29,.72); color: var(--paper); font-size: 12px; transform: translateX(-50%); }
html.phone .g-foot { flex-wrap: wrap; gap: 0 12px; padding: 4px var(--gutter) 6px; }

/* The end of the deck, a deck that failed: their buttons 44px, and the end card scrolls if a phone held sideways
   leaves it less than its height. */
html.phone .g-stack .g-end { overflow-y: auto; padding: 24px 20px; }
html.phone .g-end .btn-36, html.phone #discover .c-error .c-btn { height: var(--tap); padding: 0 18px; }

/* The filter lists in their panel (phone.js): the chips that shipped, counts and all, as 44px targets that wrap; the
   ceiling's two fields at 44px (16px text, the shell's rule) with Apply and Cancel beside them. */
html.phone #ph-filters .g-pop { position: static; left: auto; right: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; max-width: none; max-height: none; overflow: visible; margin: 0; padding: 2px 0 8px; border: 0; border-radius: 0; background: none; box-shadow: none; }
html.phone #ph-filters .g-chip { height: var(--tap); padding: 0 16px; font-size: 14px; }
html.phone #ph-filters .g-clear { height: var(--tap); padding: 0 10px; font-size: 14px; }
html.phone #ph-filters .g-pop-none { font-size: 13px; }
html.phone #ph-filters .g-ceil-edit { flex: 1 1 100%; flex-wrap: wrap; gap: 8px; }
html.phone #ph-filters .g-ceil-edit input { height: var(--tap); }
html.phone #ph-filters .g-ceil-edit input[name="g-max-bid"] { flex: 1 1 120px; width: auto; min-width: 0; }
html.phone #ph-filters .g-ceil-edit input[name="g-currency"] { width: 84px; }

/* A phone held sideways: the card the whole height between the bars, its figures beside its photo rather than over
   it, so the whole photo shows in the larger half of the card; the filter bar, the actions, the reasons after a pass
   and the foot in a column at its right. The stage lends its children to the view's grid (display: contents), so the
   bar, which is the view's, and the actions, which are the stage's, share the column; its listeners are unchanged. The
   cards behind sit closer, as the card is short. */
html.phone.phone-side #discover { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 244px; grid-template-rows: auto auto auto minmax(0, 1fr) auto; column-gap: 14px; padding: 6px var(--gutter); }
html.phone.phone-side #g-filters { grid-column: 2; grid-row: 1; min-width: 0; }
html.phone.phone-side .g-bar { margin: 0 calc(-1 * var(--gutter)) 0 0; padding: 0 var(--gutter) 0 0; border: 0; background: none; }
html.phone.phone-side .g-stage { display: contents; }
html.phone.phone-side .g-stack { grid-column: 1; grid-row: 1 / -1; }
html.phone.phone-side .g-stage > :not(.g-stack):not(.g-acts):not(.g-reasons):not(.g-saving) { grid-column: 1; grid-row: 1 / -1; align-self: center; } /* the loader, or a deck that failed */
html.phone.phone-side .g-acts { grid-column: 2; grid-row: 2; justify-content: flex-start; padding: 8px 0 0; }
html.phone.phone-side .g-reasons { grid-column: 2; grid-row: 3; justify-content: flex-start; padding: 8px 0 0; }
html.phone.phone-side #g-foot { grid-column: 2; grid-row: 5; padding: 6px 0 0; }
html.phone.phone-side .g-card:not(.top) { transform: translateY(calc(var(--i) * 4px)) scale(calc(1 - var(--i) * .02)); }
html.phone.phone-side .g-card { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
html.phone.phone-side .g-photo { position: relative; inset: auto; }
html.phone.phone-side .g-strip { position: relative; left: auto; right: auto; bottom: auto; max-height: none; padding: 12px 14px; background: rgba(32,30,29,.94); }
html.phone.phone-side .g-saving { top: auto; bottom: 52px; left: auto; right: var(--gutter); max-width: 244px; transform: none; }
