/* ==========================================================================
   Phones — not the desktop made narrow
   A phone has no arrow keys, no hover and no second column. It gets one screen
   at a time, targets a thumb can hit, and a transcript that arrives over the
   list rather than beside it.
   ========================================================================== */
@media (max-width: 899px) {
    .app { grid-template-columns: minmax(0, 1fr); }
    .app[data-pane="off"] .pane-detail { display: flex; }
    .pane-list { border-right: 0; }

    .pane-detail {
        position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 40;
        /* `100dvh` rather than `bottom: 0` alone, and this is the composer floating in a band of
           dead space on a phone. A fixed element is laid out against the *large* viewport — the
           one with the browser's own bottom bar hidden — so it runs on underneath that bar, and
           the composer, which is the last thing in it, sits below the edge of what you can see
           with its bottom padding stranded above it. The dynamic unit is the height that is
           actually on screen right now, so the box lands on the real bottom edge. */
        height: var(--vvh, 100dvh);
        /* And it moves with the visible viewport as well. When the keyboard opens, iOS pans what
           you can see rather than moving the layout, so a fixed element stays where the layout
           put it — which is behind the keyboard. */
        top: var(--vvt, 0px);
        background: var(--bg);
        /* iOS can lose the fixed compositor layer when a transformed pane finishes sliding in:
           the list has already become hidden, while the detail layer stops painting, leaving the
           global header over a black page. Swap visibility atomically instead; this screen change
           is navigation, and reliability is worth more than its 260ms decoration. */
        transform: none;
        visibility: hidden;
        pointer-events: none;
        transition: none;
    }
    .app[data-view="detail"] .pane-detail { transform: none; visibility: visible; pointer-events: auto; }
    .app[data-view="detail"] .pane-list { visibility: hidden; }

    /* There is one line of header on a phone and three counts will not fit on it. The one that
       goes is the one that is only ever a footnote. */
    .counts .quiet:not(:only-child) { display: none; }

    .detail-head .back { display: block; }
    /* The kind column, narrowed. It is still worth its place — `Explore` and `general-purpose`
       are different enough to matter — but a fixed 106px of a 390px screen is a quarter of the
       row spent on a word that repeats down the whole list. */
    .agents .one .kind { width: 74px; }
    .detail-head { padding-left: 8px; gap: 8px; }
    /* One line of header, and the name of the session is the part of it worth keeping. A control
       that cannot be pressed yet is the first thing to go. */
    .detail-head .chip:disabled { display: none; }
    /* The status line stays. It used to be hidden here — a desktop luxury — but which model
       this session is on, what it has cost and how much of the plan's window is left is *more*
       worth a row away from the machine, not less: it is the reading you cannot get by looking
       over at the terminal. It is the tightest row on the screen and it earns its 34px. */
    .status-line { padding-left: 12px; padding-right: 12px; }
    .status-line .item + .item::before, .status-line .files::before,
    .status-line .deploy::before { padding: 0 6px; }
    .status-line .limits { padding-left: 10px; gap: 10px; }
    /* Cost stays on the phone row now. It used to be hidden here, on the argument that a turn is
       never stopped by what it has cost — but away from the Mac this row is the only place the
       money is, and since Claude Code's own `total_cost_usd` sits behind it the figure is finally
       worth reading rather than an estimate that ran 80% high.

       That leaves more content than 390 points can hold, so something has to give, and the
       decision is which. **The branch gives.** Ellipsised it still identifies itself, while the
       two things beside it fail badly rather than gracefully: `.context` and `.cost` are
       `flex: 0 0 auto` and cannot shrink at all, so pressure on the button clips them instead —
       measured at 390, `$11.57` drew as `$11.`, a wrong number that looks like a right one — and
       the model word, given the whole squeeze, vanishes outright along with its 13px logo rather
       than ellipsising. Hence a shrink factor here and no `overflow` on the button: at 390 with
       `feature/context-fill` the branch yields to 87px and `Opus 5` keeps 36 of its 40.

       The tree itself comes back here too — see the note at the 1080px breakpoint. */
    .status-line .files { display: flex; flex-shrink: 20; }
    .filter-row .slash { display: none; }

    .row { padding: 13px 14px; margin-bottom: 8px; gap: 4px 12px; }
    .row .title { font-size: 15px; }
    .row .meta { font-size: 11.5px; }
    .row .line { font-size: 12px; }
    .row:hover { background: var(--card); }
    .row[data-state="waiting"]:hover { background: #2f2322; }
    .row:active { background: var(--card-hi); }

    /* The row itself belongs to the list's vertical reorder animation, so the horizontal gesture
       moves only its contents. The real button travels in from the uncovered edge and remains a
       normal focusable control once the gesture has put it there. */
    .row[data-swipe] { overflow: hidden; touch-action: pan-y; --swipe-action-w: 126px; }
    .row[data-swipe] > .mark,
    .row[data-swipe] > .title,
    .row[data-swipe] > .meta,
    .row[data-swipe] > .state {
        transform: translateX(var(--swipe-x, 0px));
        transition: transform 180ms var(--ease);
    }
    .row[data-swipe="dragging"] > .mark,
    .row[data-swipe="dragging"] > .title,
    .row[data-swipe="dragging"] > .meta,
    .row[data-swipe="dragging"] > .state,
    .row[data-swipe="dragging"] > .swipe-end { transition: none; }
    .row > .swipe-end {
        display: none;
        position: absolute; z-index: 3; top: -1px; right: -1px; bottom: -1px;
        width: var(--swipe-action-w, 126px);
        align-items: center; justify-content: center;
        padding: 0 12px;
        border-radius: 0 var(--radius) var(--radius) 0;
        background: #402622; color: var(--accent);
        font-size: 12.5px; font-weight: 600;
        transform: translateX(var(--swipe-button-x, 126px));
        transition: transform 180ms var(--ease), background 160ms var(--ease);
    }
    .row[data-swipe] > .swipe-end:not([hidden]) { display: flex; }
    .row > .swipe-end:active { background: #573028; }

    .tx-scroll { padding: 14px 16px 16px 16px; }
    .tx-scroll.home { padding: 0; }
    .home-hero {
        align-items: flex-start;
        padding: clamp(40px, 10vh, 76px) 24px 46vh;
    }
    .home-hero::before {
        background-size: auto 72%;
        background-position: 85% 100%;
    }
    .home-hero::after {
        background: linear-gradient(180deg, rgba(14,14,17,0.02) 0%, rgba(14,14,17,0.20) 38%, rgba(14,14,17,0.62) 100%);
    }
    .home-hero .copy { transform: none; max-width: 300px; }
    .home-hero h1 { font-size: clamp(28px, 9vw, 38px); }

    .empty.home-hero-list {
        min-height: calc(var(--vvh, 100dvh) - var(--head-h) - 58px);
        padding: 44px 24px 50vh;
        text-align: left;
        background:
            linear-gradient(180deg, rgba(14,14,17,0) 0%, rgba(14,14,17,0.06) 34%, rgba(14,14,17,0.72) 100%),
            url("/hero-orchestration-v4-task-clinic.webp") 85% 100% / auto 70% no-repeat;
    }
    .empty.home-hero-list::before {
        content: ""; display: block; width: 30px; height: 2px;
        margin-bottom: 16px; background: var(--accent);
    }
    .empty.home-hero-list b {
        max-width: 12ch; margin-bottom: 8px;
        color: var(--ink); font-size: clamp(25px, 8vw, 34px); line-height: 1.08;
        font-weight: 620; letter-spacing: -0.03em;
    }
    .entry { grid-template-columns: minmax(0, 1fr); gap: 3px; padding: 9px 0; }
    .entry .who { text-align: left; display: flex; gap: 8px; align-items: baseline; }
    .entry .who time { margin: 0; }
}

/* ==========================================================================
   Touch screens — the sixteen pixel rule
   iOS zooms the page when you focus a text field whose type is smaller than
   16px, and there is no way back from that zoom now that the viewport is
   fixed: the page would simply sit at 1.3× for the rest of the session. So
   every field that can be focused is at least 16px on a screen you touch.
   Keyed on the pointer rather than the width, because a landscape iPad is
   wider than the phone breakpoint and zooms exactly the same way.
   ========================================================================== */
@media (pointer: coarse) {
    .filter-row input,
    .sheet .find,
    .composer .msg,
    #door-name, #door-password, #door-pw-name { font-size: 16px; }
    /* The six pairing boxes are set at 22px, and at 19px on the narrowest phones, so they are
       already well over the line and are deliberately left to their own rule. */
}

/* ==========================================================================
   Reduced motion — every animation here is decoration on top of a state that
   is already legible, so all of it can go.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
    .pane-detail { transition: none; }
    /* A skeleton without the sheen rather than no skeleton. What it is saying — "this is on its
       way, the screen has not hung" — is exactly as useful to somebody who has asked for less
       movement, and it is the moving part they turned off, not the message. */
    .skel .bar { animation: none; background-image: none; }
}
