        /* ==========================================================================
           #Q  Sync — the manifest
           --------------------------------------------------------------------------
           A room off the sidebar, drawn by public/29b-sync.js. Built 2026-09-08.

           Takes the Rooms-off-Home head. One act at the right, and it is magenta: sending
           is what puts the record where the record lives. Nothing else here changes
           anything, so nothing else carries that ink.

           The page has one thing to say and says it at the top, in the largest type this
           world allows itself — which is not large. A traveller opens this room with one
           question, and an answer they have to assemble out of a list is not an answer.
           ========================================================================== */
        #syncPage {
            background: var(--log-stock);
        }

        #syncPage.active {
            display: flex;
            flex-direction: column;
            height: 100vh;
            height: 100dvh;
            min-height: 0;
            overflow: clip;
        }

        /* ---- the head ------------------------------------------------------------ */

        /* The head, its title and Back are the room head (.room-bar, css/11-home.css, since
           2026-09-16). What is this room's own: the page is a column with its own scroller,
           so the head must not shrink into it. */
        #syncPage .sy-bar {
            flex: none;
        }

        /* Send now, the head's one action, in Back's word. */
        #syncPage .sy-act {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            text-decoration: underline;
            text-underline-offset: 0.25em;
            text-decoration-thickness: 1px;
            background: none;
            border: none;
            padding: 0;
            cursor: pointer;
            color: var(--log-ink);
            display: inline-flex;
            align-items: center;
            min-height: 44px;
        }
        #syncPage .sy-bar .sy-act { justify-self: end; }

        /* Sending changes the record — it is the act that makes the record real anywhere
           but this phone. The One-Ink Rule's magenta, and the only stroke of it here. */
        #syncPage .sy-act.is-mark { color: var(--log-magenta); }

        /* ---- the sheet ----------------------------------------------------------- */

        #syncPage .sy-body {
            flex: 1;
            min-height: 0;
            display: flex;
            flex-direction: column;
            overflow-y: auto;
            -webkit-overflow-scrolling: touch;
            padding-bottom: calc(var(--sp-2xl) + env(safe-area-inset-bottom, 0px));
        }

        /* ---- the answer ---------------------------------------------------------- */

        /* The one sentence the room exists to say, on the sheet's own heading band. It is
           not a banner and it is not coloured: this world says "all is well" by writing it
           down, not by turning something green. */
        #syncPage .sy-state {
            display: flex;
            flex-direction: column;
            gap: var(--sp-2xs);
            padding: var(--sp-md) var(--sp-lg);
            background: var(--log-stock-band);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        #syncPage .sy-state-word {
            font-family: var(--log-print);
            font-size: var(--fs-base);
            font-weight: 600;
            letter-spacing: 0.1em;
            text-transform: uppercase;
            line-height: 1.25;
            color: var(--log-ink);
        }

        /* The Stamped-State Rule, in the headline. A traveller with no account is not in a
           state of the queue at all -- there is nowhere for anything to have gone -- and
           printing "Everything is on the record" over that was the loudest untrue line on
           the page. The state is a word in a hairline box, in the softer ink, and it is
           content: nothing here is pressable. Added by the 2026-09-08 finish review. */
        #syncPage .sy-state-stamp {
            align-self: flex-start;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            color: var(--log-ink-soft);
            border: 1px solid var(--log-rule);
            padding: 2px var(--sp-xs);
        }

        #syncPage .sy-state-under {
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.4;
            color: var(--log-ink-soft);
        }

        /* ---- the manifest -------------------------------------------------------- */

        /* One waiting thing is one ruled row, at the sheet's own pitch: what it is at the
           left, where it stands at the right. The Register's entry row, again — this app
           has one way of listing things and this is it. */
        #syncPage .sy-line {
            display: grid;
            grid-template-columns: 1fr auto;
            align-items: center;
            gap: var(--sp-sm);
            min-height: var(--log-row);
            padding: 0 var(--sp-lg);
            border-bottom: 1px solid var(--log-rule);
        }

        #syncPage .sy-what {
            font-family: var(--log-write);
            font-size: var(--fs-body);
            color: var(--log-ink);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        #syncPage .sy-when {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--log-ink-soft);
            white-space: nowrap;
        }

        /* A refusal is the one state on this page that is not merely "not yet", and port is
           what this world uses for a fault. It marks the state word, not the whole row: the
           thing itself is still the traveller's, and it is still here. */
        #syncPage .sy-line.is-refused .sy-when { color: var(--log-port); }

        /* ---- what is kept on this phone (2026-09-18, 39-offline.js) ---------------- */
        /* The other direction of the page's question: not what waits to go up, but what was brought down to read
           without signal. A heading of the sheet's own kind, then one entry per journey — its name, and under it the
           stamp with when, how many files and how much, which is too long to stand at the right of one line. */
        #syncPage .sy-sub {
            padding: var(--sp-md) var(--sp-lg) var(--sp-2xs);
            border-bottom: 1px solid var(--log-rule-firm);
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--log-ink);
        }
        #syncPage .sy-line.is-kept {
            grid-template-columns: minmax(0, 1fr);
            gap: 2px;
            padding-top: var(--sp-xs);
            padding-bottom: var(--sp-xs);
        }
        /* A conflict: the two choices at the foot of its entry, in the print of every act on this sheet. Neither is magenta:
           neither adds a line to the record or takes one away — each decides which version of a line stays. */
        #syncPage .sy-choose {
            display: flex;
            justify-content: flex-end;
            gap: var(--sp-lg);
        }
        /* A download: REMOVE alone at the left, DOWNLOAD AGAIN at the right, apart (owner, 2026-09-18). */
        #syncPage .sy-choose.is-apart { justify-content: space-between; }
        #syncPage .sy-pick {
            min-height: 44px;
            padding: 0;
            border: none;
            background: none;
            cursor: pointer;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            text-decoration: underline;
            text-underline-offset: 0.25em;
            text-decoration-thickness: 1px;
            color: var(--log-ink);
        }
        /* REMOVE (a download) takes the magenta every removal takes. */
        #syncPage .sy-pick.is-drop { color: var(--log-magenta); }
        /* A journey's state lines, on Today and here (offlineRows, 39-offline.js): the stamps one column and one width,
           the sentences beside them, each starting on the stamp's own line. */
        .off-rows {
            display: grid;
            grid-template-columns: max-content minmax(0, 1fr);
            gap: var(--sp-2xs) var(--sp-xs);
            align-items: baseline;
        }
        .off-rows .log-note-stamp { justify-self: stretch; text-align: center; }
        .off-rows .is-wide { grid-column: 1 / -1; }
        .off-rows .log-note-stamp.is-asking { color: var(--log-ink); border-color: var(--log-rule-firm); }
        #syncPage .sy-sub[data-focus-home]:focus:not(:focus-visible) { outline: none; }
        #syncPage .sy-kept {
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.45;
            color: var(--log-ink-soft);
        }

        /* ---- what it means ------------------------------------------------------- */

        #syncPage .sy-note {
            margin: 0;
            padding: var(--sp-sm) var(--sp-lg);
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.45;
            color: var(--log-ink-soft);
        }
        #syncPage .sy-note:empty { display: none; }

        /* The Ruled-To-The-Foot Rule: what is left of the sheet is ruled stock. */
        #syncPage .sy-rule-out {
            flex: 1;
            min-height: calc(var(--log-row) * 2);
            background-image: repeating-linear-gradient(to bottom,
                transparent 0,
                transparent calc(var(--log-row) - 1px),
                var(--log-rule) calc(var(--log-row) - 1px),
                var(--log-rule) var(--log-row));
        }
