/* ui/adapters/overrides.css — loads LAST (after additions.css + tabler).
   The prototype paints a fake map (CSS gradients + absolutely-positioned DOM
   pins). R3-0 puts a REAL MapLibre basemap in #map-root behind the React root,
   so the prototype's mock map layers must go transparent to let it show through.
   NO other visual overrides live here (spec R3-0 §5). */

/* Mock map backdrop (atoms.jsx <Ymap>) — the gradient "landmasses" (.map),
   the ::before road grid and the ::after water band all go transparent. */
.ym .map,
.ym .map::before,
.ym .map::after {
  background: transparent !important;
  background-image: none !important;
}

/* R3-FIX1 F1 — the Home mock-map div (.map) stays mounted UNDER the CityMap
   screen and, being pointer-events:auto, swallowed every marker/map click so
   the real basemap behind #root never received a tap (SpotSheet, pending focus,
   drop-note, move-pin, note markers were all dead). Its only children are the
   hidden mock .pin spans, so making the whole mock-map layer click-transparent
   lets taps reach the real map + its real markers (z-0). Scoped to BOTH shells
   (.ym mobile, .ymd desktop — desktop was equally dead since these rules were
   .ym-only). Paste-bar / TopBar / BottomNav / MapCtl are siblings of .map, not
   children, so they keep their own pointer-events. */
.ym .map, .ymd .map { pointer-events: none; }

/* Mock pins on the backdrop map (atoms.jsx) — hidden; real markers arrive in a
   later R3 wave. Scoped to direct children of .map so real UI pins elsewhere
   are untouched. */
.ym .map > .pin {
  display: none !important;
}

/* City-map surface fake fills (citymap.jsx / .cvx__map / .spotx__map /
   .citypick__map) — transparent so the real basemap shows through there too. */
.ym .citymap__map,
.ym .cvx__map,
.ym .spotx__map,
.ym .citypick__map {
  background: transparent !important;
  background-image: none !important;
}

/* ── R3-3 CityMap: real basemap + real maplibregl markers ─────────────────── */

/* The full-surface shells paint an opaque `background: var(--bg)` that would
   hide the real map behind #root. Make the CityMap surface transparent so the
   singleton basemap (its real markers live on it) shows through. */
.ym .citymap {
  background: transparent !important;
}

/* Let taps in the empty map area fall through to the real map + its markers
   (z-0), while every floating UI card keeps its own pointer-events. The mock
   map layer and the fake region labels are inert. */
.ym .citymap { pointer-events: none; }
.ym .citymap > *:not(.citymap__map) { pointer-events: auto; }
.ym .citymap__map { pointer-events: none !important; }
/* R3-FIX1 F1 — desktop shell (.ymd) needs the SAME pass-through (its .citymap
   container otherwise ate every tap in the open map area). .spotx is excluded:
   desktop.css deliberately makes the SpotSheet backdrop click-through (only its
   .spot-sheet panel is interactive), and re-enabling it here would break that. */
.ymd .citymap { pointer-events: none; }
.ymd .citymap > *:not(.citymap__map):not(.spotx) { pointer-events: auto; }
.ymd .citymap__map { pointer-events: none !important; }

/* R6-W4 P3 — TOP BUG: with a spot open, the desktop map + POI list were DEAD.
   `.spotx` is a full-bleed inset:0 backdrop that is a DIRECT CHILD of `.citymap`
   (citymap.jsx CityMapScreen). desktop.css:325 already declares it click-through
   (`.ymd .spotx { pointer-events: none }`, specificity 0,2,0) — but the MOBILE
   pass-through rule three lines up (`.ym .citymap > *:not(.citymap__map)`,
   specificity 0,3,0) ALSO matches the desktop shell (its class list is
   "ym ymd") and outweighs it, flipping the backdrop back to `auto`. Result: the
   backdrop swallowed every pointer event over the map and over the left POI
   panel — no pan, no other pin, no other list row — until the X was pressed.
   The .ymd twin at :64 excludes .spotx correctly, but that only removes the
   desktop re-enable; the .ym rule still won on its own.
   Fix: one .ymd-scoped rule at equal specificity (0,3,0) that comes LATER in
   source order, so it wins on the desktop shell only. NOT `:not(.spotx)` on the
   .ym rule — MOBILE deliberately wants the .spotx surface opaque and blocking
   (its own contract lives further down, see Mo3). The `.spot-sheet` panel keeps
   its own `pointer-events: auto` (desktop.css:330), so the card stays fully
   interactive while everything behind it is live again. */
.ymd .citymap > .spotx { pointer-events: none; }

/* R3-FIX1 F1 — the shell layers over the real map are BOTH default
   pointer-events:auto and cover inset:0: `#root` (z-1, fixed) and its child
   `.ym`/`.ym.ymd` (absolute). Either one caught taps in the OPEN map area even
   after .map / .citymap went transparent (the real map + markers live on
   #map-container at z-0, behind #root). In CityMap mode make BOTH layers
   click-through; interactive descendants keep pointer-events:auto (the standard
   none-parent / auto-child cascade) so panels, FABs, sheets, the bottom nav and
   overlays still receive taps, while empty map area falls through to the map. */
#root:has(.citymap), .ym:has(.citymap) { pointer-events: none; }
/* pointer-events INHERITS, so the none above would also disable the shell's own
   UI (top bar, bottom nav, map controls, overlays). Re-assert `auto` on the
   root's direct children EXCEPT the two transparent pass-through layers (the
   mock `.map` and the `.citymap` surface, which stay none so the map shows
   through); each re-enabled region's own children then inherit `auto` normally. */
.ym:has(.citymap) > *:not(.map):not(.citymap) { pointer-events: auto; }
.ym .citymap__map .cvx__label,
.ym .citymap__map .citymap__water { display: none !important; }

/* ── R4-W1 Task 1 + 4 — the globe lives everywhere the basemap is the backdrop ──
   Home/Exploring (.map) and Map-Pick (.citypick) both sit over the ONE real
   MapLibre basemap (#map-container, z0, behind #root). The R3-FIX1 pass-through
   only freed the CityMap (:has(.citymap)); the same none-parent / auto-child
   pattern is generalized here so a real pointer drag / wheel-zoom / double-tap
   reaches the basemap on the home globe too, while every real UI child (BottomNav,
   MapCtl, paste hero, sheets, city surfaces) keeps its own pointer-events. `.map`
   is always mounted (Home renders under every sheet), so `:has(.map)` is
   effectively "the shell is up" — exactly when the basemap should own the empty
   area. `.citymap` and `.citypick` are EXCLUDED from the auto re-enable: `.citymap`
   keeps its own internal rules above; `.citypick` gets the CityMap-style
   pass-through below (Map-Pick, Task 4). Covers both shells (the desktop root is
   `.ym.ymd`, so `.ym:has(.map)` matches it too). */
#root:has(.map), .ym:has(.map) { pointer-events: none; }
.ym:has(.map) > *:not(.map):not(.citymap):not(.citypick) { pointer-events: auto; }

/* Map-Pick surface (tripcities.jsx CityPickScreen) — same contract as `.citymap`:
   the surface is a transparent pass-through so drags + real city-dot taps reach
   the basemap + its dest-dots layer, while every floating control (mode switch,
   zoom, back, bottom bar, add-menu) stays clickable. `.citypick__map` is inert —
   the real dots live on the basemap, not in the DOM. The decorative SE-Asia region
   labels are hidden (the JSX no longer renders the mock city markers). */
.ym .citypick { background: transparent !important; pointer-events: none; }
/* R5-W1 Task 5 — extend the pass-through: `.citypick__view` (the Map-area framing
   rectangle) is pointer-events:none by DESIGN (citymap.css:513) so the user can
   pan/zoom the basemap "inside" the frame to choose an area. The blanket child
   re-enable below flipped it to `auto`, so in Map-area mode the frame covered the
   map and swallowed drags (pick mode already panned — no frame there). Exclude it
   too (like `.citypick__map`) so BOTH modes pan/zoom the real basemap. */
.ym .citypick > *:not(.citypick__map):not(.citypick__view) { pointer-events: auto; }
.ym .citypick__map { pointer-events: none !important; }
.ym .citypick .cvx__label { display: none !important; }

/* City-overview hero: a resolved Pexels city photo fills the existing frame;
   failures stay on the mirror's striped `.cv-photo` placeholder. */
.ym .cv-hero .cv-photo__img { width: 100%; height: 100%; object-fit: cover; object-position: center 45%; display: block; }

/* R4-W1 Task 3 — the live city-search rows (TripSetup "Add a city" + "Where from")
   reuse the design's `.trip-addres` list. A keyboard/hover highlight (top hit is
   preselected, Enter takes it) and an honest muted empty/busy row are the only new
   states; the coral "Add"/"Set" affordance + row layout are the mirror's. */
.ym .trip-addres__row.on { background: var(--surface-muted); }
.ym .trip-addres__empty { cursor: default; color: var(--text-2); }
.ym .trip-addres__empty .trip-addres__fl { color: var(--text-3); }
.ym .trip-addres__empty b { font-weight: 600; color: var(--text-2); }
.ym .trip-addres__sub { font-weight: 500; color: var(--text-3); }
.ym .trip-addres__empty .ti-loader-2 { animation: ym-r4spin 0.8s linear infinite; }
@keyframes ym-r4spin { to { transform: rotate(360deg); } }

/* SpotSheet mini-map: its two hardcoded Singapore street labels are demo — hide
   them (the centred pin still shows the real spot's own emoji + name). The
   .spotx__map real-basemap backdrop is a follow-up (see report). */
.ym .spotx__map .cvx__label { display: none !important; }

/* R3-FIX5 superseded by R6-W4 Mo3 — the mobile `.spotx` backdrop no longer paints
   an opaque `--bg`, so there is no blank strip left to fill: the REAL basemap now
   shows (and receives taps) above the sheet. The mirror's decorative mock pin
   (top:40%) + label (top:46%) therefore go back to their design positions, where
   the 62%-tall `.spot-sheet` covers them — the spot the user opened is already
   drawn on the real map by its real marker, so lifting a SECOND mock pin into the
   visible strip would now double it. Rules deleted (see Mo3 block at the bottom). */

/* Real markers: maplibregl owns the WRAPPER (.cm-mk) transform+opacity
   (positioning); the design `.cm-spot` visual + wiggle animation live on the
   INNER child, so no transform trap (Scout A RISK #4). Dimming is filter:opacity
   on the wrapper, never opacity/transform (maplibre overwrites those). The
   markers render OUTSIDE .ym (on #map-container), so these rules are unscoped. */
.cm-mk { cursor: pointer; will-change: transform; }
/* R3-FIX1 F8 — `position: relative` (NOT static) so the design's absolutely
   positioned marker details (.cm-spot__del / __ftag / __pendtag / .citymap__notelbl
   / .citymap__notecount) anchor to the marker, matching the prototype where
   `.cm-spot` is position:absolute. Transform stays `none` (maplibre owns the
   wrapper transform — trap-safe). */
.cm-mk .cm-spot { position: relative; transform: none; left: auto; top: auto; }
.cm-mk .cm-spot:active { transform: scale(.92); }
.cm-mk--dim { filter: opacity(.32); }
.cm-mk__noteic { display: grid; place-items: center; }
.cm-mk__note .cm-mk__noteic i { font-size: 30px; color: var(--coral); line-height: 1;
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.32)); }

/* R3-FIX1 F4 — honest inline hint when a real comment write fails (no alert()). */
.cm-senderr { display: flex; align-items: center; gap: 6px; margin: 2px 4px 4px;
  font: 600 12px/1.35 var(--font-body), system-ui; color: var(--coral); }

/* R3-FIX1 F6b — honest empty state for a city with no published guides. */
.cm-guides__empty { display: flex; align-items: center; gap: 7px; padding: 12px 12px 14px;
  font: 500 12.5px/1.4 var(--font-body), system-ui; color: var(--text-2); }
.cm-guides__empty i { color: var(--text-3); }

/* R3-FIX1 F10 — TripDetail booking status: the Desktop side-copy
   `.td-bkstatus--side` is design-intended desktop-only, but the mirror's mobile
   rule (additions.css:1118, specificity 0,1,0) loses to `.td-bkrow .td-bkstatus`
   (app.css, 0,2,0), so it leaked onto mobile and overlapped the pills / clipped
   the hotel name. Hide it on the mobile shell only (desktop `.ymd` keeps it). */
.ym .td-bkrow .td-bkstatus--side { display: none !important; }

/* R3-FIX2 minor — desktop CityMap Layers/modal close-X sat UNDER the TopBar's
   overhanging free-user chrome (quota-pill / ymd-drophint / crown, z-index 55 >
   the modal's 47), so a click at the X centre hit `ti-crown` and did nothing
   (scrim-close still worked). The overhang only appears for a FREE user — the
   prototype defaulted to plan:'premium', so this collision never showed there.
   Lift the desktop CityMap modal (and its scrim) above the overhang. */
.ymd .cm-modal { z-index: 60; }
.ymd .cm-modal__scrim { z-index: 59; }

/* R3-FIX4 B1 — Scroll-Falle on the first-run golden path. The .ym shell root (and
   the full-bleed .citymap surface) paint off-canvas mock-map layers — the .map
   gradient's ::before (inset:-20% road grid, rotate(-4deg)) and its rotated
   ::after water band — that overflow the 390-wide viewport (probe: scrollWidth
   509 × scrollHeight 1030 at 390×844). With app.css's `overflow:hidden` the box
   stays a SCROLL CONTAINER, so the browser's native focus / scrollIntoView
   handoff (About-you onboarding step, and CityMap edit / SpotSheet / share-toggle)
   programmatically scrolled the WHOLE React UI layer off-canvas (probe: .ym
   scrollLeft 54 / scrollTop 186) while the real MapLibre basemap behind #root
   stayed put — the sheet landed at x=-54/y=-85, content clipped. `overflow:clip`
   keeps the identical visual clipping but makes the box a NON-scroll-container, so
   scrollLeft/scrollTop can no longer be moved. `.ym` carries no transform, so its
   position:fixed descendants (GlobalParsePill, the R3-FIX4 B2 members-popover
   portal) still resolve against the viewport and are NOT clipped by this. Belt:
   boot.js also pins the shell scroll back to 0 (defence on engines that still
   honour a programmatic scroll on a clipped box). Adapter CSS, not a mirror edit. */
/* R3-FIX6 minor — .cvx (the City-overview surface) is the same box constellation
   as the B1 trap: a fixed surface over the basemap with an oversized mock-map
   child (probe: scrollHeight 1030 > clientHeight 844 at 390×844). No misbehaviour
   was observed, but fold it into the same non-scroll-container safeguard so a
   stray focus/scrollIntoView can never scroll it off-canvas. Optically identical. */
.ym, .ym .citymap, .ym .cvx { overflow: clip !important; }

/* ── R5-W1 Task 4 — Layers FAB into the clean top-right corner ────────────────
   Desktop CityMap hides the Add + Share FABs (they live in the TopBar) and, in
   desktop.css:268, parked the lone remaining Layers FAB at the BOTTOM-right
   ("above the Surfaces button"). But that dev Surfaces launcher (.ymd-launch) was
   removed in the R3-0 shell patch, so the button floats in the mid/bottom-right
   void with nothing around it (Kaio: "der Layers-Button sitzt im Nirgendwo, mittig
   rechts").
   Restore the shell's own top-right convention: the generic `.ymd .citymap__ctl`
   rule (desktop.css:207) already says `top/right: var(--edge)` — the citymap-only
   rule at :268 is the one that pushed it to the bottom. `.citymap` is the offset
   parent and ALREADY starts below the TopBar (`.ymd .citymap { top: var(--top-h) }`,
   desktop.css:144), so `--edge` alone lands the FAB in the panel's top-right corner
   (≈84px viewport-y) — clear of the TopBar chrome (profile pfp) and the centered
   quota-pill. (Adding --top-h here would double-count the bar and leave it adrift
   ~150px down — still "im Nirgendwo".) overrides.css loads AFTER desktop.css, so
   this wins. Mobile already stacks it tidily in the top-right (Add · Share ·
   Layers) — left unchanged. */
.ymd[data-panel="citymap"] .citymap__ctl {
  top: var(--edge);
  bottom: auto;
  right: var(--edge);
}

/* R5-W1 Task 3 (Kaio) — sent-state: the emailed address sits IN the sentence, not
   as a heavy standalone <b>. Kaio's ask was explicit: "NICHT gross/fett — normale,
   feinere Typo im Satz". So the address carries NO extra weight at all (it inherits
   the lead's 400); it is set apart only by the primary ink against the lead's muted
   tone — enough to check the address at a glance, nothing that reads as bold. */
.ym .signin-lead .signin-sent__addr { font-weight: 400; color: var(--text-1); }

/* R3-FIX4 (feinschliff) — the paste-sheet attach menu (.paste-attachmenu) drops
   DOWN from the attach button and overflows ~42px past the viewport at 390×844,
   clipping its "Uploads are a Premium feature" footer. NOT patched here: the menu
   is position:absolute inside the .sheet (overflow:hidden), so flipping it upward
   is worse — it gets clipped against the sheet top (verified). It needs an upstream
   max-height/anchor fix in the Claude-Design prototype (the finding flagged it as a
   possible design-truth to verify against the prototype first). Left as documented. */

/* ══════════════════════════════════════════════════════════════════════════════
   R6-W4 — layout, pointer-events, desktop chrome  (Kaio review round 6)
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── P4 / P5 — the desktop map-surface cards CENTRE vertically ─────────────────
   Kaio: "centered, growing up and down, then scrollable."
   desktop.css:147-151 pins .cv-sheet / .cm-panel / .spot-sheet to top:--edge AND
   bottom:--edge with `height: calc(100% - --edge*2) !important` — a full-height
   column. A short city (3 spots) therefore drew a 500px slab of dead white space
   below the last card, and the same for the spot detail.
   Centre them instead and let the box hug its content until it hits the viewport
   limit, at which point the inner scroll container takes over:
     • top:50% / bottom:auto / translateY(-50%)  → the card grows up AND down
     • height:auto !important                    → beats BOTH the shared !important
       rule above and citymap.jsx:207's inline `style={{height: h*100+"%"}}` on
       .cm-panel (an inline declaration loses to an author `!important`)
     • max-height: calc(100% - --edge*2)         → never taller than the surface
   Offset parent = .cvx / .citymap / .spotx, which already start at --top-h
   (desktop.css:144), so 50% is the centre of the map area, not of the viewport.
   TRANSFORM TRAP (re-verified, this repo has been bitten by it): the only `rise`
   animation in play sits on the PARENT surfaces (.cvx/.citymap/.spotx, citymap.css:8)
   — `@keyframes rise { from { transform: translateY(26px); opacity:.4 } }`,
   app.css:192 — with NO fill-mode and NO `to { transform: none }`. It never lands
   on .cv-sheet / .cm-panel / .spot-sheet, which carry no animation of their own,
   so nothing overwrites the translateY(-50%) centering. Safe. */
.ymd .cv-sheet,
.ymd .cm-panel,
.ymd .spot-sheet {
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
  height: auto !important;
  max-height: calc(100% - var(--edge) * 2);
}
/* The inner scroll containers are `flex: 1` in the mirror (citymap.css:50/337/459)
   — flex-basis 0 + grow. In a column flex box of height:auto there is no free
   space to grow INTO and a 0 basis contributes 0 to the intrinsic height, so the
   list would collapse to nothing. `flex: 0 1 auto` = size to content, shrink only
   when the card hits its max-height; each already has `overflow-y: auto`, which
   also resolves their `min-height: auto` to 0 so they really can shrink and scroll. */
.ymd .cv-sheet__body,
.ymd .cm-list,
.ymd .spot-sheet__body { flex: 0 1 auto; }

/* Desktop renders POI detail as a fixed right-side card, not a draggable mobile
   sheet. Hide the inert grab affordance (and therefore its grab cursor) there;
   the functional mobile handle remains untouched. */
.ymd .spot-sheet__grab { display: none; }

/* ── M1 — the Layers popover hangs under the Layers FAB ────────────────────────
   `.cm-modal` (citymap.css:365) is a bare `left:14px; right:14px` box with no
   `top`, and desktop.css:215 centres it horizontally for every modal. `.cm-layers`
   never got a `top` of its own (unlike .cm-pinspot 24% / .cm-sharesheet 26%), so
   it landed at its static position — a wide card floating right under the top nav,
   nowhere near the FAB that opened it. Anchor it to the FAB instead: same right
   edge, one FAB-height (46px, citymap.css:176) + 10px below it, and narrow enough
   to read as a popover rather than a dialog.
   Deliberately scoped to `.cm-modal.cm-layers` (0,3,0) — the generic `.ymd .cm-modal`
   (0,2,0) stays untouched, so the Share and Add-a-spot modals keep their centering.
   `transform: none` also cancels desktop.css's translateX(-50%); the mirror's
   `animation: rise` on .cm-modal has no fill-mode and its implicit to-keyframe is
   the cascaded value, so it settles on `none` — no transform trap. */
.ymd .cm-modal.cm-layers {
  left: auto;
  right: var(--edge);
  top: calc(var(--edge) + 56px);
  transform: none;
  width: 360px;
}

/* ── H1 — the Note button hugs the search bar ─────────────────────────────────
   The top bar is a flex row: brand · nav · .ymd-search · .ymd-notebtn · right group.
   THREE auto margins competed for the free space — desktop.css:65
   `.ymd-search { margin: 0 auto }` (two) and `.ymd-top__right { margin-left: auto }`
   (one) — so a third of the slack was injected BETWEEN the search and the Note
   button, stranding it mid-bar (Kaio: it should sit right next to the search).
   Fix without un-centering the search: collapse the search's RIGHT auto margin and
   the right group's LEFT auto margin to zero, and move the single remaining right
   auto onto the Note button. Free space then splits over exactly two autos — one
   before the search, one after the Note button — so search+Note travel as one
   block, separated only by the bar's own 18px gap, and the block still floats
   between the two side groups (measured: search centre lands within ~25px of the
   viewport centre at both 1440 and 1920 — visually centred).
   `:has(.ymd-notebtn)` keeps this to the CityMap panel; every other surface (no
   Note button) keeps the mirror's original three-auto behaviour untouched.
   The search keeps `flex: 1 1 auto` + `max-width: 620px`: flexible lengths resolve
   BEFORE auto margins, so it still grows to its full 620px first. */
.ymd .ymd-top:has(.ymd-notebtn) .ymd-search { margin-right: 0; }
.ymd .ymd-top:has(.ymd-notebtn) .ymd-notebtn { margin-right: auto; }
.ymd .ymd-top:has(.ymd-notebtn) .ymd-top__right { margin-left: 0; }

/* ── Mo3 (CSS half) — mobile: the map behind an open place stays visible + tappable
   `.spotx` paints an opaque `background: var(--bg)` (citymap.css:7) and — via the
   mobile pass-through at :57 above — was `pointer-events: auto`, so an open place
   sealed the map off completely: nothing to see, nothing to tap. Make the backdrop
   a transparent pass-through like the other surfaces, so the REAL basemap shows
   through and receives the tap (Wave 3 wires that tap to dismiss the sheet), while
   `.spot-sheet` and every other floating child of `.spotx` stay interactive.
   `.spotx__map` is the mock map layer — it stays inert, the real map is behind #root.
   Specificity 0,3,0 == the :57 rule, and this comes later, so it wins on the mobile
   shell; the desktop shell is excluded by :not(.ymd) and keeps the P3 contract. */
.ym:not(.ymd) .spotx { background: transparent; pointer-events: none; }
.ym:not(.ymd) .spotx > *:not(.spotx__map) { pointer-events: auto; }

/* ── Mo1 (.botnav half) — the blue band under the bottom nav ───────────────────
   app.css:89 pins `.botnav { bottom: 12px }`. On a notched iPhone the home-indicator
   inset sits UNDER that, so the map (which fills to the bottom of the viewport) drew
   a strip of blue water between the nav and the indicator. Lift the nav clear of the
   safe area; `max()` keeps the design's 12px on every device that has no inset.
   (The other half of Mo1 — the map filling the notch + the viewport-height math —
   is Wave 5's app.html work and is NOT touched here.) */
.ym .botnav { bottom: max(12px, calc(env(safe-area-inset-bottom, 0px) + 6px)); }

/* ── Mo5b — iOS must not zoom the page when an input is focused ────────────────
   Kaio: "it shouldn't zoom in if I press into the text field. It always zooms in."
   Mobile Safari auto-zooms on focus whenever the field's computed font-size is
   < 16px, and the design's fields sit at 13–15px. Raise every text-entry field to
   16px on coarse-pointer devices only, so the desktop/pointer typography is
   untouched. `!important` is required: most fields set their size through a `font:`
   shorthand on a 2-class selector (e.g. `.spot-cmt__add input`, 0,2,1), which would
   otherwise outweigh this guard (0,1,1).
   Deliberately NOT solved with `maximum-scale=1` in the viewport meta — that kills
   pinch-zoom for everyone and is an accessibility regression. */
@media (pointer: coarse) {
  .ym input,
  .ym textarea,
  .ym select { font-size: 16px !important; }
}

/* ── R6-W2 C1e — the REAL basemap behind the city overview ───────────────────
   Kaio's C1 makes the city OVERVIEW the landing surface of every globe-dot tap, so
   the mirror's hardcoded fake map (city.jsx: "LUXEMBOURG / AUSTRIA / SWITZERLAND /
   Geneva / Zürich" + two fake pins) now sits behind EVERY city — Swiss labels under
   a city called Dakar. Fixed WITHOUT touching the mirrored city.jsx (a design-sync
   would clobber a JSX edit; this file survives):

   (a) `.cvx` paints an opaque `background: var(--bg)` (citymap.css:6-9) that hid the
       real MapLibre singleton living behind #root — the same blocker `.citymap`
       already has an override for above. Make it transparent, so the REAL basemap
       shows through the top strip / the area right of the desktop sidebar. The
       camera is flown to the city by ui/adapters/city-adapter.js (focusCamera), so
       what's behind the card is that actual city, not a decorative fill.
   (b) The fake region labels go. (The mock `.pin`s already die on the existing
       `.ym .map > .pin` rule — `.cvx__map` carries the `.map` class too, which is
       also what makes its gradient fill transparent.)
   Pointer-events are deliberately NOT opened up here: the overview is a reading
   surface (card + "Back to globe"), the map behind it is a backdrop, and the
   `:has(.map)` pass-through cascade above is load-bearing enough as it is. */
.ym .cvx { background: transparent !important; }
.ym .cvx__map .cvx__label { display: none !important; }

/* R6-W2 C1b — "Go Deeper" is now the ONLY route into My Map (a globe dot lands on
   the overview, not on the map), so it has to READ as the primary action. The
   mirror gives it and the secondary "Add to" the identical neutral surface+border
   treatment, which made the one thing the user must press indistinguishable from
   the one they may. Promote it to the app's established filled-primary pattern
   (coral fill + white ink, exactly like .cm-seg button.on / .cv-fromchip.on /
   .cm-fab.coral); "Add to" keeps the outline treatment and becomes the clear
   secondary. Tokens only — no new colours. */
.ym .cv-deeper {
  background: var(--coral);
  border-color: var(--coral);
  color: #fff;
  box-shadow: var(--shadow-md);
}

/* ══════════════════════════════════════════════════════════════════════════════
   R7 — Trips & Maps fixes (Kaio Testrunde 5)
   ══════════════════════════════════════════════════════════════════════════════ */

/* T1 — the DATES / "Set dates" card becomes a real <button> that opens Trip setup
   (tripdetail.jsx Hub). Strip the UA button chrome so it reads exactly like the old
   <span> it replaces (the .td-hero__cd class keeps the flex layout + coral fill),
   and add the pointer that ui/app.css:644 never had. */
.ym .td-hero__cd--btn {
  cursor: pointer;
  border: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: inherit;
  -webkit-appearance: none;
          appearance: none;
  transition: background .15s ease, transform .1s ease;
}
.ym .td-hero__cd--btn:hover { background: color-mix(in srgb, var(--coral) 15%, var(--surface)); }
.ym .td-hero__cd--btn:active { transform: scale(.98); }

/* T3 — honest empty state inside the Transport FROM/TO city picker when a real trip
   has zero cities (instead of silently showing the demo city list). */
.ym .td-cityempty { display: flex; flex-direction: column; gap: 8px; padding: 12px 12px 10px; }
.ym .td-cityempty > span { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-2); font-weight: 600; }
.ym .td-cityempty__cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 12px; border-radius: 10px; border: 1px solid var(--coral);
  background: var(--coral); color: #fff; font-weight: 700; font-size: 12.5px; cursor: pointer;
}

/* TS4 — the trip-setup "Searching…" spinner never spun: a spinner in this app is a
   keyframe PLUS an animation rule on the icon, and only the keyframe existed for
   this one. Scope strictly to the loader glyph so the "no city found" pin that
   shares .trip-addres__fl does not spin. (pwspin: ui/additions.css:123.) */
.ym .trip-addres__fl i.ti-loader-2 { animation: pwspin 1s linear infinite; }

/* Every visible loading glyph must actually communicate progress. Several
   surfaces (notably "Loading your trips…") rendered the icon without the only
   scoped animation rule above. */
.ym i.ti-loader-2 { animation: pwspin 1s linear infinite; }

/* T4/T5 — Places & Timeline empty states get a real call-to-action button, and a
   loading skeleton (reusing the .td-ghost rows from the browsing placeholder) so a
   still-fetching trip never flashes an empty void. */
.ym .td-empty__cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 12px; padding: 9px 14px; border-radius: 11px; border: 0;
  background: var(--coral); color: #fff; font-weight: 700; font-size: 13px; cursor: pointer;
  transition: transform .1s ease, filter .15s ease;
}
.ym .td-empty__cta:hover { filter: brightness(1.05); }
.ym .td-empty__cta:active { transform: scale(.98); }
.ym .td-skel { display: flex; flex-direction: column; gap: 12px; padding: 14px 2px; }
.ym .td-skel .td-ghost { animation: pwpulse 1.4s ease-in-out infinite; }
@keyframes pwpulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

/* TN1/TN2 — inline edit + author/moderation delete on shared-notes comments. The
   op buttons sit at the end of the .td-cmt flex row and only appear for the author
   (edit + delete) or an owner/editor (moderation delete). */
.ym .td-cmt__ops { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; align-self: flex-start; }
.ym .td-cmt__op {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border: 0; border-radius: 8px; background: transparent;
  color: var(--text-3); cursor: pointer; font-size: 14px;
  transition: background .12s ease, color .12s ease;
}
.ym .td-cmt__op:hover { background: var(--surface-2, rgba(0,0,0,.05)); color: var(--text-1); }
.ym .td-cmt__op--del:hover { background: color-mix(in srgb, #e5484d 14%, transparent); color: #e5484d; }
.ym .td-cmt__edit { display: flex; align-items: center; gap: 4px; margin-top: 2px; }
.ym .td-cmt__edit input {
  flex: 1; min-width: 0; padding: 5px 8px; border-radius: 8px;
  border: 1px solid var(--border, rgba(0,0,0,.12)); background: var(--surface); color: inherit; font: inherit; font-size: 13px;
}
.ym .td-cmt__ebtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border: 0; border-radius: 8px; background: var(--surface-2, rgba(0,0,0,.05));
  color: var(--text-2); cursor: pointer; font-size: 14px;
}
.ym .td-cmt__ebtn:hover { color: var(--text-1); }

/* TP3 — pending trip/map invitations in the Trips & maps switcher: a small card
   with Accept / Decline the invitee acts on before becoming a member. */
.ym .tripsw__invites { margin-bottom: 8px; }
.ym .tripinv {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 14px; margin-bottom: 8px;
  border: 1px solid color-mix(in srgb, var(--coral) 35%, var(--border, rgba(0,0,0,.1)));
  background: color-mix(in srgb, var(--coral) 6%, var(--surface));
}
.ym .tripinv__ico { font-size: 22px; line-height: 1; }
.ym .tripinv__tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ym .tripinv__tx b { font-size: 14px; font-weight: 700; }
.ym .tripinv__tx span { font-size: 12px; color: var(--text-2); }
.ym .tripinv__acts { display: inline-flex; gap: 6px; flex-shrink: 0; }
.ym .tripinv__btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 7px 11px; border-radius: 10px; border: 0; cursor: pointer;
  font-size: 12.5px; font-weight: 700;
}
.ym .tripinv__btn--yes { background: var(--coral); color: #fff; }
.ym .tripinv__btn--no { background: var(--surface-2, rgba(0,0,0,.05)); color: var(--text-2); }
.ym .tripinv__btn--yes:hover { filter: brightness(1.05); }
.ym .tripinv__btn--no:hover { color: var(--text-1); }
.ym .tripsw__invite-err {
  display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
  padding: 10px 12px; border-radius: 12px; font-size: 13px;
  background: rgba(220, 53, 69, .08); color: var(--coral);
}
