        /* ==========================================================================
           #W  Home, while a journey is under way — the second home
           --------------------------------------------------------------------------
           Drawn by public/29i-underway.js. Built 2026-09-09.

           WHAT IT IS. The same page id as Home (#mainPage), because it is the same
           destination: the bottom bar's HOME must not point at two places. The globe and
           its sheet are hidden, this is shown in their stead, and JOURNEYS, at the top of
           the menu, puts them back (the head's right word is CONTENTS since 2026-09-18). `isTripCurrent()` alone decides whether it exists at all;
           between journeys these rules match nothing.

           WHY IT IS NOT A NEW PAGE. A second page would need its own entry in the bar, its
           own back word, its own place in the saved page state, and would drift from Home's
           grammar within a month. One id, two states, per the owner's decision recorded in
           the Home surface brief.

           THE RULES IT KEEPS. Rooms-off-Home (a ruled head, words not glyphs), Margin-Column
           (the labels sit in a column of their own, left of the rule), Ruled-To-The-Foot,
           Stamped-State (a booking says whether it is booked), Ledger's Voice (small
           numbers are words), One-Ink, No Display Face, Plate-Not-Float.

           THE ONE ACT. Everything on this screen is reading except ADD, whose four words add
           a line to the record, so they alone carry the magenta — with REMOVE, which takes a
           download away, and an unarranged night, which is a notice laid over the record
           rather than an act. Since 2026-09-18 the sheet opens with the owner's cells:
           Weather | Add, then Download & sync, then Tonight's bed and Today.
           ========================================================================== */

        /* Home's own furniture, while a journey is on. Not `display:none` on a parent —
           #homeHero carries the globe, and hiding it after initHomeGlobe() has built a map
           inside it is how a map ends up sized to a zero-height box. The globe is simply
           never started in this state (see showPage), and these two are taken out of flow. */
        #mainPage.is-underway .home-hero,
        #mainPage.is-underway .home-sheet {
            display: none;
        }

        /* The page keeps block flow rather than becoming a full-height flex column. Home
           scrolls; so does this. A full-height column here would have to re-solve the
           bottom bar's allowance, the sticky cover's margin collapse and the frame's
           transform, all of which #mainPage has already settled. */
        /* NO BOTTOM PADDING. The app's own bar is fixed and pages reserve --nav-h for it;
           this page's bar is IN THE FLOW at the end of the column, so the reserve was 24px
           of stock under a bar that was already at the bottom — the page stood 884px tall in
           an 860px window and scrolled a rule's width past its own foot. A screen that is
           one screenful must measure one screenful. */
        #mainPage.is-underway {
            background: var(--log-stock);
            padding-bottom: 0;
        }

        /* ---- the head ----------------------------------------------------------- */
        /* Three parts, like every other room's: a way out on the left, what you are
           looking at in the middle, a way on at the right. Sticky, because the journey's
           name is the one thing that should not scroll away from a traveller reading a
           list of today. */
        #homeUnderway .uw-bar {
            position: sticky;
            top: 0;
            z-index: 3;
            display: grid;
            grid-template-columns: 1fr auto 1fr;
            align-items: center;
            gap: var(--sp-sm);
            padding: calc(var(--sp-2xs) + env(safe-area-inset-top, 0px)) var(--sp-lg) var(--sp-2xs);
            background: var(--log-stock);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        #homeUnderway .uw-title {
            margin: 0;
            font-family: var(--log-print);
            font-size: var(--fs-small);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            line-height: 1.2;
            color: var(--log-ink);
            text-align: center;
            /* A journey can be called anything; the sheet cuts a long one rather than
               letting it push the two words off their edges. */
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            max-width: 46vw;
        }

        /* Words, underlined, in the printed voice. The same control the trip plan's head
           uses — this room and that one are two views of one journey and should not have
           two different ideas of what a way out looks like. */
        #homeUnderway .uw-word {
            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;
            /* One line, always: a longer word here broke in two at 375 (2026-09-17). */
            white-space: nowrap;
        }
        #homeUnderway .uw-bar .uw-word:last-child { justify-self: end; }

        /* ---- the dateline -------------------------------------------------------- */
        /* WHAT THIS PAGE WAS MISSING. Every line on it was --fs-body or smaller, and nine
           near-identical rules ran down the sheet, so the eye landed nowhere and the screen
           had no first answer — the place you are was the smallest, softest thing on it,
           inside a sentence, in the light pressure.

           A dateline is what a log page opens with: the reckoning printed small, and then
           the position. So: the count and the date in the printed voice, and under it the
           PLACE, which is the one thing worth reading from arm's length. Two steps up the
           scale, in the full ink, on the sheet's own band.

           No display face is added for it (this world has none, and its authority is the
           ruling). It is the same written face two sizes up, which is the only kind of
           emphasis a log has. */
        #homeUnderway .uw-dateline {
            padding: var(--sp-sm) var(--sp-lg) var(--sp-md);
            background: var(--log-stock-band);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        #homeUnderway .uw-count {
            margin: 0 0 var(--sp-2xs);
            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);
        }

        /* Where you are. The weather shared this line until 2026-09-18 and has a cell of its own
           now; the line keeps its wrapping, so a long stop name is read whole, never cut. */
        #homeUnderway .uw-here {
            display: flex;
            flex-wrap: wrap;
            align-items: baseline;
            justify-content: space-between;
            gap: var(--sp-2xs) var(--sp-sm);
        }

        #homeUnderway .uw-place {
            font-family: var(--log-write);
            font-size: var(--fs-lg);
            font-weight: 500;
            line-height: 1.15;
            color: var(--log-ink);
        }


        /* ---- tonight ------------------------------------------------------------- */
        /* THE ONE FACT WHOSE GOING WRONG IS A REAL PROBLEM, drawn as an entry. It had been a
           label in a margin and a value beside it, at the same weight as the weather; a bed
           is not a field on a form. The tab prints above it the way a stamp sits above what
           it certifies, the name takes --fs-base, where it is sits under, and the state is
           stamped at the right on the name's own baseline. */
        #homeUnderway .uw-tonight {
            padding: var(--sp-sm) var(--sp-lg) var(--sp-md);
        }

        /* One bed. There can be more than one — four travelling together and two rooms is an
           ordinary night — so the entry is a block that repeats rather than a fixed set of
           cells under the tab. Separated by space, not by a rule: they are two halves of one
           answer to one question, not two sections. */
        #homeUnderway .uw-bed {
            display: grid;
            grid-template-columns: 1fr auto;
            align-items: baseline;
            column-gap: var(--sp-sm);
        }
        #homeUnderway .uw-bed + .uw-bed {
            margin-top: var(--sp-md);
        }

        #homeUnderway .uw-tab {
            display: block;
            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);
        }

        #homeUnderway .uw-name {
            grid-column: 1;
            grid-row: 1;
            font-family: var(--log-write);
            font-size: var(--fs-base);
            line-height: 1.3;
            color: var(--log-ink);
        }

        #homeUnderway .uw-bed .uw-where {
            grid-column: 1;
            grid-row: 2;
        }

        #homeUnderway .uw-bed .uw-state {
            grid-column: 2;
            grid-row: 1;
            justify-self: end;
        }

        /* TAKE ME THERE. A printed word under the address, underlined the way every door in
           this world is underlined — it leaves for a map, so it is a door and not an act,
           and it takes the ink rather than the magenta. Its hit area is grown around it
           rather than under it, so the block's rhythm is unchanged. */
        #homeUnderway .uw-dir {
            grid-column: 1;
            grid-row: 3;
            justify-self: start;
            position: relative;
            margin-top: var(--sp-2xs);
            padding: 0;
            /* Never wider than its own word: the hit area is grown by the pseudo-element
               below, and a full-width button here would put an invisible target across the
               whole row. */
            align-self: start;
            background: none;
            border: none;
            cursor: pointer;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--log-ink);
            text-decoration: underline;
            text-underline-offset: 0.25em;
            text-decoration-thickness: 1px;
        }
        /* Grown around the word rather than under it, so the bed block's rhythm is
           unchanged. Scoped to the BED's copy: inside a row this pseudo-element would reach
           up into the entry button above it and quietly steal the last thirteen pixels of
           its press target — a control eating the one it hangs from. */
        #homeUnderway .uw-tonight .uw-dir::after {
            content: '';
            position: absolute;
            inset: -15px -10px;
        }

        /* An unarranged night is a notice laid over the record, which is what the magenta
           marks since the rule was widened. It takes the tab as well as the line, because
           what is wrong is the NIGHT and not merely this sentence about it. */
        #homeUnderway .uw-tonight.is-open .uw-name,
        #homeUnderway .uw-tonight.is-open .uw-tab {
            color: var(--log-magenta);
        }

        /* ---- the sheet ---------------------------------------------------------- */
        /* THE MARGIN COLUMN. The day's times are printed in a column of their own, and a
           rule runs down between that column and what is written in it — the same
           arrangement as the stops sheet, at the same offset, because they are the same
           instrument read from two rooms. */
        /* THE RULING SPANS THE SHEET. The sheet used to carry the side padding and every
           row inherited it, so the hairlines ran 24px short at both ends while the heading
           bands and the standfirst above them bled to the page edge — two different ideas
           of where the sheet ends, on one sheet. The padding moved into the rows: the rules
           now run edge to edge and the text still starts on the same margin. */
        #homeUnderway .uw-sheet {
            padding: 0;
        }
        /* The column rule runs beside the rows that HAVE a margin column and stops there.
           Drawn down the whole sheet it went straight through "Nothing written down yet
           today." and out past the act at the foot — a rule that divides nothing, which is
           worse than no rule, because a reader takes a ruled column to mean there is
           something in it. */
        #homeUnderway .uw-ruled {
            position: relative;
        }
        #homeUnderway .uw-ruled::before {
            content: '';
            position: absolute;
            top: 0;
            bottom: 0;
            left: calc(var(--sp-lg) + var(--uw-col, 44px) + (var(--sp-sm) / 2) - 1px);
            width: 1px;
            background: var(--log-rule-firm);
            pointer-events: none;
        }

        /* Where it is, under what it is. A location is how you find the thing, not what the
           thing is, so it takes the softer pressure and its own line. */
        #homeUnderway .uw-where {
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.4;
            color: var(--log-ink-soft);
        }

        /* ---- the state stamp ---------------------------------------------------- */
        /* ⚠️ IN THE INK, NOT IN PORT AND STARBOARD. The owner: booked 和 to book 颜色不是
           系统颜色. Correct — the SAME LIST in the journey's own room prints this state in
           one ink at two pressures (.dy-state, 17j): the outstanding one takes the full ink
           because it is the one still to do, and BOOKED recedes to the soft pressure because
           it is settled. Port and starboard were invented here for a stamp that already had
           a rule, and they read as a status light on a sheet that has none.

           Note the polarity that comes with borrowing it: the DEFAULT is the outstanding
           state, and `is-booked` is the modifier — which is right, because the thing worth
           the ink is the thing not yet done. */
        #homeUnderway .uw-state {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            white-space: nowrap;
            color: var(--log-ink);
        }
        #homeUnderway .uw-state.is-booked { color: var(--log-ink-soft); }

        /* ---- the bands ---------------------------------------------------------- */
        /* A heading band on the sheet's own darker stock, ruled top and bottom, bleeding to
           the page edge — the sheet's sections are divisions of one sheet, not cards laid
           on it (Plate-Not-Float). */
        #homeUnderway .uw-band {
            margin: 0;
            padding: var(--sp-2xs) var(--sp-lg);
            background: var(--log-stock-band);
            border-top: 1px solid var(--log-rule-firm);
            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);
        }
        /* The band spans the margin column too, so the rule behind it would print through
           the darker stock as a stray tick. It is drawn over. */
        #homeUnderway .uw-band { position: relative; z-index: 1; }

        /* ---- today's rows ------------------------------------------------------- */
        /* The same three-part row the Days view uses — a time, a thing, its state — and the
           category colours the thread at the left rather than the words, so ten categories
           do not put ten colours of text on one sheet (One-Ink). */
        /* THE CATEGORY THREADS THE COLUMN RULE, which is where the Days view puts it
           (.dy-row::before, 17j). It had been a 2px coloured border down the page edge —
           a second object doing the first one's job, and the one thing on this sheet that
           belonged to no other room in the app. Ten categories colour two pixels of an
           existing rule each; none of them colours a word (One-Ink). */
        /* THE ROW IS A CONTAINER; THE ENTRY IS THE BUTTON IN IT. It was one button for the
           whole row, which was right until the marked row needed a way there as well — a
           <button> cannot hold a <button>, and a second control inside the first one's press
           target is a control you cannot reach without firing the one around it. So the row
           holds the entry line and, under it, the annotation; the rule and the coloured
           thread belong to the row and close under both. */
        #homeUnderway .uw-item {
            position: relative;
            border-bottom: 1px solid var(--log-rule);
        }

        #homeUnderway .uw-open {
            display: grid;
            grid-template-columns: var(--uw-col, 44px) 1fr auto;   /* the margin, as wide as this reader's clock (underwayTimeColumn) */
            column-gap: var(--sp-sm);
            align-items: baseline;
            padding: var(--sp-sm) var(--sp-lg);
            border: none;
            width: 100%;
            box-sizing: border-box;
            text-align: left;
            font: inherit;
            background: none;
            cursor: pointer;
            /* 43px is not 44, and a marked row's entry was 35 once its foot was given to the
               way there. The floor is set here rather than left to the padding, which has a
               second job (the sheet's rhythm) and cannot serve both. */
            min-height: 44px;
            align-content: center;
        }
        /* The same press this app's other ruled rows give: the baseline thickens under the
           finger. Not a fill, not a lift (Ink-Not-Glow, Plate-Not-Float). */
        #homeUnderway .uw-open:active {
            box-shadow: inset 0 -2px 0 0 var(--log-rule-firm);
        }

        /* The way there, hanging under the entry it belongs to, in the entry's own column —
           the same arrangement as DIRECTIONS under the bed's address, because it is the same
           word doing the same job. It sits inside the row, so the row's rule closes below it
           and the category's thread runs past it: one entry, one division. */
        #homeUnderway .uw-item .uw-dir {
            /* A band of its own inside the row: 44px tall, taking no space from the entry
               above it, indented to the entry's own column. The marked row is twice the
               height of the others, which is the row it should be. */
            display: inline-flex;
            align-items: center;
            min-height: 44px;
            margin: 0 0 0 calc(var(--sp-lg) + var(--uw-col, 44px) + var(--sp-sm));
        }
        #homeUnderway .uw-item.is-next .uw-open {
            padding-bottom: var(--sp-2xs);
        }
        #homeUnderway .uw-item::before {
            content: '';
            position: absolute;
            left: calc(var(--sp-lg) + var(--uw-col, 44px) + (var(--sp-sm) / 2) - 1px);
            top: 0;
            bottom: 0;
            width: 2px;
            background: var(--uw-cat, var(--log-rule-firm));
        }

        /* THE NEXT THING, MARKED. A magenta triangle in the margin pointing at its row —
           the nights scale's own mark for "this is the one you are on", turned on its side.
           It replaces a NEXT row that restated a row already on the screen. */
        /* ⚠️ HUNG ON THE TIME, NOT MEASURED FROM THE ROW'S TOP (owner, 2026-09-18: 小红三角 没有和8:35对齐). It was placed
           at the row's padding plus 0.42em of the row's own type, while the time is micro type centred in a row held
           to 44px — two measurements from two different things, which agreed only by luck. On the time's own line
           box, centred on it, it cannot drift from the figure it points at. Same x as before: 5px clear of the time. */
        #homeUnderway .uw-item.is-next .uw-time,
        #homeUnderway .uw-item.is-now-pale .uw-time { position: relative; }
        #homeUnderway .uw-item.is-next .uw-time::before,
        #homeUnderway .uw-item.is-now-pale .uw-time::before {
            content: '';
            position: absolute;
            right: calc(100% + 5px);
            top: 50%;
            transform: translateY(-50%);
            /* Cut, not built from borders: the same 6 by 8 triangle, drawn as a shape. */
            width: 6px;
            height: 8px;
            background: var(--log-magenta);
            clip-path: polygon(0 0, 100% 50%, 0 100%);
        }
        /* What is still under way while the next thing is within the hour: the same mark, paler (see marksToday). */
        #homeUnderway .uw-item.is-now-pale .uw-time::before { opacity: 0.35; }

        #homeUnderway .uw-time {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.08em;
            font-variant-numeric: tabular-nums;
            color: var(--log-ink-soft);
            white-space: nowrap;
        }

        #homeUnderway .uw-what {
            font-family: var(--log-write);
            font-size: var(--fs-body);
            line-height: 1.4;
            color: var(--log-ink);
        }

        #homeUnderway .uw-item .uw-state {
            grid-column: 3;
            justify-self: end;
        }

        /* ---- what a quiet day says --------------------------------------------- */
        /* A REST DAY IS NOT AN EMPTY SCREEN — the question left open when the two homes
           were first sketched (2026-09-04) and answered here. It says so in words rather
           than leaving the sheet blank, because a blank sheet on a day with nothing on it
           is indistinguishable from a sheet that failed to load. */
        /* No rule under it. Everything that can follow this line draws its own rule on top —
           a heading band, or the magenta of an act — and a hairline sixteen pixels above one
           of those reads as a doubled rule rather than as two divisions. */
        #homeUnderway .uw-nothing {
            margin: 0;
            padding: var(--sp-md) var(--sp-lg);
            font-family: var(--log-write);
            font-size: var(--fs-body);
            line-height: 1.5;
            color: var(--log-ink-soft);
        }

        /* The slot kept for what is around stood here from 2026-09-18 to 2026-09-20: five words, inert, with a
           line saying they were not drawing yet. They draw now, under the journey's map, where a place found can be
           seen standing in its street (owner: 放到 map 页面) — see .tp-near in 17j-trip-plan.css. */

        /* ---- the one act -------------------------------------------------------- */
        /* WRITE TODAY DOWN. One press from opening the app to a diary form with today's
           date already in it. It was eleven presses (Home, the journey, the tab bar, the
           day, the day's +, a chooser, the sheet, the +, the form, the date field, the
           picker) — every one of them a place the intention could be put down and not
           picked up again.

           A full-width ruled band rather than a floating button: the record is written on
           the sheet, not on something hovering over it, and a bar the width of the page is
           a bigger target than any circle in a corner. */
        /* THREE ACTS, one block. Each writes to the record, so each takes the magenta; they
           are ruled between rather than spaced apart, because they are one offer with three
           answers and not three floating buttons. Full-bleed bands: the record is written on
           the sheet, and a band the width of the page is a bigger target than any circle in
           a corner. */

        #homeUnderway .uw-act {
            margin: 0;
            padding: var(--sp-xs) 0;
            background: none;
            border: none;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--log-magenta);
            text-align: left;
            cursor: pointer;
            /* The word is 14px tall and a thumb is not. Grown around it, so the words stay
               on one baseline with the verb in the margin. */
            position: relative;
            min-height: 30px;
        }
        #homeUnderway .uw-act::after {
            content: '';
            position: absolute;
            inset: -8px -6px;
        }
        #homeUnderway .uw-act:active { color: var(--log-ink); }

        /* ---- the states before there is anything to say ------------------------- */
        /* The four-state reading, the same as the trip plan's: this screen makes statements
           about today and must not make them before the server has answered. */
        #homeUnderway .uw-quiet {
            margin: 0;
            padding: var(--sp-xl) var(--sp-lg);
            font-family: var(--log-write);
            font-size: var(--fs-body);
            line-height: 1.5;
            color: var(--log-ink-soft);
        }
        #homeUnderway .uw-again {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            text-decoration: underline;
            text-underline-offset: 0.25em;
            background: none;
            border: none;
            padding: 0 0 0 var(--sp-2xs);
            color: var(--log-ink);
            cursor: pointer;
        }

        /* ---- the foot ----------------------------------------------------------- */
        /* RULED TO THE FOOT. A short day left 300px of bare stock under the last rule,
           which is the one thing this world does not do: a sheet ends on a rule and a way
           on, not on an expanse of nothing. The column fills the screen and the foot is
           pushed to the bottom of it, so a quiet Tuesday and a full one close the same way.
           Scoped to .is-underway — between journeys #homeUnderway holds one row and must
           not be a screen high. */
        /* The column IS the screen. Its own bar is the last thing in it, so nothing is
           subtracted and nothing is reserved. */
        #mainPage.is-underway #homeUnderway {
            display: flex;
            flex-direction: column;
            min-height: 100dvh;
        }
        /* The journey's own bar sits at the foot. Its own rules live with the other two
           rooms that carry it (17j-trip-plan.css) — only its place on this page is set
           here, which is what differs. */
        /* ⚠️ STICKY, BECAUSE THIS BAR IS IN THE FLOW. In the other two rooms that carry
           .tp-views the parent is a viewport-height column with the sheet scrolling inside
           it, so the bar cannot move. Here the column IS the page: ten items on a busy day
           in a city and it is taller than the screen, and the journey's four views scroll
           off the bottom — which is precisely what they were put here for (方便随时查看),
           lost exactly on the days there is most to look at.

           margin-top:auto still holds it down on a quiet day; sticky holds it on screen on a
           full one. It already carries the stock and the firm rule above it, so it reads as
           the foot rather than as something floating over the sheet (Plate-Not-Float). */
        #homeUnderway .tp-views {
            margin-top: auto;
            position: sticky;
            bottom: 0;
            z-index: 2;
        }



        /* ---- the rest of the sheet --------------------------------------------- */
        /* THE RULED-TO-THE-FOOT RULE, kept the way the drawer keeps it: what is left of the
           sheet is RULED, not blank. A day with one thing on it left six hundred pixels of
           bare stock between the last entry and the foot, which reads as a page that failed
           to load rather than as a page with room on it.

           The ruling is the same pitch as the log's own (--log-row), so an unwritten line
           here and a written one on the stops sheet are the same height, and the hairline
           weight, because these lines carry nothing on their own. It is decoration in the
           sense that a ruled page is decorated — which is to say it is the instrument. */
        #homeUnderway .uw-fill {
            flex: 1 1 auto;
            min-height: 0;
            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));
        }

        /* Which leg you are on. The full ink inside a soft sentence — it is the one fact in
           that line the eye should be able to find without reading the rest. */
        #homeUnderway .uw-place { color: var(--log-ink); }

        /* ---- the bar's own height ------------------------------------------------ */
        /* 48px, the same as --nav-h. The journey's bar had been 45 — its buttons' 44px hit
           height plus a hairline — so walking from Today to Saved moved the foot three
           pixels and the two bars read as two different objects. They are the same object;
           the words in them differ. Set on all three rooms that carry it. */
        #tripMapPage .tp-views,
        #boswellPage .tp-views,
        #mainPage .tp-views {
            min-height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
            box-sizing: border-box;
        }

        /* ---- where two rules would meet ------------------------------------------ */
        /* Every block on this sheet closes with a rule and the next one opens with one, so
           wherever two blocks touch there were two rules a hair apart pretending to be one
           thick one — under TONIGHT, and under ADD AN ACTIVITY where a magenta rule landed
           on the WRITTEN DOWN band's own. The block below wins: it is the one whose rule
           says what is starting. */
        #homeUnderway .uw-ruled + .uw-band {
            border-top: none;
        }

        /* ---- the cells ---------------------------------------------------------- */
        /* THE OWNER'S DRAWING (2026-09-18): Weather beside Add, Download & sync under both, then tonight's bed and the
           day. Cells OF the sheet, ruled where they meet and bleeding to its edges, not cards with air around them
           (Plate-Not-Float): the drawing says where things go, the ruling says how this world divides a page. */
        #homeUnderway .uw-cells {
            display: grid;
            grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
            border-bottom: 1px solid var(--log-rule-firm);
        }
        #homeUnderway .uw-cell {
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            gap: var(--sp-2xs);
            min-width: 0;
            margin: 0;
            padding: var(--sp-sm) var(--sp-lg) var(--sp-md);
            background: none;
            border: none;
            text-align: left;
            color: var(--log-ink);
        }
        #homeUnderway .uw-wx-cell {
            padding-right: var(--sp-md);
            border-right: 1px solid var(--log-rule-firm);
        }
        #homeUnderway .uw-add-cell { padding-left: var(--sp-md); }
        #homeUnderway button.uw-wx-cell { cursor: pointer; }
        /* The press every ruled row on this sheet gives: the baseline thickens. Not a fill (finish review, 2026-09-18). */
        #homeUnderway button.uw-wx-cell:active { box-shadow: inset 0 -2px 0 0 var(--log-rule-firm); }
        #homeUnderway .uw-off-cell {
            grid-column: 1 / -1;
            border-top: 1px solid var(--log-rule-firm);
        }

        /* The day's high, the one number worth reading from arm's length; the rest in the soft sentence under it. */
        #homeUnderway .uw-wx-deg {
            display: inline-flex;
            align-items: center;
            gap: var(--sp-xs);
            font-family: var(--log-write);
            font-size: var(--fs-xl);
            font-weight: 500;
            line-height: 1;
            color: var(--log-ink);
        }
        #homeUnderway .uw-wx-said,
        #homeUnderway .uw-off-said {
            margin: 0;
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.45;
            color: var(--log-ink-soft);
        }

        /* ADD keeps the magenta: every word in it puts a line on the record. Two by two, one press each. */
        #homeUnderway .uw-add-cell .uw-tab { color: var(--log-magenta); }
        #homeUnderway .uw-add-grid {
            display: grid;
            /* Word-sized columns (the Word-Sized Columns Rule), and a gap between the two rows that the hit areas below
               meet across rather than overlap: 32px of word and 6px of reach each side is 44px, and 12px of gap is
               where one ends and the next begins (finish review, 2026-09-18: the second row took sixteen pixels of the
               first's). */
            grid-template-columns: repeat(2, auto);
            justify-content: start;
            column-gap: var(--sp-lg);
            row-gap: 12px;
            width: 100%;
        }

        /* Doors: underlined print, in the ink. DOWNLOAD writes nothing to the record, so it is not magenta. */
        #homeUnderway .uw-off-acts {
            display: flex;
            gap: var(--sp-lg);
            margin-top: var(--sp-2xs);
        }
        #homeUnderway .uw-door {
            position: relative;
            min-height: 30px;
            padding: 0;
            background: none;
            border: none;
            cursor: pointer;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--log-ink);
            text-decoration: underline;
            text-underline-offset: 0.25em;
            text-decoration-thickness: 1px;
        }
        #homeUnderway .uw-door::after {
            content: '';
            position: absolute;
            inset: -8px -10px;
        }
        /* The forecast page's own line mark (wxMark, 02-state.js), at the height of the figure beside it. */
        #homeUnderway .uw-wx-deg .wx-day-mark { width: 26px; height: 26px; flex: none; }
        /* THE FIGURE STANDS ON ACTIVITY'S LINE (owner, 2026-09-18: Weather 温度和右边 Activity 对齐). Both cells open
           with a tab of one height, then a first row of one height — the figure's and the first two words' — so the
           two centres meet whatever the fonts do. The weather cell is a <button>, whose line-height is not the div's. */
        #homeUnderway .uw-cell .uw-tab { line-height: 1.2; }

        /* The focus ring is drawn INSIDE the cell (focus audit, 2026-09-21). The cells run to both edges of the
           sheet, so a ring drawn outside the first one is cut in half by the screen — the one place in this world
           where a 2px offset is wrong rather than standard. */
        #homeUnderway .uw-cell:focus-visible { outline-offset: -2px; }

        #homeUnderway .uw-wx-deg,
        #homeUnderway .uw-add-grid .uw-act {
            display: flex;
            align-items: center;
            height: 32px;
            min-height: 0;
            padding: 0;
        }
        /* REMOVE left Today for the Sync page on 2026-09-19, with the rest of the download's account (underwayOfflineParts). */
        /* A row's doors, DIRECTIONS and STATUS, side by side in the entry's own column. STATUS rides on every flight
           today; DIRECTIONS only on the marked row. */
        #homeUnderway .uw-doors {
            display: flex;
            gap: var(--sp-lg);
            margin-left: calc(var(--sp-lg) + var(--uw-col, 44px) + var(--sp-sm));
        }
        #homeUnderway .uw-doors .uw-dir { margin: 0; }
        #homeUnderway .uw-add-grid .uw-act::after { inset: -6px -6px; }
        /* The cell's own heading takes focus when the act that had it is gone (offlineRefocus); a heading focused by the
           page, not by a key, draws no ring. */
        #homeUnderway .uw-tab[data-focus-home]:focus:not(:focus-visible) { outline: none; }

        /* ---- waiting (2026-09-18) -------------------------------------------------- */
        /* THE WALL'S WAITING IDIOM, ON TODAY (owner: 加载态 我想要 skeleton 的感觉). Bones of the band's stock where words
           will stand, breathing on wall-breathe (17-shelf-wall.css), still when motion is off; the words timed by the
           stylesheet — nothing for the first moment, then the room's line, then at 8s what to do — with no timers. A
           bone is a shape, never a claim: the sheet says nothing about today until it has read today. */
        #homeUnderway .uw-bone {
            display: block;
            height: 12px;
            width: 60%;
            background: var(--log-stock-band);
            animation: wall-breathe 1.8s ease-in-out infinite;
        }
        #homeUnderway .uw-bone.is-deg { width: 64px; height: 26px; margin: 3px 0; }
        #homeUnderway .uw-bone.is-said { width: 80%; }
        #homeUnderway .uw-bone.is-name { width: 58%; height: 16px; margin-top: var(--sp-2xs); }
        #homeUnderway .uw-bone.is-where { width: 40%; margin-top: var(--sp-xs); animation-delay: 0.3s; }
        #homeUnderway .uw-bone.is-time { width: calc(var(--uw-col, 44px) - 6px); }
        #homeUnderway .uw-item.is-bone .uw-open { align-items: center; min-height: 52px; cursor: default; }
        #homeUnderway .uw-item.is-bone:nth-child(2) .uw-bone { animation-delay: 0.3s; }
        #homeUnderway .uw-item.is-bone:nth-child(3) .uw-bone { animation-delay: 0.6s; }
        @media (prefers-reduced-motion: reduce) {
            #homeUnderway .uw-bone { animation: none; }
        }

        #homeUnderway .uw-wait {
            margin: 0;
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.5;
            color: var(--log-ink-soft);
            opacity: 0;
            visibility: hidden;
        }
        #homeUnderway .uw-skel .uw-wait { padding: var(--sp-md) var(--sp-lg) 0; }
        #homeUnderway .uw-wait.is-soon { animation: uw-word-in 0.4s ease 1.5s forwards, uw-word-out 0.2s ease 8s forwards; }
        #homeUnderway .uw-wait.is-late { animation: uw-word-in 0.4s ease 8s forwards; }
        /* The late line stands where the early one stood. */
        #homeUnderway .uw-skel .uw-wait.is-late { margin-top: calc(-1 * (var(--sp-md) + 1.5em)); }
        @keyframes uw-word-in { to { opacity: 1; visibility: visible; } }
        @keyframes uw-word-out { to { opacity: 0; visibility: hidden; } }

        /* Over a held copy, on the place's line at the right: the day below is what the phone kept, being checked. */
        #homeUnderway .uw-check {
            position: relative;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            text-align: right;
            color: var(--log-ink-soft);
        }
        #homeUnderway .uw-check .uw-wait { font: inherit; letter-spacing: inherit; white-space: nowrap; }
        #homeUnderway .uw-check .uw-wait.is-late { position: absolute; right: 0; top: 0; }
        #homeUnderway .uw-check.is-failed { color: var(--log-ink); }

        /* ---- one line for the download (2026-09-19) -------------------------------- */
        /* The finding and its acts share a line while they fit; the acts wrap under it, to the right, when they do not. */
        #homeUnderway .uw-off-line {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            justify-content: flex-end;
            gap: 0 var(--sp-md);
            width: 100%;
        }
        #homeUnderway .uw-off-line .uw-off-said { flex: 1 1 200px; min-width: 0; }
        #homeUnderway .uw-off-line .uw-off-acts { flex: none; width: auto; margin-top: 0; gap: var(--sp-md); }
        /* A line that asks for DOWNLOAD gives its sentence the whole width and puts the acts under it, at the right. */
        #homeUnderway .uw-off-line.has-go .uw-off-said { flex-basis: 100%; }

        /* ⚠️ THE BED'S ADDRESS ON ONE LINE (owner, 2026-09-19): a full address took three lines above the day, and
           DIRECTIONS under it already goes there. Cut with an ellipsis; the whole of it is the entry's own. */
        #homeUnderway .uw-bed { grid-template-columns: minmax(0, 1fr) auto; }
        #homeUnderway .uw-bed .uw-where {
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        /* A journey's two ends, on the entry's second line under its name (underwayRoute). */
        #homeUnderway .uw-open .uw-route { grid-column: 2 / -1; grid-row: 2; }
