trips/mock/styles.css
Greg Pomerantz efde2cc71b maps project: design, survey, mock app, and route-aware planning backend
- DESIGN.md: full design incl. driving-trip requirements (R1-R4),
  stays model, focus mode, mobile, provenance rules
- SURVEY.md: open-source landscape
- mock/: interaction mock (Florence itinerary, focus mode, stays,
  region stops, mobile layout)
- router/: Go module (stdlib-only) with Router interface
  (Valhalla + OSRM backends), stop_cost, optimize_stops, corridor,
  routectl CLI, bench (5 real NE-corridor tasks, 26 checks passing),
  integration tests, and setup-osrm.sh for the self-hosted router
- osm/: NH+MA+CT+NY PBFs (gitignored) + setup artifacts
2026-09-06 00:05:17 -04:00

339 lines
22 KiB
CSS

:root {
--ink: #1f2430; --ink2: #5b6472; --line: #e4e7ec; --bg: #f5f6f8;
--card: #ffffff; --accent: #b5533c; --accent2: #8f3f2d;
--ok: #2e9e5b; --warn: #c98a1b; --err: #c0392b;
--blue: #2f6fd6;
--shadow: 0 1px 3px rgba(20,24,35,.08), 0 8px 24px rgba(20,24,35,.07);
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif; color: var(--ink); background: var(--bg); }
.hidden { display: none !important; }
button { font: inherit; }
#map { position: fixed; inset: 0; z-index: 0; background: #dde3ea; }
.leaflet-container { font: inherit; }
/* ---------------- landing ---------------- */
#landing { position: fixed; inset: 0; z-index: 20; display: flex; align-items: center; justify-content: center;
background: linear-gradient(rgba(20,24,35,.28), rgba(20,24,35,.42)); }
.land-card { width: min(560px, 92vw); background: var(--card); border-radius: 18px; box-shadow: var(--shadow); padding: 34px 36px; }
.land-kicker { font-size: 11px; letter-spacing: .14em; color: var(--accent); font-weight: 700; margin-bottom: 10px; }
.land-card h1 { margin: 0 0 16px; font-size: 26px; font-weight: 700; letter-spacing: -.01em; }
.land-row { display: flex; gap: 8px; }
#dest { flex: 1; padding: 12px 14px; border: 1.5px solid var(--line); border-radius: 10px; font-size: 15px; outline: none; }
#dest:focus { border-color: var(--accent); }
.land-div { display: flex; align-items: center; gap: 12px; color: var(--ink2); font-size: 12px; margin: 18px 0; }
.land-div::before, .land-div::after { content: ""; flex: 1; height: 1px; background: var(--line); }
#dropzone { border: 2px dashed #cfd4dd; border-radius: 14px; padding: 22px 18px; text-align: center; transition: all .15s; }
#dropzone.over { border-color: var(--accent); background: #fbf1ee; transform: scale(1.01); }
.dz-icon { font-size: 30px; margin-bottom: 8px; }
.dz-text { font-size: 13.5px; color: var(--ink2); line-height: 1.5; }
.dz-text b { color: var(--ink); font-size: 14.5px; }
.land-hint { margin-top: 14px; font-size: 12px; color: var(--ink2); text-align: center; }
/* ---------------- buttons ---------------- */
.btn { border: 0; border-radius: 10px; padding: 11px 16px; font-size: 14px; font-weight: 600; cursor: pointer; transition: filter .12s, transform .05s; }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--accent); color: #fff; }
.btn.primary:hover { filter: brightness(1.08); }
.btn.ghost { background: #eef0f4; color: var(--ink); }
.btn.ghost:hover { background: #e4e7ee; }
.btn.small { padding: 8px 12px; font-size: 12.5px; }
/* ---------------- topbar ---------------- */
#topbar { position: fixed; top: 0; left: 0; right: 0; height: 46px; z-index: 15; background: var(--card);
border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; padding: 0 16px; }
.brand { font-weight: 800; letter-spacing: .12em; font-size: 13px; color: var(--accent); }
.crumb { font-size: 13px; font-weight: 600; margin-left: 12px; }
.crumb.sub { color: var(--ink2); font-weight: 500; }
.badge { font-size: 12.5px; background: #fdf3e3; color: #8a6116; border: 1px solid #f0dcae; padding: 5px 10px; border-radius: 999px; cursor: pointer; }
.badge.ok { background: #eaf6ef; color: #1f7a45; border-color: #c9e8d6; }
/* ---------------- app layout ---------------- */
#app { position: fixed; top: 46px; left: 0; right: 0; bottom: 0; z-index: 10; display: grid;
grid-template-columns: 350px 1fr 390px; pointer-events: none; } /* center column: let events reach the map */
#rail, #chat { min-height: 0; pointer-events: auto; }
#rail { background: var(--card); border-right: 1px solid var(--line); display: flex; flex-direction: column; overflow: hidden; }
#rail-body, #chat-body { min-height: 0; }
#rail-body { flex: 1; overflow-y: auto; padding: 10px 12px 4px; }
#rail-foot { border-top: 1px solid var(--line); padding: 10px 14px 12px; background: #fbfcfd; }
#mapwrap { position: relative; pointer-events: none; } /* let wheel/drag reach the Leaflet map underneath */
#chat { background: var(--card); border-left: 1px solid var(--line); display: flex; flex-direction: column; }
#chat-body { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
#chat-input-row { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--line); }
#chat-input { flex: 1; border: 1.5px solid var(--line); border-radius: 10px; padding: 10px 12px; font-size: 13.5px; outline: none; }
#chat-input:focus { border-color: var(--accent); }
/* ---------------- rail: transit / stops / legs ---------------- */
.transit-chip { display: flex; align-items: center; gap: 8px; background: #f2f5fa; border: 1px solid #dfe6f2;
border-radius: 10px; padding: 8px 10px; margin: 4px 12px; font-size: 12.5px; }
.transit-chip .tt { font-weight: 700; }
.transit-chip .ts { color: var(--ink2); }
.stop-card { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; margin: 6px 0; background: var(--card);
box-shadow: 0 1px 2px rgba(20,24,35,.05); transition: box-shadow .2s, border-color .2s; position: relative; }
.stop-card.flash { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(181,83,60,.15); }
.stop-card.dragging { opacity: .45; }
.stop-card.optional { border: 1.5px dashed #cfae5f; background: #fffdf6; }
.grip { cursor: grab; color: #c3c9d4; font-size: 14px; margin-right: 2px; user-select: none; letter-spacing: -2px; }
.grip:active { cursor: grabbing; }
.sc-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.sc-name { font-weight: 700; font-size: 13.5px; }
.sc-times { font-size: 12px; color: var(--ink2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sc-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; align-items: center; }
.sc-sub { font-size: 11.5px; color: var(--ink2); margin-top: 5px; }
.sc-sub a { color: var(--blue); text-decoration: none; }
.sc-move { position: absolute; right: 8px; bottom: 8px; display: flex; gap: 4px; opacity: .25; }
.stop-card:hover .sc-move { opacity: 1; }
.sc-move button { border: 1px solid var(--line); background: #fff; border-radius: 6px; width: 22px; height: 20px; cursor: pointer; font-size: 10px; color: var(--ink2); }
.sc-move button:hover { background: #eef0f4; }
.leg-row { display: flex; align-items: center; gap: 8px; margin: 2px 0 2px 22px; padding: 3px 8px; cursor: pointer;
border-radius: 8px; font-size: 12px; color: var(--ink2); width: fit-content; }
.leg-row:hover { background: #eef0f4; }
.leg-ico { font-size: 13px; }
.leg-sub { font-size: 11px; color: var(--ink2); opacity: .8; }
/* ---------------- time/number chips (confidence hierarchy) ---------- */
.tc { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600;
padding: 2.5px 8px; border-radius: 999px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.t-user { background: var(--ink); color: #fff; }
.t-user::before { content: "📌"; font-size: 9px; }
.t-sched { background: #274b8f; color: #fff; }
.t-sched::before { content: "🎫"; font-size: 9px; }
.t-computed { background: #e7ebf2; color: var(--ink); }
.t-search { background: #e8f1fd; color: #1d4f9c; }
.t-search::before { content: "~"; font-weight: 800; }
.t-llm { background: transparent; border: 1.5px dashed #b9c0cc; color: var(--ink2); }
.t-llm::after { content: "est"; font-size: 9px; opacity: .8; }
.t-maybe { background: #fdf3e3; color: #8a6116; border: 1px dashed #d9b96a; }
.pchip { font-size: 11.5px; color: var(--ink2); font-weight: 600; }
.sug-note { font-size: 11px; color: var(--ink2); font-style: italic; }
/* ---------------- budget / issues / legend ---------------- */
.budget-label { font-size: 11.5px; color: var(--ink2); margin-bottom: 5px; }
.budget-bar { height: 7px; background: #e7ebf2; border-radius: 99px; overflow: hidden; }
#budget-fill { height: 100%; width: 0; background: var(--ok); border-radius: 99px; transition: width .5s ease, background .3s; }
#budget-fill.warn { background: var(--warn); }
#issues-panel { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.issue { border: 1px solid #f0dcae; background: #fdf6e8; border-radius: 10px; padding: 8px 10px; font-size: 12px; line-height: 1.45; }
.issue .it { font-weight: 700; color: #8a6116; }
.issue .fix { margin-top: 6px; }
.issue.fixed { border-color: #c9e8d6; background: #eef8f2; opacity: .75; }
.issue.fixed .it { color: #1f7a45; }
.legend { display: flex; flex-wrap: wrap; gap: 5px 10px; margin-top: 10px; font-size: 10.5px; color: var(--ink2); align-items: center; }
.legend .tc { font-size: 10px; padding: 1px 6px; }
/* ---------------- chat ---------------- */
.msg { max-width: 94%; border-radius: 14px; padding: 10px 13px; font-size: 13.5px; line-height: 1.5; animation: pop .18s ease; }
@keyframes pop { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.msg.user { align-self: flex-end; background: var(--accent); color: #fff; border-bottom-right-radius: 4px; }
.msg.ai { align-self: flex-start; background: #eef0f4; border-bottom-left-radius: 4px; }
.msg .src { display: block; font-size: 11px; color: var(--ink2); margin-top: 6px; }
.msg .src a { color: var(--blue); text-decoration: none; }
.typing { display: inline-flex; gap: 4px; padding: 12px 14px; }
.typing i { width: 6px; height: 6px; border-radius: 50%; background: #9aa3b2; animation: blink 1.2s infinite; }
.typing i:nth-child(2) { animation-delay: .2s; } .typing i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 70%, 100% { opacity: .3; } 35% { opacity: 1; } }
.chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 8px; }
.chip { border: 1.5px solid var(--line); background: #fff; border-radius: 999px; padding: 7px 13px; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: all .12s; }
.chip:hover { border-color: var(--accent); color: var(--accent); }
.chip.sel { background: var(--accent); border-color: var(--accent); color: #fff; }
.cards { display: flex; flex-direction: column; gap: 9px; margin-top: 10px; }
.scard { border: 1px solid var(--line); border-radius: 13px; overflow: hidden; background: #fff; box-shadow: var(--shadow); }
.scard-img { height: 96px; display: flex; align-items: center; justify-content: center; position: relative; }
.scard-img .skel { position: absolute; inset: 0; background: linear-gradient(100deg,#eceef2 40%,#f6f7fa 50%,#eceef2 60%); background-size: 200% 100%; animation: shimmer 1.2s infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }
.scard-img .ph { font-size: 44px; opacity: 0; transition: opacity .5s; }
.scard-img.done .ph { opacity: 1; }
.scard-img .attr { position: absolute; right: 6px; bottom: 4px; font-size: 9px; color: rgba(255,255,255,.85); text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.scard-body { padding: 10px 12px; }
.scard-name { font-weight: 700; font-size: 13.5px; }
.scard-pitch { font-size: 12.5px; color: var(--ink2); margin: 4px 0 7px; line-height: 1.45; }
.scard-enrich { font-size: 11.5px; color: var(--blue); margin-top: 6px; opacity: 0; transition: opacity .6s; }
.scard-enrich.show { opacity: 1; }
.scard-enrich a { text-decoration: none; }
.scard-foot { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.scard-foot .sp { margin-left: auto; }
.scard { transition: opacity .4s; cursor: pointer; }
.scard.added { opacity: .55; }
.scard.maybe-card { opacity: .7; }
.scard.dropped { opacity: .3; cursor: default; }
.scard-name a { color: var(--ink); text-decoration: none; }
.scard-name a:hover { color: var(--accent); text-decoration: underline; }
.scard-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .6s; }
.scard-img.done img { opacity: 1; }
/* detail sheet */
.modal-card.wide { width: min(600px, 94vw); max-height: 86vh; overflow-y: auto; position: relative; padding: 0; }
.d-img { height: 150px; display: flex; align-items: center; justify-content: center; position: relative; }
.d-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.d-emoji { font-size: 56px; }
.d-actions { display: flex; gap: 8px; margin-top: 18px; }
.d-attr { position: absolute; right: 10px; bottom: 8px; font-size: 10px; color: rgba(255,255,255,.85); text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.d-body { padding: 18px 22px 20px; }
.d-title { display: flex; align-items: baseline; gap: 10px; }
.d-title a { font-size: 19px; font-weight: 700; color: var(--ink); text-decoration: none; }
.d-title a:hover { color: var(--accent); text-decoration: underline; }
.d-kind { font-size: 11px; color: var(--ink2); border: 1px solid var(--line); padding: 2px 8px; border-radius: 99px; }
.d-facts { display: flex; flex-wrap: wrap; gap: 7px; margin: 10px 0 12px; align-items: center; }
.d-summary { font-size: 13.5px; line-height: 1.6; color: var(--ink); }
.d-links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.d-link { border: 1.5px solid var(--line); background: #fff; border-radius: 999px; padding: 7px 13px; font-size: 12.5px; font-weight: 600; color: var(--ink); text-decoration: none; transition: all .12s; }
.d-link:hover { border-color: var(--accent); color: var(--accent); }
.d-close { position: absolute; top: 10px; right: 12px; border: 0; background: rgba(255,255,255,.85); width: 28px; height: 28px; border-radius: 50%; cursor: pointer; font-size: 12px; color: var(--ink); z-index: 2; }
.d-close:hover { background: #fff; }
.pulse { animation: pulse .8s ease; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(181,83,60,.4); } 100% { box-shadow: 0 0 0 12px rgba(181,83,60,0); } }
/* ---------------- L3 editor ---------------- */
#l3-editor { position: absolute; left: 14px; bottom: 18px; z-index: 12; background: var(--card); border-radius: 14px;
box-shadow: var(--shadow); padding: 12px 14px; width: 300px; pointer-events: auto; }
.l3-title { font-weight: 700; font-size: 13.5px; }
.l3-hint { font-size: 11.5px; color: var(--ink2); margin: 5px 0 8px; line-height: 1.4; }
.l3-time { font-size: 12.5px; color: var(--ink2); display: flex; gap: 8px; align-items: center; }
#l3-close { float: right; margin-top: -4px; }
/* ---------------- modal ---------------- */
.modal { position: fixed; inset: 0; z-index: 40; background: rgba(20,24,35,.45); display: flex; align-items: center; justify-content: center; }
.modal-card { width: min(480px, 92vw); background: var(--card); border-radius: 16px; box-shadow: var(--shadow); padding: 24px 26px; }
.modal-card h2 { margin: 0 0 14px; font-size: 18px; }
#parse-table { width: 100%; border-collapse: collapse; font-size: 13px; }
#parse-table td { padding: 7px 4px; border-bottom: 1px solid var(--line); vertical-align: top; }
#parse-table td:first-child { color: var(--ink2); width: 34%; }
.conf { font-size: 10.5px; padding: 1.5px 7px; border-radius: 99px; font-weight: 700; margin-left: 6px; }
.conf.hi { background: #eaf6ef; color: #1f7a45; }
.conf.mid { background: #fdf3e3; color: #8a6116; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.wp { cursor: grab; }
.leaflet-marker-icon.wp { transition: none; }
/* ---------------- day tabs ---------------- */
.daytabs { display: flex; gap: 6px; margin-left: 14px; align-items: center; }
.daytab { border: 1px solid var(--line); background: #fff; border-radius: 999px; padding: 5px 12px;
font-size: 12px; font-weight: 600; color: var(--ink2); cursor: pointer; transition: all .12s; }
.daytab:hover { border-color: var(--accent); color: var(--accent); }
.daytab.sel { background: var(--ink); border-color: var(--ink); color: #fff; }
.daytab.dep { cursor: default; background: transparent; border-style: dashed; color: var(--ink2); }
.daytab.dep:hover { border-color: var(--line); color: var(--ink2); }
.daytab.over { border-color: var(--accent); background: #fbf1ee; color: var(--accent); }
/* ---------------- stop states ---------------- */
.t-planned { background: #e7ebf2; color: var(--ink); }
.t-maybe { background: #fdf3e3; color: #8a6116; border: 1px dashed #d9b96a; }
.t-alt { background: #eef1f6; color: #4a5a78; border: 1px dashed #9fb0cc; }
.sc-state { cursor: pointer; }
.sc-state:hover { filter: brightness(.94); text-decoration: underline; }
.stop-card.st-maybe { border: 1.5px dashed #cfae5f; background: #fffdf6; }
.stop-card.st-alt { border: 1.5px dashed #9fb0cc; background: #f8fafd; }
.or-row { margin: 2px 0 2px 24px; font-size: 11px; color: var(--ink2); font-style: italic; }
.leg-row.dim { opacity: .55; }
/* state menu popover */
.pop { position: absolute; top: 36px; right: 8px; z-index: 30; background: #fff; border: 1px solid var(--line);
border-radius: 10px; box-shadow: var(--shadow); padding: 4px; display: flex; flex-direction: column; min-width: 170px; }
.pop button { border: 0; background: none; text-align: left; padding: 7px 10px; font-size: 12.5px; border-radius: 7px; cursor: pointer; color: var(--ink); font-weight: 500; }
.pop button:hover { background: #eef0f4; }
.pop button.danger { color: var(--err); }
/* rail item numbers (match the map markers) */
.num { width: 20px; height: 20px; border-radius: 50%; background: var(--ink); color: #fff; font-size: 11px;
font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.stop-card.st-maybe .num { background: #cfae5f; }
.stop-card.st-alt .num { background: #9fb0cc; }
/* hotel / train pins */
.hotel-pin { font-size: 22px; transform: translate(-50%,-90%); transition: transform .15s; }
.hotel-pin.hotel-alt { filter: grayscale(1); opacity: .75; }
/* resolved issues toggle */
.resolved-toggle { border: 0; background: none; color: var(--ink2); font-size: 11.5px; cursor: pointer;
text-decoration: underline; padding: 2px 0; }
.resolved-toggle:hover { color: var(--ink); }
/* ---------------- focus mode (slot search) ---------------- */
#rail.dimmed { opacity: .35; pointer-events: none; }
#focusbar { position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 12;
background: var(--card); border-radius: 999px; box-shadow: var(--shadow); padding: 7px 8px 7px 15px;
display: flex; gap: 12px; align-items: center; font-size: 12.5px; pointer-events: auto; }
#focusbar-title b { color: var(--accent); }
.fb-hint { color: var(--ink2); font-size: 11px; white-space: nowrap; }
.fb-x { border: 0; background: #eef0f4; width: 26px; height: 26px; border-radius: 50%; cursor: pointer;
font-size: 11px; color: var(--ink); flex-shrink: 0; }
.fb-x:hover { background: #e2e5ec; }
/* candidate pins: teardrop + name label, right on the map */
.candwrap { position: relative; }
.cand { position: absolute; left: 0; bottom: 0; width: 26px; height: 26px; background: var(--accent); color: #fff;
border-radius: 50% 50% 50% 0; transform: rotate(-45deg); display: flex; align-items: center; justify-content: center;
border: 2.5px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,.35); transition: transform .12s; cursor: pointer; }
.cand::after { content: ''; width: 7px; height: 7px; background: #fff; border-radius: 50%; }
.candwrap:hover .cand { transform: rotate(-45deg) scale(1.15); }
.cand-lbl { position: absolute; left: 24px; top: 6px; white-space: nowrap; font-size: 11.5px; font-weight: 700;
background: rgba(255,255,255,.94); color: var(--ink); padding: 2px 8px; border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,.3); pointer-events: none; }
/* click-to-open result popup */
.focpop { width: 230px; font-size: 12.5px; }
.fp-name { font-weight: 700; font-size: 14px; margin-bottom: 3px; }
.fp-sub { color: var(--ink2); line-height: 1.4; margin-bottom: 8px; }
.fp-dist { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; margin-bottom: 8px; }
.fp-dist .pchip { margin: 0; }
.fp-facts { display: flex; gap: 7px; align-items: center; margin-bottom: 9px; }
.fp-facts .tc { margin: 0; }
.fp-actions { display: flex; gap: 6px; flex-wrap: wrap; }
/* map markers: current-day numbered vs other-day dots */
.mk { background: #b5533c; color: #fff; width: 26px; height: 26px; border-radius: 50%;
display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px;
border: 2.5px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.4); transition: transform .15s; }
.mkd { background: #fff; color: #8b93a3; border: 2px dashed #9aa3b2; box-shadow: none; }
/* vague / region placeholder stops */
.region-note { font-size: 11px; color: var(--ink2); margin-top: 5px; }
.refine-btn { margin-top: 7px; border: 1px solid var(--line); background: #f5f3ef; color: var(--accent);
border-radius: 999px; font-size: 11.5px; font-weight: 600; padding: 4px 10px; cursor: pointer; }
.refine-btn:hover { background: var(--card2); border-color: var(--accent); }
/* ---------------- mobile: single pane + bottom tab bar ---------------- */
#mobiletabs { display: none; }
@media (max-width: 860px) {
.pane-hidden { display: none !important; }
/* topbar: crumb + badge on row 1, horizontally scrollable day tabs on row 2 */
#topbar { height: auto; flex-wrap: wrap; row-gap: 8px; padding: 9px 12px; }
.tb-left { flex: 1 1 auto; min-width: 0; }
.crumb { font-size: 12.5px; }
.daytabs { margin-left: 0; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
.daytab { flex-shrink: 0; white-space: nowrap; font-size: 11.5px; padding: 5px 10px; }
.badge { font-size: 11.5px; padding: 4px 9px; }
/* one pane at a time: Plan | Map | Chat */
#app { top: 92px; bottom: 58px; grid-template-columns: 1fr; grid-template-rows: 1fr; }
#rail { border-right: 0; }
#chat { border-left: 0; }
#mobiletabs { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
height: 58px; background: var(--card); border-top: 1px solid var(--line); }
#mobiletabs button { flex: 1; border: 0; background: none; font-size: 11px; color: var(--ink2); }
#mobiletabs button.on { color: var(--accent); font-weight: 700; box-shadow: inset 0 2.5px 0 var(--accent); }
#rail-body, #chat-body { padding: 10px; }
.rail-foot { padding: 10px 12px; }
.stop-card { padding: 9px 10px; }
.msg { font-size: 13px; padding: 9px 11px; }
#chat-input-row { padding: 10px; }
.tc { font-size: 11px; }
/* map overlays */
#l3-editor { left: 8px; right: 8px; width: auto; bottom: 10px; }
#focusbar { max-width: 94vw; padding: 6px 6px 6px 12px; gap: 8px; font-size: 11.5px; }
.fb-hint { display: none; }
.cand-lbl { font-size: 10.5px; }
.focpop { width: 200px; }
/* landing + detail modal */
.land-card { padding: 24px 20px; }
.land-card h1 { font-size: 21px; }
.scard-img { height: 80px; }
.modal-card.wide { width: min(560px, 96vw); max-height: 88vh; }
.d-img { height: 120px; }
.d-body { padding: 14px 16px 16px; }
}