/* H: the hand of cities, the town table and the shop sheet (worker H). Ink on ivory paper, the published card frame, nothing new in the palette. */

/* ------------------------------------------------------------ cities: a straight, scrollable row in the main play area */
.cities-screen:not(.is-driving) .road-stage { visibility: hidden; }
.city-hand { position: absolute; left: 0; right: 0; z-index: 7; display: flex; align-items: flex-start; gap: 24px; padding: 12px 24px; overflow: auto; overscroll-behavior: contain; scroll-padding-inline: 24px; scrollbar-width: thin; scrollbar-color: var(--ink) var(--paper-2); }
.city-slot { position: relative; flex: 0 0 auto; transition: opacity .25s ease; }
.city-slot:first-child { margin-left: auto; }
.city-slot:last-child { margin-right: auto; }
.city-slot.is-lifted .tw-face { box-shadow: 0 0 0 2px var(--red), 0 6px 14px rgba(27, 26, 23, .35); }
.city-hand.is-leaving { visibility: hidden; pointer-events: none; }
.city-feedback { position: absolute; left: 24px; right: 24px; z-index: 7; text-align: center; font-size: .95rem; font-weight: 700; color: var(--red); }
.city-frame { position: relative; }
.city-frame .tw-card { width: 100%; }
.city-frame.is-condemned .tw-body { transform: rotate(90deg) scale(.66); }
.city-mark { position: absolute; z-index: 3; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .35); }
.city-mark.is-home { left: -8px; top: -8px; }
.city-mark.is-closed { right: -8px; top: -8px; color: var(--red); }
.city-cloth { position: absolute; left: 50%; top: 50%; z-index: 3; width: 52px; height: 52px; transform: translate(-50%, -50%); border-radius: 50%; display: grid; place-items: center; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .4); }
.city-cloth .sym { width: 30px; height: 30px; }
.city-plate { margin-top: 6px; display: flex; flex-direction: column; align-items: center; gap: 3px; min-height: 44px; padding: 3px 4px 4px; background: var(--paper); border: 2px solid var(--ink); box-shadow: 2px 3px 0 rgba(27, 26, 23, .35); }
.city-hand .city-plate { min-height: 102px; padding: 6px; gap: 5px; cursor: pointer; }
.cp-name { min-height: 2.3em; display: grid; place-items: center; text-align: center; font-size: .95rem; line-height: 1.15; }
.cp-facts { display: flex; flex-direction: column; gap: 5px; }
.cp-status { font-size: .85rem; font-weight: 700; text-align: center; line-height: 1.1; }
.cp-status.is-short { color: var(--red); }
.cp-row { display: flex; align-items: center; justify-content: center; gap: 4px; font-weight: 700; font-size: .98rem; line-height: 1; font-variant-numeric: tabular-nums; }
.cp-row.is-short b { color: var(--red); }
.cp-row.is-none { color: var(--red); }
.cp-row b { font-weight: 700; display: inline-flex; align-items: center; }
.cp-moment, .cp-state, .cp-shops i { font-style: normal; display: inline-grid; place-items: center; }
.cp-state { margin-left: 2px; }
.cp-state.is-watched { color: var(--red); }
.cp-shops { display: flex; flex-wrap: wrap; justify-content: center; gap: 1px 3px; }
.city-slot.is-here .city-plate { background: var(--paper-2); }

/* ------------------------------------------------------------ the town table */
.town-screen { background: var(--paper-2); }
.town-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.town-stage { position: absolute; left: 0; right: 0; top: calc(56px + var(--safe-top)); bottom: 0; }
.town-ring, .town-walkers { position: absolute; inset: 0; }
.town-walkers { pointer-events: none; z-index: 4; }
.town-shop { position: absolute; left: 0; top: 0; will-change: transform; z-index: 2; }
.town-shop .tw-card { width: 100%; }
/* Rule 231: at every moment ONE place is lit on the table. The ring is the world's own colour for "now" (--red). */
.town-shop.is-lit { z-index: 3; }
.town-shop.is-lit .tw-card { box-shadow: 0 0 0 3px var(--red), 0 0 22px 4px rgba(176, 42, 34, .45); border-radius: 6px; }
.town-center { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 1; opacity: .96; }
.town-center .tw-card { width: 100%; }
.town-center[hidden] { display: none; }
.shop-medal { position: absolute; left: -7%; top: -3%; width: 36%; aspect-ratio: 1; border-radius: 50%; border: 2px solid var(--ink); background-size: cover; background-position: 50% 10%; background-color: var(--paper-2); box-shadow: 1px 2px 0 rgba(27, 26, 23, .45); z-index: 3; pointer-events: none; }
.shop-marks { position: absolute; right: -8px; top: -9px; display: flex; gap: 3px; z-index: 4; pointer-events: none; }
.shop-marks .sym, .shop-marks .mk { pointer-events: auto; } /* B: rule 164: the marks of a shop (closed, waiting, unpaid) show their bubble: the layer is inert, the whole disc of a mark is not (JOB-066, rule 228: the pill is the target, not its 18-pixel drawing); a click on it still reaches the shop card */
.mk { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .4); font-style: normal; }
.mk-unpaid { color: var(--red); }
.mk-wait { background: var(--ink); color: var(--paper); }
/* H3: the contracts the tavern holds (the owner's ask of 2026-10-03): the board's symbol on the tavern card with the number of what is left to take, in hand included */
.mk-jobs { background: var(--ink); color: var(--paper); position: relative; }
.mk-jobs b { position: absolute; right: -7px; bottom: -7px; min-width: 17px; padding: 0 4px; border: 1.5px solid var(--ink); border-radius: 999px; background: var(--red); color: var(--paper); font-size: .72rem; font-weight: 700; line-height: 1.4; text-align: center; font-variant-numeric: tabular-nums; }
.tw-walker { position: absolute; left: 0; top: 0; transition: transform .7s cubic-bezier(.3, .7, .3, 1), width .4s ease; pointer-events: none; }
.tw-walker .tw-card { width: 100%; }
/* J: JOB-021 (rule 175): a card that rests at the tavern keeps its colours (it was drawn at .78 opacity): its place at the tavern and its tilt already say that it rests */
.tw-no { position: absolute; left: -6px; top: -8px; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); border: 2px solid var(--ink); z-index: 2; font-style: normal; }
.tw-no::after { content: ''; position: absolute; left: 12%; right: 12%; top: 50%; height: 2.5px; background: var(--red); transform: rotate(-40deg); }
.tw-ok { position: absolute; right: -6px; bottom: -8px; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: var(--ink); color: var(--paper); z-index: 2; font-style: normal; }
.town-name { display: none; margin: 0; position: absolute; left: 50%; transform: translateX(-50%); top: calc(var(--safe-top) + 12px); z-index: 21; font-size: 1.05rem; letter-spacing: .2em; text-transform: uppercase; font-weight: 700; padding: 4px 14px; background: var(--paper); border: 2px solid var(--ink); box-shadow: 2px 3px 0 rgba(27, 26, 23, .35); white-space: nowrap; pointer-events: none; }
@media (min-aspect-ratio: 11/10) { .town-name { display: block; } }
/* Reserve the title's center space so it cannot cover the bank or clock. */
.town-screen.is-wide { --town-title-width: min(42vw, 26rem); }
.town-screen.is-wide .topbar { display: grid; grid-template-columns: 48px minmax(0, 1fr) var(--town-title-width) minmax(0, 1fr) 48px; column-gap: 12px; }
.town-screen.is-wide .topbar > * { grid-row: 1; }
.town-screen.is-wide .topbar > :first-child { grid-column: 1; }
.town-screen.is-wide .topbar > :last-child { grid-column: 5; }
.town-screen.is-wide .topbar > .bank { grid-column: 2; justify-self: end; }
.town-screen.is-wide .topbar > .purse { grid-column: 4; justify-self: start; }
.town-screen.is-wide .town-name { max-width: calc(var(--town-title-width) - 12px); overflow: hidden; text-overflow: ellipsis; }
.town-screen.no-center:not(.is-wide) .town-name { display: block; top: calc(var(--safe-top) + 62px); z-index: 3; font-size: .85rem; padding: 2px 10px; }
.purse { display: flex; align-items: center; gap: 10px; font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; }
/* the bars stand on paper: ink on the wood of the table cannot be read */
.town-screen .bank, .town-screen .purse { padding: 3px 12px; background: var(--paper); border: 2px solid var(--ink); box-shadow: 2px 3px 0 rgba(27, 26, 23, .35); }
.town-screen .bank .hour-mark { margin-left: 6px; }
.purse-money, .purse-frozen { display: inline-flex; align-items: center; gap: 6px; }
.purse-frozen { font-size: 1.05rem; opacity: .8; }
.purse-frozen[hidden] { display: none; }
.town-screen .bank { font-size: 1.35rem; }
.town-fly { position: absolute; inset: 0; pointer-events: none; z-index: 30; overflow: hidden; }
.town-coin { position: absolute; width: 40px; height: 56px; z-index: 3000; border-radius: 5px; display: grid; place-items: center; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: inset 0 0 0 2px var(--paper), inset 0 0 0 3px var(--ink), 2px 3px 0 rgba(27, 26, 23, .4); pointer-events: none; }
.town-skip { position: absolute; right: 12px; bottom: calc(12px + var(--safe-bottom)); z-index: 11; }

/* the bill: a paper that slides up from the bottom; a tap folds it into a small tab */
.town-billhost { position: absolute; left: 0; right: 0; bottom: 0; z-index: 12; display: flex; justify-content: center; align-items: flex-end; pointer-events: none; padding-bottom: calc(10px + var(--safe-bottom)); }
/* JOB-2026100707 (review item 1, rule 231): the folded bill is a tab of its own, out of the coach's way. On a wide table the
   bar's right corner is empty: the tab takes it. On a phone the coach holds that corner (see the media rule below). */
.town-billhost.is-tab { justify-content: flex-end; padding-right: 12px; }
.town-bill { pointer-events: auto; cursor: pointer; width: min(94vw, 440px); max-height: 58vh; overflow-y: auto; padding: 14px 16px; background: var(--paper); color: var(--ink); border: 3px solid var(--ink); box-shadow: inset 0 0 0 4px var(--paper), inset 0 0 0 5.5px var(--ink), 5px 7px 0 rgba(27, 26, 23, .4); outline: none; }
.town-bill:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }
.town-bill.is-sliding { animation: bill-up .5s cubic-bezier(.2, .8, .3, 1); }
@keyframes bill-up { from { transform: translateY(115%); } to { transform: none; } }
.tb-head { display: flex; justify-content: center; margin-bottom: 6px; }
.tb-pay, .tb-spent, .tb-left, .tb-frozen { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tb-pay { font-size: 1.5rem; }
.tb-lines { list-style: none; margin: 0; padding: 0; }
.tb-line { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px dashed rgba(27, 26, 23, .45); }
.tb-thumb { width: 34px; height: 34px; border-radius: 50%; border: 2px solid var(--ink); background-size: cover; background-position: 50% 10%; background-color: var(--paper-2); flex: none; }
.tb-thumb.is-none { background: var(--paper-2); }
.tb-sum { margin-left: auto; display: flex; gap: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tb-sum b { display: inline-flex; align-items: center; gap: 4px; }
.tb-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 8px; padding-top: 8px; border-top: 3px double var(--ink); flex-wrap: wrap; }
.tb-left { font-size: 1.7rem; }
/* J: JOB-021 (rule 175): the frozen purse is in full colour like the rest of the bill (it was drawn at .8 opacity) */
.town-billtab { pointer-events: auto; appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; padding: 8px 16px; font-family: var(--serif); font-size: 1.2rem; font-weight: 700; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 4px var(--ink), 3px 4px 0 rgba(27, 26, 23, .35); }
.town-billtab:hover, .town-billtab:focus-visible { background: var(--ink); color: var(--paper); outline: none; box-shadow: inset 0 0 0 3px var(--ink), inset 0 0 0 4px var(--paper); }
/* JOB-2026100707 (review item 1, rule 228): while the sheet of standing orders is open it is the top of the table. At 390 the sheet reaches
   the whole bottom bar, and a bar button on top of it buries an order switch and the totals (the review's own watch-out: the first tab fix
   left "LÉGENDE" sitting on the last row). The bar's own buttons stand down; they come back in their own corners with the folded tab. */
.town-screen.is-bill-open .town-legend-btn,
.town-screen.is-bill-open .town-coach { display: none; }

/* JOB-202610080322: the sheet the dock keeper hands over at the arrival (`.town-reck`) is a raised sheet too, and it reaches the bottom of the
   screen exactly as the bill does. Measured on the built app at 390x844 and 1440x900: the coach button of the bar stood on the sheet's own
   total line (6513.8 px2 of the paper covered at 390, the control's whole corner at 1440). Same rule, same reason as the bill's (rule 228): the
   bar's own buttons stand down while the sheet is up; the screen drops `is-reck-open` with the sheet and they come back in their corners. */
.town-screen.is-reck-open .town-legend-btn,
.town-screen.is-reck-open .town-coach { display: none; }

/* ------------------------------------------------------------ H4: the legend of the table */
/* The owner's ask of 2026-10-03: « we should simply have a legend on the side ... those buttons too tiny, dont know what they are ».
   A named pill at the bottom left, opposite the |>> finish button, opens a paper that draws every mark the table uses beside its word. */
.town-legend-btn { position: absolute; left: 12px; bottom: calc(12px + var(--safe-bottom)); z-index: 13; appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; font-family: var(--serif); font-size: 1rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 4px var(--ink), 3px 4px 0 rgba(27, 26, 23, .35); }
.town-legend-btn:hover, .town-legend-btn:focus-visible, .town-legend-btn[data-on="1"] { background: var(--ink); color: var(--paper); outline: none; box-shadow: inset 0 0 0 3px var(--ink), inset 0 0 0 4px var(--paper); }
.town-legend-btn .sym { flex: none; }
.town-legend { position: absolute; left: 12px; bottom: calc(70px + var(--safe-bottom)); z-index: 40; display: flex; flex-direction: column; width: min(88vw, 320px); max-height: min(72dvh, 560px); background: var(--paper); color: var(--ink); border: 3px solid var(--ink); box-shadow: inset 0 0 0 4px var(--paper), inset 0 0 0 5.5px var(--ink), 5px 7px 0 rgba(27, 26, 23, .45); }
/* JOB-2026100707 (review item 1, rule 231): on a phone the bottom bar is full (legend 144 + gap + coach), so the folded tab has
   no room in it. The tab takes the left corner, the coach keeps its own (narrowed, coach.css), and the legend rises above it. */
@media (max-width: 600px) {
  .town-billhost.is-tab { justify-content: flex-start; padding-right: 0; padding-left: 12px; }
  .town-billhost.is-tab .town-billtab { max-width: calc(100vw - 168px); }
  .town-legend-btn { left: auto; right: 12px; bottom: calc(88px + var(--safe-bottom)); font-size: .85rem; padding: 6px 10px; gap: 6px; }
  .town-legend { left: auto; right: 12px; bottom: calc(136px + var(--safe-bottom)); }
}
.town-legend[hidden] { display: none; }
.tl-head { flex: none; display: flex; align-items: center; gap: 10px; padding: 6px 8px 6px 12px; border-bottom: 2px solid var(--ink); }
.tl-title { flex: 1; font-size: 1rem; letter-spacing: .16em; text-transform: uppercase; }
.tl-shut { width: 40px; height: 40px; }
.tl-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 12px 12px; }
.tl-group { margin: 12px 0 4px; font-size: .8rem; letter-spacing: .18em; text-transform: uppercase; opacity: .75; }
.tl-group:first-child { margin-top: 0; }
.tl-list { list-style: none; margin: 0; padding: 0; }
.tl-row { display: flex; align-items: center; gap: 10px; min-height: 34px; padding: 3px 0; border-top: 1px dashed rgba(27, 26, 23, .3); }
.tl-row:first-child { border-top: none; }
.tl-row .sym { flex: none; }
.tl-name { font-size: 1rem; font-weight: 700; }
.tl-face { flex: none; width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--ink); background: var(--paper-2); object-fit: cover; object-position: 50% 10%; }
/* on a wide screen the legend is a rail beside the table, not a sheet over it */
@media (min-aspect-ratio: 11/10) {
  .town-legend { bottom: auto; top: calc(var(--safe-top) + 64px); width: 300px; max-height: calc(100dvh - 168px - var(--safe-top) - var(--safe-bottom)); }
}

/* ------------------------------------------------------------ the shop sheet */
.shop-sheet { place-items: center; }
.shop-panel { --kw: clamp(72px, 7.4vw, 100px); --ccw: clamp(46px, 5vw, 68px); position: relative; width: min(98vw, 1240px); height: min(96dvh, 880px); display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 0; background: var(--paper); color: var(--ink); border: 3px solid var(--ink); box-shadow: inset 0 0 0 5px var(--paper), inset 0 0 0 6.5px var(--ink), 6px 8px 0 rgba(27, 26, 23, .45); overflow: hidden; }
/* JOB-066 (rule 223): the head stays; everything under it is ONE scrolling body (the keeper and his lines, the people, the controls, the cards): no small inner window cuts a card, the sheet scrolls when it must */
.shop-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; margin: 0 -6px; padding: 4px 6px 14px; scrollbar-gutter: stable; scroll-padding-top: var(--ctl-h, 72px); }
.shop-body > [hidden] { display: none; }
.garage-modes { display: flex; gap: 8px; padding-bottom: 4px; }
.garage-workshop { padding: 0 8px 40px; }
.gw-status { min-height: 1.3em; margin: 0 0 8px; color: var(--red); font-weight: 700; }
.gw-trucks { display: flex; gap: 10px; overflow-x: auto; padding: 5px; scroll-padding: 5px; }
.gw-truck { flex: 0 0 180px; display: flex; align-items: center; gap: 10px; background: var(--paper); border: 2px solid var(--ink); color: var(--ink); font: inherit; text-align: left; padding: 7px; cursor: pointer; }
.gw-truck-art { width: 48px; height: 72px; flex: none; position: relative; container-type: inline-size; }
.gw-truck-art > .tw-face { position: absolute; inset: 0; }
.gw-truck-art .tw-art { object-fit: contain; }
.gw-truck span { min-width: 0; font-weight: 700; }
.gw-truck.is-on, .gw-part.is-on { box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--red); }
.gw-capacity { margin: 10px 5px; font-size: .9rem; }
.gw-fitted { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 5px; }
.gw-fitted button { display: inline-flex; gap: 5px; align-items: center; padding: 6px 8px; min-height: 44px; background: var(--paper-2); color: var(--ink); border: 1px solid var(--ink); font: inherit; font-size: .85rem; cursor: pointer; }
.gw-systems { display: flex; flex-wrap: wrap; gap: 7px; padding: 5px; border-block: 1px solid var(--ink); }
.gw-system { display: inline-flex; gap: 5px; align-items: center; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); padding: 8px 10px; min-height: 44px; font: inherit; font-weight: 700; cursor: pointer; }
.gw-system.is-on { background: var(--ink); color: var(--paper); }
.garage-workshop button:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }
.gw-current { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin: 14px 5px; }
.gw-current .btn { min-height: 44px; padding: 5px 12px; font-size: .9rem; }
.gw-choice { display: grid; grid-template-columns: minmax(0, 1.8fr) minmax(250px, 1fr); align-items: start; gap: 16px; }
.gw-options { display: flex; flex-wrap: wrap; justify-content: center; align-items: stretch; gap: 14px; padding: 8px 5px; }
.gw-part { width: min(30%, 170px); min-width: 125px; display: flex; flex-direction: column; gap: 6px; align-items: center; background: var(--paper); border: 2px solid var(--ink); color: var(--ink); padding: 8px; font: inherit; text-align: center; cursor: pointer; }
.gw-part strong { font-size: 1rem; }
.gw-part > span { margin-top: auto; font-weight: 700; }
.gw-part figure { width: 100%; margin: 0; }
.gw-artframe { position: relative; width: 100%; aspect-ratio: 2/3; container-type: inline-size; }
.gw-artframe > .tw-face { position: absolute; inset: 0; }
.gw-part figure img { display: block; width: 100%; aspect-ratio: 2/3; height: auto; object-fit: contain; }
.gw-part figcaption { font-size: .68rem; margin-top: 3px; }
.gw-part small { font-variant-numeric: tabular-nums; }
.gw-preview { max-width: 620px; width: 100%; box-sizing: border-box; margin: 8px auto 0; padding: 14px; border: 2px solid var(--ink); background: var(--paper-2); }
.gw-preview h3 { margin: 0 0 8px; font-size: 1.15rem; }
.gw-preview p { margin: 7px 0; }
.gw-stats { display: grid; gap: 5px; }
.gw-stats > span { display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: 6px; font-size: .95rem; }
.gw-stats b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.gw-install { min-height: 48px; width: 100%; margin-top: 8px; }
.gw-reason { color: var(--red); font-size: .92rem; }
.garage-workshop button:disabled { cursor: default; border-style: dashed; }
@media (max-width: 700px) {
  .garage-workshop { padding: 0 3px 30px; }
  .gw-truck { flex-basis: 158px; font-size: .92rem; }
  .gw-truck-art { width: 40px; height: 60px; }
  .gw-systems { flex-wrap: nowrap; overflow-x: auto; scroll-padding: 5px; }
  .gw-system { flex: none; }
  .gw-choice { display: block; }
  .gw-options { flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto; scroll-padding: 5px; }
  .gw-part { width: 138px; min-width: 138px; flex: none; }
  .gw-preview { padding: 10px; }
}
.shop-head { flex: none; display: flex; align-items: center; gap: 12px; }
.shop-title { flex: 1; display: flex; align-items: center; gap: 10px; font-size: 1.1rem; letter-spacing: .16em; text-transform: uppercase; min-width: 0; }
.shop-title span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shop-bars { display: flex; align-items: center; gap: 14px; font-weight: 700; font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.shop-bars .bank, .shop-bars .purse-money { display: inline-flex; align-items: center; gap: 6px; font-size: 1.15rem; }
/* the keeper is a small card beside his lines; the people (the companions and the musicians) under the lines, in one compact row that wraps */
.shop-top { display: grid; grid-template-columns: var(--kw) minmax(0, 1fr); grid-template-areas: "keeper talk" "keeper people"; gap: 8px 14px; align-items: start; }
.shop-people { grid-area: people; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 18px; min-width: 0; }
.shop-keeper { grid-area: keeper; width: var(--kw); align-self: start; }
.shop-keeper .tw-card { width: 100%; cursor: default; }
.shop-kname { margin-top: 4px; text-align: center; font-weight: 700; letter-spacing: .03em; font-size: clamp(.68rem, 1.1vw, .8rem); line-height: 1.15; text-wrap: balance; }
.shop-talk { grid-area: talk; align-self: center; min-width: 0; }
.shop-talk[hidden] { display: none; }
.shop-line { appearance: none; cursor: pointer; width: 100%; display: flex; flex-direction: column; align-items: stretch; gap: 8px; text-align: left; padding: 12px 16px; font-family: var(--serif); color: var(--ink); background: var(--paper); border: 2px solid var(--ink); box-shadow: 3px 4px 0 var(--ink); position: relative; }
.shop-line:hover, .shop-line:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.sl-text { font-size: clamp(1rem, 2.1vw, 1.4rem); line-height: 1.35; text-wrap: pretty; }
.shop-line[data-kind="report"] .sl-text, .shop-line[data-kind="unpaid"] .sl-text { font-style: italic; }
.sl-dots { display: flex; gap: 6px; }
.sl-dots i { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--ink); }
.sl-dots i.is-on { background: var(--ink); }
.mc-eff { max-width: 100%; text-align: center; font-weight: 700; font-size: clamp(.7rem, 1.7vw, .82rem); line-height: 1.2; text-wrap: balance; }
.mc-target { width: var(--mcw); display: flex; flex-direction: column; align-items: center; gap: 6px; flex: none; }
.mc-target .tw-card { width: 100%; }
.mc-tname { font-size: .8rem; text-align: center; line-height: 1.2; }
.sl-badge { position: absolute; right: 12px; top: 10px; display: grid; place-items: center; width: 30px; height: 30px; border: 2px solid var(--ink); border-radius: 50%; background: var(--paper-2); font-style: normal; }
.shop-line:has(.sl-badge) .sl-text { padding-right: 40px; }
.sl-next { position: absolute; right: 12px; bottom: 10px; animation: hand-bob .8s steps(1) infinite; }
.shop-crew { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 10px; padding: 9px 8px 2px 4px; min-width: 0; }
.shop-crew[hidden] { display: none; }
.crew-spot { position: relative; flex: none; width: var(--ccw); }
.crew-spot .tw-card { display: block; width: 100%; } /* upright, face up, in full colour (rules 175, 226): never lying on a bench, never a back */
.crew-spot.is-truck { height: auto; min-height: calc(var(--ccw) * 1.1); display: flex; flex-direction: column; align-items: center; gap: 6px; width: calc(var(--ccw) * 1.25); cursor: help; }
.crew-spot.is-truck:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }
.crew-spot.is-truck .tw-card { position: static; width: 100%; transform: none; }
.crew-spot.is-truck .mc-fx { top: 100%; }
.crew-spot.is-truck:hover .mc-fx, .crew-spot.is-truck:focus-visible .mc-fx, .crew-spot.is-explained .mc-fx { display: flex; }
.crew-spot.is-truck:hover, .crew-spot.is-truck:focus-visible, .crew-spot.is-explained { z-index: 7; }
.crew-mark { position: absolute; right: -8px; top: -8px; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .4); font-style: normal; z-index: 2; cursor: help; }
.crew-mark .sym { width: 14px; height: 14px; }
.crew-spot.is-waiting .crew-mark, .crew-spot.is-carried .crew-mark { color: var(--red); } /* what is missing is said in red, like the reason marks of the cards (a shut shop, a man to bring back) */

.shop-menu { display: block; }
.shop-controls { position: sticky; top: 0; z-index: 8; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; margin: 8px -6px 0; padding: 8px 6px; background: var(--paper); border-top: 2px solid var(--ink); border-bottom: 2px solid var(--ink); }
.shop-menu[hidden] { display: none; }
.sm-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.sm-tab { appearance: none; cursor: pointer; position: relative; display: inline-flex; align-items: center; gap: 10px; height: 46px; padding: 0 14px 0 12px; font-family: var(--serif); font-size: 1rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); box-shadow: inset 0 0 0 2px var(--paper), inset 0 0 0 3px var(--ink); }
.sm-tab-label { display: inline-flex; align-items: center; gap: 8px; }
.sm-tab-name { white-space: nowrap; }
.sm-tab b { font-style: normal; min-width: 0; padding: 0 7px; border: 1.5px solid currentColor; border-radius: 999px; background: transparent; color: inherit; font-size: .85rem; font-weight: 700; letter-spacing: 0; line-height: 1.45; font-variant-numeric: tabular-nums; }
.sm-tab b:empty { display: none; }
.sm-tab.is-on { background: var(--ink); color: var(--paper); box-shadow: inset 0 0 0 2px var(--ink), inset 0 0 0 3px var(--paper); }
.sm-tab.is-on b { background: transparent; color: var(--paper); }
.sm-tab.is-none { border-style: dashed; }
.sm-tab:hover, .sm-tab:focus-visible { outline: 3px solid var(--red); outline-offset: 1px; }
.sm-badge { position: absolute; left: -7px; top: -8px; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); font-style: normal; }
.sm-for { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-left: auto; }
.sm-who { font-weight: 700; font-size: .98rem; letter-spacing: .03em; max-width: 14em; }
.sm-for[hidden] { display: none; }
.sm-chip { appearance: none; cursor: pointer; position: relative; width: 46px; height: 46px; border-radius: 50%; padding: 0; border: 2px solid var(--ink); background-color: var(--paper-2); background-size: cover; background-position: 50% 10%; color: var(--ink); }
.sm-chip.is-on { box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--ink); }
.sm-chip.is-none { border-style: dashed; }
.sm-chip:hover, .sm-chip:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.sm-jp { position: absolute; right: -6px; bottom: -6px; display: inline-flex; align-items: center; gap: 1px; padding: 0 4px; font-style: normal; font-size: .72rem; font-weight: 700; background: var(--paper); border: 1.5px solid var(--ink); border-radius: 999px; }
.sm-phrase { display: flex; gap: 8px; align-items: center; }
.sm-phrase[hidden] { display: none; }
/* H3: the whole job board in one gesture (the owner's ask of 2026-10-03). A wide bar under the tabs, named with its count (rule 223), on the contracts tab only:
   the same ink, the same box as a tab, so it reads as one of the sheet's controls and never as a card. */
.sm-takeall { appearance: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 48px; margin-top: 8px; padding: 0 14px; font-family: var(--serif); font-size: 1rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); box-shadow: inset 0 0 0 2px var(--paper), inset 0 0 0 3px var(--ink); }
.sm-takeall[hidden] { display: none; }
.sm-takeall .st-label { display: inline-flex; align-items: center; gap: 10px; }
.sm-takeall .st-n { padding: 0 9px; border: 1.5px solid currentColor; border-radius: 999px; font-size: .88rem; font-weight: 700; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.sm-takeall:hover, .sm-takeall:focus-visible { outline: 3px solid var(--red); outline-offset: 1px; }
.sm-phrase input { flex: 1; min-width: 0; height: 46px; padding: 0 12px; font-family: var(--serif); font-size: 1.05rem; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); }
.sm-phrase .btn { min-height: 46px; padding: 6px 16px; }
.sm-cards { --mcw: clamp(78px, min(12vw, 19dvh), 168px); display: flex; flex-wrap: wrap; justify-content: center; align-content: flex-start; gap: 16px 14px; padding: 22px 6px 96px; } /* no overflow here: the BODY of the sheet scrolls, an inner window never cuts a card (rule 223); room under the last row for the words of a card (.mc-fx) */
.mcard { appearance: none; padding: 0; border: 0; background: none; cursor: pointer; width: var(--mcw); display: flex; flex-direction: column; align-items: center; gap: 6px; color: var(--ink); position: relative; transition: transform .16s ease; flex: none; }
.mcard:hover, .mcard:focus-visible { outline: none; }
.mcard > .mc-face, .mcard > .pr, .mcard > .mc-eff, .mcard > .mc-acts { transition: transform .16s ease; }
.mcard:hover > .mc-face, .mcard:hover > .pr, .mcard:hover > .mc-eff, .mcard:hover > .mc-acts, .mcard:focus-visible > .mc-face, .mcard:focus-visible > .pr, .mcard:focus-visible > .mc-eff, .mcard:focus-visible > .mc-acts { transform: translateY(-4px); }
.mcard:focus-visible .mc-face { outline: 3px solid var(--red); outline-offset: 3px; border-radius: 4px; }
.mcard.is-lifted { transform: translateY(-10px) scale(1.09); z-index: 3; }
.mcard.is-lifted .pr { background: var(--ink); color: var(--paper); }
.mc-face { position: relative; display: block; width: 100%; aspect-ratio: 2 / 3; }
.mc-face > .tw-face { position: absolute; inset: 0; }
/* H2: rule 175: no greyed-out card: a card that cannot be taken yet keeps its colours and says why with a symbol on it (.mc-why).
   J: JOB-021 (the director's reading, 10-02): that symbol is a SMALL BADGE on the corner of the card, the same place and size as the lock of a skill card that cannot be learned yet (main.css .sk-mark, JOB-060): one language
   of reasons across the game. It was a big stamp on the middle of the picture, five times in a row. The picture is never hidden; what is missing is said in red on the plate under the card. A card that is already
   had (the check) is the red seal of a learned skill. */
.mc-why { position: absolute; top: 1px; right: 1px; z-index: 2; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--red); border: 2px solid var(--ink); font-style: normal; box-shadow: 1px 2px 0 rgba(27, 26, 23, .4); }
.mc-why .sym { width: 62%; height: 62%; }
.mc-why.is-already-has, .mc-why.is-already-learned, .mc-why.is-nothing-to-do { background: var(--red); color: var(--paper); }
/* R4 (the owner's ask, 2026-10-09): the reason a card cannot be taken is a plain sentence ON the card, under its picture, read from the real gating
   (shopwords.js jobWhy). The symbol badge stays the mark at a glance; the sentence says the missing thing in words, in the red of the reason. */
.mc-why-text { display: block; max-width: 100%; padding: 0 2px; font-family: var(--serif); font-size: clamp(.72rem, 1.9vw, .86rem); line-height: 1.15; color: var(--red); text-align: center; }
.cf-paint-sym { display: grid; place-items: center; background: var(--paper-2); }
.cf-bigsym { width: 46%; height: 46%; color: var(--ink); opacity: .9; }
.mc-flash { position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%); width: 64px; height: 64px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--red); border: 3px solid var(--red); font-style: normal; z-index: 4; animation: flash-pop .3s ease-out; }
@keyframes flash-pop { from { scale: .4; opacity: 0; } to { scale: 1; opacity: 1; } }
.pr { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 1px 8px; min-width: 62%; max-width: 100%; padding: 2px 6px; font-weight: 700; font-size: clamp(.8rem, 2.2vw, .95rem); line-height: 1.2; font-variant-numeric: tabular-nums; background: var(--paper); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .3); }
.pr b { display: inline-flex; align-items: center; gap: 3px; font-weight: 700; }


/* a phone: the keeper and his lines side by side, the people in one wrapping row under them, then the controls and the cards (the sheet scrolls) */
@media (max-width: 700px), (max-aspect-ratio: 1/1) {
  .shop-panel { width: 100vw; height: 100dvh; border-width: 0; box-shadow: none; padding: calc(var(--safe-top) + 10px) 10px 0; gap: 8px; --kw: clamp(68px, 19vw, 88px); --ccw: clamp(38px, calc((100vw - 20px - 7 * 8px) / 8.2), 52px); }
  .shop-body { padding-bottom: calc(var(--safe-bottom) + 14px); }
  .shop-top { grid-template-areas: "keeper talk" "people people"; }
  .shop-crew, .shop-band { display: contents; } /* the companions and the musicians flow in ONE wrapping run */
  .shop-people { gap: 8px 8px; padding: 9px 6px 2px 2px; }
  .sl-text { font-size: 1rem; }
  .shop-line { padding: 9px 12px; }
  .shop-controls { gap: 8px 12px; }
  .sm-for { margin-left: 0; }
  .sm-tab { height: 38px; padding: 0 6px 0 6px; font-size: .8rem; gap: 4px; letter-spacing: .03em; }
  .sm-tab-label { gap: 4px; }
  .sm-tab .sym { width: 18px; height: 18px; }
  .sm-tab b { padding: 0 5px; font-size: .74rem; }
  .sm-tabs { gap: 6px; }
  .sm-chip { width: 38px; height: 38px; }
  .sm-for { gap: 6px 8px; flex: 1 1 100%; }
  .sm-who { font-size: .86rem; flex: 1 1 0; min-width: 8em; }
  .shop-controls { padding: 6px 6px; }
  .sm-cards { --mcw: clamp(78px, calc((100vw - 60px) / 3), 118px); gap: 12px 10px; }
}
@media (prefers-reduced-motion: reduce) { .tw-walker, .mcard, .city-slot { transition: none; } .sl-next { animation: none; } .town-bill.is-sliding { animation: none; } .town-reck.is-sliding { animation: none; } }

/* the musicians of the town in the tavern (brief 09 point 9): a card each under the keeper's lines; a tap = he plays one piece */
.shop-band { --bw: var(--ccw); display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 10px; padding: 9px 8px 2px; }
@media (min-width: 701px) and (min-aspect-ratio: 1/1) { .shop-band { margin-left: auto; } }
.shop-band[hidden] { display: none; }
.band-card { appearance: none; padding: 0; border: 0; background: none; cursor: pointer; position: relative; width: var(--bw); flex: none; color: var(--ink); transition: transform .16s ease; }
.band-card:hover, .band-card:focus-visible { transform: translateY(-4px); outline: none; }
.band-card:focus-visible .tw-card { outline: 3px solid var(--red); outline-offset: 3px; border-radius: 4px; }
.band-card .tw-card { display: block; width: 100%; cursor: pointer; }
.band-note { position: absolute; right: -8px; top: -8px; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .4); font-style: normal; z-index: 2; }
.band-note .sym { width: 14px; height: 14px; }
.band-card.is-playing .band-note { background: var(--ink); color: var(--paper); animation: band-pulse .9s ease-in-out infinite; }
@keyframes band-pulse { 0%, 100% { scale: 1; } 50% { scale: 1.2; } }
@media (prefers-reduced-motion: reduce) { .band-card.is-playing .band-note { animation: none; } }

/* the records (dossiers): the back of a record's card in the Codex carries PARTIR; a record that opened flies to the Codex button of the return screen */
.tw-lift.sheet { position: fixed; inset: auto; z-index: auto; display: block; place-items: normal; } /* a flipped lifted card with buttons on its back is a sheet for the pad (records.js) but stays a card */
.tw-lift.is-flipped .tw-front { pointer-events: none; } /* the face that turned away must not take the click meant for the button on the back */
.rec-back .tw-lore-frame { justify-content: flex-start; }
.rec-marks { display: flex; gap: 3cqw; justify-content: center; }
.rec-marks i { font-style: normal; display: grid; place-items: center; width: 9cqw; height: 9cqw; border: .5cqw solid var(--ink); border-radius: 50%; }
.rec-marks .sym { width: 6cqw; height: 6cqw; }
.rec-actions { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 3cqw; }
/* JOB-2026100702 (section 5): the rule that styled the locked mark of an unfinished record is gone with it: a record whose files are absent is not a card at all. */
.rec-go { min-height: 0; padding: 2.6cqw 6cqw; font-size: 5.4cqw; letter-spacing: .12em; gap: 2.4cqw; box-shadow: inset 0 0 0 .8cqw var(--paper), inset 0 0 0 1.2cqw var(--ink), .8cqw 1cqw 0 rgba(27, 26, 23, .35); pointer-events: auto; }
.rec-go .sym { width: 6cqw; height: 6cqw; }
.rec-fly { position: fixed; width: 44px; height: 66px; z-index: 3000; pointer-events: none; border: 2px solid var(--ink); border-radius: 4px; background: var(--paper) url(../assets/ui/card-back.svg) center/cover; box-shadow: 2px 3px 0 rgba(27, 26, 23, .4); }
.rec-dot { position: absolute; right: -6px; top: -6px; width: 14px; height: 14px; border-radius: 50%; background: var(--red); border: 2px solid var(--paper); }
.btn.is-rec-glow { animation: mfan-glow 1.1s ease-out 2; }

/* H: the endless road (roadworld.js): a fight stops the truck and its stand-in card lies beside the road, with the road's kind */
.road-waypoint.is-stop { z-index: 4; }
.road-waypoint.is-stop .tw-card { filter: drop-shadow(0 6px 10px rgba(27, 26, 23, .38)); }
.is-driving .road-node.is-stop { pointer-events: auto; cursor: pointer; }
.road-waypoint.is-stop:focus-visible { outline: 3px solid var(--red); outline-offset: 4px; }
.stop-badge { position: absolute; left: 0; top: 0; width: 100%; height: 0; z-index: 5; pointer-events: none; }
.stop-kind { position: absolute; left: -13px; top: -15px; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .45); font-weight: normal; }
.stop-marks { position: absolute; right: -11px; top: -13px; display: flex; flex-direction: column; gap: 4px; }
.stop-marks i { font-style: normal; display: grid; place-items: center; width: 25px; height: 25px; border-radius: 50%; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); box-shadow: 1px 1px 0 rgba(27, 26, 23, .4); }
.stop-state.is-watched, .stop-state.is-closed, .stop-state.is-condemned { color: var(--red); }
@media (max-width: 520px) { .stop-kind { width: 32px; height: 32px; left: -11px; top: -13px; } .stop-marks i { width: 21px; height: 21px; } }
.stop-kind .sym { width: 25px; height: 25px; }
.stop-marks .sym { width: 16px; height: 16px; }
@media (max-width: 520px) { .stop-kind .sym { width: 21px; height: 21px; } .stop-marks .sym { width: 14px; height: 14px; } }
/* H: a notorious on the road: a star among the marks of its stop card, its rare drops on the tarp */
.stop-notorious { color: var(--red); }
.ret-parts { margin-top: 6px; }
.ret-cell.is-rare .tw-card { filter: drop-shadow(0 0 7px rgba(168, 52, 42, .55)); }

/* H: the job board of the tavern (jobsworld.js): pay, turns and the state of the road under the card, the needs of the job as symbols on it, a red slash on the one the convoy does not meet */
.job-pr { display: flex; gap: 8px; align-items: center; justify-content: center; }
.job-pr b { display: inline-flex; align-items: center; gap: 2px; }
.job-pr .is-watched, .job-pr .is-closed, .job-pr .is-condemned { color: var(--red); }
.mc-face .job-reqs { position: absolute; left: 3%; right: 3%; bottom: 14%; z-index: 2; display: flex; flex-wrap: wrap; gap: 3px; justify-content: center; }
.job-req { position: relative; display: inline-flex; align-items: center; gap: 1px; min-width: 24px; height: 24px; padding: 0 4px; border-radius: 12px; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); box-shadow: 1px 1px 0 rgba(27, 26, 23, .4); font-size: 12px; font-weight: 700; line-height: 1; }
.job-req.is-unmet { color: var(--red); border-color: var(--red); }
.job-no { position: absolute; left: 8%; right: 8%; top: 50%; height: 2.5px; background: var(--red); transform: rotate(-40deg); }
.mc-face .job-held { position: absolute; right: -6px; top: -8px; z-index: 3; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--ink); color: var(--paper); font-style: normal; }
.mc-why.is-needs { color: var(--red); }
.mc-face .job-kind { position: absolute; left: -7px; top: -9px; z-index: 3; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .4); font-style: normal; }
.mc-face .job-kind.job-star { top: 26px; width: 26px; height: 26px; color: var(--red); }
/* JOB-2026100508: a rare or very rare load pays more than an ordinary one: a load mark at the top right of the card, red for the rarest */
.mc-face .job-cargo { position: absolute; right: -7px; top: -9px; z-index: 3; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .4); font-style: normal; }
.mc-face .job-cargo.is-very-rare { color: var(--red); border-color: var(--red); }
/* JOB-2026100515: what the load demands of the trip (fragile, perishable, precious): its own mark at the top left, so it sits
   beside the rarity mark instead of over it. A bulk load asks nothing of its own and wears none. */
.mc-face .job-cargo.is-load { right: auto; left: -7px; }
.mc-face .job-cargo.is-load.is-perishable { color: var(--red); border-color: var(--red); }
/* H: a job: its symbol on the destination card of the hand, what rides with the truck, the kind among the marks of a stop */
.city-mark.is-job { right: -8px; bottom: 26px; left: auto; top: auto; }
.road-rider { position: absolute; left: calc(10% + var(--i, 0) * 42%); top: 62%; width: 70%; z-index: 0; transform: rotate(calc(-5deg + var(--i, 0) * 6deg)); pointer-events: none; filter: drop-shadow(0 2px 3px rgba(27, 26, 23, .4)); }
.road-rider.is-symbol { display: grid; place-items: center; aspect-ratio: 1; border-radius: 50%; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); top: 76%; }
.road-rider .tw-card { width: 100%; }
.stop-job { color: var(--ink); }
.ret-job { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 2px auto 8px; padding: 6px 14px; width: fit-content; background: var(--paper); border: 2px solid var(--ink); box-shadow: 2px 3px 0 rgba(27, 26, 23, .4); }
.ret-job .rj-res { position: relative; display: inline-grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; border: 2px solid var(--ink); }
.ret-job.is-fail .rj-res { color: var(--red); border-color: var(--red); }
.ret-job .rj-no { position: absolute; left: 12%; right: 12%; top: 50%; height: 2.5px; background: var(--red); transform: rotate(-40deg); }

/* H: rule 161: what an item does, under its price, in plain words with the number: on hover, on focus, on a lifted card, on a long press (phone) */
.mc-fx { display: none; position: absolute; left: 50%; top: calc(100% + 2px); transform: translateX(-50%); z-index: 6; min-width: 100%; max-width: 190%; padding: 4px 8px 5px; flex-direction: column; align-items: center; gap: 1px; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 2px 3px 0 rgba(27, 26, 23, .45); pointer-events: none; text-align: center; }
.mc-fx i { font-style: normal; font-weight: 700; font-size: clamp(.74rem, 1.9vw, .9rem); line-height: 1.25; white-space: nowrap; }
.mcard:hover .mc-fx, .mcard:focus-visible .mc-fx, .mcard.is-lifted .mc-fx, .mcard.is-explained .mc-fx { display: flex; }
.mcard.is-explained, .mcard:hover, .mcard:focus-visible, .mcard.is-lifted { z-index: 7; }

/* ------------------------------------------------------------ J: JOB-021 the money on screen (rules 172, 192, 175)
   ONE glyph (the piastre), ONE way to write a number, a purse that counts, price plates that name what is missing in red ink. Nothing in this block is greyed, dimmed or washed out:
   a card the purse cannot pay keeps its colours and carries the reason as a symbol on it. */
.money { display: inline-flex; align-items: center; gap: .24em; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.money.is-lack, .pr .is-lack { color: var(--red); }
.mcard.is-lifted .pr .is-lack, .mcard.is-lifted .pr-miss { color: #F0877D; } /* the lifted plate is paper on ink: a lighter red keeps the lack readable */

/* the purse beside the hourglass on the road and the cities hand; what a payment brought rises under it as `+ $350` */
.topbar .purse-top { font-size: 1.6rem; gap: 8px; }
.purse, .purse-money, .cur { position: relative; }
.money-pop { position: absolute; right: 0; top: calc(100% + 6px); z-index: 40; padding: 1px 10px; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .3); font-size: 1.1rem; pointer-events: none; }

/* the three currencies, named once as round tokens of the shop header: the piastre (the purse), the experience, the job points; each symbol's bubble says what it buys */
.cur { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-variant-numeric: tabular-nums; }
.shop-bars { gap: 10px; }
.shop-bars .bank, .shop-bars .cur { padding: 1px 12px 1px 9px; border: 2px solid var(--ink); border-radius: 999px; background: var(--paper); box-shadow: 1px 2px 0 rgba(27, 26, 23, .3); font-size: 1.2rem; }
@media (max-width: 700px), (max-aspect-ratio: 1/1) { .shop-head { flex-wrap: wrap; } .shop-bars { order: 3; width: 100%; justify-content: center; } }

/* the price plate: only the tokens the card costs; the one the purse lacks in red ink with the missing amount, and a small market beside it (where piastres come from); a sale shows `+ $` and the count */
.pr-miss { font-style: normal; font-weight: 700; font-size: .85em; color: var(--red); }
.pr-from { display: inline-flex; align-items: center; gap: 2px; font-style: normal; font-weight: 700; font-size: .85em; color: var(--ink); opacity: .75; } /* JOB-2026100508: the share of a lesson the crew's pool adds, beside the price, before the confirmation */
.pr-earn { display: inline-grid; place-items: center; font-style: normal; }
.pr-earn .sym { width: 14px; height: 14px; }
.pr-count { font-size: .9em; }

/* the tarp: what the fight paid, one plate for each payment (the place or the road, then the purse of a finished record in a double frame), and the parts below */
.ret-earn { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px 14px; margin: 0 0 12px; }
.ret-earn .ret-pay { margin: 0; }
.ret-parts b { display: inline-flex; align-items: center; gap: .24em; } /* the parts plate: the glyph and the number on one line, like the money plates (a symbol is a block) */
.ret-pay.is-record { padding: 6px 18px; box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 4px var(--ink), 2px 3px 0 rgba(27, 26, 23, .3); }

/* the arrival bill: one line for each standing order with its switch (on = the piastre of that order is spent at the next arrival, off = skipped); the line keeps its colours either way */
.tb-order { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 5px 0; border-top: 1px dashed rgba(27, 26, 23, .45); }
.tb-shop { display: inline-grid; place-items: center; width: 34px; height: 34px; flex: none; border-radius: 50%; border: 2px solid var(--ink); background: var(--paper); }
/* Rule 228: nothing important is only an icon. The name of the order stands in the line, and the bubble carries the rest. */
.tb-name { flex: 1 1 auto; min-width: 0; font-size: .78rem; font-weight: 700; line-height: 1.15; overflow: hidden; text-overflow: ellipsis; }
.tb-tabname { flex: none; }
.tb-thumbs { display: inline-flex; gap: 4px; flex: 0 1 auto; min-width: 0; overflow: hidden; padding: 0 0 4px 0; }
.tb-pair { position: relative; display: inline-flex; flex: none; margin-right: 10px; }
.tb-thumb.is-gear { position: absolute; right: -10px; bottom: -4px; width: 20px; height: 20px; border-width: 1.5px; }
.tb-order .tb-sum { margin-left: auto; flex: none; align-items: center; }
.tb-lack { color: var(--red); }
.tb-switch { appearance: none; cursor: pointer; position: relative; flex: none; width: 52px; height: 32px; padding: 0; border-radius: 999px; border: 2px solid var(--ink); background: var(--paper); }
.tb-switch i { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--ink); transition: transform .16s ease; }
.tb-switch.is-on { background: var(--ink); }
.tb-switch.is-on i { transform: translateX(20px); background: var(--paper); }
.tb-switch:hover, .tb-switch:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .tb-switch i { transition: none; } }

/* ------------------------------------------------------------ W3: JOB-019 (rule 177): a service shows the cards it acts on, their state now and what it brings them to; a whole service shows the same cards with a mark and says so.
   Full colour everywhere (rule 175): the whole mark is a small red seal beside the number, never a faded card. A symbol is never taller than its number (rule 160). */
.mc-acts { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: flex-start; gap: 4px 7px; width: 100%; }
.act-row { display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: clamp(.74rem, 1.8vw, .86rem); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.act-face { display: block; width: clamp(26px, calc(var(--mcw, 100px) * .3), 46px); flex: none; }
.act-face .tw-card { width: 100%; }
.act-nums { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
.act-nums .sym { width: .95em; height: .95em; }
.act-nums b { font-weight: 700; }
.act-nums em { font-style: normal; font-weight: 700; }
.act-whole { display: inline-grid; place-items: center; width: 1.15em; height: 1.15em; margin-left: 2px; border-radius: 50%; background: var(--red); color: var(--paper); font-style: normal; flex: none; }
.act-whole .sym { width: 75%; height: 75%; }
.act-more { text-align: center; font-weight: 700; font-size: .8rem; }
.mc-acts.is-faceless .act-face { display: none; }
.mcard[data-acts="whole"] .mc-eff { color: var(--ink); }

/* ------------------------------------------------------------ W3: JOB-019 (7b, audit K1): the turns, seen. A ring around the hourglass of the top bar fills over the minutes one turn takes to come back (turnsring.js);
   `-N` leaves the counter, `+1` comes in; out of turns the counter is red and the minutes left stand beside it. No dimming anywhere: the track is a thin ink circle, the fill a thick one. */
.bank.has-ring { position: relative; }
.tring { position: relative; display: inline-grid; place-items: center; width: 34px; height: 34px; flex: none; }
.tring-svg { pointer-events: none; position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.tring-track { fill: none; stroke: var(--ink); stroke-width: 1.1; }
.tring-fill { fill: none; stroke: var(--ink); stroke-width: 3.8; stroke-linecap: round; transition: stroke-dashoffset 1s linear; }
.bank .tring .sym { width: 17px; height: 17px; }
.bank.is-out .bank-n, .bank.is-out .sb-turns { color: var(--red); }
.bank.is-out .tring-track, .bank.is-out .tring-fill { stroke: var(--red); }
.tr-pop { position: absolute; top: calc(100% - 6px); z-index: 40; padding: 0 7px; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: 1px 2px 0 rgba(27, 26, 23, .3); font-style: normal; font-size: 1.05rem; font-weight: 700; line-height: 1.25; pointer-events: none; font-variant-numeric: tabular-nums; }
.tr-pop.is-minus { color: var(--red); }
.shop-bars .tring { width: 28px; height: 28px; }
.shop-bars .bank .tring .sym { width: 14px; height: 14px; }
.shop-bars .tr-pop { top: 50%; translate: 0 -50%; }
/* leftover D1 of JEV-021: in the header of a shop the rising `+ $` stands on the purse (money.js), so it never crosses the keeper's words under the header */
.shop-bars .money-pop { top: 50%; right: 0; translate: 0 -50%; }
/* out of turns, under the place chosen: what the trip costs and the minutes left before it can be paid: symbols and numbers, no sentence, full colour */
.go-wait { display: inline-flex; align-items: center; gap: 18px; padding: 6px 18px; background: var(--paper); color: var(--ink); border: 2px solid var(--ink); box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 4px var(--ink), 2px 3px 0 rgba(27, 26, 23, .35); font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.go-wait b { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; }
.go-wait .sym { width: .85em; height: .85em; }
.go-wait .go-wait-n { color: var(--red); }

/* ------------------------------------------------------------ W3: JOB-019 (leftover D3 of JEV-021): at 1440x700 (a wide, short screen) the sheets of the tavern and of the workshop must not scroll.
   The cards of the menu take the height that is left (container units of their own area: never taller than the room, one row when it can), the words of a card stand over its picture instead of below it (below it, they
   made a bottom edge to scroll to), the people of the shop and the keeper take less. The tall screens keep their sizes (the formula is a MIN of the old one). */
@media (min-aspect-ratio: 11/10) and (max-height: 760px) {
  .shop-panel { height: 98dvh; padding: 8px 12px 0; gap: 6px; --kw: clamp(64px, 12dvh, 92px); --ccw: clamp(40px, 6.6dvh, 58px); }
  .shop-top { gap: 6px 12px; }
  .shop-line { padding: 7px 12px; gap: 5px; }
  .sl-text { font-size: clamp(.92rem, 1.5vw, 1.15rem); line-height: 1.25; }
  .sm-tab { height: 38px; }
  .sm-chip { width: 36px; height: 36px; }
  .shop-controls { padding: 5px 6px; margin-top: 6px; }
  .sm-cards { padding: 16px 6px 90px; gap: 10px; }
  .mc-fx { top: 30%; max-width: 230%; }
  .act-face { width: clamp(22px, calc(var(--mcw, 90px) * .26), 34px); }
  .mc-acts { gap: 2px 5px; }
}

/* ------------------------------------------------------------ W3: JOB-019 (Z1, Z2): the return screen: the verdict first, in a plaque; the rows carry a symbol; nothing under the mode mark of the corner */
.ret-verdict { margin: 0; padding: 8px 26px; background: var(--paper); color: var(--ink); border: 3px solid var(--ink); box-shadow: inset 0 0 0 4px var(--paper), inset 0 0 0 5.5px var(--ink), 4px 6px 0 rgba(27, 26, 23, .4); font-size: clamp(1.4rem, 5.4vw, 2.2rem); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; text-align: center; text-wrap: balance; max-width: 100%; }
.ret-verdict.is-lost { color: #78221C; } /* the verdict of a lost convoy at night (the hour wash multiplies the plaque: --red read 4.17:1 on the paper, 4.6 at p10 with a lighter red; this reads over 5; found by the gate, acceptance contrast) */
.ret-terminal-reason { margin: 0 auto; padding: 12px 16px; max-width: 48rem; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); line-height: 1.45; text-align: center; }
/* This neutral indoor tabletop has no sky. The world weather/clock stays intact for the next location. */
.return-screen.is-terminal-return #wash { display: none; }
.ret-board.has-terminal .ret-scroll { bottom: calc(138px + var(--safe-bottom)); }
.ret-board.has-terminal .ret-bar .btn { flex: 1; min-width: 0; max-width: 360px; padding: 12px; font-size: clamp(.85rem, 2.5vw, 1.05rem); letter-spacing: .08em; }
@media (min-width: 600px) { .ret-board.has-terminal .ret-scroll { bottom: calc(94px + var(--safe-bottom)); } }
.ret-head span { display: inline-flex; align-items: center; gap: 8px; }
.ret-head span .sym { width: 1.1em; height: 1.1em; }
.ret-row-lost .tw-fallen-mark { pointer-events: auto; } /* the struck mark of a lost card has its bubble (rule 164): « Tombé : l'église les ramène » */
@media (max-width: 899px) { .ret-scroll.has-mark { padding-top: calc(var(--safe-top) + 64px); } }

/* W3: JOB-019 (W1, W2): the keeper's round portrait on a shop card and the fallen mark of a card carried to the church answer the hover (their bubbles), the layers stay inert elsewhere */
.shop-medal { pointer-events: auto; cursor: pointer; }
.tw-walker .tw-fallen-mark { pointer-events: auto; }

/* JOB-2026100518: the sheet the dock keeper hands over when a haul is settled at his dock (JOB-033, JOB-037). It sits over the table and
   under the bill (which is the last word of the arrival), never blocks a tap on the table, and its lines follow the bill's paper. */
.town-reckhost { position: absolute; left: 0; right: 0; bottom: 0; z-index: 11; display: flex; justify-content: center; align-items: flex-end; pointer-events: none; padding-bottom: calc(10px + var(--safe-bottom)); }
.town-reck { pointer-events: auto; cursor: pointer; width: min(94vw, 440px); max-height: 58vh; overflow-y: auto; padding: 14px 16px; background: var(--paper); color: var(--ink); border: 3px solid var(--ink); box-shadow: inset 0 0 0 4px var(--paper), inset 0 0 0 5.5px var(--ink), 5px 7px 0 rgba(27, 26, 23, .4); outline: none; }
.town-reck:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }
.town-reck.is-sliding { animation: bill-up .5s cubic-bezier(.2, .8, .3, 1); }

.haul-sheet .rk-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.haul-sheet .rk-row + .rk-row { border-top: 1px dashed rgba(27, 26, 23, .45); }
.haul-sheet .rk-good { display: inline-flex; align-items: center; gap: 6px; }
.haul-sheet .rk-units { font-weight: 700; font-variant-numeric: tabular-nums; }
.haul-sheet .rk-value { margin-left: auto; font-size: 1.4rem; }
.haul-sheet .rk-lost { display: inline-flex; align-items: center; gap: 5px; color: var(--red); font-weight: 700; }
.haul-sheet .rk-cracked { display: inline-flex; align-items: center; gap: 4px; }
.haul-sheet .rk-calc { justify-content: center; flex-wrap: wrap; gap: 8px; }
.haul-sheet .rk-op { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; font-variant-numeric: tabular-nums; }
.haul-sheet .rk-fee-n { font-size: 1.5rem; }
.haul-sheet .rk-lines { list-style: none; margin: 8px 0 0; padding: 0; }
.haul-sheet .rk-line { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-top: 1px dashed rgba(27, 26, 23, .45); font-weight: 700; }
.haul-sheet .rk-line .money { margin-left: auto; }
.haul-sheet .rk-forgiven { display: inline-flex; align-items: center; gap: 4px; text-decoration: line-through; }
.haul-sheet .rk-rule { border: none; border-top: 3px double var(--ink); margin: 10px 0 0; }
.haul-sheet .rk-left { justify-content: space-between; }
.haul-sheet .rk-left-n { font-size: 1.7rem; }
.haul-sheet .rk-xp, .haul-sheet .rk-jp { display: inline-flex; align-items: center; gap: 5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.haul-sheet .rk-second { flex-wrap: wrap; gap: 14px; font-weight: 700; }
.haul-sheet .rk-fight-money, .haul-sheet .rk-fight-parts, .haul-sheet .rk-owed { display: inline-flex; align-items: center; gap: 5px; font-variant-numeric: tabular-nums; }
.haul-sheet .rk-neg { color: var(--red); }
.haul-sheet .rk-pos { color: var(--ink); }

/* JOB-2026100518: the Quick Run, on the cities screen. The button sits on the left of the topbar, its sheet asks the road and the
   budget, and the receipt tells what the run did. Same paper and ink as the bill and the dock sheet. */
.qr-sheet { place-items: center; }
.qr-sheet .sheet-card { width: min(92vw, 460px); }
.qr-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0 0 6px; font-size: 1.35rem; letter-spacing: .16em; text-transform: uppercase; }
.qr-head b { font-size: 1.05rem; letter-spacing: .04em; text-transform: none; }
.qr-lead { margin: 0 0 10px; font-weight: 700; opacity: .8; }
.qr-lead.qr-refused { color: var(--red); }
.qr-grid { grid-template-columns: 1fr; }
.qr-entry { min-height: 58px; flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 14px; }
.qr-entry.is-short { opacity: 1; border-style: dashed; }
.qr-entry.is-short .qr-name { color: var(--red); }
.qr-name { font-size: 1.15rem; }
.qr-sub { display: inline-flex; align-items: center; gap: 5px; font-size: 1rem; letter-spacing: .02em; font-variant-numeric: tabular-nums; }
.qr-state { display: inline-flex; align-items: center; }
.qr-why { font-size: .9rem; letter-spacing: .04em; color: var(--red); }
.qr-lines { list-style: none; margin: 6px 0 0; padding: 0; }
.qr-line { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px dashed rgba(27, 26, 23, .45); font-weight: 700; }
.qr-line i { display: inline-flex; align-items: center; }
.qr-line span { flex: 1; text-align: left; }
.qr-line b { font-variant-numeric: tabular-nums; }
.qr-line.is-neg b { color: var(--red); }
.qr-line.is-pos b { color: var(--ink); }
.qr-acts { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; }
.qr-go { flex: 1; }

/* Cargo identity is display metadata: long names wrap without concealing prices or routes. */
.cargo-identity { display: flex; flex-direction: column; gap: 3px; min-width: 0; max-width: 100%; text-align: center; overflow-wrap: anywhere; font: 14px/1.3 var(--font-body, sans-serif); }
.cargo-product { font-size: 16px; }
.cargo-producer, .cargo-type, .cargo-destination { display: block; }
.mcard > .cargo-identity { width: 100%; padding: 4px; }
.town-bill > .cargo-identity { margin: 6px 0; }
.rk-load > .cargo-identity { flex: 1; }
.cargo-face .cf-band { gap: 1cqw; padding: 1cqw 3cqw; }
.cargo-face .cf-name { line-height: 1.05; }
.cargo-face-producer { display: block; font-size: 3.7cqw; line-height: 1.1; overflow-wrap: anywhere; }
.cargo-face-japanese { display: block; font-size: 3.7cqw; line-height: 1.1; }
.cargo-face { container-type: inline-size; }
.cargo-face .cargo-name-band { gap: .3cqw; padding: .5cqw 1cqw; background: #eeeadd; box-sizing: border-box; }
.cargo-face .cargo-name-band .cf-name { font-size: 4.3cqw !important; letter-spacing: .01em; }
.cargo-face .cargo-name-band .cargo-face-producer, .cargo-face .cargo-name-band .cargo-face-japanese { font-size: 3.3cqw; line-height: 1.02; }

/* R6 (JEV-2026100905): the end-of-fight workshop, one page over the table. The overlay never eats a tap meant for the
   topbar (the back button leaves the town all the same) and never runs the table off the side of a phone: only the
   panel takes pointers, and it stays inside the screen. */
.ws-overlay { position: fixed; inset: 0; z-index: 40; display: flex; align-items: flex-start; justify-content: center; padding: calc(64px + var(--safe-top)) 12px calc(12px + var(--safe-bottom)); box-sizing: border-box; overflow-y: auto; pointer-events: none; background: rgba(27, 26, 23, .28); }
.ws-panel { pointer-events: auto; position: relative; width: min(560px, 100%); max-width: 100%; box-sizing: border-box; display: flex; flex-direction: column; gap: 12px; padding: 18px; background: var(--paper); border: 3px solid var(--ink); box-shadow: inset 0 0 0 5px var(--paper), inset 0 0 0 6.5px var(--ink), 6px 8px 0 rgba(27, 26, 23, .45); }
.ws-head { display: flex; flex-direction: column; gap: 6px; text-align: center; }
.ws-title { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 0; font-family: var(--serif); font-size: 1.5rem; letter-spacing: .12em; text-transform: uppercase; }
.ws-lead { margin: 0; font-size: .95rem; line-height: 1.35; color: var(--ink); }
.ws-earn { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 18px; padding: 8px 10px; border-top: 1px solid var(--wash); border-bottom: 1px solid var(--wash); }
.ws-earn-line { display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.ws-plus { font-style: normal; font-variant-numeric: tabular-nums; }
.ws-kills { font-size: .9rem; }
.ws-choices { display: flex; flex-direction: column; gap: 10px; }
.ws-empty { margin: 0; padding: 10px; text-align: center; font-size: .95rem; color: var(--wash); }
.ws-msg { margin: 0; text-align: center; font-size: .95rem; }
.ws-card { display: flex; flex-direction: column; gap: 6px; width: 100%; box-sizing: border-box; padding: 12px; text-align: left; background: var(--paper-2); border: 2px solid var(--ink); color: var(--ink); font: inherit; cursor: pointer; }
.ws-card-static { cursor: default; }
.ws-card-top { display: flex; align-items: center; gap: 8px; font-family: var(--serif); font-size: 1.05rem; letter-spacing: .06em; text-transform: uppercase; }
.ws-card-top b { font-weight: 700; }
.ws-card-line { font-size: .92rem; line-height: 1.3; }
.ws-card-does { color: var(--wash); }
.ws-card-price { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; font-variant-numeric: tabular-nums; }
.ws-stats { list-style: none; display: flex; flex-direction: column; gap: 3px; margin: 0; padding: 0; }
.ws-stat { display: flex; align-items: baseline; gap: 8px; font-size: .9rem; font-variant-numeric: tabular-nums; }
.ws-stat-name { flex: 1; min-width: 0; text-align: left; }
.ws-stat-val { display: inline-flex; align-items: baseline; gap: 5px; }
.ws-arrow { font-style: normal; color: var(--wash); }
.ws-trucks { list-style: none; display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; }
.ws-truck { display: flex; align-items: center; }
.ws-truck.is-on { justify-content: space-between; gap: 10px; font-size: .95rem; }
.ws-truck.is-on i { font-style: normal; color: var(--wash); }
.ws-truck-btn { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; box-sizing: border-box; padding: 8px 10px; background: var(--paper); border: 1.5px solid var(--ink); color: var(--ink); font: inherit; cursor: pointer; }
.ws-truck-btn i { font-style: normal; color: var(--wash); }
.ws-bar { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
.ws-go { flex: 1; }
.ws-village { flex: none; }

/* audit 2026-10-09 cut 9: one result line in plain words, one big CONTINUER, the Codex a small corner link */
.ret-total { display: inline-flex; align-items: center; gap: 10px; font-size: 1.15rem; }
.ret-total-word { font-family: var(--serif); font-weight: 700; letter-spacing: .02em; }
.ret-total .ret-parts { display: inline-flex; align-items: center; gap: 4px; }
.ret-bar .btn.ret-go { min-width: min(320px, 80vw); padding: 16px 28px; font-size: 1.2rem; letter-spacing: .1em; }
.ret-codex { position: absolute; top: calc(10px + var(--safe-top, 0px)); right: 12px; z-index: 5; appearance: none; cursor: pointer; padding: 6px 12px; font-family: var(--serif); font-size: .85rem; letter-spacing: .06em; color: var(--ink); background: var(--paper); border: 2px solid var(--ink); }
.ret-codex:hover, .ret-codex:focus-visible { background: var(--ink); color: var(--paper); outline: none; }
.ret-codex .rec-dot { position: relative; top: -6px; margin-left: 4px; }

/* R11 (JEV-2026100905 item 4): the one-time invitation to keep the road, over the workshop */
.ws-invite { position: fixed; inset: 0; z-index: 41; pointer-events: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; padding: 24px 20px calc(24px + var(--safe-bottom, 0px)); text-align: center; background: rgba(27, 26, 23, .82); color: var(--paper); }
.ws-invite-title { margin: 0; font-family: var(--serif); font-size: 1.5rem; letter-spacing: .12em; }
.ws-invite-lead { margin: 0; max-width: 420px; font-size: 1rem; line-height: 1.45; }
.ws-invite-bar { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
