        /* ── carried from css/23-legacy-plate.css on 2026-09-22, as that part was deleted. It
           says of itself that what it argues is "kept in css/17s-plan-trip.css", so it belongs
           beside that rule rather than in a file nobody will open again. ── */
        /* ⚠️ REMOVED 2026-09-11, not overridden. The observation was right and is kept in
           css/17s-plan-trip.css: the browser's focus ring draws a rounded rectangle around a
           field that has no box, so the underline carries the focus instead. The COLOUR was
           `var(--accent)` — #5D675B, the retired world's sage — and this selector is
           (1 id, 3) against the new room's (1 id, 2) AND loads later, so it won twice over:
           there was no visible focus on any text field in the room, and the one colour that
           did appear was the world this round exists to leave.

           `#planTripForm` names nothing outside #planTripModal, so removing it here takes
           nothing else with it. The replacement is written at the depth that actually wins;
           adding a fifth rule at a losing depth is what the last four attempts did. */


        /* ══════════════════════════════════════════════════════════════
           MOVED OUT OF css/10-legacy-home-sheet.css · 2026-09-21  (prepended)
           6 rules (the banner said 7: .image-tab.active came across and was deleted here as dead,
           a few lines below). DESIGN.md: a surface's rules go in that surface's part, and the
           legacy parts only shrink.
           ⚠️ 10-legacy-home-sheet.css loaded BEFORE this file. This placement keeps
           their order against THIS PART’S OWN rules and nothing else: against the 25 part(s)
           between #10 and #36 the move reverses it. The banner used to claim they "keep that
           place" full stop, which was never true (review, 2026-09-22). Checked separately.
           ══════════════════════════════════════════════════════════════ */
        /* Multi-select Countries */

        .image-tab {
            padding: 8px 20px;
            border: none;
            background: transparent;
            color: var(--log-ink-soft);
            font-family: var(--log-write);
            font-size: 15px;
            letter-spacing: 1px;
            text-transform: uppercase;
            cursor: pointer;
            border-bottom: 2px solid transparent;
            transition: all 0.3s;
        }


        /* `.image-tab.active` was here and matched nothing. The three cover tabs are written
           `class="image-tab is-on"` (33-markup-trip.js:665) and switchImageTab (11-ai-chat.js:1091)
           toggles `is-on` on the TABS and `active` on the VIEWS — so the tab never wears the
           class this rule asked for. It was dressing the picked tab in --primary, the outgoing
           world; the rule that actually paints it is #planTripModal .image-tab.is-on below.
           Deleted 2026-09-21, coming out of css/10-legacy-home-sheet.css. The sibling
           `.image-view.active` IS live — the views do take `active`. */


        .image-view {
            display: none;
        }


        .image-view.active {
            display: block;
        }

        /* Image Upload */
        .image-upload-area {
            border: 2px dashed var(--log-rule-firm);
            border-radius: 0;
            padding: var(--sp-2xl) var(--sp-xl);
            text-align: center;
            cursor: pointer;
            transition: all 0.3s;
        }


        .image-upload-area:hover {
            border-color: var(--log-ink);
            /* Was the sage panel — --surface-sage and --rule-sage, a 12% and a 32% mix of the
               retired accent. The comment above says why it exists: these fields answer a
               different question from the ones above it, so the block is set apart. This world
               sets a block apart with the sheet’s own heading band and a hairline, not with a
               second surface colour. (2026-09-24) */
            background: var(--log-stock-band);
        }


        .image-upload-area.has-image {
            padding: 0;
            border: none;
        }

        /* ==========================================================================
           #AD  Add a trip — the title page of a log
           ==========================================================================

           Migrated into the deck log on 2026-09-11, at the owner's word: "add a trip 页面
           整个页面还是旧世界 需要迁移". It was the last room of the outgoing world that a
           NEW reader meets first — everything it leads to (the journey, the calendar, the
           journal, the day) had been migrated around it, so the one screen where a journey
           is begun was still cream, sage and serif while every room it opens onto was
           chart stock and copying pencil.

           ⚠️ EVERY RULE HERE IS QUALIFIED BY #planTripModal. Not a house style — a
           necessity. `.form-input`, `.form-label`, `.settings-block`, `.btn`, `.modal-*`
           and `.country-modal` are all dressed in css/23-legacy-plate.css and
           css/24-tail.css, which load AFTER this file. An unqualified rule here would lose
           to them on order alone; an id-qualified one wins on specificity wherever it sits.
           The same reasoning as css/17q-editor.css, and the reason both files look
           over-specified read on their own.

           ⚠️ AND ONE ID IS NOT ALWAYS ENOUGH. 24-tail writes a good deal of this form at
           `#planTripForm .settings-block .form-input` — one id and TWO classes — which
           beats every single-id selector here regardless of order. Those rules are written
           again at the foot of this file at matching depth. Three rules in this round were
           written, photographed, and found to have changed nothing before that was noticed;
           the values in the browser are what settled it, not the reading.

           ⚠️ AND THE ROOM IS NOT REBUILT, ONLY DRESSED. The markup carries a view mode and
           an edit mode over one shell, a country picker, a participant picker, an
           ownership lock that greys a companion's fields, and a visibility ladder — five
           behaviours this round does not touch. What changed in the markup is three
           things: a head band instead of two floating × glyphs, CHANGE instead of a pencil,
           and a third way to a cover. */

        /* ---- moved here from css/07-legacy-plan-trip.css (2026-09-15) -----------------

           At the top, and not with the rest at the foot, because 07 loads BEFORE this file: the
           rules below lost to anything in this file at the same depth, and at the top they still
           do. See the note at the foot for how they were chosen and checked. */
        #planTripModal .form-input:focus,
        #planTripModal .form-textarea:focus {
            border-color: var(--log-ink, #43276B);
            outline-offset: 1px;
            outline: none;
        }
        #planTripModal .modal-content {
            padding: 0;
        }
        #planTripModal .modal-actions {
            margin-top: 20px;
        }
        #planTripModal .image-upload-area {
            padding: 0;
            background-color: initial;
        }
        /* The inks below were --text-light and --text-primary, the outgoing world's, carried in with the rules on
           2026-09-15 because they still decided something; the deck log's are the ones meant (2026-09-17, what the outgoing world still painted (capture --legacy)). */
        #planTripModal .ntrip-cv-ph {
            color: var(--log-ink-soft);
        }
        #planTripModal .ntrip-tabs {
            flex-shrink: 0;
            outline: 1px solid var(--log-ink);
        }
        #planTripModal .ntrip-tabs .image-tab {
            border-color: currentcolor;
            color: var(--log-ink);
            letter-spacing: 0.06em;
            padding: 4px 8px;
        }


        /* ---- the shell ---------------------------------------------------------- */

        #planTripModal .modal-content {
            background: var(--log-stock);
            border-radius: 0;
            box-shadow: none;
            display: flex;
            flex-direction: column;
        }

        #planTripModal .modal-body {
            background: var(--log-stock);
            /* ⚠️ NO PADDING, NO WIDTH, NO MARGIN. The editor's round found this element
               carrying THREE separate insets plus an explicit width:90% — content padding
               24, body margin 17.8, body padding 20 — so fixing two of the three looked
               exactly like fixing none. The margin column belongs to the rows inside, at
               one value, named once. */
            padding: 0;
            margin: 0;
            width: auto;
            flex: 1;
            min-height: 0;
        }

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

        /* One ruling tall, like every other head in this world. It sits OUTSIDE
           .modal-body so it does not scroll away: this room is longer than a screen, and a
           way out that leaves before the first field is filled is not a way out. */
        #planTripModal .ptrip-top {
            flex: none;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: var(--sp-sm);
            min-height: var(--log-row);
            padding: var(--sp-2xs) var(--sp-lg);
            padding-top: calc(var(--sp-2xs) + env(safe-area-inset-top, 0px));
            background: var(--log-stock-band);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        /* Which journey this is, or that it is a new one. Stamped-State: a state the app
           knows, the app prints. */
        #planTripModal .ptrip-what {
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--log-ink);
        }

        #planTripModal .ptrip-close,
        #planTripModal .tsv-edit {
            flex: none;
            display: inline-flex;
            align-items: center;
            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);
        }

        /* ---- the cover plate ---------------------------------------------------- */

        /* The photograph, and nothing written on it. The two chips that used to float here
           are on their own band below — see .ntrip-tabs. */
        #planTripModal .ntrip-hero {
            position: relative;
            aspect-ratio: 16 / 9;
            height: auto;
            background: var(--log-stock-band);
            border-bottom: 1px solid var(--log-rule-firm);
            overflow: hidden;
        }

        #planTripModal .image-upload-area,
        #planTripModal .upload-preview,
        #planTripModal .link-preview,
        #planTripModal .image-view {
            position: absolute;
            inset: 0;
            width: auto;
            height: auto;
            margin: 0;
            border: none;
            border-radius: 0;
            background-size: cover;
            background-position: center;
        }
        /* The cover's button inherited `transition: all 0.3s` from the outgoing upload box (10-legacy-home-sheet.css), so
           focusing it drew a 3px black ring first and eased it into the ink over a third of a second (focus audit,
           2026-09-14). Nothing on it should move. */
        #planTripModal .image-upload-area { transition: none; }

        /* .image-view's display rule lives in the outgoing stylesheet; only the chosen one
           is on screen, and the others must not stack behind it and take the press. */
        #planTripModal .image-view { display: none; }
        #planTripModal .image-view.active { display: block; }

        /* ---- the empty plate, behind all three ways ----------------------------- */

        /* A hill, a sun, a sky — the drawing the capture fixtures have used for months, in
           this world's three inks. It is the LAST thing in the stack, so any chosen
           photograph (upload, link or search) simply covers it. */
        #planTripModal .ptrip-plate {
            position: absolute;
            inset: 0;
            width: 100%;
            height: 100%;
            display: block;
        }
        #planTripModal .ptrip-sky { fill: var(--log-rule-firm); }
        #planTripModal .ptrip-hill { fill: var(--log-ink); }
        #planTripModal .ptrip-sun { fill: var(--log-stock-band); }

        /* What UPLOAD and LINK each put ON the plate. One band, two contents — which is what
           makes the three tabs read as three ways to the same thing rather than three
           screens. SEARCH puts nothing here: its grid is right below the plate and needs no
           second announcement.

           ⚠️ A BAND AT THE FOOT, NOT WORDS IN THE MIDDLE. --log-on-oilskin over the sky is
           3.76:1, measured — under the 4.5 that text this size needs. The wash is the one
           the search grid's photographer credits already use, and it is legible over any
           photograph as well as over this drawing. */
        #planTripModal .ntrip-cv-ph,
        #planTripModal .ntrip-cv-urlbar {
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            top: auto;
            display: flex;
            /* ⚠️ `row`, AND IT IS LOAD-BEARING. css/07-section-sheet.css:133 sets (that part was called css/07-legacy-plan-trip.css until 2026-09-24)
               `flex-direction: column` on `.ntrip-cv-ph`, and this block never named the
               property — so `justify-content: flex-start` was acting on the VERTICAL axis
               (pushing the sentence to the band's top) and `align-items: center` on the
               horizontal (centring it). UPLOAD's words came out centred and high; LINK's
               field, which has no such legacy rule, came out at the margin. The two bands
               were still two designs, which is the exact thing the owner asked to fix.

               The capture assertion did not see it: it compared the two BANDS' rectangles,
               which were identical, rather than the two CONTENTS' left edges. Measuring the
               box instead of the thing inside it — the same miss as the right-column
               alignment three days ago. The assertion now measures the contents. */
            flex-direction: row;
            align-items: center;
            /* Both bands start at the room's margin column, so the two tabs differ in what
               they say and in nothing else. */
            justify-content: flex-start;
            gap: var(--sp-sm);
            min-height: 44px;
            padding: 0 var(--sp-lg);
            box-sizing: border-box;
            border-radius: 0;
            background: rgba(22, 25, 26, 0.62);
        }

        /* The camera icon and the chain-link icon are out of the markup, not hidden here:
           a rule that hides an element nobody draws is the next reader's ten minutes. */

        /* ⚠️ THE WORDS NEED THEIR OWN SELECTOR. css/07-section-sheet.css sets (renamed from css/07-legacy-plan-trip.css, 2026-09-24)
           `.ntrip-cv-ph .upload-text` to --font-serif — two classes, so it beat a single id
           on the parent, and the one sentence on an otherwise empty plate came out in
           Vollkorn: the outgoing world's serif, alone, in the middle of a deck-log room. A
           child with its own font rule inherits nothing. */
        #planTripModal .ntrip-cv-ph .upload-text {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--log-on-oilskin);
        }

        #planTripModal .ntrip-cv-urlbar input {
            flex: 1;
            min-width: 0;
            min-height: 44px;
            padding: 0;
            border: none;
            background: none;
            outline: none;
            font-family: var(--log-write);
            font-size: var(--fs-body);
            color: var(--log-on-oilskin);
            box-shadow: none;
        }
        #planTripModal .ntrip-cv-urlbar input::placeholder {
            color: var(--log-on-oilskin);
            opacity: 0.72;
        }

        /* ---- the three ways to a cover ------------------------------------------ */

        /* A band of printed words, under the plate. The chosen one is underscored, which is
           how this world has said "this one" since Home's PLAN IT / LIVE IT / KEEP IT. */
        #planTripModal .ntrip-tabs {
            position: static;
            display: flex;
            align-items: stretch;
            gap: var(--sp-xl);
            min-height: var(--log-row);
            padding: 0 var(--sp-lg);
            background: var(--log-stock-band);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        #planTripModal .image-tab {
            display: inline-flex;
            align-items: center;
            min-height: 44px;
            padding: 0;
            border: none;
            border-radius: 0;
            background: 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-soft);
        }

        #planTripModal .image-tab.is-on {
            color: var(--log-ink);
            box-shadow: inset 0 -3px 0 0 var(--log-ink);
        }

        /* ---- searching for one -------------------------------------------------- */

        /* ⚠️ THE PANEL'S DRESSING MOVED TO css/17t-stop.css ON 2026-09-11, unscoped, when
           the stop sheet asked for the same search. It was written here as
           `#planTripModal .ucov-*` — one room's dressing for a component that now has two
           rooms, which is a copy waiting to happen: the same fault as the two pickers where
           one kept its magnifier, and the two calendars before them.

           What stays here is only where the panel SITS in this room. */
        #planTripModal .ucov {
            padding: var(--sp-md) var(--sp-lg) var(--sp-lg);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        /* ---- the fields --------------------------------------------------------- */

        /* One margin column for the whole room, at --sp-lg. It was 20px, which is neither
           this world's 24 nor anything else's. */
        #planTripModal .settings-block {
            padding: var(--sp-lg) var(--sp-lg) var(--sp-md);
            background: var(--log-stock);
            border: none;
            border-radius: 0;
        }
        #planTripModal .settings-block.is-personal,
        #planTripModal .settings-block.is-visibility {
            border-top: 1px solid var(--log-rule-firm);
        }

        /* WHOSE these fields are, printed at the head of each block. The right-hand half is
           the whole reason a companion can look at a locked Budget field and know it is
           locked because it is not theirs, rather than because the app is broken. */
        #planTripModal .settings-block-head {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: var(--sp-sm);
            margin: 0 0 var(--sp-md);
            padding-bottom: var(--sp-2xs);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        #planTripModal .settings-block-title,
        #planTripModal .settings-block-who,
        #planTripModal .mys-fixed-head {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.16em;
            text-transform: uppercase;
        }
        #planTripModal .settings-block-title { color: var(--log-ink); }
        #planTripModal .settings-block-who,
        #planTripModal .mys-fixed-head { color: var(--log-ink-soft); }

        #planTripModal .form-section,
        #planTripModal .mys-field {
            margin: 0 0 var(--sp-md);
        }

        /* The label printed, the value written. The distinction is the whole grammar of
           this world: the app stamps, the traveller writes. */
        #planTripModal .form-label {
            display: block;
            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);
        }

        /* ⚠️ A SOLID HAIRLINE, NOT A DOTTED ONE. Every field in this room was `1px dotted`
           — the outgoing world's way of saying "you may write here". This world rules its
           sheet, and a ruled line is solid; a dotted one reads as a cut-here mark against
           the lattice the calendar and the pickers draw two screens away. */
        #planTripModal .form-input,
        #planTripModal .form-textarea,
        #planTripModal .ntrip-dest,
        #planTripModal .category-selector {
            width: 100%;
            box-sizing: border-box;
            min-height: 44px;
            padding: var(--sp-2xs) 0;
            border: none;
            border-bottom: 1px solid var(--log-rule-firm);
            border-radius: 0;
            background: none;
            outline: none;
            font-family: var(--log-write);
            font-size: var(--fs-base);
            color: var(--log-ink);
            text-align: left;
        }

        #planTripModal .form-textarea {
            min-height: 88px;
            padding: var(--sp-xs) 0;
            line-height: 1.5;
            resize: none;
        }

        #planTripModal .form-input::placeholder,
        #planTripModal .form-textarea::placeholder,
        #planTripModal .ntrip-dest-ph {
            color: var(--log-ink-soft);
            opacity: 1;
        }

        /* ⚠️ AT TWO IDS, BECAUSE THE ROOM'S OWN BASE RULE IS AT TWO IDS. The plain-field
           border below is written `#planTripModal #planTripForm .settings-block .form-input`
           to beat css/24-tail.css — which means a focus rule at ONE id loses to it and the
           underline never changes. Specificity is not a ladder you climb once. The sage
           version of this rule was removed from css/23-legacy-plate.css the same day; the
           observation it carried is kept here.

           The browser's own ring draws a rounded rectangle around a field that has no box,
           so it is turned off and the underline carries the focus instead. */
        #planTripModal #planTripForm .settings-block .form-input:focus,
        #planTripModal #planTripForm .settings-block .form-textarea:focus,
        #planTripModal #planTripForm .settings-block .ntrip-dates:focus-within,
        #planTripModal #planTripForm .settings-block .category-selector:focus,
        #planTripModal #planTripForm .settings-block #myBudgetInput:focus,
        #planTripModal .ucov-input:focus {
            outline: none;
            border-bottom-color: var(--log-ink);
            box-shadow: inset 0 -2px 0 0 var(--log-ink);
        }

        /* A field somebody else owns. It keeps its ink and gives up its rule — a greyed
           VALUE would say the trip has no budget rather than that the budget is not yours
           to set, which is the distinction the block head above it just drew. */
        #planTripModal .form-input:disabled,
        #planTripModal .form-textarea:disabled,
        #planTripModal .ntrip-dest:disabled {
            color: var(--log-ink);
            border-bottom-style: dashed;
            border-bottom-color: var(--log-rule);
            opacity: 1;
            cursor: default;
        }

        #planTripModal .ntrip-dest { cursor: pointer; }

        /* The nights, beside the dates. Printed, because it is the app's arithmetic on what
           the traveller chose and not something they wrote. */
        #planTripModal .ntrip-dates {
            display: flex;
            align-items: baseline;
            gap: var(--sp-md);
        }
        #planTripModal .ntrip-dates .form-input { flex: 1; min-width: 0; }
        #planTripModal .ntrip-nights {
            flex: none;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            font-variant-numeric: lining-nums tabular-nums;
            color: var(--log-ink-soft);
            white-space: nowrap;
        }

        /* A note under a field: the app explaining itself, quietly, in its own voice. */
        #planTripModal .mys-note {
            margin-top: var(--sp-2xs);
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.45;
            color: var(--log-ink-soft);
        }

        /* ---- the two pickers ---------------------------------------------------- */

        /* Countries and travelling-with are ONE component opened twice — both are
           `.country-modal`, both draw `.country-list-item`, and 14-friends-ui.js says so in
           a comment. It hangs under the field it belongs to rather than covering the screen,
           which is the decision the outgoing world already made and got right.

           ⚠️ THE ROW IS `.country-list-item`, NOT `.country-item`. The first pass here
           dressed `.country-item` — a class this app does not have — so every rule in this
           block matched nothing, and the owner opened the form and saw it: 感觉是半个新世界
           半个旧世界. Half was right. The panel, its border and its search row took the
           deck log because those selectors were real; the ROWS stayed on the outgoing
           world's cream, because that one was not. Third time this round a rule was written
           at the right depth against the wrong name and passed silently. */
        #planTripModal .country-modal {
            /* ⚠️ 220px IN A 382px COLUMN. That width WAS in css/10-legacy-home-sheet.css, deleted 2026-09-21, and
               it is the same fault the journal editor's place picker had four days ago,
               which was reported as "the field cannot be used": a list that opens at a bit
               over half the field's width reads as a tooltip rather than a list of choices.
               It hangs under the field, so it should span the field. */
            width: auto;
            left: 0;
            right: 0;
            margin-top: var(--sp-xs);
            max-height: 320px;
            border: 1px solid var(--log-rule-firm);
            border-radius: 0;
            background: var(--log-stock);
            box-shadow: none;
        }

        #planTripModal .country-search {
            display: flex;
            align-items: center;
            gap: var(--sp-xs);
            height: auto;
            min-height: 44px;
            padding: 0 var(--sp-sm);
            border-bottom: 1px solid var(--log-rule-firm);
            background: var(--log-stock-band);
        }
        /* The magnifier is out of the markup (see 33-markup-trip.js); this stays so that a
           picker somewhere else which still draws one is at least the right ink. */
        #planTripModal .country-search svg { color: var(--log-ink-soft); flex: none; }
        #planTripModal .country-search:focus-within {
            border-bottom-color: var(--log-ink);
            color: var(--log-ink);
        }
        #planTripModal .country-search input {
            flex: 1;
            min-width: 0;
            height: auto;
            border: none;
            background: none;
            outline: none;
            font-family: var(--log-write);
            font-size: var(--fs-base);
            letter-spacing: normal;
            color: var(--log-ink);
        }
        #planTripModal .country-search input::placeholder {
            color: var(--log-ink-soft);
            opacity: 1;
        }

        #planTripModal .country-list {
            flex: 1;
            min-height: 0;
            padding: 0;
            overflow-y: auto;
            overscroll-behavior: contain;
            -webkit-overflow-scrolling: touch;
            background: var(--log-stock);
        }

        /* A row. 44, not the 30 the outgoing world gave it — these are the only rows in this
           app you scroll fast and tap precisely, and thirty is a miss. */
        #planTripModal .country-list-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: var(--sp-sm);
            min-height: 44px;
            padding: var(--sp-2xs) var(--sp-sm);
            border-bottom: 1px solid var(--log-rule);
            background: var(--log-stock);
            cursor: pointer;
        }
        #planTripModal .country-list-item:last-child { border-bottom: none; }
        #planTripModal .country-list-item:hover { background: var(--log-stock-band); }

        #planTripModal .country-name {
            min-width: 0;
            font-family: var(--log-write);
            font-size: var(--fs-base);
            letter-spacing: normal;
            color: var(--log-ink);
        }

        /* ⚠️ A CHOSEN COUNTRY IS A FILLED ROW, not a coloured word. It was
           `.selected .country-name { color: accent; font-weight: 600 }` — a chosen row and
           an unchosen one differed by a hue and half a weight on a 13px word, on the
           outgoing world's cream, in a list you scroll. This is the same figure/ground flip
           the calendar's written days and the date picker's chosen days use, three screens
           apart, and it is legible at a glance in a moving list. */
        #planTripModal .country-list-item.selected {
            background: var(--log-ink);
        }
        #planTripModal .country-list-item.selected .country-name {
            color: var(--log-on-oilskin);
            font-weight: 600;
        }

        /* Nothing found. Not a row you can press, and it says so by not looking like one. */
        #planTripModal .country-list-item.is-empty {
            cursor: default;
            background: var(--log-stock);
        }
        #planTripModal .country-list-item.is-empty:hover { background: var(--log-stock); }
        #planTripModal .country-list-item.is-empty .country-name { color: var(--log-ink-soft); }

        #planTripModal .country-list-item:focus-visible {
            outline: none;
            box-shadow: inset 0 0 0 2px var(--log-ink);
        }

        /* The remove mark on a chip. It is the one glyph this room keeps, because it is a
           removal sitting inside a word and a word there would read as part of the name —
           and it takes the magenta, which removal is drawn in everywhere (owner, 2026-09-17: 打开表单算写记录，删除统一用品红); it was port red.
           Its colour had been written into the markup as `stroke="var(--accent)"`, where no
           stylesheet could reach it; the markup now says currentColor. */
        #planTripModal .ntrip-dest-chip svg,
        #planTripModal .participant-chip svg {
            color: var(--log-magenta);
            flex: none;
            cursor: pointer;
        }

        /* ---- the way out, and the two acts -------------------------------------- */

        #planTripModal .modal-actions {
            display: flex;
            align-items: center;
            gap: var(--sp-xl);
            min-height: var(--log-row);
            padding: var(--sp-2xs) var(--sp-lg);
            padding-bottom: calc(var(--sp-2xs) + env(safe-area-inset-bottom, 0px));
            background: var(--log-stock-band);
            border-top: 1px solid var(--log-rule-firm);
        }

        #planTripModal .modal-actions .btn {
            flex: none;
            width: auto;
            min-height: 44px;
            padding: 0;
            border: none;
            border-radius: 0;
            background: none;
            box-shadow: 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;
        }

        /* SAVE takes the magenta: it is the press that writes a journey into the record,
           and it is the only one on this band that does. CANCEL is a way out and ways out
           are ink. DELETE is the magenta, as every removal is (owner, 2026-09-17: 打开表单算写记录，删除统一用品红);
           it was port red, which is a refusal's colour. */
        #planTripModal .modal-actions .btn-primary { color: var(--log-magenta); }
        #planTripModal .modal-actions .btn-primary:active {
            box-shadow: inset 0 -2px 0 0 var(--log-magenta);
        }
        #planTripModal .modal-actions .btn-secondary { color: var(--log-ink); }
        #planTripModal .modal-actions .btn-danger { color: var(--log-magenta); }

        /* ⚠️ SAVE ON THE RIGHT, THE WAY OUT ON THE LEFT (owner, 2026-09-11: cancel 左边
           save 右边). The act you came to perform sits under the thumb; the way out sits
           where a way out sits everywhere else in this world — at the start of the line, as
           BACK and PREVIOUS and CLOSE all do.

           ⚠️ BY `order`, NOT BY MOVING THE MARKUP. The submit button has to stay first in
           TREE order: a form's implicit submission — Enter in a text field — fires the first
           submit button in the document, not the first one on screen. Reordering the markup
           would have put Save where the eye wants it and quietly made Cancel the thing that
           Enter presses. */
        #planTripModal .modal-actions .btn-secondary,
        #planTripModal .modal-actions .btn-danger { order: 1; }
        #planTripModal .modal-actions .btn-primary { order: 2; margin-left: auto; }

        /* ---- the reading mode --------------------------------------------------- */

        /* ⚠️ `height: auto` IS LOAD-BEARING. 24-tail gives this a fixed `height: 168px`
           (it stays sticky, which is its decision and a good one — the photograph is the
           trip's identity and should not scroll away). Adding `aspect-ratio` on top of a
           fixed height makes the ratio derive the WIDTH instead: the plate came out
           298.664px wide in a 430px sheet — 168 × 16/9, exactly — and sat as a grey block
           three-quarters across the room. Measured, not noticed: at the pane's scale it
           looked like an image that had not loaded. */
        #planTripModal .tsv-cover {
            height: auto;
            aspect-ratio: 16 / 9;
            background-size: cover;
            background-position: center;
            background-color: var(--log-stock-band);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        /* No photograph: the sheet's own ruling, at --log-row pitch, the same as the empty
           cover plate on the form. */
        #planTripModal .tsv-cover.is-blank {
            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));
        }

        #planTripModal .tsv-head {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: var(--sp-md);
            min-height: var(--log-row);
            padding: var(--sp-xs) var(--sp-lg);
            background: var(--log-stock-band);
            border-bottom: 1px solid var(--log-rule-firm);
        }
        #planTripModal .tsv-headtext { min-width: 0; }

        #planTripModal .tsv-title {
            font-family: var(--log-print);
            font-size: var(--fs-lg);
            font-weight: 600;
            letter-spacing: 0.02em;
            color: var(--log-ink);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        #planTripModal .tsv-dates {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            font-variant-numeric: lining-nums tabular-nums;
            color: var(--log-ink-soft);
        }

        #planTripModal .tsv-section {
            padding: var(--sp-lg) var(--sp-lg) var(--sp-md);
            background: var(--log-stock);
            border: none;
        }
        #planTripModal .tsv-section.is-mine,
        #planTripModal .tsv-section.is-see {
            border-top: 1px solid var(--log-rule-firm);
        }

        #planTripModal .tsv-head-row {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: var(--sp-sm);
            margin-bottom: var(--sp-md);
            padding-bottom: var(--sp-2xs);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        #planTripModal .tsv-eyebrow,
        #planTripModal .tsv-who,
        #planTripModal .tsv-label {
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
        }
        #planTripModal .tsv-eyebrow { color: var(--log-ink); }
        #planTripModal .tsv-who,
        #planTripModal .tsv-label { color: var(--log-ink-soft); }

        #planTripModal .tsv-fields > div,
        #planTripModal .tsv-set-row {
            padding: var(--sp-xs) 0;
            border-bottom: 1px solid var(--log-rule);
        }

        #planTripModal .tsv-value,
        #planTripModal .tsv-notes {
            font-family: var(--log-write);
            font-size: var(--fs-base);
            line-height: 1.5;
            color: var(--log-ink);
        }
        /* The one thing on this screen that is a READING rather than a value, so it keeps
           the margin rule the outgoing world gave it — in the log's ink, not the sage. */
        #planTripModal .tsv-notes {
            white-space: pre-wrap;
            padding-left: var(--sp-sm);
            border-left: 2px solid var(--log-rule-firm);
        }
        #planTripModal .tsv-role,
        #planTripModal .tsv-cur { color: var(--log-ink-soft); }

        #planTripModal .tsv-fixed-row,
        #planTripModal .mys-fixed-row {
            display: flex;
            flex-direction: column;
            gap: 2px;
            padding: var(--sp-xs) 0;
            border-bottom: 1px solid var(--log-rule);
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.45;
            color: var(--log-ink-soft);
        }
        /* The explanation beside each rule. It needs its own selector rather than inheriting
           from the row: 24-tail addresses `.tsv-fixed-row span` directly, and an element
           with its own colour rule inherits nothing from its parent's. Found by reading the
           computed value (#66645C, the outgoing world's secondary text) rather than the
           stylesheet, which said what I meant. */
        #planTripModal .tsv-fixed-row span,
        #planTripModal .mys-fixed-row span {
            flex: none;
            color: var(--log-ink-soft);
        }

        /* ⚠️ `width: auto` — 24-tail sets these to a fixed 76px, which is right for the
           two-column row it was written for and wrong here: stacked, a 76px box turned
           "Trip details" into "TRIP" over "DETAILS" and the pair read as two entries. */
        #planTripModal .tsv-fixed-row b,
        #planTripModal .mys-fixed-row b {
            width: auto;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            color: var(--log-ink);
        }

        /* ---- reachable without a pointer ---------------------------------------- */

        /* Both the journal and the calendar were found on 2026-09-11 to be unusable without
           a mouse. This room is mostly real inputs and real buttons and so starts in better
           shape, but its focus ring has to be visible against chart stock — the browser's
           own is a thin blue line drawn for white. */
        #planTripModal button:focus-visible,
        #planTripModal [tabindex]:focus-visible {
            outline: 2px solid var(--log-ink);
            outline-offset: 2px;
        }

        /* ==========================================================================
           The rules that had to be written twice as deep
           ==========================================================================

           ⚠️ EVERYTHING BELOW IS SCOPED `#planTripModal #planTripForm .settings-block`,
           and that is not belt-and-braces. css/24-tail.css dresses this form at
           `#planTripForm .settings-block .form-input` — one id and two classes — which
           beats the single-id selectors above no matter which file loads later. Three of
           this round's rules were written, photographed, and found to have changed
           nothing for exactly that reason.

           What 24-tail still owns here is BEHAVIOUR: the chip rows, the companion lock,
           the two pickers' anchoring. Those are not re-decided; only their dressing is.
           The colour bands, the floating cover chips and the shared action row were
           REMOVED from that file rather than overridden — see the notes left in their
           place. */

        #planTripModal #planTripForm .settings-block {
            margin: 0;
            padding: var(--sp-lg) var(--sp-lg) var(--sp-md);
            background: var(--log-stock);
            border: none;
        }
        #planTripModal #planTripForm .settings-block.is-personal,
        #planTripModal #planTripForm .settings-block.is-visibility {
            background: var(--log-stock);
            border-top: 1px solid var(--log-rule-firm);
        }

        #planTripModal #planTripForm .settings-block-head {
            margin: 0 0 var(--sp-md);
            padding-bottom: var(--sp-2xs);
            border-bottom: 1px solid var(--log-rule-firm);
        }

        #planTripModal #planTripForm .settings-block .form-input,
        #planTripModal #planTripForm .settings-block .form-textarea {
            font-family: var(--log-write);
            font-size: var(--fs-base);
            letter-spacing: normal;
            color: var(--log-ink);
            border: none;
            border-bottom: 1px solid var(--log-rule-firm);
            border-radius: 0;
            background: none;
        }
        #planTripModal #planTripForm .settings-block .form-textarea {
            padding: var(--sp-xs) 0;
            line-height: 1.5;
        }

        /* ⚠️ THE PLACEHOLDERS NEEDED THIS DEPTH TOO. css/23-legacy-plate.css (deleted 2026-09-24) wrote them at
           `#planTripForm .settings-block .form-input::placeholder`, so the single-id rule
           above lost and this room showed TWO greys: "Select destinations…" in the log's ink
           (its placeholder is a span, which took the shallower rule) and the other three in
           the outgoing world's #66645C. Two colours for one kind of word, in one column. */
        #planTripModal #planTripForm .settings-block .form-input::placeholder,
        #planTripModal #planTripForm .settings-block .form-textarea::placeholder {
            color: var(--log-ink-soft);
            opacity: 1;
        }

        #planTripModal #planTripForm .settings-block-head .settings-block-title { color: var(--log-ink); }
        #planTripModal #planTripForm .settings-block-head .settings-block-who { color: var(--log-ink-soft); }
        #planTripModal #planTripForm .settings-block .form-label { color: var(--log-ink-soft); }

        /* The chip rows and the two boxes of the budget field. Same hairline as every
           other field: one way of saying "you may write here", drawn once. */
        #planTripModal #planTripForm .settings-block .ntrip-dest,
        #planTripModal #planTripForm .settings-block .selected-participants,
        #planTripModal #planTripForm .settings-block .ntrip-dates,
        #planTripModal #planTripForm .settings-block .category-selector,
        #planTripModal #planTripForm .settings-block #myBudgetInput {
            border: none;
            border-bottom: 1px solid var(--log-rule-firm);
            border-radius: 0;
            background: none;
            font-family: var(--log-write);
            font-size: var(--fs-base);
            color: var(--log-ink);
            /* ⚠️ 44, NOT 36. Every field in this room was 36px tall and 24-tail says so in
               five places, on the argument that one height across the screen reads as one
               instrument. It does — and 36 is under the smallest reliable touch target, so
               the argument was being made about a control people miss. Caught by the
               capture, not by looking: the row LOOKS fine at 36, which is the whole reason
               the check counts pixels rather than photographing them. */
            min-height: 44px;
            box-sizing: border-box;
        }

        /* The dates row carries a rule and the field inside it must still be pressable.
           24-tail zeroes the input's own height so the ROW can draw the line under both the
           range and the nights — correct, and it left a 21px press target on the one field
           in this room that opens a whole second instrument. The line stays on the row; the
           height goes back on the input. */
        #planTripModal #planTripForm .settings-block .ntrip-dates {
            border-bottom: 1px solid var(--log-rule-firm);
        }
        #planTripModal #planTripForm .settings-block .ntrip-dates .form-input {
            min-height: 44px;
            padding: 0;
            border-bottom: none;
        }

        #planTripModal #planTripForm .settings-block .ntrip-dest-chip,
        #planTripModal #planTripForm .settings-block .participant-chip {
            font-family: var(--log-write);
            font-size: var(--fs-base);
            color: var(--log-ink);
        }

        /* The way to add one. A word, in the ink that this world gives to acts that change
           the record — the same magenta SAVE takes, because adding a companion to a journey
           is a change to the journey. */
        #planTripModal #planTripForm .settings-block .ntrip-dest-add {
            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;
            color: var(--log-magenta);
        }
        #planTripModal #planTripForm .settings-block .ntrip-dest-ph {
            font-family: var(--log-write);
            font-size: var(--fs-base);
            letter-spacing: normal;
            color: var(--log-ink-soft);
        }

        /* Who sees the outline: four rungs, one chosen. A ruled row with the chosen rung in
           the ink — the same figure/ground flip the calendar's marked days use, and the
           same lattice: 1px of rule showing between cells. */
        #planTripModal .mys-ladder {
            display: flex;
            gap: 1px;
            border: 1px solid var(--log-rule-firm);
            background: var(--log-rule);
        }
        #planTripModal .mys-rung {
            flex: 1;
            min-width: 0;
            min-height: 44px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: none;
            background: var(--log-stock);
            cursor: pointer;
            font-family: var(--log-print);
            font-size: var(--fs-micro);
            font-weight: 600;
            letter-spacing: 0.12em;
            text-transform: uppercase;
            color: var(--log-ink);
        }
        #planTripModal .mys-rung.is-on {
            background: var(--log-ink);
            color: var(--log-on-oilskin);
        }

        /* ---- a companion's view: locked, not hidden ----------------------------- */

        /* The lock is the ABSENCE of the mark that says "you may write here". No padlock,
           no greying: a greyed value says the trip has no budget rather than that the
           budget is not yours to set, and that distinction is what the block head above it
           has just drawn. This is the decision 24-tail already made and got right; only the
           ink changes. */
        #planTripModal #planTripForm .settings-block.is-not-mine .form-input,
        #planTripModal #planTripForm .settings-block.is-not-mine .form-textarea {
            font-family: var(--log-write);
            font-size: var(--fs-base);
            color: var(--log-ink);
            -webkit-text-fill-color: var(--log-ink);
            border: none;
            opacity: 1;
        }
        #planTripModal #planTripForm .settings-block.is-not-mine .ntrip-nights {
            font-size: var(--fs-body);
            color: var(--log-ink-soft);
        }
        #planTripModal #planTripForm .settings-block.is-not-mine .ntrip-dest-chip + .ntrip-dest-chip::before,
        #planTripModal #planTripForm .settings-block.is-not-mine .participant-chip + .participant-chip::before {
            color: var(--log-ink-soft);
        }

        /* ---- moved here from the legacy stylesheets (2026-09-15) -----------------------

           Everything the outgoing files still decided in this room, and nothing else. Each
           rule below was a rule in css/07-legacy-plan-trip.css, css/23-legacy-plate.css or
           css/24-tail.css that changed a computed value somewhere in this room when it was
           taken out, measured in ten states and three focus states at 430 and 1440 wide. Only
           the declarations that changed something came across, under the rule's own selector
           (an id added where it had none), in the order the cascade read them. With all of it
           here and the old rules gone, every element in the room computed the same values as
           before, in every one of those states. The rules that decided nothing were deleted.

           The selectors are the old ones on purpose: they were winning by their specificity,
           and a rewrite at another depth is how this room lost rules before (see the head of
           this file). Folding them into the sections above is a later job, and each fold has to
           be measured the same way. */
        #planTripForm .settings-block .form-input,
        #planTripForm .settings-block .form-textarea {
            padding: 0 0 var(--sp-xs);
        }
        #planTripForm .settings-block .form-textarea {
            min-height: 4.5em;
        }
        #planTripForm .settings-block .form-input::placeholder,
        #planTripForm .settings-block .form-textarea::placeholder {
            font-family: var(--log-write);
            font-size: 15px;
        }
        #planTripForm .settings-block .form-input:focus,
        #planTripForm .settings-block .form-textarea:focus {
            outline: none;
            border-bottom-color: var(--log-ink, #43276B);
        }
        #planTripForm .settings-block-title,
        #planTripForm .settings-block-who,
        #planTripForm .settings-block .form-label {
            font-family: var(--log-write);
            letter-spacing: 0.14em;
        }
        #planTripForm .settings-block-who {
            font-weight: 400;
        }
        #planTripForm .settings-block .form-section {
            margin-bottom: var(--sp-md);
        }
        #planTripForm .settings-block .form-section:last-child {
            margin-bottom: 0px;
        }
        #planTripForm .settings-block .mys-field {
            margin-top: var(--sp-md);
        }
        /* Only the leading: this rule came later than #planTripModal .mys-note and overrode its face and ink with the
           outgoing ones (2026-09-17, what the outgoing world still painted (capture --legacy)). */
        #planTripForm .mys-note {
            line-height: 1.5;
        }
        #planTripForm .settings-block .category-selector {
            height: 44px;
        }
        #planTripForm .settings-block .category-selector .dropdown-arrow {
            width: 14px;
            height: 14px;
            stroke: var(--log-ink-soft);
        }
        #planTripForm .settings-block .form-row-split .form-input {
            height: 44px;
            font-variant-numeric: lining-nums tabular-nums;
        }
        #planTripForm .settings-block .form-row-split .form-input:focus {
            border-color: var(--log-ink, #43276B);
        }
        #planTripForm .settings-block .currency-dropdown {
            background: var(--log-stock);
        }
        #planTripForm .settings-block .currency-option {
            padding: 8px;
            font-size: 13px;
        }
        #planTripModal.is-viewing #planTripForm {
            display: none;
        }
        #planTripModal .modal-content {
            height: 100%;
            max-height: 100%;
        }
        #planTripModal #planTripForm {
            padding-bottom: 0px;
        }
        @media (min-width: 768px) {
            .app-frame > #planTripModal #planTripForm {
                padding-bottom: var(--nav-h);
            }
        }
        #planTripForm .settings-block .form-textarea {
            resize: none;
        }
        #planTripForm .settings-block .form-row-split {
            row-gap: 8px;
            column-gap: 8px;
            align-items: flex-start;
        }
        #planTripModal #planTripForm .settings-block .category-selector {
            width: 82px;
            padding: 4px 0;
        }
        #planTripForm .settings-block .form-row-split > .form-group:first-child {
            flex-shrink: 0;
        }
        #planTripForm .settings-block .form-row-split > .form-group:last-child {
            flex-grow: 1;
            min-width: 0px;
        }
        #planTripModal #planTripForm .settings-block #myBudgetInput {
            padding: 4px 0;
        }
        #planTripModal #planTripForm .settings-block .ntrip-dest,
        #planTripForm .settings-block .selected-participants {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            padding-top: 4px;
            padding-bottom: 4px;
        }
        #planTripForm .settings-block .ntrip-dest-chip,
        #planTripForm .settings-block .participant-chip {
            display: inline-flex;
            align-items: center;
            row-gap: 5px;
            column-gap: 5px;
            height: auto;
        }
        #planTripModal #planTripForm .settings-block .ntrip-dest,
        #planTripForm .settings-block .selected-participants {
            row-gap: 14px;
            column-gap: 14px;
        }
        #planTripForm .settings-block .ntrip-dest-add {
            line-height: 1;
            cursor: pointer;
        }
        #planTripForm #selectedDestinationsText {
            display: contents;
        }
        #planTripModal #planTripForm .settings-block .ntrip-dates {
            padding-top: 4px;
            padding-bottom: 4px;
        }
        #planTripForm .mys-fixed {
            margin-top: 0px;
            padding-top: 0px;
            border-top-width: 0px;
            border-top-style: none;
            border-top-color: currentcolor;
        }
        #planTripForm .settings-block.is-not-mine .form-section {
            margin-bottom: 14px;
        }
        #planTripForm .settings-block.is-not-mine .form-label {
            margin-bottom: 2px;
        }
        #planTripForm .settings-block.is-not-mine .ntrip-dest-add,
        #planTripForm .settings-block.is-not-mine .ntrip-dest-chip svg,
        #planTripForm .settings-block.is-not-mine .participant-chip svg {
            display: none;
        }
        #planTripModal #planTripForm .settings-block.is-not-mine .form-input,
        #planTripModal #planTripForm .settings-block.is-not-mine .form-textarea,
        #planTripModal #planTripForm .settings-block.is-not-mine .ntrip-dates,
        #planTripModal #planTripForm .settings-block.is-not-mine .ntrip-dest,
        #planTripModal #planTripForm .settings-block.is-not-mine .selected-participants {
            border-bottom-width: medium;
            border-bottom-style: none;
            border-bottom-color: currentcolor;
            min-height: 0px;
            padding-top: 0px;
            padding-bottom: 0px;
        }
        #planTripModal #planTripForm .settings-block.is-not-mine .ntrip-dest,
        #planTripModal #planTripForm .settings-block.is-not-mine .selected-participants {
            row-gap: 0px;
            column-gap: 0px;
        }
        #planTripForm .settings-block.is-not-mine .ntrip-dest {
            pointer-events: none;
        }
        #planTripForm .settings-block.is-not-mine .ntrip-dest-chip + .ntrip-dest-chip::before,
        #planTripForm .settings-block.is-not-mine .participant-chip + .participant-chip::before {
            content: "·";
            margin-right: 6px;
            margin-left: 6px;
        }

        /* ---- the notes that stood beside those rules (2026-09-15) ----------------------

           Each rule above left a comment behind in its old file, and with the rule gone the comment
           stood over nothing. The words are kept here, as they were written, because several record
           a decision that is still in force (the 44px floor on the chip rows, the rule that runs to
           the end of the Dates row, a companion's fields drawn without a line). Where one says
           "here" or "above", it meant its old file. */
        /* ·· from css/07-legacy-plan-trip.css ·· */
        /* 13a cover hero on top */
        /* ⚠️ THE 20px SIDE MARGIN ON THE FORM'S DIRECT CHILDREN WENT 2026-09-11. It gave
           this room a second margin column: the colour blocks bled to the edges and carried
           their own 20, and everything else was inset by this rule — so the cover's tab band
           and the search panel sat 20px in from a sheet whose fields started at 24. One
           margin column, named once, on the rows inside; see css/17s-plan-trip.css. A
           duplicate of this rule in css/24-tail.css went the same day. */
        /* Destination chips (13a) */
        /* Dates field with auto nights (13a) */
        /* 封面右上角的关闭。原来是「不透明纸色底块 + 1px 描边 + 深色 ×」——
           那一套是为了让它在过曝照片上还能读出来。底块后来跟着「封面上不放
           任何非控件的东西」拆了,描边却留着,于是照片上浮着一个 44px 的空方框。
           现在:无底、无框,浅色 × 加一圈深色字形描边(见样式表末尾)。 */
        /* ·· from css/23-legacy-plate.css, deleted 2026-09-24 ·· */
        /* ----- Trip settings, per the design -----
           A ledger page, not a web form: the value is set in the display serif at reading
           size, the label is a small letter-spaced cap above it, and a single hairline sits
           under the value. No boxes — a boxed field competes with the value inside it. */
        /* 占位符不用斜体。斜体是第三种字形 —— §4 只定义了衬线与无衬线两族,
           而且占位符会被替换成正体的值,同一格里前后两种字形。
           两个下拉的搜索行早已是正体(.country-search / 朋友选择器),这一屏
           剩下的五个字段是最后一处斜体。 */
        /* Numbers in the display serif default to oldstyle figures, which stagger above and
           below the line — right for a date, wrong for a sum, where the eye wants a column. */
        /* Strip the number spinner: nobody reaches a budget by stepping. */
        /* ===== Trip settings: the magazine treatment =====
           Two panels on the page, each answering one question — what is this trip, and what
           is this trip to me. Panels rather than a continuous form because the questions are
           different in kind, and the eye should be told so before it starts reading. */
        /* The personal panel takes the sage tint — the same colour the register uses for
           "this is yours", so the association is already learnt. */
        /* 段眉、归属注、字段标签同一档 —— 和显示页(.tsv-eyebrow / .tsv-who /
           .tsv-label)逐条一致:9.5px 大写、字距 0.14em,三者只靠字重分别。
           此前编辑页是段眉 3px、归属注 0.95px、字段标签句首大写无字距 ——
           三种字距加一种大小写,而显示页那边同样三样东西只有一种写法。
           两态共用骨架,眉题式对不上就没有骨架可言。 */
        /* ⚠️ Type at reading size, not display size.
           A form is a column of answers; setting every one of them at heading size makes the
           page shout and pushes the panel off the screen. --fs-base reads as a written
           answer, which is what these are. */
        /* Fields sit closer together inside a panel — the panel edge already separates them
           from everything else, so they do not each need their own margin of silence. */
        /* 说明行 12px 无衬线 —— 和显示页固定规则那几行同一档。
           原来是 Vollkorn 13px:衬线在这一套里标记「读物」(Notes),
           一句字段说明不是读物。 */
        /* ===== Budget currency picker =====
           The activity picker's CURRENT appearance, not its base one.
           
           ⚠️ Those styles live under `.card4b .bp-fold` and carry `` throughout.
           Copying the markup alone left this picker falling back to the plain
           `.category-selector` rules underneath — bigger type, no fill, square corners —
           which is why it kept looking like a different control however many times the
           structure was matched. The scope is what makes it look right, and the scope does
           not travel with the markup.
           
           These are the same declarations, re-stated for this form. Duplication is the cost
           of a design that is scoped to one card; the alternative is moving those rules to
           a shared class, which would touch the expense form and is not worth the risk
           today. */
        /* The amount sits beside it, same height and same box — a money row reads as one
           control in two parts, not as two unrelated fields. */
        /* ·· from css/24-tail.css ·· */
        /* 被钉到抽屉矩形时要撑满它:.modal.active 默认把内容居中，
           而这一屏比矩形高，居中会让页眉滚出上沿、按钮停在半空
           （openModal 里 editorOpen 分支的注释记过同一个坑)。
           改成竖向 flex + body 独自滚动。 */
        /* The geometry stays — this room is taller than the sheet and the body is what
           scrolls. The BAND COLOUR went on 2026-09-11: the whole --ts-band-* gradient
           (paper → deeper → green) was the outgoing world's way of segmenting this form,
           and the deck log segments with rules on one stock. See css/17s-plan-trip.css. */
        /* 底部导航的让位 —— --nav-h 的第四个引用点。
           弹窗从抽屉进来时会被搬到 <body> 上、钉在抽屉矩形里,导航不在它下面;
           但从首页「Add a Trip」进来时它还长在 .app-frame 里,导航就压在它
           最后 48px 上,动作行正好被切掉一半(84px 的行只剩上面 36px)。
           用子选择器区分这两种处境:portal 出去之后这条自然失效。
           色块仍然通到下沿 —— 让位是让给导航,不是在中间留一道缝。 */
        /* The dotted底边 — the outgoing world's mark for "you may write here" — went on
           2026-09-11. This world rules its sheet and a ruled line is solid; a dotted one
           reads as a cut-here mark beside the lattice the calendar and the date picker draw.
           The replacement is in css/17s-plan-trip.css. `resize: none` survives there, and
           for the reason given here: this screen already scrolls. */
        /* 币种和金额是一个字段的两半,不是两个字段 —— 16px 的间隔把它们读成
           并排的两格。收到 8px,和 chip 之间的距离同一档。 */
        /* 币种格定宽 82,金额吃剩下的。原来两格各带内联 flex:1 等分 146,
           82px 的币种右边空出 64px —— 看着像两个字段而不是一个。 */
        /* ⚠️ min-height WAS 36px AND IS NOW THE ROOM'S (44, in css/17s-plan-trip.css). It is
           REMOVED here rather than overridden there: both selectors carry two ids and two
           classes, so this file wins on load order alone, and a rule written at matching
           depth in 17s changed nothing. That is the trap the head of index.html warns about
           and it cost two capture runs to see.

           36 came from "every control on this screen is 36, so one height reads as one
           instrument" — which is a real argument about a size people miss. The capture
           counts pixels for exactly this: the row LOOKS fine at 36. */
        /* chip 不加框。名字后面跟一个 accent 色的 × 已经说清「这是一枚可删的东西」——
           再套一个纸面加发丝边,就是在一条点线底边上又画一个盒子,同一格里两种边界。
           Destinations 与 Travelling with 共用这一条,两处必须逐像素一致。 */
        /* chip 之间要拉开:没有框之后,6px 的 gap 会让两个名字读成一个词组。 */
        /* 两处的「+ Add」必须一模一样。Destinations 的那个坐在一个 <button> 里,
           按钮不继承字族 —— 不显式写死,两处就是两种字。 */
        /* chip 直接成为 .ntrip-dest 的 flex 子项 —— 这个 span 只是个取值用的锚点,
           不该在 chip 和它的 flex 容器之间多一层。原来靠给它内联 display:flex
           解决,而内联值赢过样式表:那条 gap:8px 让 Destinations 比
           Travelling with 窄 6px,两个本该一样的字段就此对不齐。 */
        /* 占位文字在一个 <button> 里 —— 按钮不继承字族,这里不写死就落回
           系统默认(实测 Arial)。同一格里换了字体,而且只在「还没选」时换。 */
        /* The row carries the rule so that the range and the nights sit over one line — the
           decision stands. The `min-height: 0` it put on the INPUT does not: it left a 21px
           press target on the one field in this room that opens a whole second instrument.
           Both are now in css/17s-plan-trip.css, and removed here for the load-order reason
           in the note above. */
        /* 段眉:标题 + 归属注,不带下划线。 */
        /* ---- 同行者态:The trip 锁住,不隐藏 ----
           锁的写法就是显示页的写法:没有点线底边、没有 chip、没有 + Add。
           没有「可以写」的记号,本身就是「不能改」最清楚的说法 —— 所以
           不挂锁图标,也不再整段压到 55% 不透明度(那读作「坏了」,
           不是「不是你的」)。 */
        /* 只读态没有搜索行,也没有「+ Add」。搜索行的默认收起是内联的,
           所以这里用 !important 才盖得住 —— 同行者态下它一律不出现。 */
        /* 锁住 = 一条线都没有。两个 id 的选择器是为了盖过上面
           #planTripModal #planTripForm 那条 chip 行底边。 */
        /* 一串名字之间的分隔:chip 的底和边都没了,靠一个间隔点断句。 */

        /* ---- from a spreadsheet (2026-09-15) ------------------------------------------------------------------
           Two words, as every act in the log is. IMPORT changes the record, so it is the magenta; the template
           only hands a file over, so it is the ink. */
        #planTripModal .ptrip-import-acts {
            display: flex;
            flex-wrap: wrap;
            gap: 0 var(--sp-lg);
            margin-top: var(--sp-xs);
        }
        #planTripModal .ptrip-import-act {
            min-height: 44px;
            margin: 0;
            padding: 0;
            border: none;
            border-radius: 0;
            background: none;
            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);
            cursor: pointer;
        }
        #planTripModal .ptrip-import-act.is-record { color: var(--log-magenta); }
        #planTripModal .tsv-import-note {
            margin: var(--sp-xs) 0 0;
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.5;
            color: var(--log-ink-soft);
        }

        /* ══════════════════════════════════════════════════════════════
           MOVED OUT OF css/23-legacy-plate.css · 2026-09-21  (appended)
           14 rules. DESIGN.md: a surface's rules go in that surface's part, and the
           legacy parts only shrink.
           ⚠️ 23-legacy-plate.css loaded AFTER this file. Placing them
           at the foot keeps their order against THIS PART’S OWN rules — and nothing else.
           Against the parts BETWEEN #33 and #50 the order is reversed by this move, and
           whether that matters was a separate question somebody had to answer. See DESIGN.md.
           ══════════════════════════════════════════════════════════════ */
        /* ----- Trip settings: this person's own fields -----
           Set apart from the trip's fields above by a sage panel, because they answer a
           different question: not "what is this trip" but "what is this trip to me". */
        #mySettingsSection {
            margin-top: var(--sp-xl);
            padding: var(--sp-lg);
            background: var(--log-stock-band);
            border: 1px solid var(--log-rule);
        }

        /* Two blocks, one question each: what is this trip, and what is this trip to me.
           The heading names the block and says whose it is — a companion should not have to
           tap a field to find out it is locked. */
        .settings-block { margin-bottom: var(--sp-xl); }


        .settings-block-head {
            display: flex;
            align-items: baseline;
            gap: var(--sp-sm);
            padding-bottom: var(--sp-sm);
            margin-bottom: var(--sp-lg);
            border-bottom: 1px solid var(--log-rule);
        }


        .settings-block-title {
            font-family: var(--log-write);
            font-size: 11px;
            letter-spacing: 2.5px;
            text-transform: uppercase;
            color: var(--log-ink);
        }

        /* 归属注靠右。排版(字号/字距/字重/颜色)在下面的收口规则里,
           这里只留布局。 */
        .settings-block-who { margin-left: auto; }


        .mys-field { margin-top: var(--sp-lg); }

/* The ladder. Four rungs on one row, so the labels are short and the type is small;
           a wrapped ladder stops reading as a scale. */
        .mys-ladder { display: flex; border: 1px solid var(--log-rule-firm); background: var(--log-stock); }


        .mys-rung {
            flex: 1;
            padding: 8px 0;
            border: none;
            border-right: 1px solid var(--log-rule);
            background: transparent;
            cursor: pointer;
            font-family: var(--log-write);
            font-size: 11px;
            letter-spacing: 1.2px;
            text-transform: uppercase;
            color: var(--log-ink-soft);
        }


        .mys-rung:last-child { border-right: none; }

        /* The chosen rung takes the primary control’s ground: --log-oilskin describes itself as
           "cover boards; also the primary control", and .acs-go in 05-interaction.css already
           uses that pair. Was --accent on --on-dark — the retired sage carrying its own text
           colour, which is the shape this world replaced with one ink at two pressures. */
        .mys-rung.is-on { background: var(--log-oilskin); color: var(--log-on-oilskin); }

        /* Rules with no switch. Stated because a missing control otherwise reads as a
           missing feature, and people go looking for it. */
        .mys-fixed {
            margin-top: var(--sp-lg);
            padding-top: var(--sp-md);
            border-top: 1px solid var(--log-rule);
        }


        .mys-fixed-row {
            display: flex;
            gap: var(--sp-sm);
            font-family: var(--log-write);
            font-size: var(--fs-small);
            line-height: 1.5;
            color: var(--log-ink-soft);
        }


        .mys-fixed-row + .mys-fixed-row { margin-top: var(--sp-xs); }

        .mys-fixed-row b { font-weight: 500; color: var(--log-ink); min-width: 62px; }
