/* Built from frontend/src by Vite. Do not edit. source-hash: b584dc46de05d2ceb5607449da3c572cc7d6140b9b7b87a5de59802b595a8fcc */
/* The colours, the page itself and the controls every part shares: buttons and the holders. */

/* Dark mode only - no light theme by design. */
:root {
  color-scheme: dark;
  --bg: #08090b;
  --panel: #0e1013;
  --panel-2: #14171b;
  --line: #23262c;
  --line-soft: #191c21;
  --text: #e8e6e3;
  --muted: #9a968f;
  --dim: #635f59;
  --accent: #4ea1ff;
  --accent-dim: #1d3557;
  --good: #4fbf8b;
  --warn: #cfa76a;
  --bad: #d95f5f;
  --remote: #22d68a;
  --hybrid: #37b6ff;
  --onsite: #4d7cff;
  --home: #e05a9a;
  --radius: 10px;
  --shadow: 0 8px 26px rgba(0, 0, 0, 0.45);
}

* { box-sizing: border-box; }

body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.btn {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 550;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.05s;
}
.btn:hover { background: #1c2025; border-color: #333840; }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #04121e; }
.btn.primary:hover { background: #6bb2ff; }
.btn.tiny { padding: 4px 9px; font-size: 11.5px; }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

/* A class rule with display: flex would otherwise outrank [hidden]. */
[hidden] { display: none !important; }

/* The holders the board script draws its parts into take no room of their own. */
.mount { display: contents; }
/* The map beside the job list, the handle between them and how they stack on narrower screens. */

html, body {
  height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.layout { flex: 1 1 auto; display: flex; min-height: 0; }
.mapwrap { position: relative; flex: 1 1 auto; min-width: 0; }

/* The width is the reader's own once they drag the handle beside the list. */
.sidebar {
  flex: 0 0 var(--sidebar-width, 420px);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-left: 1px solid var(--line);
  min-height: 0;
  /* Otherwise a long unbreakable token widens the column past 420px. */
  min-width: 0;
}

.split-handle {
  flex: 0 0 6px;
  margin-right: -6px;
  position: relative;
  z-index: 500;
  cursor: col-resize;
  touch-action: none;
  background: transparent;
}
.split-handle:hover,
.split-handle:focus-visible,
.split-handle.dragging { background: var(--accent); opacity: 0.6; outline: none; }
body.resizing { cursor: col-resize; user-select: none; }

@media (max-width: 1000px) {
  .layout { flex-direction: column; }
  .sidebar { flex: 1 1 auto; border-left: none; border-top: 1px solid var(--line); }
  .split-handle { display: none; }
  .mapwrap { flex: 0 0 45vh; }
}

@media (max-width: 700px) {
  /* The browser bars change the height of a phone screen as it scrolls, and 100% of the
     small viewport leaves the list short. */
  html, body { height: 100dvh; }

  /* A third of the screen for the map, the rest for the jobs. The sidebar takes a basis of
     zero, because with basis auto its own basis is the height of every card it has rendered,
     and the map ends up shrunk to its floor on every phone whatever the screen height. */
  .mapwrap { flex: 0 0 38dvh; min-height: 200px; }
  .sidebar { flex: 1 1 0; min-height: 0; }
}
/* What Leaflet draws: the pins, the home and heart pins, the drive trace and its labels, the switches and popups. */

/* The colour of open water once the filter below has been through it, so a tile that has
   not arrived yet reads as sea rather than as a hole punched in the map. */
/* The map is a layer of its own, so Leaflet's controls at 1000 rank only against the map's
   panes. Left in the page's layer they sat over the Applications panel and the filter
   menus, which stand at 900, and a tap on the List tab reached the layer switch under it. */
#map { position: absolute; inset: 0; z-index: 0; background: #0f1114; }

/* Two fingers zoom the map, so the browser is not to zoom the page under them. */
#map { touch-action: none; }

.home-wrap {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  /* Just the icon, with a dark shadow so it reads on any ground. */
  background: none;
  border: 0;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.85)) drop-shadow(0 0 1px rgba(0, 0, 0, 0.6));
  cursor: grab;
  transition: transform 0.12s ease;
}
.home-wrap:hover { transform: scale(1.08); }
.home-pin { display: block; width: 32px; height: 32px; }

/* While it is being held. */
.home-wrap.unlocked {
  cursor: grabbing;
  animation: homepulse 1.1s ease-in-out infinite;
}
@keyframes homepulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.15); }
}


/* Label sitting on the max-radius ring. */
.radius-label {
  background: rgba(8, 9, 11, 0.94) !important;
  border: 1px solid rgba(224, 90, 154, 0.55) !important;
  color: #f0a3c8 !important;
  font-size: 10.5px !important;
  font-weight: 600;
  letter-spacing: 0.4px;
  padding: 2px 7px !important;
  border-radius: 5px !important;
  box-shadow: none !important;
}
.radius-label::before { display: none !important; }

/* Freeway shields: interstates blue, state routes green, like the real signs, in the same
   dimmed colours as the highway signs on the map. */
.shield {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 750;
  letter-spacing: 0.3px;
  color: #d5dbe3;
  white-space: nowrap;
  border: 1px solid rgba(213, 219, 227, 0.28);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}
.shield.interstate { background: #1d3566; }
.shield.state { background: #1c4630; }
/* Total drive time at the end of the route. */
.route-total {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 6px;
  background: rgba(8, 9, 11, 0.94);
  border: 1.5px solid var(--accent);
  color: var(--text);
  font-size: 12px;
  font-weight: 750;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
}
/* The label is centred on its point on the route line. */
.route-total-icon { text-align: center; }
.route-total small {
  display: block;
  font-size: 9px;
  font-weight: 500;
  color: var(--muted);
  margin-top: -1px;
}
/* The cross on the label's corner that clears the route. The label itself lets clicks through
   to the map, so the cross takes them for itself. */
.route-total { position: relative; }
.route-clear {
  position: absolute;
  top: -9px;
  right: -9px;
  width: 18px;
  height: 18px;
  padding: 0;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  background: rgba(8, 9, 11, 0.96);
  color: var(--text);
  font: 700 13px/1 system-ui, sans-serif;
  cursor: pointer;
  pointer-events: auto;
}
.route-clear:hover { background: var(--accent); }
/* A fingertip needs more than the drawn cross. */
.route-clear::before { content: ""; position: absolute; inset: -8px; }

.shield small {
  font-size: 9px;
  font-weight: 600;
  opacity: 0.85;
  margin-left: 4px;
}

/* Hover label naming the employer at a pin. */
.pin-tip {
  background: rgba(8, 9, 11, 0.96) !important;
  border: 1px solid var(--line) !important;
  color: var(--text) !important;
  font-size: 11.5px !important;
  padding: 5px 9px !important;
  border-radius: 7px !important;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.6) !important;
  white-space: nowrap;
}
.pin-tip b { font-weight: 650; }
.pin-tip .tip-sub { display: block; color: var(--muted); font-size: 10.5px; margin-top: 1px; }
.pin-tip::before { border-top-color: var(--line) !important; }
body.resizing #map { pointer-events: none; }

.pin-count {
  color: #06101c;
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
}
.pin.stacked {
  border-radius: 50%;
  display: grid;
  place-items: center;
}

.heart-wrap {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  /* Just the icon, with a dark shadow so it reads on any ground. */
  background: none;
  border: 0;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.85)) drop-shadow(0 0 1px rgba(0, 0, 0, 0.6));
  cursor: grab;
  transition: transform 0.12s ease;
}
.heart-wrap:hover { transform: scale(1.08); }
.heart-pin { display: block; width: 32px; height: 32px; }

/* While it is being held. */
.heart-wrap.unlocked {
  cursor: grabbing;
  animation: heartpulse 1.1s ease-in-out infinite;
}
@keyframes heartpulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.15); }
}


/* Sized and shaped to match the crime control it sits under. */
.leaflet-bar.heart-toggle a,
.leaflet-touch .heart-toggle a {
  position: relative;
  display: flex !important;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: auto;
  min-width: 42px;
  height: 42px;
  padding: 0 12px 0 10px;
  font-size: 24px;
  line-height: 1;
  text-decoration: none;
  background: var(--panel-2, #16181d);
  color: #ff6b6b;
  transition: background 0.12s ease, box-shadow 0.12s ease;
}
.heart-toggle a:hover { background: #23262d; }
.heart-toggle .toggle-label { color: #ffffff; }

/* On, the switch takes the soft red of a card's Archive button (jobs.css). */
.heart-toggle.on a {
  background: rgba(255, 92, 92, 0.16);
  color: #ff8a8a;
  box-shadow: inset 0 0 0 1px rgba(255, 92, 92, 0.45);
}
.heart-toggle.on .toggle-label { color: #ecc4c4; }
.heart-toggle.on a:hover { background: rgba(255, 92, 92, 0.26); }

.heart-total {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 6px;
  background: rgba(8, 9, 11, 0.94);
  border: 1px solid #ff1a1a;
  color: #ffd2d2;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
}

.leaflet-popup-content-wrapper {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 9px;
  box-shadow: var(--shadow);
}
.leaflet-popup-tip { background: var(--panel-2); border: 1px solid var(--line); }
.leaflet-popup-content { margin: 10px 12px; font-size: 12.5px; }
.leaflet-popup-content b { font-size: 13px; }
.leaflet-container a.leaflet-popup-close-button { color: var(--muted); }
.leaflet-control-zoom a {
  background: var(--panel-2) !important;
  color: var(--text) !important;
  border-color: var(--line) !important;
}
.leaflet-control-attribution {
  background: rgba(13, 17, 26, 0.8) !important;
  color: var(--dim) !important;
}
.leaflet-control-attribution a { color: var(--muted) !important; }
/* The map's credit, kept but small and faint. */
.leaflet-container .leaflet-control-attribution {
  font-size: 8.5px;
  line-height: 1.3;
  padding: 0 4px;
  opacity: 0.55;
}
.leaflet-container .leaflet-control-attribution:hover { opacity: 0.9; }
.leaflet-control-attribution svg { width: 9px !important; height: 6px !important; }
.leaflet-bar a { cursor: pointer; }
/* The zoom buttons, side by side at the top centre of the map (map.ts). */
.leaflet-top.leaflet-centre { left: 50%; transform: translateX(-50%); }
.leaflet-centre .leaflet-control-zoom { display: flex; margin: 10px 0 0; }
.leaflet-centre .leaflet-control-zoom a { border-bottom: 0 !important; }
.leaflet-centre .leaflet-control-zoom a:first-child { border-radius: 4px 0 0 4px; border-right: 1px solid var(--line) !important; }
.leaflet-centre .leaflet-control-zoom a:last-child { border-radius: 0 4px 4px 0; }
/* The recenter button closes the bar: + − and the target that brings the map back home. */
.leaflet-centre .leaflet-control-zoom a.leaflet-control-zoom-out { border-right: 1px solid var(--line) !important; }
.leaflet-centre .leaflet-control-zoom a.leaflet-control-recenter {
  display: grid;
  place-items: center;
  color: #ff7ab8 !important;
}
.leaflet-centre .leaflet-control-zoom a.leaflet-control-recenter:hover { color: #ffb0d5 !important; }

/* Transparent click target around the dot - see pin() in app.js. */
.pin-hit {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
}

.pin {
  border-radius: 50%;
  border: 2px solid #08090b;
  box-shadow: 0 0 0 2px currentColor, 0 0 10px currentColor, 0 2px 6px rgba(0, 0, 0, 0.85);
}

/* The pin the list is narrowed to: a soft yellow halo, as on the narrowed list (jobs.css). */
.pin.pin-spot {
  box-shadow: 0 0 0 2px currentColor, 0 0 0 5px rgba(255, 214, 10, 0.55), 0 0 16px 6px rgba(255, 214, 10, 0.35),
    0 2px 6px rgba(0, 0, 0, 0.85);
  animation: pin-spot-in 0.35s ease-out;
}
@keyframes pin-spot-in {
  from { box-shadow: 0 0 0 2px currentColor, 0 0 0 5px rgba(255, 214, 10, 0), 0 0 16px 6px rgba(255, 214, 10, 0),
    0 2px 6px rgba(0, 0, 0, 0.85); }
}

/* A job picked from the list shows where it is. */
.pin.pin-flash { animation: pinflash 0.6s ease-out 3; }
@keyframes pinflash {
  0%   { box-shadow: 0 0 0 2px currentColor, 0 0 0 4px #ffffff, 0 0 14px 6px currentColor; }
  100% { box-shadow: 0 0 0 2px currentColor, 0 0 0 14px rgba(255, 255, 255, 0), 0 0 10px currentColor; }
}

/* Doubled selectors beat Leaflet's ".leaflet-touch .leaflet-bar a" (30px). */
.leaflet-bar.crime-toggle a,
.leaflet-touch .crime-toggle a {
  position: relative;
  display: flex !important;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: auto;
  min-width: 42px;
  height: 42px;
  padding: 0 12px 0 10px;
  font-size: 24px;
  line-height: 1;
  text-decoration: none;
}

.crime-toggle a {
  background: var(--panel-2, #16181d);
  color: var(--text, #e8eaed);
  transition: background 0.12s ease, box-shadow 0.12s ease;
}
.crime-toggle a:hover { background: #23262d; }

/* On, a toggle takes the soft blue of Open posting (jobs.css) rather than solid blue. */
.crime-toggle.on a {
  background: rgba(78, 161, 255, 0.16);
  box-shadow: inset 0 0 0 1px rgba(78, 161, 255, 0.45);
  color: #cfe0f2;
}
.crime-toggle.on a:hover { background: rgba(78, 161, 255, 0.26); }

.crime-toggle.busy a { cursor: progress; }
.crime-toggle-icon svg,
.heart-toggle-icon svg,
.toggle-icon svg { display: block; width: 22px; height: 22px; }
.crime-toggle.busy .crime-toggle-icon { animation: crime-pulse 0.7s ease-in-out infinite; }

@keyframes crime-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

.route-busy {
  display: none;
  align-items: center;
  gap: 8px;
  background: rgba(18, 21, 27, 0.94);
  border: 1px solid #2b313c;
  border-radius: 999px;
  padding: 6px 13px 6px 11px;
  font-size: 11.5px;
  color: #c9d1da;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  white-space: nowrap;
}
.route-busy.on { display: flex; }

.route-busy-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 2px solid rgba(78, 161, 255, 0.3);
  border-top-color: var(--accent, #4ea1ff);
  animation: route-spin 0.7s linear infinite;
}

@keyframes route-spin {
  to { transform: rotate(360deg); }
}

.leaflet-bar.jobs-toggle a,
.leaflet-bar.housing-toggle a,
.leaflet-touch .jobs-toggle a,
.leaflet-touch .housing-toggle a {
  position: relative;
  display: flex !important;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: auto;
  min-width: 42px;
  height: 42px;
  padding: 0 12px 0 10px;
  font-size: 24px;
  line-height: 1;
  text-decoration: none;
  background: var(--panel-2, #16181d);
  color: var(--text, #e8eaed);
  transition: background 0.12s ease, box-shadow 0.12s ease;
}

/* The word beside each icon. Sized and weighted like the rest of the page rather than the
   glyph, which is set large enough to read as a picture. */
.toggle-label {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* A Leaflet bar is sized to its widest child, so without this the switches sit in a column
   of mismatched widths. */
.leaflet-top.leaflet-left .leaflet-bar { width: max-content; }

.jobs-toggle a:hover,
.housing-toggle a:hover { background: #23262d; }

.jobs-toggle.on a,
.housing-toggle.on a {
  background: rgba(78, 161, 255, 0.16);
  box-shadow: inset 0 0 0 1px rgba(78, 161, 255, 0.45);
  color: #cfe0f2;
}

.jobs-toggle.on a:hover,
.housing-toggle.on a:hover { background: rgba(78, 161, 255, 0.26); }

.housing-toggle.busy a { cursor: progress; }
.housing-toggle.busy .toggle-icon {
  animation: crime-pulse 0.7s ease-in-out infinite;
}

@media (max-width: 700px) {
  /* Pinch does the job, and the buttons were a 30px target besides. */
  .leaflet-control-zoom { display: none; }

  /* Four 42px toggles ran down the left edge of a 230px map. */
  .leaflet-bar a,
  .leaflet-touch .leaflet-bar a {
    width: 34px !important;
    height: 34px !important;
    padding: 0 !important;
    justify-content: center !important;
    font-size: 19px;
  }
  /* A word beside each icon would cover the map on a screen this narrow. */
  .toggle-label { display: none; }

  /* A pin tap opens this over the map and nothing closes it. The same jobs are listed
     below, with more detail than a tooltip carries. */
  .pin-tip { display: none !important; }
}

/* Four arrows round the home and heart pins while the mouse is over them: they can be dragged. */
.home-wrap, .heart-wrap { position: relative; }
.move-arrows {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 66px;
  height: 66px;
  margin: -33px 0 0 -33px;
  fill: #ffffff;
  stroke: rgba(8, 9, 11, 0.85);
  stroke-width: 1.5;
  stroke-linejoin: round;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
@media (hover: hover) {
  .home-wrap:hover .move-arrows,
  .heart-wrap:hover .move-arrows,
  .unlocked .move-arrows { opacity: 1; transform: none; }
}

/* The Value switch under the Housing button, shown only while Housing is on. */
.leaflet-bar.housing-toggle,
.leaflet-bar.crime-toggle { position: relative; overflow: visible; }
/* Crime has Partner's job under it, so while its Heat switch shows, the buttons below make
   room for it. */
.leaflet-bar.crime-toggle { transition: margin-bottom 0.18s ease-out; }
.leaflet-bar.crime-toggle.on { margin-bottom: 50px; }
.heat-switch-holder {
  position: absolute;
  left: 0;
  top: calc(100% + 8px);
  display: none;
}
.housing-toggle.on .heat-switch-holder,
.crime-toggle.on .heat-switch-holder { display: block; animation: heat-switch-in 0.18s ease-out; }
@keyframes heat-switch-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
.heat-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--line, #2b313c);
  background: var(--panel-2, #16181d);
  color: var(--text, #e8eaed);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
}
.heat-switch:hover { background: #23262d; }
.heat-switch:focus-visible { outline: 2px solid var(--accent, #4ea1ff); outline-offset: 1px; }
.heat-switch-track {
  position: relative;
  width: 30px;
  height: 17px;
  border-radius: 999px;
  background: #3a404c;
  transition: background 0.15s ease;
}
.heat-switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #e8eaed;
  transition: transform 0.15s ease;
}
.heat-switch.on .heat-switch-track { background: rgba(78, 161, 255, 0.3); box-shadow: inset 0 0 0 1px rgba(78, 161, 255, 0.55); }
.heat-switch.on .heat-switch-thumb { transform: translateX(13px); background: #cfe0f2; }

/* Rentals gathered into a house mark while zoomed out (homeClusters.ts), filled with the
   group's middle rent on the home-value scale. No bigger than a job pin. */
.home-cluster {
  display: block;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.7));
  cursor: zoom-in;
  transition: transform 0.12s ease;
}
.home-cluster:hover { transform: scale(1.15); }

/* While Crime is on, a mark sits on a soft diamond in the crime colour of the city it stands in
   (crimeHalos.ts). The icon is its own stacking context, so the diamond goes behind its face. */
.leaflet-marker-icon > .crime-diamond {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: -1;
  width: var(--halo-size, 24px);
  aspect-ratio: 1;
  border-radius: 3px;
  background: var(--halo);
  opacity: 0.55;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12);
  transform: translate(-50%, -50%) rotate(45deg);
  pointer-events: none;
}
.leaflet-marker-icon > .crime-diamond.arriving { animation: crime-diamond-in 0.35s ease-out; }
@keyframes crime-diamond-in {
  from { opacity: 0; transform: translate(-50%, -50%) rotate(45deg) scale(0.4); }
}
@media (prefers-reduced-motion: reduce) {
  .leaflet-marker-icon > .crime-diamond.arriving { animation: none; }
}

/* Under the crime key: where the shading is by neighbourhood rather than by city. */
.crime-detail { margin-top: 4px; font-size: 10.5px; color: var(--dim, #8b919a); max-width: 180px; }

/* With the crime heat map off, the city outlines take no hover or click (crime.tsx). */
.crime-inert path.leaflet-interactive { pointer-events: none !important; cursor: inherit; }

/* On a crime diamond a job pin keeps its ring but drops its coloured glow, so the diamond shows. */
.leaflet-marker-icon.crime-halo .pin:not(.pin-flash):not(.pin-spot) {
  box-shadow: 0 0 0 2px currentColor, 0 2px 5px rgba(0, 0, 0, 0.85);
}

/* A clicked pin on a crime diamond: the yellow halo goes round the diamond, outlining it, rather
   than over it, and the pin keeps its plain ring. */
.leaflet-marker-icon.crime-halo .pin.pin-spot {
  box-shadow: 0 0 0 2px currentColor, 0 2px 5px rgba(0, 0, 0, 0.85);
  animation: none;
}
.leaflet-marker-icon.crime-halo:has(.pin.pin-spot) > .crime-diamond {
  opacity: 0.75;
  box-shadow: 0 0 0 2px rgba(255, 214, 10, 0.75), 0 0 14px 4px rgba(255, 214, 10, 0.35);
  transition: box-shadow 0.35s ease-out, opacity 0.35s ease-out;
}

/* With Crime on, a job pin draws in a little and its diamond grows and deepens, so the diamond
   reads around it rather than hiding behind it. */
.leaflet-marker-icon .pin { transition: transform 0.3s ease; }
.leaflet-marker-icon.crime-halo .pin { transform: scale(0.8); }
.leaflet-marker-icon.crime-halo:has(.pin) > .crime-diamond {
  width: min(calc(var(--halo-size, 24px) * 1.3), 34px);
  opacity: 0.72;
}
/* Search, Filters and Score weights above the job list. */

.filters {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line-soft);
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 0 0 auto;
}

.search {
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 8px 11px;
  border-radius: 8px;
  font-size: 13px;
  outline: none;
}
.search:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(78, 161, 255, 0.18); }

.filter-row { display: flex; gap: 14px; flex-wrap: wrap; }
.chk { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); cursor: pointer; }
.chk input { accent-color: var(--accent); width: 14px; height: 14px; cursor: pointer; }

/* A labelled dropdown sized to sit in a filter row. */
.pickone { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--muted); }
.pickone select {
  background: var(--panel-2, #16181d);
  color: var(--text, #e8eaed);
  border: 1px solid var(--line, #2b313c);
  border-radius: 6px;
  padding: 3px 6px;
  font-size: 12.5px;
  cursor: pointer;
}
.pickone select:focus { outline: none; border-color: var(--accent, #4ea1ff); }

/* Match and pay sit on one line, each as a label and a dropdown. */
.pickone-row { display: flex; gap: 12px; }
.pickone-row .pickone { flex: 1 1 0; min-width: 0; }
.pickone-row select { flex: 1 1 auto; min-width: 0; }
.sortrow { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--dim); }

/* Each person's own split of the match number: four rows dragged into order. */
.weights { font-size: 12px; color: var(--muted); }
.weights > summary.weights-open {
  display: inline-flex; align-items: center; gap: 7px;
  list-style: none; cursor: pointer;
  color: var(--muted);
}
.weights[open] > summary.weights-open { border-color: #6b717c; color: var(--text); }
.weights > summary.weights-open::-webkit-details-marker { display: none; }
.weights > summary.weights-open::after {
  content: ""; width: 6px; height: 6px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform 0.12s;
}
.weights[open] > summary.weights-open::after { transform: translateY(1px) rotate(-135deg); }
.weights-rank { list-style: none; margin: 8px 0 0; padding: 0; display: flex;
  flex-direction: column; gap: 4px; }
.weights-rank li {
  display: flex; align-items: center; gap: 10px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 7px 10px 7px 8px;
  color: var(--text);
  cursor: grab;
  user-select: none;
  touch-action: none;
}
.weights-rank li:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.weights-rank li.dragging { cursor: grabbing; opacity: 0.75; border-color: var(--accent);
  position: relative; z-index: 2; }
/* A knurled grip: two columns of three dots. */
.weights-rank .rank-grip {
  flex: 0 0 auto; width: 8px; height: 14px;
  background-image: radial-gradient(circle, var(--dim) 1.2px, transparent 1.4px);
  background-size: 4px 4.67px;
}
.weights-rank li:hover .rank-grip,
.weights-rank li.dragging .rank-grip {
  background-image: radial-gradient(circle, var(--accent) 1.2px, transparent 1.4px);
}
.weights-rank .rank-name { flex: 1 1 auto; }
.weights-rank .rank-switch { height: 22px; flex: 0 0 auto; cursor: pointer; }
.weights-rank li.off .rank-name { color: var(--dim); }
.sortrow select {
  flex: 1;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 6px 8px;
  border-radius: 7px;
  font-size: 12.5px;
  outline: none;
  cursor: pointer;
}

.filters .more { display: block; }
.filters .more-body { display: flex; flex-direction: column; align-items: stretch; gap: 10px;
  margin-top: 10px; }
/* The filters fold away under one button on every screen, closed until it is opened. */
.filters .more-summary {
  display: inline-flex; align-items: center; gap: 7px;
  list-style: none; cursor: pointer; font-size: 11.5px; padding: 4px 10px;
  color: var(--muted);
}
.filters .more-summary::-webkit-details-marker { display: none; }
.filters .more-summary::after {
  content: ""; width: 6px; height: 6px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform 0.12s;
}
.filters .more[open] > .more-summary::after { transform: translateY(1px) rotate(-135deg); }
/* Coloured exactly like Score weights: grey, lighter only while open, on every screen. */
.filters .more-summary.on { border-color: var(--line); color: var(--muted); }
.filters .more[open] > .more-summary { border-color: #6b717c; color: var(--text); }
/* Filters and Score weights sit centred on one line, Score weights just right of Filters; its
   rows open below everything. --filters-w and --weights-w are the two buttons' widths, kept by
   SidebarFilters. */
.fold-row { position: relative; }
.fold-row > .more > .more-summary {
  margin-left: calc(50% - (var(--filters-w, 84px) + 8px + var(--weights-w, 120px)) / 2);
}
.fold-row > .weights > summary.weights-open {
  position: absolute; top: 0;
  left: calc(50% - (var(--filters-w, 84px) + 8px + var(--weights-w, 120px)) / 2 + var(--filters-w, 84px) + 8px);
  font-size: 11.5px; padding: 4px 10px;
}
.fold-row > .weights[open] > .weights-rank { margin-top: 10px; }
/* The question asked once, after the first setup, above the rows it is about. */
/* Asking for priorities after the first setup: a purple marker ring round Score weights. */
.filters .weights.asking > summary.weights-open {
  position: relative;
  border-color: #a078eb;
  color: #e6d6ff;
  box-shadow: 0 0 0 2px rgba(160, 120, 235, 0.55);
  animation: weights-ring 1.6s ease-in-out infinite;
}
@keyframes weights-ring {
  0%, 100% { box-shadow: 0 0 0 2px rgba(160, 120, 235, 0.55), 0 0 0 0 rgba(160, 120, 235, 0.45); }
  50% { box-shadow: 0 0 0 2px rgba(160, 120, 235, 0.8), 0 0 0 7px rgba(160, 120, 235, 0); }
}
@media (prefers-reduced-motion: reduce) { .filters .weights.asking > summary.weights-open { animation: none; } }

/* The shared rent and bedroom limits in the Filters panel. */
.homes-filter-row { align-items: center; gap: 8px 12px; font-size: 12.5px; color: var(--muted); }
.homes-filter-label { color: var(--text); font-weight: 600; }
.homes-filter-row label { display: flex; align-items: center; gap: 6px; }
.homes-filter-row select { width: 72px; cursor: pointer; }
.homes-filter-row input,
.homes-filter-row select {
  width: 72px;
  padding: 3px 6px;
  background: var(--panel-2, #16181d);
  border: 1px solid var(--line, #2b313c);
  border-radius: 6px;
  color: var(--text);
  font: inherit;
}
.homes-filter-row select:focus,
.homes-filter-row input:focus { outline: none; border-color: var(--accent, #4ea1ff); }

/* Checkboxes in a popover, since <select multiple> cannot show "2 selected". */
.picks { gap: 8px; }

.multi { position: relative; flex: 1 1 0; min-width: 0; }

.multi-btn {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 22px 6px 10px;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.multi-btn:hover { border-color: #3a3f4a; }
.multi.active .multi-btn { border-color: var(--accent); }

/* The caret is drawn on the wrapper so it doesn't move with the label. */
.multi::after {
  content: "";
  position: absolute;
  right: 10px;
  top: 21px;
  border: 4px solid transparent;
  border-top-color: var(--dim);
  pointer-events: none;
}

.multi-cap { font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--dim); }
.multi-val {
  font-size: 12.5px;
  color: var(--text);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.multi-menu {
  position: absolute;
  z-index: 900;
  top: calc(100% + 4px);
  left: 0;
  right: auto;
  width: max-content;
  min-width: 100%;
  max-width: calc(100vw - 16px);
  max-height: 300px;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 9px 10px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55);
}
.multi-menu .chk { white-space: nowrap; }

@media (min-width: 701px) {
  .multi[data-multi="industry"] .multi-menu { left: auto; right: 0; }
}

/* The native clear button only paints on hover; #searchClear replaces it. */
.search::-webkit-search-cancel-button,
.search::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }

.searchwrap { position: relative; display: flex; }
.searchwrap .search { padding-right: 34px; }
/* The search box leads the list: taller, larger type, a magnifier and a firmer edge. */
.filters .searchwrap .search {
  padding: 12px 40px 12px 40px;
  font-size: 15px;
  border-radius: 10px;
  border: 1.5px solid #3a404c;
  background: #1a1d23;
}
.filters .searchwrap .search::placeholder { color: var(--dim); }
.search-icon {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  pointer-events: none;
}
.searchwrap:focus-within .search-icon { color: var(--text); }

/* Chrome draws its own cancel button inside a search field, in the same corner as ours. */
.search::-webkit-search-cancel-button { display: none; }

.search-clear {
  position: absolute;
  z-index: 2;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: #2b3038;
  color: var(--text);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.search-clear:hover { background: #3a4048; }

@media (max-width: 700px) {
  .filters { padding: 10px 12px; gap: 9px; }

  /* An overlay, like the trip settings. In the flow it left the job list about 85 pixels
     tall, so the sliders were changing results nobody could see. */
  .filters { position: relative; z-index: 900; }
  .filters .more-body {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% + 6px);
    margin-top: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: var(--shadow);
    max-height: 62dvh;
    overflow-y: auto;
  }
  /* Not full width: it is a way in to the filters, not the thing you came for. */
  .filters .more { display: inline-block; flex: 0 0 auto; }
  /* Full width, so the Filters button's centring is measured against the row. */
  .filters .fold-row > .more { display: block; }
  .filters .more-summary { display: inline-flex; padding: 6px 12px; font-size: 12.5px; }
  .search { min-height: 40px; font-size: 16px; }
  .filter-row { flex-wrap: wrap; gap: 8px; }
  .homes-filter-row input,
  .homes-filter-row select { min-height: 36px; font-size: 16px; }

  /* The menus opened past the bottom of the screen, inside a body that does not scroll. */
  .multi-menu {
    position: fixed;
    left: 8px;
    right: 8px;
    top: auto;
    bottom: 8px;
    width: auto;
    min-width: 0;
    max-width: none;
    max-height: 50dvh;
  }

  /* Under 16px iOS zooms the page on focus and never zooms back out. These three selects
     sit outside .field and were missed by the rule above. */
  .pickone select,
  .sortrow select,
  .multi-val { font-size: 16px; }

  /* The controls a thumb actually uses on this screen: apply, archive, reset, show all. */
  .card .btn,
  .spot-bar .btn,
  .sortrow .btn,
  .pickone select,
  .sortrow select { min-height: 36px; padding: 7px 12px; font-size: 13px; }
  .chk { min-height: 36px; display: inline-flex; align-items: center; }
  .chk input { width: 18px; height: 18px; }
  .search-clear { width: 32px; height: 32px; }
}

/* Score weights read top to bottom as highest to lowest priority, with a label at each end. */
.weights-end {
  display: flex; align-items: center; gap: 6px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.6px; text-transform: uppercase;
  color: var(--muted);
}
.weights-end::before {
  content: ""; width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
}
.weights-end.top { margin-top: 10px; color: var(--text); }
.weights-end.top::before { border-bottom: 7px solid currentColor; }
.weights-end.bottom { margin-top: 6px; }
.weights-end.bottom::before { border-top: 7px solid currentColor; }
.fold-row > .weights[open] > .weights-end.top + .weights-rank { margin-top: 6px; }
/* No blue in Score weights: a part switched on is a light grey track with a dark knob. */
.weights-rank .switch input:checked + .switch-track { background: #c9ccd1; border-color: #c9ccd1; }
.weights-rank .switch input:checked + .switch-track::after { background: #0b1016; }
.weights-rank .switch input:focus-visible + .switch-track { box-shadow: 0 0 0 3px rgba(201, 204, 209, 0.3); }
.weights-rank li:focus-visible, .weights-rank li.dragging { outline-color: #c9ccd1; border-color: #c9ccd1; }
/* The job list and its cards. */

.card, .card * { overflow-wrap: anywhere; }

/* The scrollbar is always reserved, so the column never shifts as the list length changes. */
.joblist {
  flex: 1 1 auto;
  overflow-y: scroll;
  scrollbar-gutter: stable;
  /* Room at the foot for the cart ribbon's raised circle. */
  padding: 10px 12px 50px;
}
/* The list is narrowed to one place on the map. */
.joblist.spot-only {
  box-shadow: inset 0 0 0 1.5px rgba(255, 214, 10, 0.4), inset 0 0 14px rgba(255, 214, 10, 0.12);
  border-radius: 6px;
  animation: spot-halo-in 0.35s ease-out;
}
@keyframes spot-halo-in {
  from { box-shadow: inset 0 0 0 1.5px rgba(255, 214, 10, 0), inset 0 0 14px rgba(255, 214, 10, 0); }
  to { box-shadow: inset 0 0 0 1.5px rgba(255, 214, 10, 0.4), inset 0 0 14px rgba(255, 214, 10, 0.12); }
}
.joblist::-webkit-scrollbar { width: 10px; }
.joblist::-webkit-scrollbar-thumb { background: #242830; border-radius: 6px; border: 2px solid var(--panel); }

.card {
  background: var(--panel-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 11px 12px;
  margin-bottom: 9px;
  transition: border-color 0.15s, background 0.15s, transform 0.08s;
}
.card:hover { border-color: #3a3f48; background: #181b20; }
.card.active { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(78, 161, 255, 0.4); }

.card.applied {
  border-left: 3px solid var(--good);
  background: linear-gradient(90deg, rgba(34, 214, 138, 0.07), var(--panel-2) 60%);
}
.applied-badge,
.closed-badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.7px;
  padding: 1px 5px;
  border-radius: 4px;
  margin-right: 6px;
  vertical-align: 1px;
}
.applied-badge { background: var(--good); color: #04140d; }
.closed-badge { background: var(--muted, #8a93a6); color: #0b0e14; }
.closed-note {
  font-size: 11px;
  color: var(--muted, #8a93a6);
  margin: 2px 0 4px;
}
.btn.applied-on {
  background: rgba(34, 214, 138, 0.14);
  border-color: rgba(34, 214, 138, 0.5);
  color: var(--good);
}
.btn.applied-on:hover { background: rgba(34, 214, 138, 0.24); }

.card.flash { animation: cardflash 1.2s ease-out; }
@keyframes cardflash {
  0%   { box-shadow: 0 0 0 2px var(--accent), 0 0 18px rgba(78, 161, 255, 0.5); }
  100% { box-shadow: 0 0 0 1px rgba(78, 161, 255, 0.4); }
}

.card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.card-title { font-size: 13.5px; font-weight: 620; line-height: 1.35; margin: 0; cursor: pointer; }
.card-title:hover { text-decoration: underline; }
.card-title:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.card-company { font-size: 12px; color: var(--muted); margin: 2px 0 0; }

.score {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  border-radius: 9px;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  border: 1px solid;
}
.score.hi { color: var(--good); background: rgba(53, 211, 154, 0.1); border-color: rgba(53, 211, 154, 0.35); }
.score.mid { color: var(--warn); background: rgba(242, 193, 78, 0.1); border-color: rgba(242, 193, 78, 0.32); }
.score.lo { color: var(--bad); background: rgba(239, 95, 107, 0.09); border-color: rgba(239, 95, 107, 0.3); }
/* Not yet ranked, which is not the same as ranked badly. Grey read as a dead listing, so these carry the board's own blue until a number arrives. */
.score.none { color: #8a929e; background: rgba(138, 146, 158, 0.06); border-color: rgba(138, 146, 158, 0.2); }
.score.scoring { width: auto; min-width: 40px; padding: 0 6px; font-size: 10px; font-weight: 600; }

.card-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
/* Tags are plain labels, flat and quiet, so they are never taken for the buttons below them. A
   dot between them keeps them apart without drawing a box round each. */
.card-meta { gap: 2px 0; }
.tag {
  font-size: 11px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0;
  background: none;
  border: 0;
  color: var(--dim);
  white-space: nowrap;
}
.tag::before { content: "\00b7"; display: inline-block; width: 15px; text-align: center;
  color: #4a4f58; }
.card-meta { margin-left: -15px; clip-path: inset(0 0 0 15px); }
.tag.remote { color: var(--remote); }
.tag.hybrid { color: var(--hybrid); }
.tag.onsite { color: var(--onsite); }
.tag.pay { color: var(--good); }
.tag.paylow { color: var(--bad); }

.card-detail { margin-top: 10px; padding-top: 10px; border-top: 1px solid #22262c; display: none; }
.card.open .card-detail { display: block; }

.bars { display: flex; flex-direction: column; gap: 5px; margin-bottom: 10px; }
.bar { display: grid; grid-template-columns: 62px 1fr 30px; align-items: center; gap: 8px; font-size: 11px; color: var(--dim); }
/* Spans, so they need display: block for width and height to apply. */
.bar .track {
  display: block;
  height: 5px;
  background: #1a1d22;
  border-radius: 3px;
  overflow: hidden;
}
.bar .fill {
  display: block;
  height: 100%;
  min-width: 2px;
  background: var(--accent);
  border-radius: 3px;
  transition: width 0.25s ease;
}
.bar .fill.hi { background: #22d68a; }
.bar .fill.mid { background: #f0b34a; }
.bar .fill.lo { background: #ff6b6b; }
.bar .val { text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
.bar .bar-why { color: var(--dim); font-style: italic; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }

.skills { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-bottom: 10px; }
.skill { font-size: 10.5px; padding: 0; background: none; border: 0; color: #9ccbff; }

.commute-box {
  background: #141619;
  border: 1px solid #242830;
  border-radius: 8px;
  padding: 8px 10px;
  margin-bottom: 10px;
  font-size: 12px;
}
.commute-box .big { font-size: 15px; font-weight: 660; color: var(--text); }
.commute-box .leave { color: var(--warn); font-weight: 600; }
.your-commute { display: flex; align-items: center; }
.commute-label { margin-right: 8px; color: var(--muted); font-weight: 600; font-size: 11.5px; }
.partner-commute { display: flex; align-items: center; flex-wrap: wrap; gap: 0 2px; margin-top: -4px; }
.partner-commute-label { display: inline-flex; align-items: center; gap: 4px; margin-right: 8px;
  color: #ff8a8a; font-weight: 600; font-size: 11.5px; }
.partner-commute .heart-text-mark { color: #ff4d4d; }
.commute-box .prov { font-size: 10.5px; color: var(--dim); margin-top: 3px; }

/* Parts of an open card that unfold and fold away as their switch changes (Reveal.tsx). */
.reveal { display: grid; grid-template-rows: 1fr; }
.reveal-inner { min-height: 0; overflow: hidden; }
.reveal.entering { animation: reveal-in 280ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.reveal.leaving { animation: reveal-out 280ms cubic-bezier(0.6, 0, 0.8, 0.2) forwards; pointer-events: none; }
@keyframes reveal-in {
  from { grid-template-rows: 0fr; opacity: 0; transform: translateY(-4px); }
  to { grid-template-rows: 1fr; opacity: 1; transform: none; }
}
@keyframes reveal-out {
  from { grid-template-rows: 1fr; opacity: 1; transform: none; }
  to { grid-template-rows: 0fr; opacity: 0; transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
  .reveal.entering, .reveal.leaving { animation-duration: 1ms; }
}

/* The heading over the recommended homes in an open card. */
.job-rent { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600;
  margin-bottom: 8px; letter-spacing: 0.2px; color: var(--muted); }
.job-rent-icon { flex: 0 0 auto; }
.job-rent:empty { display: none; }

/* Every button on a card, in one row at its foot. */
/* The card's buttons, all one size and centred: two to a row on a narrow list, four in one
   row once the card is wide enough, and an odd one out centred under the rest. */
.card-buttons-box { container-type: inline-size; margin-top: 10px; }
.card-buttons { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.card-buttons > .btn {
  flex: 0 0 calc(50% - 3px);
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  white-space: nowrap;
}
@container (min-width: 440px) {
  .card-buttons > .btn { flex-basis: calc(25% - 4.5px); }
}
.card-buttons a.btn { text-decoration: none; }

.empty { text-align: center; color: var(--dim); padding: 40px 20px; font-size: 13px; }

.more-sentinel {
  text-align: center;
  color: var(--dim);
  font-size: 11.5px;
  padding: 10px 0 16px;
  letter-spacing: 0.3px;
}

.tag.pending { color: var(--dim); font-style: italic; }
/* A drive worked out from the previous home, shown until its new one lands. */
.drive-stale { opacity: 0.45; }
.tag.loc { max-width: 260px; }

/* De-select, in the yellow of the narrowed list's halo. */
.btn.tiny.spot-clear { background: #ffd60a; border-color: #ffd60a; color: #1d1700; font-weight: 650; }
.btn.tiny.spot-clear:hover { background: #ffe14d; border-color: #ffe14d; }
.spot-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-bottom: 1px solid var(--line);
  background: #101820;
  font-size: 12px;
}
.spot-text { flex: 1; min-width: 0; color: var(--text); }

/* Mark applied carries a green hue, the colour it turns once applied. */
.btn.tiny.mark-applied { display: inline-flex; align-items: center; gap: 4px; }
.mark-applied-check { flex: 0 0 auto; }
.btn.tiny.mark-applied { border-color: rgba(34, 214, 138, 0.22); color: #9ec9b4; background: rgba(34, 214, 138, 0.03); }
.btn.tiny.mark-applied:hover { background: rgba(34, 214, 138, 0.1); border-color: rgba(34, 214, 138, 0.4); }
/* Open posting matches Mark applied: a faint tint and border, here in the board's blue. */
.btn.tiny.open-posting { display: inline-flex; align-items: center; gap: 4px;
  border-color: rgba(78, 161, 255, 0.22); color: #a3bfdc; background: rgba(78, 161, 255, 0.03); }
.btn.tiny.open-posting:hover { background: rgba(78, 161, 255, 0.1); border-color: rgba(78, 161, 255, 0.4); }
.open-posting-icon { flex: 0 0 auto; }
/* Archive carries a red hue and an X: the card leaves the list. */
.btn.tiny.archive-btn { display: inline-flex; align-items: center; gap: 4px;
  border-color: rgba(255, 92, 92, 0.22); color: #d6a3a3; background: rgba(255, 92, 92, 0.03); }
.btn.tiny.archive-btn:hover { background: rgba(255, 92, 92, 0.1); border-color: rgba(255, 92, 92, 0.4); }
.archive-x { font-size: 14px; line-height: 1; font-weight: 700; margin-top: -1px; }
/* Purple, because green means match score. Filled like a primary button; once in the cart, a
   deeper purple. */
.btn.tiny.apply-to { display: inline-flex; align-items: center; gap: 5px;
  background: #b28cff; border-color: #b28cff; color: #160a2e; }
.card-cart-icon { flex: 0 0 auto; }
.btn.tiny.apply-to:hover { background: #c3a4ff; border-color: #c3a4ff; }
.btn.tiny.apply-to.on { background: #4c2a7a; border-color: #8a63d2; color: #ecdcff; }
.btn.tiny.apply-to.on:hover { background: #5c3591; }

.card.queued { box-shadow: inset 3px 0 0 #8a63d2; }

@media (max-width: 700px) {
  .joblist { padding: 10px 10px 28px; }
  .joblist::-webkit-scrollbar { width: 0; }
}

/* A copy of a card on its way into the Archived button (archiveFlight.ts). */
.archive-ghost {
  position: fixed;
  z-index: 10005;
  margin: 0;
  overflow: hidden;
  pointer-events: none;
  transform-origin: center;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
}
/* Homes for rent: the recommended homes on a card, a listing popup and the rent and bedroom limits. */

/* The homes recommended for the open job: city, rent and the drive, then the cheaper ones. */
.job-homes { margin-top: 2px; }
.job-homes-label { margin: 8px 0 4px; color: var(--dim); font-size: 11px; letter-spacing: 0.2px; }
.job-homes-list {
  background: #141619;
  border: 1px solid #242830;
  border-radius: 8px;
}
.job-home {
  display: grid;
  grid-template-columns: 1fr 0.8fr auto;
  gap: 6px;
  width: 100%;
  padding: 6px 9px;
  background: none;
  border: 0;
  border-bottom: 1px solid #1e2228;
  color: var(--text);
  font: inherit;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  text-align: left;
  cursor: pointer;
}
.job-home:last-child { border-bottom: 0; }
.job-home:hover { background: #1a1e24; }
.job-home.on { background: #123a37; }
.job-home > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job-home-rent { font-weight: 640; }
.job-home-city { color: var(--muted); }
.job-home-drive { text-align: right; }
/* Between the job and the heart: city, rent, and both drives. */
.job-home.pair { grid-template-columns: 1fr 0.8fr auto auto; column-gap: 10px; }
.job-home-heart { white-space: nowrap; }
.heart-text-mark { display: inline-block; flex: none; margin-right: 3px; vertical-align: -1px; }
.job-homes-empty { padding: 6px 0; color: var(--dim); font-size: 11.5px; }
.job-homes-wait { padding: 6px 0; }
.job-homes-wait .route-busy-dot { display: inline-block; }

/* A home for rent. The photo box keeps its size while the picture loads. */
.home-photo {
  width: 100%;
  height: 132px;
  margin-bottom: 7px;
  border-radius: 6px;
  overflow: hidden;
  background: #1a1e24;
}
.home-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.home-photo.missing { display: none; }
.home-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 11.5px;
}
.home-step {
  width: 24px;
  height: 22px;
  padding: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--text);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.home-step:hover { background: #1c2025; }
.home-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.home-actions .btn { background: var(--panel); }
.home-actions .btn.primary { background: var(--accent); }
.leaflet-container .home-actions a.btn { color: var(--text); text-decoration: none; }
.home-here { display: inline-flex; align-items: center; padding: 3px 8px; border: 1px solid #ff3d95;
  border-radius: 6px; color: #ffc2de; font-size: 11.5px; font-weight: 600; }
.leaflet-popup-content .home-back { display: block; margin-top: 8px; }

/* The drive from the listing to the job, and to the heart. */
.home-pair { margin: 2px 0 3px; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.pair-heart { white-space: nowrap; }

/* Rent and bedroom limits for the listing dots. */
.house-filters { display: flex; flex-wrap: wrap; gap: 5px 10px; margin-top: 6px; }
.house-filters label { display: flex; align-items: center; gap: 5px; }
.house-filters select { width: 62px; cursor: pointer; }
.house-filters select[data-housing-filter="minBeds"] { width: 52px; }
.house-filters input,
.house-filters select {
  width: 62px;
  padding: 2px 5px;
  background: #1b1f26;
  border: 1px solid #2b313c;
  border-radius: 5px;
  color: #e8edf3;
  font: inherit;
}

@media (max-width: 700px) {
  /* A home's popup scrolls as one inside the map's height, so its photo is shorter. */
  .home-popup .home-photo { height: 84px; }
}

@media (max-width: 700px) {
  /* A home's buttons come before its photo, so they show without scrolling the popup. */
  .home-popup .home-pop { display: flex; flex-direction: column; }
  .home-popup .home-pop > .home-actions { order: -1; margin-top: 0; margin-bottom: 8px; }
}
/* The top bar: the brand, the fields, the Settings fold, the Applications, Feedback and account buttons. */

.topbar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  /* Room on the right for the account pinned into the corner. */
  padding: 12px 18px 12px 18px;
  background: linear-gradient(180deg, #101215, #0b0d0f);
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
  isolation: isolate;
}
/* The cart's purple contour map (topoBackground.ts) faintly behind the bar, kept dim and
   behind everything so the titles and boxes read as before. */
.topbar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--topo);
  background-size: 1600px auto;
  background-position: center 38%;
  opacity: 0.5;
}
/* A job added to the cart: the contour lines brighten and swell a touch (CartButton.tsx). */
.topbar.topo-ripple::before { animation: topo-swell 1.1s ease-out; }
/* And the wordmark flickers once, like a flash of lightning. */
.topbar.topo-ripple .brand h1 { animation: brand-flash 0.7s linear; }
@keyframes brand-flash {
  0%, 100% { color: #a078eb; text-shadow: none; }
  6% { color: #f3ecff; text-shadow: 0 0 10px rgba(205, 180, 255, 0.9); }
  12% { color: #a078eb; text-shadow: none; }
  20% { color: #e6d9ff; text-shadow: 0 0 6px rgba(205, 180, 255, 0.7); }
  30% { color: #a078eb; text-shadow: none; }
}
@keyframes topo-swell {
  0% { opacity: 0.5; transform: scale(1); filter: none; }
  25% { opacity: 0.95; transform: scale(1.012); filter: brightness(1.5); }
  100% { opacity: 0.5; transform: scale(1); filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  .topbar.topo-ripple::before, .topbar.topo-ripple .brand h1 { animation: none; }
}

.brand { display: flex; align-items: center; gap: 12px; }
/* The mark floats on the bar, with no box around it. */
.logo {
  width: 38px; height: 38px;
  display: grid; place-items: center;
}
.logo svg { display: block; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45)); }
/* Turning while the board works out something the reader is waiting to see (logoSpin.ts). */
.logo.spinning svg { animation: logo-spin 1s linear infinite; }
@keyframes logo-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .logo.spinning svg { animation: logo-pulse 1.4s ease-in-out infinite; }
  @keyframes logo-pulse { 50% { opacity: 0.55; } }
}
/* The wordmark in the cart's purple: a heavy slanted face in one flat, matte colour. The faces
   are ones the computer already has, so nothing is fetched from elsewhere. */
.brand h1 {
  margin: 0;
  font-family: "Trebuchet MS", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  font-size: 19px;
  font-weight: 800;
  font-style: italic;
  letter-spacing: 0.4px;
  color: #a078eb;
  padding-right: 2px;
}

.controls { display: flex; align-items: flex-end; gap: 6px; flex-wrap: wrap; }
.field { display: flex; flex-direction: column; gap: 4px; }
.field span { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.7px; color: var(--dim); }
.field input,
.field select {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 13px;
  min-width: 210px;
  outline: none;
}
.field.short input, .field.short select { min-width: 86px; }
.topbar .field input, .topbar .field select { height: 32px; font-family: inherit; }
/* The two address boxes share whatever room is left in the bar and shrink rather than
   force a second line. The bar is a fixed budget: every field added, and every button
   renamed to something longer, comes out of these two. */
.field.mid { flex: 1 1 116px; min-width: 84px; max-width: 132px; }
.field.mid input { min-width: 0; width: 100%; }
.field.tiny-field input { min-width: 82px; width: 82px; }
.field select { cursor: pointer; }
.field input:focus, .field select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(78, 161, 255, 0.18);
}

/* The bar in two sides. Left, the commute group grows into whatever room there is; right,
   the account row sits over the salary floor and the Applications button. */
.topbar .controls { flex: 1 1 auto; min-width: 0; }
.topbar-right { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end;
  gap: 5px; }
/* The pay box sits on the same line as the last row of settings: the bar's two sides share
   one foot, with the brand centred on its own. */
@media (min-width: 701px) {
  .topbar { align-items: flex-end; }
  .topbar .brand-stack { align-self: center; }
}
.topbar-actions { display: flex; align-items: flex-end; gap: 6px; }
.topbar .whorow { display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: var(--dim); }
.topbar .whorow .btn { white-space: nowrap; padding: 2px 7px; font-size: 11px; }

/* The home address is what every drive is measured from, so it is the widest box in the bar
   and says what it is for. An empty one is outlined until it is filled in. */
.field.home-field { flex: 0 1 220px; min-width: 150px; max-width: 220px; }
.field.home-field input:placeholder-shown { border-color: var(--accent); }

/* An on and off switch in place of a two-choice dropdown. The checkbox stays the control. */
.switch { position: relative; display: inline-flex; align-items: center; height: 32px; }
.switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; z-index: 1; }
.switch-track { width: 40px; height: 22px; border-radius: 11px; background: var(--panel-2);
  pointer-events: none;
  border: 1px solid var(--line); position: relative; transition: background 0.12s; }
.switch-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px;
  height: 16px; border-radius: 50%; background: var(--muted); transition: transform 0.12s; }
/* On, the switch takes the soft blue of Open posting (jobs.css). */
.switch input:checked + .switch-track { background: rgba(78, 161, 255, 0.3); border-color: rgba(78, 161, 255, 0.55); }
.switch input:checked + .switch-track::after { transform: translateX(18px); background: #cfe0f2; }
.switch input:focus-visible + .switch-track { box-shadow: 0 0 0 3px rgba(78, 161, 255, 0.3); }
/* The field rules size every input in the bar; the hidden checkbox covers the track only. */
.field.short .switch input { min-width: 0; min-height: 0; width: 100%; height: 100%; padding: 0;
  border: 0; }
.who-name { max-width: 14ch; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--muted); }

.heart-field span { color: #ff8a8a; }
.field.mid.heart-field { max-width: 240px; }
.heart-field input { border-color: #6b2222; }
/* The box grows in from nothing beside the home address and folds back when the heart goes. */
.heart-field.entering { overflow: hidden; animation: heart-field-in 260ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.heart-field.leaving { overflow: hidden; pointer-events: none;
  animation: heart-field-out 260ms cubic-bezier(0.6, 0, 0.8, 0.2) forwards; }
@keyframes heart-field-in {
  from { max-width: 0; min-width: 0; opacity: 0; transform: translateY(-6px) scale(0.92); }
  to { max-width: 240px; min-width: 84px; opacity: 1; transform: none; }
}
@keyframes heart-field-out {
  from { max-width: 240px; min-width: 84px; opacity: 1; transform: none; }
  to { max-width: 0; min-width: 0; opacity: 0; transform: translateY(-6px) scale(0.92); }
}
@media (prefers-reduced-motion: reduce) {
  .heart-field.entering, .heart-field.leaving { animation-duration: 1ms; }
}
.heart-field input:focus {
  border-color: #ff1a1a;
  box-shadow: 0 0 0 3px rgba(255, 26, 26, 0.18);
}

/* The applications button keeps its words on one line whatever else is in the bar. */
.cart-btn { position: relative; white-space: nowrap; padding-left: 10px; padding-right: 10px;
  display: inline-flex; align-items: center; }
.cart-icon { display: block; flex: 0 0 auto; }
.cart-btn.has { border-color: #6a4a9c; color: #c9a9ff; }
.cart-btn.on { background: #4c2a7a; border-color: #8a63d2; color: #ecdcff; }
.cart-count {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: 5px;
  border-radius: 9px;
  background: #2a2f38;
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.cart-btn.has .cart-count { background: #8a63d2; color: #16081f; }

/* Above the phone breakpoint the group is always open and its summary is not drawn, so the
   fields lie out in the row exactly as they did before they were wrapped. A details element
   keeps a box of its own whatever display it is given, so the box is made a flex row rather
   than dissolved. */
.more { display: flex; align-items: flex-end; gap: 10px; }
.more-summary { display: none; }
.more-body { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }

/* The whole Arrive by field opens the time picker, so it has to look clickable. */
.field:has(#arriveInput), #arriveInput { cursor: pointer; }

@media (max-width: 700px) {
  .topbar {
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px 12px;
  }

  /* The mark alone. The wordmark costs a third of the bar and says nothing new. */
  .brand h1 { display: none; }
  .logo { width: 34px; height: 34px; }
  .logo svg { width: 26px; height: 26px; }

  /* The mark held a left column that every wrapped row had to clear, which cost 13 percent
     of the width on a 360 screen. Nobody needs telling which site they are on here. */
  .brand { display: none; }
  .controls {
    flex: 1 1 0;
    min-width: 0;
    align-items: stretch;
    gap: 8px;
  }

  /* Three lines: the account, then the home address with the commute settings beside it,
     then the salary floor with the Applications button. The right side's box is dissolved so
     the account line can go to the top of the bar. */
  .topbar .controls { flex: 1 1 100%; align-items: center; }
  .controls > .field { flex: 1 1 100%; }
  .controls > .field.mid { max-width: none; }
  .controls > .field.home-field { flex: 1 1 0; min-width: 0; flex-direction: row;
    align-items: center; gap: 6px; }
  .topbar-right { display: contents; }
  .topbar-actions { flex: 1 1 100%; align-items: center; gap: 8px; }
  .topbar-actions .field { flex: 1 1 0; min-width: 0; flex-direction: row; align-items: center;
    gap: 6px; }
  .topbar-actions .field > span { white-space: nowrap; }
  /* Off screen rather than gone, because the span is the field's name to a screen reader. */
  .controls > .field > span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* Except the home address, whose name stays on screen: the customer could not find it. */
  .controls > .field.home-field > span {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    flex: 0 0 auto;
  }
  .field.mid input { min-width: 0; width: 100%; }
  .field input,
  .field select {
    min-width: 0;
    width: 100%;
    /* Under 16px, iOS zooms the page the moment the field takes focus. */
    font-size: 16px;
    min-height: 40px;
  }

  .more { display: block; flex: 1 1 0; min-width: 0; }
  .topbar .more { flex: 0 0 auto; }

  .more-summary {
    display: block;
    padding: 8px 10px;
    text-align: center;
    list-style: none;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .more-summary::-webkit-details-marker { display: none; }
  .more[open] .more-summary { border-color: var(--accent); }
  /* Something is set inside a group that is folded shut. */
  .more-summary.on { border-color: var(--accent); color: var(--accent); }

  /* The open group drops as a panel under the bar. Left in the flow it stretched the two
     buttons beside it to its own height and squeezed the fields into a third of the width. */
  /* Above the map, which is a layer of its own at 0, with the page's other overlays. */
  .topbar { position: relative; z-index: 1200; }
  .topbar .more-body {
    position: absolute;
    left: 12px;
    right: 12px;
    top: calc(100% + 4px);
    z-index: 30;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    padding: 12px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: var(--shadow);
  }
  .topbar .more-body .field.switch-field { justify-content: flex-start; }

  /* The salary floor and Applications share one line, half each. */
  .topbar .btn:not(.more-summary) {
    flex: 1 1 0;
    min-width: 0;
    padding: 8px 10px;
    font-size: 13px;
    white-space: nowrap;
  }
  /* The count kept dropping to a second line and made its button taller than the other two. */
  .cart-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
  /* A line of its own above the controls. Pinned into the corner it sat over the Applications
     button, so a tap meant for the list signed the reader out. */
  .topbar .whorow { position: static; order: -1; flex: 1 1 100%; justify-content: flex-end; }
  .topbar .whorow .btn { flex: 0 0 auto; padding: 4px 10px; font-size: 12px; }
}

@media (max-width: 700px) {
  /* The pay box takes the room the Applications button does not need, and its number fits. */
  .topbar .btn.cart-btn { flex: 0 0 auto; }
  .topbar-actions .field.tiny-field input { min-width: 0; width: 100%; }
}

/* On a phone the box takes the whole row, so it fades and drops in rather than growing wide. */
@media (max-width: 700px) {
  .heart-field.entering { animation-name: heart-field-in-phone; }
  .heart-field.leaving { animation-name: heart-field-out-phone; }
}
@keyframes heart-field-in-phone {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
@keyframes heart-field-out-phone {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(-8px); }
}
/* The Applications panel and everything drawn in it. */

.cart-panel {
  position: fixed;
  top: var(--topbar-h, 68px);
  right: 12px;
  /* Clear of the cart ribbon, which stays on top. */
  bottom: 92px;
  width: 560px;
  max-width: calc(100vw - 24px);
  z-index: 900;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid #6a4a9c;
  border-radius: var(--radius);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  overflow: hidden;
}
.cart-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  background: #1b1424;
  font-size: 13px;
}
.cart-summary { color: var(--muted); font-size: 11.5px; margin-left: auto; }
.cart-close {
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.cart-close:hover { color: var(--text); }

/* Picking several at once, and the lever that says whether the run waits for you. */
.cart-tools {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  background: #150f1c;
  font-size: 12px;
}
.cart-all { white-space: nowrap; }

.lever { display: flex; align-items: center; gap: 6px; margin-left: auto; cursor: pointer; }
.lever input { position: absolute; opacity: 0; width: 0; height: 0; }
.lever-track {
  width: 30px;
  height: 17px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  position: relative;
  transition: background 0.14s ease, border-color 0.14s ease;
}
.lever-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--dim);
  transition: transform 0.14s ease, background 0.14s ease;
}
.lever input:checked + .lever-track { background: #3c2a55; border-color: #8a63d2; }
.lever input:checked + .lever-track .lever-knob { transform: translateX(13px); background: #c9a6ff; }
.lever input:focus-visible + .lever-track { box-shadow: 0 0 0 3px rgba(138, 99, 210, 0.3); }
.lever-text { color: var(--text); white-space: nowrap; }
.lever input:checked ~ .lever-text { color: #c9a6ff; }

/* The pick box is large and sits in a wider hit area, so a near miss does not open the row. */
.cart-pick-hit { flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  width: 48px; min-height: 48px; margin: -8px 0 -8px -8px; cursor: pointer; }
.cart-pick { width: 32px; height: 32px; margin: 0; cursor: pointer; accent-color: var(--accent); }

.cart-runbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border-top: 1px solid var(--line);
  background: #150f1c;
  font-size: 12px;
}
/* One line. A long title wrapped to a second line and was cut off by the bar's own edge. */
.cart-run-text {
  flex: 1;
  color: var(--muted);
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cart-body { flex: 1; overflow-y: auto; padding: 10px 12px; }
.cart-empty { color: var(--dim); font-size: 12px; padding: 24px 4px; text-align: center; }

.cart-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 12px;
  cursor: pointer;
  margin-bottom: 7px;
  border: 1px solid var(--line-soft);
  border-left: 3px solid #8a63d2;
  border-radius: 8px;
  background: var(--panel-2);
  cursor: pointer;
  color: inherit;
  text-decoration: none;
}
.cart-row:hover { background: #1c2025; border-color: #8a63d2; }
.cart-row:hover .cart-text b { text-decoration: underline; }
/* The title is the row's button, drawn as the bold title it sits in. */
.cart-open { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.cart-open:focus-visible { outline: 2px solid #8a63d2; outline-offset: 2px; border-radius: 3px; }
.cart-row .score { width: 38px; height: 38px; font-size: 14px; }
.cart-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.cart-text b { font-size: 14px; font-weight: 620; line-height: 1.3; }
.cart-sub { color: var(--muted); font-size: 12px; }
.cart-err { color: var(--bad); font-size: 10.5px; margin-top: 2px; }

.cart-state {
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 5px;
  border: 1px solid;
}
.cart-state.queued { color: #c9a9ff; border-color: #6a4a9c; background: rgba(138, 99, 210, 0.12); }
.cart-state.applying { color: var(--warn); border-color: rgba(242, 193, 78, 0.45); background: rgba(242, 193, 78, 0.1); }
.cart-state.applied { color: var(--good); border-color: rgba(34, 214, 138, 0.45); background: rgba(34, 214, 138, 0.1); }
.cart-state.failed { color: var(--bad); border-color: rgba(239, 95, 107, 0.45); background: rgba(239, 95, 107, 0.1); }

/* Still on the list, but the board no longer carries the posting. */
.cart-row.retired { opacity: 0.85; }
.cart-row.applied { border-left-color: var(--good); }
.cart-row.failed { border-left-color: var(--bad); }
.cart-row.applying { border-left-color: var(--warn); }

.cart-drop {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--line, rgba(255, 255, 255, 0.18));
  border-radius: 6px;
  color: var(--text, inherit);
  font-size: 12.5px;
  line-height: 1;
  cursor: pointer;
  padding: 6px 10px;
}
/* Remove is a plain X, square beside Find. */
.cart-drop { min-width: 30px; min-height: 30px; padding: 0; font-size: 18px; color: var(--muted); }
.cart-drop:hover { color: var(--bad); border-color: var(--bad); }

.cart-find {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 12.5px;
  line-height: 1;
  cursor: pointer;
  padding: 6px 10px;
}
.cart-find:hover { color: var(--accent); }

.cart-mark {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1;
  cursor: pointer;
  padding: 6px 8px;
}
.cart-mark:hover { color: var(--good); border-color: var(--good); }
.cart-mark.done {
  color: var(--good);
  border-color: rgba(34, 214, 138, 0.45);
  background: rgba(34, 214, 138, 0.12);
}
.cart-mark.done:hover { color: var(--muted); border-color: var(--line); background: none; }
.history-row.archived.flash { animation: cardflash 1.2s ease-out; }

@media (max-width: 700px) {
  .cart-panel { width: auto; max-width: none; max-height: 78dvh; }

/* It opened under the bar that holds the button which opens it. */
  .cart-panel { top: auto; bottom: 0; left: 0; right: 0; border-radius: 12px 12px 0 0; }

  /* Remove, find and mark sit next to each other inside a row that opens the posting. At
     17 pixels the wrong one was a coin toss. */
  .cart-drop,
  .cart-find,
  .cart-mark,
  .cart-close { min-width: 40px; min-height: 40px; }

  /* A row's tick box, score, state and three buttons took the whole width and left the title
     none. The title keeps the first line; the state and buttons take a second. */
  .cart-row { flex-wrap: wrap; gap: 8px 10px; }
  .cart-row .cart-text { flex: 1 1 0; min-width: 55%; }
  .cart-row .cart-state { margin-left: auto; }
  .typed-label { flex-basis: 40%; }
}

/* Questions waiting on an answer. The button is amber rather than purple, because it asks
   something of the reader instead of offering something to do. */
.ask-item {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
  background: #17131f;
}
.ask-item .ask-where { font-size: 12px; color: var(--dim); margin-bottom: 4px; }
.ask-item .ask-prompt { margin-bottom: 8px; line-height: 1.35; }
.ask-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ask-row input[type="text"], .ask-row select, .ask-row textarea {
  flex: 1 1 220px;
  min-width: 160px;
  background: #100c16;
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 9px;
  font: inherit;
}
.ask-row textarea { min-height: 70px; resize: vertical; }
.ask-empty { color: var(--dim); font-size: 12px; padding: 24px 4px; text-align: center; }

/* What an agent is doing with a posting on the apply list. */
.cart-agent { display: block; font-size: 12px; color: #c9a9ff; margin-top: 2px; }

.cart-btn.needs { border-color: #e0a423; color: #ffdb8f; }


/* The answers already given: two columns on a wide panel, one on a narrow one, so the whole
   set can be read without scrolling past a single tall column of boxes. */
.detail-group { margin-bottom: 16px; }
.detail-group h4 {
  margin: 0 0 8px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
  border-bottom: 1px solid var(--line);
  padding-bottom: 4px;
}
.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 8px 14px;
}
.detail-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.detail-row label {
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--dim);
  cursor: help;
}
.detail-row.blank label { color: #d2a13f; }
.detail-row input, .detail-row select, .detail-row textarea {
  width: 100%;
  box-sizing: border-box;
  background: #100c16;
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 9px;
  font: inherit;
  font-size: 13px;
}
.detail-row.blank input, .detail-row.blank select, .detail-row.blank textarea {
  border-color: #6b5320;
}
.detail-row input:focus, .detail-row select:focus, .detail-row textarea:focus {
  border-color: var(--accent);
  outline: none;
}
.detail-row textarea { min-height: 76px; resize: vertical; grid-column: 1 / -1; }
/* A letter and a list want the width of the panel rather than half of it. */
.detail-row:has(textarea), .detail-row:has(.detail-list) { grid-column: 1 / -1; }
.detail-list { font-size: 13px; }
.detail-list ul { margin: 2px 0 0; padding-left: 18px; }
.detail-empty { color: var(--dim); }

/* What has been sent. */
.history-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 11px;
  margin-bottom: 8px;
  background: #17131f;
}
.history-row.ready { border-color: #6a4a9c; }
.history-row.submitted { border-color: #2f7a4a; }
.history-row.failed { border-color: #7a3030; }
.history-row.asking { border-color: #9c7a2a; }
.history-text { flex: 1 1 auto; min-width: 0; }
.history-text b { display: block; }
.history-text b a { color: inherit; text-decoration: none; }
.history-text b a:hover { text-decoration: underline; }
.history-side a.btn { text-decoration: none; }
.history-note { display: block; font-size: 12px; color: var(--dim); }
.history-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.history-when { font-size: 11px; color: var(--dim); white-space: nowrap; }

/* What the agent typed, read back before submitting. */
.typed {
  margin-top: 8px;
  border-top: 1px solid var(--line);
  padding-top: 6px;
}
.typed-row { display: flex; gap: 8px; padding: 2px 0; font-size: 12px; }
.typed-label { flex: 0 0 150px; color: var(--dim); }
.typed-value { flex: 1 1 auto; min-width: 0; word-break: break-word; }
.history-side .btn { white-space: nowrap; }

/* The page as the agent left it, so the form is looked at rather than described. One picture a
   screen, in the order the agent went through them. */
.shots { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.changes { margin-top: 8px; display: grid; gap: 4px; }
.change-row { display: flex; gap: 8px; font-size: 12px; }
.change-status { color: var(--dim); min-width: 92px; }
.change-row.failed .change-status { color: #c0392b; }
.change-ask { display: flex; gap: 8px; align-items: flex-start; margin-top: 8px; }
.change-input { flex: 1; min-width: 0; font: inherit; font-size: 13px; padding: 6px 8px; resize: vertical;
  background: #100c16; color: var(--text); border: 1px solid var(--line); border-radius: 8px; }
.shot {
  width: 148px;
  height: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #0d0a12;
  cursor: zoom-in;
  display: block;
}
.shot:hover { border-color: #8a63d2; }
/* The button a picture sits in, drawn as the picture alone. */
.shot-open { padding: 0; border: 0; background: none; border-radius: 8px; cursor: zoom-in; }
.shot-open:disabled { cursor: default; }
.shot-open:focus-visible { outline: 2px solid #8a63d2; outline-offset: 2px; }
.shot-full {
  position: fixed;
  inset: 0;
  z-index: 10020;
  background: rgba(8, 6, 12, 0.92);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: auto;
  padding: 20px;
  cursor: zoom-out;
}
.shot-full img { max-width: 100%; height: auto; border-radius: 8px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6); }

/* One application, read inside the board. No window opens unless Open posting is pressed. */
.one-head { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.one-title { margin: 0 0 8px; font-size: 16px; line-height: 1.3; }
.one-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 6px 14px;
  margin-bottom: 12px;
}
.one-fact { display: flex; flex-direction: column; }
.one-fact span { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--dim); }
.one-desc {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text);
  white-space: pre-wrap;
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 12px;
  background: #130f1a;
}
.one-run {
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: 10px;
  padding: 10px 12px;
  background: #17131f;
}
.one-run.ready { border-left-color: #8a63d2; }
.one-run.submitted { border-left-color: #2f7a4a; }
.one-run.failed { border-left-color: #7a3030; }
.one-run.asking { border-left-color: #d2a13f; }
.one-run-head { display: flex; gap: 10px; align-items: baseline; margin-bottom: 4px; }

/* What became of every attempt, counted. "Sent" is the only one that left the building, so it
   is the one coloured like a finished thing; everything else reads as still in hand. */
.history-stats {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 10px;
  background: rgba(255, 255, 255, 0.03);
}
.stat-line { display: flex; flex-wrap: wrap; gap: 14px; }
.stat-line .stat { font-size: 12px; color: var(--dim); }
.stat-line .stat b { font-size: 16px; color: var(--text); margin-right: 4px; }
.stat-line .stat.submitted b { color: #4cc27a; }
.stat-line .stat.ready b { color: #b08ae0; }
.stat-line .stat.asking b { color: #e0b64c; }
.stat-line .stat.failed b { color: #e07a7a; }
.stat-note { margin-top: 8px; font-size: 12px; color: var(--dim); }

/* The state of one attempt, at the front of its row, so a filled-in form is never read as a
   form that was sent. */
.attempt-badge {
  display: inline-block;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 4px;
  margin-right: 6px;
  vertical-align: middle;
  background: #3a3a44;
  color: #d8d8e0;
}
.attempt-badge.submitted { background: #2f7a4a; color: #eafff2; }
.attempt-badge.ready { background: #4a3a70; color: #e4d8ff; }
.attempt-badge.asking { background: #7a5f1e; color: #ffeec2; }
.attempt-badge.failed { background: #7a3030; color: #ffdede; }
.attempt-badge.working, .attempt-badge.starting { background: #26506e; color: #d6ecff; }

.card-attempt:empty { display: none; }
.attempt-step { font-size: 11.5px; color: var(--muted); margin-top: 7px; }
.attempt-step.failed { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.attempt-step.failed .attempt-reason { color: var(--text); }
.cart-row .attempt-step { margin-top: 2px; }
.one-run .attempt-step { margin: 0 0 6px; }
.attempt-badge.queued { background: #3b3252; color: #e0d4ff; }
.cart-state.progress { color: #d6ecff; border-color: rgba(78, 161, 255, 0.45); background: rgba(78, 161, 255, 0.12); }

.doc-list { display: flex; flex-direction: column; gap: 6px; }
.doc-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px dashed #4a3a63;
  border-radius: 10px;
  padding: 8px 12px;
  background: #16111f;
}
.doc-row.has { border-style: solid; border-color: #4c3a6b; }
.doc-row.over { border-color: #8a63d2; background: #1b1428; }
.doc-row .clip { flex: 0 0 auto; color: #c9a9ff; }
.doc-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.doc-text b { font-size: 12.5px; }
.doc-name { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-missing { font-size: 12px; color: #d2a13f; }
.ask-row.doc-row { border-style: solid; }
.detail-fold { margin-top: 4px; }
.detail-fold summary { cursor: pointer; font-size: 12px; color: var(--muted); padding: 4px 0; }
.detail-hint { font-size: 11px; color: var(--dim); }
.date-pick { display: flex; gap: 6px; }
.date-pick select { flex: 1 1 50%; }
.date-pick input { flex: 1 1 50%; }

/* A list of jobs, schools or references, one small form an entry. */
.list-editor { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.list-entry {
  width: 100%;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px;
}
.list-entry label { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--dim); cursor: default; }
.list-entry .list-wide { grid-column: 1 / -1; }
.list-entry .list-flag { flex-direction: row; align-items: center; gap: 6px; }
.list-entry .list-flag input { width: auto; }
.list-entry > .btn { justify-self: start; align-self: end; }

/* The cart as a wide ribbon at the foot of the job list, always on screen. */
.sidebar .cart-btn.cart-ribbon {
  /* Over the board, with a raised circle at its centre (::before); the full-screen cart and
     the toasts sit above it. */
  position: relative;
  z-index: 10000;
  overflow: visible;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: 64px;
  margin: 0;
  border-radius: 0;
  border: 0;
  /* The top edge is drawn by ::after, along the hump too; the border keeps its room. */
  border-top: 1px solid transparent;
  --ribbon-line: #6a4a9c;
  background: #2b1d47;
  color: #e6d6ff;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: 0.02em;
}
.sidebar .cart-btn.cart-ribbon:hover { background: #3a2760; }
.sidebar .cart-btn.cart-ribbon.has { background: #4c2a7a; --ribbon-line: #8a63d2; }
.sidebar .cart-btn.cart-ribbon.has:hover { background: #5c3591; }
.sidebar .cart-btn.cart-ribbon.on { background: #6a3fa8; }
.sidebar .cart-btn.cart-ribbon.needs { --ribbon-line: #e0a423; }
/* A raised hump at the ribbon's centre: its sides leave the ribbon's top edge level, tangent
   to it, and round over the top, covering the cards behind. Masked to shape, so it takes the
   ribbon's colour in every state. */
.sidebar .cart-btn.cart-ribbon::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -21px;
  width: 260px;
  height: 21px;
  margin-left: -130px;
  background: inherit;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 260 21'%3E%3Cpath d='M0 21L0 20.5C60 20.5 70 0.5 130 0.5S200 20.5 260 20.5L260 21Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 260 21'%3E%3Cpath d='M0 21L0 20.5C60 20.5 70 0.5 130 0.5S200 20.5 260 20.5L260 21Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  z-index: -1;
}
/* The ribbon's top edge, one line along the flats and over the hump alike. */
.sidebar .cart-btn.cart-ribbon::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -21px;
  height: 21px;
  background: var(--ribbon-line);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 260 21'%3E%3Cpath d='M0 20.5C60 20.5 70 0.5 130 0.5S200 20.5 260 20.5' fill='none' stroke='black' stroke-width='1.2'/%3E%3C/svg%3E") center bottom / 260px 21px no-repeat, linear-gradient(to right, #000 calc(50% - 130px), transparent calc(50% - 130px), transparent calc(50% + 130px), #000 calc(50% + 130px)) left bottom / 100% 1px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 260 21'%3E%3Cpath d='M0 20.5C60 20.5 70 0.5 130 0.5S200 20.5 260 20.5' fill='none' stroke='black' stroke-width='1.2'/%3E%3C/svg%3E") center bottom / 260px 21px no-repeat, linear-gradient(to right, #000 calc(50% - 130px), transparent calc(50% - 130px), transparent calc(50% + 130px), #000 calc(50% + 130px)) left bottom / 100% 1px no-repeat;
  pointer-events: none;
  z-index: -1;
}
.cart-ribbon > * { position: relative; }
/* The Archived button: small and see-through, floating over the map's corner just left of
   the cart ribbon, off the ribbon itself. */
.cart-ribbon-wrap { position: relative; flex: 0 0 auto; }
.archived-btn {
  position: absolute;
  z-index: 10001;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border: 1px solid rgba(230, 214, 255, 0.28);
  border-radius: 999px;
  background: rgba(20, 14, 28, 0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  color: rgba(230, 214, 255, 0.8);
  font: inherit;
  font-size: 11.5px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.archived-btn:hover { background: rgba(40, 28, 56, 0.75); color: #f3eaff; }
.archived-btn.on { background: rgba(255, 255, 255, 0.2); border-color: rgba(230, 214, 255, 0.45); color: #fff; }
/* The archived bin, rising over the map from its button (ArchivedBin.tsx, BIN_MS). */
.archived-bin {
  position: absolute;
  z-index: 10001;
  right: calc(100% + 12px);
  bottom: calc(50% + 22px);
  display: flex;
  flex-direction: column;
  width: 360px;
  max-height: min(60vh, 520px);
  border: 1px solid rgba(230, 214, 255, 0.22);
  border-radius: 12px;
  background: rgba(16, 12, 22, 0.94);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
  overflow: hidden;
  transform-origin: 85% 100%;
}
.archived-bin.in { animation: bin-in 0.2s cubic-bezier(0.2, 0.8, 0.2, 1); }
.archived-bin.out { animation: bin-out 0.2s ease-in forwards; pointer-events: none; }
@keyframes bin-in { from { opacity: 0; transform: translateY(10px) scale(0.92); } }
@keyframes bin-out { to { opacity: 0; transform: translateY(10px) scale(0.92); } }
@media (prefers-reduced-motion: reduce) {
  .archived-bin.in, .archived-bin.out { animation-duration: 0.01s; }
}
.archived-bin-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  color: #e6d6ff;
}
.archived-bin-body { flex: 1; overflow-y: auto; padding: 10px; min-height: 0; }
.archived-search {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 10px 0;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--dim);
}
.archived-search:focus-within { border-color: rgba(138, 99, 210, 0.7); color: #e6d6ff; }
.archived-search input {
  flex: 1;
  min-width: 0;
  padding: 8px 0;
  border: 0;
  outline: none;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 13px;
}

/* Stacked on a phone the map is far above, so the button floats just over the ribbon's left
   end and the bin rises from there across the width. */
@media (max-width: 700px) {
  .archived-btn { right: auto; left: 10px; top: auto; bottom: calc(100% + 10px); transform: none; }
  .archived-bin { right: 10px; left: 10px; width: auto; bottom: calc(100% + 48px); transform-origin: 10% 100%; }
}
.cart-ribbon .cart-count { position: static; min-width: 22px; height: 22px; font-size: 12px; }

/* A job just added: the ribbon bounces once and its count pops. */
.cart-ribbon.added { animation: cart-added 0.5s cubic-bezier(0.3, 1.5, 0.6, 1); }
.cart-ribbon.added .cart-count { animation: cart-count-pop 0.5s ease-out; }
.cart-ribbon.added .cart-icon { animation: cart-icon-hop 0.5s ease-out; }
@keyframes cart-added {
  0% { background: #8a63d2; }
  100% { background: #4c2a7a; }
}
@keyframes cart-count-pop {
  0% { transform: scale(1); }
  40% { transform: scale(1.45); }
  100% { transform: scale(1); }
}
@keyframes cart-icon-hop {
  0%, 100% { transform: translateY(0) rotate(0); }
  35% { transform: translateY(-5px) rotate(-8deg); }
  70% { transform: translateY(1px) rotate(3deg); }
}
@media (prefers-reduced-motion: reduce) {
  .cart-ribbon.added, .cart-ribbon.added .cart-count, .cart-ribbon.added .cart-icon { animation: none; }
}

/* The cart over the whole screen, above the ribbon. */
.cart-panel.full {
  inset: 0;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: auto;
  max-width: none;
  max-height: none;
  z-index: 10002;
  border: 0;
  border-radius: 0;
  background-color: #0d0a12;
  box-shadow: none;
}
/* A portal: a circle widens out of the cart ribbon (--portal-x/y, ApplicationsPanel.tsx) with
   a glow at the ribbon, and the sheet rises into it a beat later.
   Closing runs it backwards into the ribbon. */
.cart-panel.full.in { animation: cart-portal-in 0.62s cubic-bezier(0.65, 0, 0.25, 1); }
.cart-panel.full.out { animation: cart-portal-out 0.46s cubic-bezier(0.6, 0, 0.8, 0.4) forwards; pointer-events: none; }
.cart-panel.full.in .cart-sheet { animation: cart-sheet-rise 0.62s cubic-bezier(0.2, 0.9, 0.25, 1); }
.cart-panel.full.out .cart-sheet { animation: cart-sheet-sink 0.3s ease-in forwards; }
/* The contour map (topoBackground.ts) fills the space either side of the sheet. It fades in
   once the portal has opened, and out first as it closes. */
.cart-panel.full::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: var(--topo);
  background-size: cover;
  background-position: center;
}
.cart-panel.full.in::before { animation: topo-fade-in 0.7s ease-out 0.6s both; }
.cart-panel.full.out::before { animation: topo-fade-out 0.15s ease-in forwards; }
@keyframes topo-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes topo-fade-out { to { opacity: 0; } }
.cart-panel.full .cart-sheet { position: relative; z-index: 1; }
.cart-panel.full::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at var(--portal-x, 85%) var(--portal-y, 100%),
    rgba(170, 120, 255, 0.55), rgba(106, 63, 168, 0.25) 18%, transparent 45%);
}
.cart-panel.full.in::after { animation: cart-portal-glow 0.9s ease-out; }
.cart-panel.full.out::after { animation: cart-portal-glow 0.46s ease-in reverse; }
@keyframes cart-portal-in {
  from { clip-path: circle(0 at var(--portal-x, 85%) var(--portal-y, 100%)); }
  to { clip-path: circle(150% at var(--portal-x, 85%) var(--portal-y, 100%)); }
}
@keyframes cart-portal-out {
  from { clip-path: circle(150% at var(--portal-x, 85%) var(--portal-y, 100%)); }
  to { clip-path: circle(0 at var(--portal-x, 85%) var(--portal-y, 100%)); }
}
@keyframes cart-sheet-rise {
  0%, 25% { opacity: 0; transform: translateY(70px) scale(0.96); filter: blur(6px); }
  100% { opacity: 1; transform: none; filter: none; }
}
@keyframes cart-sheet-sink {
  to { opacity: 0; transform: translateY(50px) scale(0.97); filter: blur(4px); }
}
@keyframes cart-portal-glow {
  0% { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cart-panel.full.in, .cart-panel.full.out, .cart-panel.full.in .cart-sheet, .cart-panel.full.out .cart-sheet,
  .cart-panel.full.in::after, .cart-panel.full.out::after,
  .cart-panel.full.in::before, .cart-panel.full.out::before { animation-duration: 0.01s; animation-delay: 0s; }
}
.cart-sheet {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1080px;
  height: 100%;
  margin: 0 auto;
  background: var(--panel);
  border-left: 1px solid #3a2a52;
  border-right: 1px solid #3a2a52;
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.6);
  min-height: 0;
}
.cart-panel.full .cart-head { padding: 14px 18px; font-size: 16px; }
.cart-panel.full .cart-close { font-size: 26px; }
.cart-panel.full .cart-body { padding: 0; display: flex; flex-direction: column; }
.cart-panel.full .cart-body[hidden] { display: none; }
.cart-panel.full #cartBody ~ .cart-body:not([hidden]) { padding: 12px 18px; display: block; }

/* Cart, Checkout, Receipt. */
.checkout-flow { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.step-trail {
  display: flex;
  justify-content: center;
  gap: 28px;
  margin: 0;
  padding: 14px 18px 10px;
  list-style: none;
  font-size: 12.5px;
  color: var(--dim);
}
.step-trail li { display: flex; align-items: center; gap: 7px; }
.step-dot {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 700;
}
.step-trail li.on { color: #e6d6ff; font-weight: 650; }
.step-trail li.on .step-dot { background: #6a3fa8; border-color: #8a63d2; color: #fff; }
.step-trail li.done { color: var(--muted); }
.step-trail li.done .step-dot { background: rgba(79, 191, 139, 0.15); border-color: rgba(79, 191, 139, 0.5); color: var(--good); }
.step-body { flex: 1; overflow-y: auto; padding: 12px 18px; min-height: 0; }
.cart-panel.full .cart-tools { padding: 10px 18px; }
.cart-tools-note { color: var(--dim); font-size: 12px; }

.checkout-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  background: #150f1c;
}
.checkout-count { margin-right: auto; color: var(--muted); font-size: 12.5px; }
.checkout-go.btn.primary { background: #6a3fa8; border-color: #8a63d2; color: #fff; padding: 9px 22px; font-weight: 650; }
.checkout-go.btn.primary:hover:not(:disabled) { background: #7c4cc4; }
.checkout-go.btn.primary:disabled { opacity: 0.45; }

/* A line's three choices. */
.cart-panel.full .cart-row { cursor: default; align-items: flex-start; }
.line-opts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.line-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.line-opt input { margin: 0; accent-color: #8a63d2; }
.line-opt.on { border-color: rgba(138, 99, 210, 0.6); background: rgba(138, 99, 210, 0.14); color: #e6d6ff; }

/* The checkout step. */
.checkout-section { margin-bottom: 22px; }
.checkout-section h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0 10px;
  font-size: 13px;
  color: #e6d6ff;
}
.checkout-section .cart-count { position: static; }
.checkout-hint { color: var(--dim); font-size: 11.5px; margin: 4px 0 0; }
.checkout-busy { color: var(--muted); font-size: 12.5px; padding: 6px 0 14px; }
.hand-row, .receipt-row, .ready-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  margin-bottom: 7px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: var(--panel-2);
}
.hand-row .cart-text, .receipt-row .cart-text, .ready-row .cart-text { flex: 1; min-width: 0; }
.hand-row.applied { border-color: rgba(79, 191, 139, 0.45); }
.btn.tiny.good { color: var(--good); border-color: rgba(79, 191, 139, 0.5); background: rgba(79, 191, 139, 0.1); }

/* The receipt. */
.receipt-head { text-align: center; padding: 6px 0 16px; }
.receipt-head h2 { margin: 0 0 4px; font-size: 22px; color: #e6d6ff; }
.receipt-total { margin-top: 8px; font-size: 14px; color: var(--muted); }
.receipt-total b { color: var(--text); }
.receipt-mark {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 13px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.06);
  color: var(--muted);
}
.receipt-row.sent .receipt-mark, .receipt-row.applied .receipt-mark { background: rgba(79, 191, 139, 0.15); color: var(--good); }
.receipt-row.failed .receipt-mark { background: rgba(255, 99, 99, 0.14); color: #ff8a8a; }
.receipt-state { display: block; font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.receipt-row.sent .receipt-state, .receipt-row.applied .receipt-state { color: var(--good); }
.receipt-row.failed .receipt-state { color: #ff8a8a; }

@media (max-width: 700px) {
  .step-trail { gap: 14px; }
  .cart-tools-note { display: none; }
  .cart-sheet { border: 0; }
}

/* A line's readiness at checkout. */
.ready-chip {
  flex: 0 0 auto;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 650;
}
.ready-row.ready .ready-chip { padding: 0; color: var(--good); }
/* A line still waiting on answers puts out a yellow tab on its left with the count, under a
   Pending questions title over the tab column. */
.ready-list.pending { padding-left: 30px; }
.pending-title {
  margin: 0 0 6px -30px;
  font-size: 10.5px;
  font-weight: 750;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #f0c75e;
}
.ready-row { position: relative; }
.ready-row .attention-tab {
  position: absolute;
  left: -27px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 27px;
  height: 26px;
  border-radius: 7px 0 0 7px;
  background: #f0c75e;
  color: #2a1f3d;
  font-size: 12.5px;
  font-weight: 800;
  box-shadow: -2px 1px 4px rgba(0, 0, 0, 0.35);
}
.ready-row.waiting { border-left-color: #f0c75e; }

/* A line leaving the cart (CartList.tsx, LEAVE_MS): marked applied it brightens green and fades
   up; taken out with the X it slides off to the right. Either way the space it held folds shut. */
.cart-row.leaving { overflow: hidden; pointer-events: none; }
.cart-row.leaving.applied { animation: row-applied 0.38s ease-in forwards; }
.cart-row.leaving.removed { animation: row-removed 0.38s ease-in forwards; }
@keyframes row-applied {
  0% { border-color: rgba(79, 191, 139, 0.7); background: rgba(79, 191, 139, 0.14); }
  45% { opacity: 1; transform: none; }
  80% { opacity: 0; transform: translateY(-6px) scale(0.98); }
  100% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; margin-bottom: 0; border-width: 0; }
}
@keyframes row-removed {
  0% { opacity: 1; transform: none; }
  60% { opacity: 0; transform: translateX(60px); }
  100% { opacity: 0; transform: translateX(60px); max-height: 0; padding-top: 0; padding-bottom: 0; margin-bottom: 0; border-width: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cart-row.leaving.applied, .cart-row.leaving.removed { animation-duration: 0.01s; }
}

/* History, at the cart's bottom left; it shakes when a line is marked applied. */
.btn.history-btn { display: inline-flex; align-items: center; gap: 6px; }
.btn.history-btn .cart-count { position: static; }
.btn.history-btn.shake { animation: history-shake 0.55s ease-in-out; border-color: rgba(79, 191, 139, 0.6); color: var(--good); }
@keyframes history-shake {
  0%, 100% { transform: none; }
  15% { transform: translateX(-4px) rotate(-3deg); }
  30% { transform: translateX(4px) rotate(3deg); }
  45% { transform: translateX(-3px) rotate(-2deg); }
  60% { transform: translateX(3px) rotate(2deg); }
  75% { transform: translateX(-1px); }
}
@media (prefers-reduced-motion: reduce) { .btn.history-btn.shake { animation: none; } }
.checkout-bar .checkout-count { margin-left: 4px; }

/* Checkout itself is green: the go button of the cart. */
#cartRun.checkout-go.btn.primary { background: #1f9d64; border-color: #34c483; color: #fff; }
#cartRun.checkout-go.btn.primary:hover:not(:disabled) { background: #25b574; }

/* Find on map, on a history line: a faint purple with a pin. */
.btn.tiny.find-on-map { display: inline-flex; align-items: center; gap: 4px;
  border-color: rgba(138, 99, 210, 0.3); color: #c9b3ef; background: rgba(138, 99, 210, 0.05); }
.btn.tiny.find-on-map:hover { background: rgba(138, 99, 210, 0.14); border-color: rgba(138, 99, 210, 0.55); }
.receipt-row .btn.tiny { flex: 0 0 auto; }

/* Questions to answer or My details, at checkout: one shown at a time. */
.concern-tabs { display: flex; gap: 6px; margin-bottom: 12px; border-bottom: 1px solid var(--line); }
.concern-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-bottom: -1px;
  padding: 8px 14px;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: 8px 8px 0 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.concern-tab:hover { color: var(--text); }
.concern-tab.on { color: #e6d6ff; background: var(--panel-2); border-color: var(--line); font-weight: 650; }
.concern-tab .cart-count { position: static; }
.concern-tab .cart-count.due { background: rgba(240, 199, 94, 0.18); color: #f0c75e; }
/* Finished waits, grayed out, until nothing is left to answer. */
#checkoutDone:disabled { background: #2a2a30; border-color: #3a3a42; color: #8a8a94; opacity: 1; cursor: not-allowed; }
.ready-row { flex-wrap: wrap; }
.ready-row a.btn, .receipt-row a.btn, .cart-row a.btn { text-decoration: none; }

/* Checkout lines are laid out in three columns, the same on every line: the title, the state
   (the tape, or Ready) centred in a column of its own, and the buttons on the right. The state
   and buttons line up from line to line and never reach the title. Narrow, the title takes
   the first row and the state and buttons share the second. */
.ready-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 190px 270px;
  align-items: center;
  column-gap: 14px;
}
.ready-row .cart-text { min-width: 0; }
.ready-state { display: flex; justify-content: center; align-items: center; min-height: 28px; }
.line-buttons { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
@media (max-width: 760px) {
  .ready-row { grid-template-columns: minmax(0, 1fr); row-gap: 10px; }
  .ready-state { justify-content: flex-start; }
  .line-buttons { flex-wrap: wrap; justify-content: flex-start; }
}

/* The Job Cart's close X, large and easy to hit. */
.cart-panel.full .cart-head .cart-close {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin: -8px -6px -8px 4px;
  font-size: 46px;
  line-height: 1;
  border-radius: 10px;
  transition: background 0.15s ease, color 0.15s ease, transform 0.2s ease;
}
.cart-panel.full .cart-head .cart-close:hover { background: rgba(255, 255, 255, 0.08); color: #fff; transform: rotate(90deg); }

/* The history rises over the cart from the bottom and falls back down (AppliedHistory.tsx). The
   caret at its top centre pushes it down again. */
.cart-sheet { overflow: hidden; }
.history-sheet {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-top: 1px solid #3a2a52;
  box-shadow: 0 -18px 40px rgba(0, 0, 0, 0.55);
}
.history-sheet.in { animation: history-rise 0.4s cubic-bezier(0.2, 0.9, 0.25, 1); }
.history-sheet.out { animation: history-fall 0.32s cubic-bezier(0.55, 0, 0.85, 0.35) forwards; pointer-events: none; }
@keyframes history-rise { from { transform: translateY(100%); } }
@keyframes history-fall { to { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) {
  .history-sheet.in, .history-sheet.out { animation-duration: 0.01s; }
}
.history-close {
  align-self: center;
  display: grid;
  place-items: center;
  width: 64px;
  height: 34px;
  margin-top: 6px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}
.history-close:hover { color: #e6d6ff; background: rgba(255, 255, 255, 0.06); }
.history-close:hover svg { animation: caret-nudge 0.7s ease-in-out infinite; }
@keyframes caret-nudge { 50% { transform: translateY(4px); } }
.history-title { margin: 0 0 4px; text-align: center; font-size: 15px; color: #e6d6ff; }

/* Back to the cart, a plain arrow. */
.btn.back-btn { display: grid; place-items: center; width: 40px; height: 36px; padding: 0; }

/* Clear cart, at the right of the cart's tools: red like Archive, asking once more before it
   empties the cart; the lines then slide out one after another. */
.btn.tiny.clear-cart {
  margin-left: auto;
  border-color: rgba(255, 92, 92, 0.22);
  color: #d6a3a3;
  background: rgba(255, 92, 92, 0.03);
}
.btn.tiny.clear-cart:hover { background: rgba(255, 92, 92, 0.1); border-color: rgba(255, 92, 92, 0.4); }
.btn.tiny.clear-cart.confirming { background: rgba(255, 92, 92, 0.2); border-color: rgba(255, 92, 92, 0.6); color: #ffd0d0; }
.cart-clearing .cart-row { pointer-events: none; animation: row-removed 0.38s ease-in forwards; }
.cart-clearing .cart-row:nth-child(2) { animation-delay: 0.04s; }
.cart-clearing .cart-row:nth-child(3) { animation-delay: 0.08s; }
.cart-clearing .cart-row:nth-child(n + 4) { animation-delay: 0.12s; }
/* The toast and the working strip along the bottom of the map. */

.toast {
  position: fixed;
  bottom: 22px; left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 10px 16px;
  border-radius: 9px;
  font-size: 13px;
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s, transform 0.2s, visibility 0s linear 0.2s;
  z-index: 10010;
  max-width: 70vw;
}
.toast.show { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
  transition: opacity 0.2s, transform 0.2s, visibility 0s; }
/* Its button still answers while the notice fades out; hidden once the fade ends. */
.toast.acts { pointer-events: auto; }
.toast-act {
  margin-left: 10px; padding: 2px 10px; border-radius: 6px; cursor: pointer;
  background: transparent; border: 1px solid var(--accent); color: var(--accent); font: inherit;
}

/* Centred along the bottom of the map. In the left corner it sat over the crime and home
   value legends. */
.working {
  position: absolute;
  bottom: 22px; left: 0; right: 0;
  width: max-content;
  margin: 0 auto;
  /* Over the map, which is a layer of its own at 0, and under every panel and overlay. */
  z-index: 800;
  display: none;
  flex-direction: column;
  gap: 6px;
  max-width: min(320px, calc(100% - 24px));
  padding: 9px 12px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 9px;
  box-shadow: var(--shadow);
  font-size: 12.5px;
  color: var(--muted);
  pointer-events: none;
}
.working.show { display: flex; }
.working-row { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.working-dot {
  flex: 0 0 auto;
  width: 9px; height: 9px;
  border-radius: 50%;
  border: 2px solid #8a63d2;
  border-top-color: transparent;
  animation: working-spin 0.8s linear infinite;
}
@keyframes working-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .working-dot { animation: none; border-top-color: #8a63d2; opacity: 0.55; }
}

@media (max-width: 700px) {
  .working { bottom: 14px; font-size: 12px; max-width: calc(100% - 20px); }
  /* On a phone the applications panel comes up from the same corner. Whoever opened it is
     reading it, so the strip stands down until it is closed. */
  body:has(#cartPanel:not([hidden])) .working { display: none; }
}
/* The crime and home-value overlays: legends, popups and the listing dot key. */

.crime-legend,
.house-legend {
  background: rgba(18, 21, 27, 0.92);
  border: 1px solid #2b313c;
  border-radius: 8px;
  padding: 10px 12px;
  min-width: 230px;
  max-width: 268px;
  box-sizing: border-box;
  font-size: 11px;
  line-height: 1.45;
  color: #c9d1da;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}

.crime-legend strong,
.house-legend strong { color: #e8edf3; font-size: 11.5px; }

.crime-ramp,
.house-ramp {
  display: flex;
  margin: 7px 0 3px;
  border-radius: 3px;
  overflow: hidden;
  height: 9px;
}

.crime-ramp span,
.house-ramp span { flex: 1; }

/* The value key fades out and folds away while the Value switch is off. */
.house-value-key {
  max-height: 60px;
  overflow: hidden;
  transition: opacity 0.25s ease, max-height 0.25s ease, margin 0.25s ease;
}
.house-legend.values-off .house-value-key { opacity: 0; max-height: 0; margin-bottom: -2px; }

.crime-scale,
.house-scale {
  display: flex;
  justify-content: space-between;
  color: #8a94a2;
  font-size: 10px;
}

.crime-note,
.house-note {
  color: #98a2b0;
  margin-top: 5px;
}

.crime-key { display: flex; align-items: center; gap: 6px; margin-top: 5px; color: #98a2b0; }
.crime-swatch { flex: 0 0 auto; width: 14px; height: 10px; border-radius: 2px; }
.crime-swatch.small { background: rgba(90, 98, 112, 0.2); border: 1px dashed #6b7280; }
.crime-swatch.none { background: transparent; border: 1px solid #3a414d; }

/* What the teal dots are, in the legend's own text colour rather than the muted notes. */
.house-keyrow { margin-top: 6px; color: #c9d1da; }
.leaflet-container.over-house-dot { cursor: pointer; }

.crime-pop,
.house-pop { font-size: 12px; line-height: 1.5; }
/* Zillow for this ZIP, renting and buying. */
.house-links { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 5px; }
.house-pop .house-links a { color: var(--accent); }
.crime-pop strong,
.house-pop strong { display: block; margin-bottom: 3px; font-size: 13px; }
.crime-pop .crime-note,
.house-pop .house-note { margin-top: 4px; }

/* The legend dot, matching the rental dots on the map: coloured by rent on the value ramp. */
.house-key {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: linear-gradient(135deg, #3f9a7d, #5579b8 55%, #b087bf);
  border: 1px solid #0b1016;
  vertical-align: -1px;
  margin-right: 3px;
}

@media (max-width: 700px) {
  /* The legend covered two thirds of a phone map. The ramp and its two ends carry the
     meaning; the sourcing lines below it do not, and they are in the privacy page. */
  /* A legend takes a third of a phone map and sits on the toggle that turns its own layer
     off. The colours run cheap to dear either way, which the pins do not need explaining. */
  .crime-legend,
  .house-legend { display: none; }
}
.house-pop-zip { margin-top: 8px; padding-top: 8px; border-top: 1px solid rgba(255, 255, 255, 0.12); }
/* The opening questions. */

@media (max-width: 700px) {
  /* The browser bars take part of 100vh, and the buttons at the card's foot went under them. */
  .welcome-card { max-height: calc(100dvh - 40px); }
}

/* Shown once, the first time an account opens the board. Everything behind it is still
   loading while it is up, so the reader answers and the board is already there. */
.welcome {
  position: fixed;
  inset: 0;
  z-index: 10050;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(8, 10, 14, 0.82);
  backdrop-filter: blur(3px);
}
.welcome[hidden] { display: none; }

.welcome-card {
  width: min(560px, 100%);
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  background: var(--panel, #12151b);
  border: 1px solid var(--line, #2b313c);
  border-radius: 14px;
  padding: 22px 22px 18px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.welcome-card h2 { margin: 0 0 18px; font-size: 20px; font-weight: 650; }

.welcome-field { display: block; margin-bottom: 16px; }
.welcome-field > span {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  margin-bottom: 7px;
}
.welcome-field > span em {
  font-style: normal;
  font-weight: 400;
  color: var(--muted);
  margin-left: 5px;
}
.welcome-field input[type="text"],
.welcome-field input[type="file"] {
  width: 100%;
  padding: 9px 10px;
  border-radius: 8px;
  border: 1px solid var(--line, #2b313c);
  background: var(--panel-2, #16181d);
  color: var(--text, #e8eaed);
  font-size: 13.5px;
}
.welcome-field input[type="text"]::placeholder { color: var(--muted); opacity: 1; }
.welcome-field small { display: block; margin-top: 5px; color: var(--muted); font-size: 11.5px; }

/* Matching cities under the home city field. In the flow rather than floating: the card
   scrolls, and a floating list was cut off at its bottom edge. */
.city-list {
  list-style: none;
  margin: 4px 0 0;
  padding: 4px;
  max-height: 216px;
  overflow-y: auto;
  border: 1px solid var(--line, #2b313c);
  border-radius: 8px;
  background: var(--panel-2, #16181d);
}
.city-list[hidden] { display: none; }
.city-option {
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text, #e8eaed);
  cursor: pointer;
}
.city-option:hover,
.city-option.on { background: var(--accent-dim, #1d3557); }

.welcome-file {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 168px;
  aspect-ratio: 1;
  margin: 0 auto;
  padding: 14px;
  box-sizing: border-box;
  border-radius: 10px;
  border: 1px solid var(--line, #2b313c);
  background: var(--panel-2, #16181d);
}
.welcome-file-name {
  flex: 0 0 auto;
  max-width: 100%;
  min-width: 0;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13.5px;
  color: var(--text, #e8eaed);
}
.welcome-file-name.none { color: var(--muted); }
.welcome-file .clip { flex: 0 0 auto; width: 36px; height: 36px; color: var(--accent, #4ea1ff); }

/* The resume heading stands out: accent colour, heavier and larger than the other field labels. */
.welcome-field > span.welcome-resume-title {
  color: var(--accent, #4ea1ff);
  font-size: 14px;
  font-weight: 750;
  letter-spacing: 0.02em;
  text-align: center;
}

.welcome-says { min-height: 18px; color: var(--bad, #ef5f6b); font-size: 12.5px; }
.welcome-says.working { color: var(--muted); }

.welcome-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
.welcome-buttons button {
  padding: 9px 18px;
  border-radius: 8px;
  border: 1px solid var(--accent, #4ea1ff);
  background: var(--accent, #4ea1ff);
  color: #0b1016;
  font-size: 13.5px;
  font-weight: 620;
  cursor: pointer;
}
.welcome-buttons button.ghost {
  background: transparent;
  border-color: var(--line, #2b313c);
  color: var(--muted);
  font-weight: 500;
}
.welcome-buttons button:disabled { opacity: 0.55; cursor: progress; }

/* Kinds of work and industries: a two-column grid of rows, each a label and a switch. */
.welcome-switches {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}
@media (max-width: 480px) {
  .welcome-switches { grid-template-columns: 1fr; }
}
.welcome-switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--line, #2b313c);
  background: var(--panel-2, #16181d);
  color: var(--text, #e8eaed);
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.welcome-switch:hover { background: #1c1f26; }
.welcome-switch:focus-visible { outline: 2px solid var(--accent, #4ea1ff); outline-offset: 1px; }
.welcome-switch.on { border-color: var(--accent, #4ea1ff); }
.welcome-switch.on .welcome-switch-label { font-weight: 600; }
.welcome-switch-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.welcome-switch-track {
  position: relative;
  flex: 0 0 auto;
  width: 32px;
  height: 18px;
  border-radius: 999px;
  background: #3a404c;
  transition: background 0.15s ease;
}
.welcome-switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #e8eaed;
  transition: transform 0.15s ease;
}
.welcome-switch.on .welcome-switch-track { background: var(--accent, #4ea1ff); }
.welcome-switch.on .welcome-switch-thumb { transform: translateX(14px); background: #0b1016; }

/* The copy of the card that shrinks into the button that reopens it (closeAnimation.ts). */
.welcome-ghost {
  position: fixed;
  z-index: 10051;
  margin: 0;
  overflow: hidden;
  pointer-events: none;
  transform-origin: center;
}

/* The silhouette on the Personal profile buttons, above the filters and in Account settings. */
#welcomeAgain, #editSetup { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
#welcomeAgain[hidden] { display: none; }
#welcomeAgain { color: var(--muted); border-color: var(--line); background: var(--panel-2); }
#welcomeAgain:hover { color: var(--text); border-color: #6b717c; }
.profile-icon { flex: 0 0 auto; }
/* The cover shown until the first listings are on the board. */

/* The cover shown until the first listings are on the board. */
.boot-cover { position: fixed; inset: 0; z-index: 10100; display: grid; place-items: center;
  background: var(--bg); transition: opacity 0.15s ease-out; }
.boot-cover.gone { opacity: 0; pointer-events: none; }
.boot-mark { display: flex; flex-direction: column; align-items: center; gap: 14px;
  animation: boot-pulse 1.4s ease-in-out infinite; }
.boot-mark span { font-size: 26px; font-weight: 680; letter-spacing: 0.4px; color: var(--text); }
@keyframes boot-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.7; transform: scale(0.96); } }
/* Account settings. */

.topbar .whorow .account-btn { display: inline-flex; align-items: center; max-width: 20ch; }
.account-btn .who-name { color: inherit; }
.account-btn .account-gear { flex: 0 0 auto; margin-left: 6px; opacity: 0.85; }
.account-btn:hover .account-gear, .account-btn.on .account-gear { opacity: 1; }
.account-btn.on { background: #1b1424; border-color: #6a4a9c; }

.account-panel {
  position: fixed;
  top: var(--topbar-h, 68px);
  right: 12px;
  width: 360px;
  max-width: calc(100vw - 24px);
  z-index: 940;
  background: var(--panel);
  border: 1px solid #6a4a9c;
  border-radius: var(--radius);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  overflow: hidden;
}
.account-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 16px;
  margin: 0;
  padding: 12px;
  font-size: 13px;
  border-bottom: 1px solid var(--line);
}
.account-facts dt { color: var(--muted); }
.account-facts dd { margin: 0; color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.account-actions { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px;
  border-bottom: 1px solid var(--line); }
.account-delete { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px; }
.account-confirm { display: flex; flex-wrap: wrap; gap: 8px; }
.btn.danger { border-color: #6e3434; color: #f0a8a8; }
.btn.danger:hover { background: #2a1616; border-color: var(--bad); }
.btn.danger.solid { background: var(--bad); border-color: var(--bad); color: #1c0707; }
.btn.danger.solid:hover { background: #e47474; }
.account-says { flex: 1 1 100%; font-size: 12.5px; color: var(--muted); }
.account-says:empty { display: none; }
.account-says.bad { color: var(--bad); }

@media (max-width: 700px) {
  .account-panel { left: 12px; right: 12px; width: auto; }
  .account-panel .btn { min-height: 40px; padding: 8px 14px; }
}
/* The Feedback box. */

/* Under the logo: the brand and a small grey Feedback button stacked. */
.brand-stack { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.btn.feedback-btn { white-space: nowrap; display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; font-size: 11px; font-weight: 500;
  background: transparent; border-color: var(--line); color: var(--dim); }
.btn.feedback-btn:hover { background: var(--panel-2); border-color: #6b717c; color: var(--muted); }
.btn.feedback-btn.on { background: var(--panel-2); border-color: #6b717c; color: var(--text); }
.feedback-icon { display: block; flex: 0 0 auto; width: 13px; height: 13px; }

.feedback-panel {
  position: fixed;
  top: var(--topbar-h, 68px);
  left: 12px;
  width: 380px;
  max-width: calc(100vw - 24px);
  z-index: 950;
  background: var(--panel);
  border: 1px solid #2f5f96;
  border-radius: var(--radius);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
}
.feedback-form { display: flex; flex-direction: column; gap: 10px; padding: 10px 12px 12px; }
.feedback-head { display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; }
.feedback-form textarea {
  width: 100%;
  min-height: 120px;
  resize: vertical;
  box-sizing: border-box;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text);
  padding: 9px 10px;
  font: inherit;
  font-size: 14px;
}
.feedback-form textarea:focus { outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(78, 161, 255, 0.18); }
.feedback-foot { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.feedback-says { margin-right: auto; font-size: 12.5px; color: var(--muted); }
.feedback-says.good { color: var(--good); }
.feedback-says.bad { color: var(--bad); }

@media (max-width: 700px) {
  .topbar .btn.feedback-btn { flex: 0 0 auto; padding: 3px 9px; font-size: 11.5px; }
  .feedback-panel { left: 12px; right: 12px; width: auto; }
}
/* The sign-in cover's look. The rules that hide the board until it is unlocked, and the cover's
   own place over the page, stay inline in board.html so the board stays hidden even if this
   stylesheet fails to load. */

#lockscreen form { display: flex; flex-direction: column; gap: 12px; width: 260px; }
#lockscreen .lockTitle { color: #eee; font-size: 20px; font-weight: 600; }
#lockscreen input {
  padding: 10px; border-radius: 6px; border: 1px solid #444;
  background: #1c1c1c; color: #eee; font-size: 15px;
}
#lockscreen button {
  padding: 10px; border-radius: 6px; border: 0; background: #e0483c;
  color: #fff; font-size: 15px; cursor: pointer;
}
#lockscreen .lockSays { color: #e0483c; font-size: 13px; min-height: 16px; }
#lockscreen .lockWait { color: #eee; text-align: center; }
/* Touch screens: a tap leaves the hover look stuck on whatever was last tapped, so on a screen
   without hover each control keeps its own look under the finger. This file is last in
   styles.ts, after every hover rule it undoes, and each state (open, on cart, waiting, applied)
   is put back after the plain reset so it keeps its look. */

@media (hover: none) {
  /* :not(.active) so undoing the hover look does not also undo the selected look. */
  .card:hover:not(.active) { border-color: var(--line-soft); background: var(--panel-2); }
  .btn:hover { background: var(--panel-2); border-color: var(--line); }
  .btn.primary:hover { background: var(--accent); border-color: var(--accent); }
  .home-wrap:hover { transform: none; }

  .btn.danger:hover { background: var(--panel-2); border-color: #6e3434; }
  .btn.danger.solid:hover { background: var(--bad); border-color: var(--bad); }
  .btn.applied-on:hover { background: rgba(34, 214, 138, 0.14); border-color: rgba(34, 214, 138, 0.5); }
  .btn.tiny.apply-to:hover { background: #b28cff; border-color: #b28cff; }
  .btn.tiny.open-posting:hover { background: rgba(78, 161, 255, 0.03); border-color: rgba(78, 161, 255, 0.22); }
  .btn.tiny.archive-btn:hover { background: rgba(255, 92, 92, 0.03); border-color: rgba(255, 92, 92, 0.22); }
  .btn.tiny.mark-applied:hover { background: rgba(34, 214, 138, 0.03); border-color: rgba(34, 214, 138, 0.22); }
  .btn.tiny.apply-to.on:hover { background: #4c2a7a; border-color: #8a63d2; }
  .feedback-btn:hover { background: var(--panel-2); border-color: #2f5f96; }
  .feedback-btn.on:hover { background: var(--accent-dim); border-color: var(--accent); }
  .account-btn.on:hover { background: #1b1424; border-color: #6a4a9c; }
  .cart-btn.has:hover { border-color: #6a4a9c; }
  .cart-btn.on:hover { background: #4c2a7a; border-color: #8a63d2; }
  .cart-btn.needs:hover { border-color: #e0a423; }
  .more-summary.on:hover { border-color: var(--accent); }
}
/*$vite$:1*/