/* ==========================================================================
   Screens — Home, Scout, Yard, Bay, Runner, Desk
   ========================================================================== */

/* ---- Screen heading ---------------------------------------------------- */
.screen-head {
  display: flex;
  align-items: flex-end;
  gap: var(--s-5);
  margin-bottom: var(--s-5);
}
.screen-head__title { font-size: var(--t-h1); font-weight: 800; letter-spacing: -0.02em; }
.screen-head__sub { color: var(--c-text-3); font-size: var(--t-sm); margin-top: 0.15rem; }

/* ==========================================================================
   HOME — six equal agent cards in a row

   The approved mockup drew five. Post made it six, and six is the count the
   row is now proportioned for: one line, no wrap, every workspace on screen
   at once without a scroll. That last part is the whole job of this screen —
   a home that hides two of the six behind a scroll is a worse answer than
   slightly smaller cards, which is why this is a single row and not a 3x2.

   Two numbers moved to buy the sixth column, and both were already wrong:

   - The portrait box was 272px TALL, in pixels, while everything else in
     the app scales with the root size. It carried a square picture, so at
     any width under the mockup's it drew a square image floating in a
     letterboxed box — 220x272 at 1440 with five cards, and it would have
     been 175x272 with six. It is a scaling SQUARE now, which is the shape
     the pictures actually are.
   - The card's 33rem floor was set by that fixed box plus generous slack.
     With the box proportional the floor follows the content instead of
     holding the cards open, so six read as cards rather than columns.
   ========================================================================== */

.home {
  /* Bottom room clears the fixed build credit — see .page in base.css. */
  padding: var(--s-7) var(--page-x) 7.5rem;
  max-width: var(--page-max);
  margin: 0 auto;
}

.agent-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--s-5);
  align-items: stretch;
}

.agent-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Centred, which is what lets the floor below be a floor rather than a
     ceiling. With the content pinned to the top, every rem of card height
     past the content piled up as dead space under the blurb; centred, the
     card can stand tall enough to hold the row against the header without
     any one card looking bottom-heavy. */
  justify-content: center;
  gap: var(--s-4);
  /* The floor the five-card row already shipped with, kept. Only the column
     count and the portrait's shape moved; the card is the card. */
  min-height: 33rem;
  padding: var(--s-5) var(--s-5) var(--s-6);
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: 20px;
  color: inherit;
  text-decoration: none;
  position: relative;
  overflow: hidden;
  transition: background var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.agent-card:hover {
  background: var(--c-surface-2);
  border-color: rgba(224, 31, 38, 0.55);
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}
/* The red hairline again: it slides in along the card's foot on hover. */
.agent-card::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 3px;
  background: var(--c-red);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--dur) var(--ease);
}
.agent-card:hover::after,
.agent-card:focus-visible::after { transform: scaleX(1); }

/* The portrait box: the avatar sits in it at the mockup's size, and
   .avatar-feather (components.css) draws the soft edge over the image
   rather than masking the image itself — the note there says why. The
   avatar is visible from its first paint; nothing reveals it. */
.agent-card__portrait {
  width: 100%;
  max-width: 17rem;
  /* Square, and scaling with everything else.
     It used to be a flat 272px tall — a number inherited from the image's
     own height attribute back when five cards were wide enough to hide it.
     The pictures ARE square, so a box that keeps its height while the column
     narrows just draws grey air above and below the robot. An aspect ratio
     says the true thing once and holds at every width and every count.
     `--feather-rgb` below still has to match whatever sits behind it. */
  aspect-ratio: 1 / 1;
  height: auto;
  flex: none;
  margin-bottom: var(--s-2);
  --feather-rgb: var(--c-surface-rgb);
  /* In step with the card's own background transition below, so the rim of
     the portrait never sits a shade off the card it is fading into while
     the hover is still travelling. */
  transition: --feather-rgb var(--dur) var(--ease);
}
/* The card lightens under the cursor, so the edge it fades into changes
   with it. */
.agent-card:hover .agent-card__portrait { --feather-rgb: var(--c-surface-2-rgb); }
.agent-card__name {
  font-size: 2.75rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.05;
}
.agent-card__desc {
  font-size: var(--t-body);
  color: var(--c-text-3);
  text-align: center;
  max-width: 15rem;
  line-height: 1.4;
}
.agent-card__status {
  margin-top: auto;
  padding-top: var(--s-4);
}

/* ==========================================================================
   SCOUT — main column + right rail
   ========================================================================== */

.scout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--rail-w);
  gap: var(--s-5);
  align-items: start;
}
.scout__main { display: grid; gap: var(--s-5); min-width: 0; }
.scout__rail { display: grid; gap: var(--s-5); }

.results-count {
  font-size: var(--t-sm);
  color: var(--c-text-3);
  padding: 0 var(--s-1);
}

/* Right-rail rows sit tighter than main-column rows. */
.rail-row { padding: var(--s-3) var(--s-5); gap: var(--s-3); }
.rail-row .row__title { font-size: var(--t-body); font-weight: 600; }

.saved-row { padding: var(--s-3) var(--s-4) var(--s-3) var(--s-5); }
.saved-row .row__title { font-size: var(--t-sm); font-weight: 700; }
.saved-row .row__sub { font-size: var(--t-xs); }
.saved-row .price { font-size: var(--t-h3); }
/* Quantity and the note the counter wrote against it — the two fields that
   make a shortlist line useful, so they are on the row, not behind an edit. */
.saved-row__note {
  font-size: var(--t-xs);
  color: var(--c-text-2);
  margin-top: 0.15rem;
}
.saved-row .record-actions { margin-left: 0; }

/* A block action closing out a rail panel (Save a part), sitting on the
   same gutter as the rows above it. */
.rail-action {
  padding: var(--s-3) var(--s-5) var(--s-4);
  border-top: 1px solid var(--c-line-soft);
}

/* ==========================================================================
   YARD — vehicle grid + detail
   ========================================================================== */

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
}
.toolbar__search { flex: 1; min-width: 22rem; }
.toolbar .searchbar { height: 3.75rem; }
.toolbar .searchbar__input { font-size: var(--t-h3); }

.vehicle-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-5);
}
.vehicle-card {
  display: flex;
  flex-direction: column;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  overflow: hidden;
  text-align: left;
  color: inherit;
  position: relative;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.vehicle-card:hover {
  border-color: var(--c-surface-4);
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
}
.vehicle-card__photo {
  aspect-ratio: 16 / 10;
  background: linear-gradient(160deg, #2b3036 0%, #1e2226 100%);
  display: grid;
  place-items: center;
  color: var(--c-text-2);
  position: relative;
}
.vehicle-card__badge { position: absolute; top: var(--s-3); left: var(--s-3); }
/* A COLUMN, not a grid, so the price row's `margin-top: auto` can claim the
   slack — inside a grid an auto margin only ever moves an item within its own
   track, and the track is sized to its content, so nothing moved. Camper names
   run long ("2015 Forest River Cherokee 274DBH" wraps where its neighbours do
   not) and without this the prices sit at four heights across one row, which
   reads as a sloppy lot. */
.vehicle-card__body {
  padding: var(--s-4) var(--s-4) var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  flex: 1;
}
.vehicle-card__name { font-size: var(--t-h3); font-weight: 700; letter-spacing: -0.01em; }
.vehicle-card__trim { font-size: var(--t-sm); color: var(--c-text-3); }
/* Campers carry a condition as well as a status: what shape it is in, and
   whether it is for sale, are two different questions. The status rides the
   photo like a vehicle's; the condition sits in the body where it cannot be
   mistaken for it. */
.vehicle-card__cond { display: flex; }
.vehicle-card__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  /* Bottom of the card, so every price in a row lines up. */
  margin-top: auto;
  padding-top: var(--s-2);
}
.vehicle-card__price { font-size: var(--t-h2); font-weight: 800; letter-spacing: -0.02em; }
.vehicle-card__days { font-size: var(--t-xs); color: var(--c-text-3); text-align: right; }

/* Sold vehicles read as settled, not as an error. */
.vehicle-card--sold .vehicle-card__photo { filter: grayscale(1) brightness(0.7); }
.vehicle-card--sold .vehicle-card__price { color: var(--c-text-3); text-decoration: line-through; }

/* ---- Detail layout (Yard / Bay / Desk share this shape) ---------------- */
.detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 30rem;
  gap: var(--s-5);
  align-items: start;
}
.detail__main { display: grid; gap: var(--s-5); min-width: 0; }
.detail__side { display: grid; gap: var(--s-5); }
.detail__hero {
  aspect-ratio: 16 / 6.5;
  background: linear-gradient(160deg, #2b3036 0%, #1e2226 100%);
  display: grid;
  place-items: center;
  color: var(--c-text-2);
}
.detail__facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
  padding: var(--s-5);
}
.detail__body { padding: var(--s-5); display: grid; gap: var(--s-5); }

.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-sm);
  color: var(--c-text-3);
  margin-bottom: var(--s-4);
}
.breadcrumb button { color: var(--c-text-2); font-weight: 600; }
.breadcrumb button:hover { color: var(--c-text); text-decoration: underline; }

/* ==========================================================================
   BAY — job list + work order
   ========================================================================== */

.job-row__vehicle { font-size: var(--t-sm); color: var(--c-text-2); }
.job-row__problem { font-size: var(--t-sm); color: var(--c-text-3); margin-top: 0.1rem; }
.job-row__tech {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-sm);
  color: var(--c-text-2);
  white-space: nowrap;
}
.tech-avatar {
  width: 2rem; height: 2rem;
  border-radius: 50%;
  background: var(--c-surface-4);
  display: grid;
  place-items: center;
  font-size: var(--t-micro);
  font-weight: 800;
  color: var(--c-text);
  flex: none;
}

.timeline { display: grid; gap: var(--s-4); }
.timeline__item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-4);
  align-items: start;
}
.timeline__marker {
  width: 0.75rem; height: 0.75rem;
  border-radius: 50%;
  background: var(--c-surface-4);
  margin-top: 0.45rem;
  position: relative;
  flex: none;
}
.timeline__item--done .timeline__marker { background: var(--c-green); }
.timeline__item--current .timeline__marker { background: var(--c-red); box-shadow: 0 0 0 4px rgba(224,31,38,0.18); }
.timeline__when { font-size: var(--t-xs); color: var(--c-text-3); }
.timeline__what { font-size: var(--t-sm); }

.line-items { display: grid; gap: var(--s-2); }
.line-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--c-line-soft);
  font-size: var(--t-sm);
}
.line-item:last-child { border-bottom: 0; }
.line-item__total { font-weight: 800; font-size: var(--t-h3); }

/* ==========================================================================
   RUNNER — active calls + history
   ========================================================================== */

.call-card {
  display: grid;
  gap: var(--s-4);
  padding: var(--s-5);
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  border-left: 3px solid var(--c-red);
}
.call-card__head { display: flex; align-items: flex-start; gap: var(--s-4); }
.call-card__who { flex: 1; min-width: 0; }
.call-card__name { font-size: var(--t-h2); font-weight: 800; letter-spacing: -0.015em; }
.call-card__phone { font-size: var(--t-body); color: var(--c-text-2); margin-top: 0.1rem; }
.call-card__facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-4); }
.call-card__notes {
  padding: var(--s-4);
  background: var(--c-surface-2);
  border-radius: var(--r-btn);
  font-size: var(--t-sm);
  color: var(--c-text-2);
  line-height: 1.5;
}
.call-card__actions { display: flex; gap: var(--s-3); }

.active-calls { display: grid; gap: var(--s-4); }

/* ==========================================================================
   DESK — customers + profile
   ========================================================================== */

.customer-avatar {
  width: 3.5rem; height: 3.5rem;
  border-radius: 50%;
  background: var(--c-surface-4);
  display: grid;
  place-items: center;
  font-size: var(--t-body);
  font-weight: 800;
  flex: none;
}
.customer-avatar--lg { width: 5.5rem; height: 5.5rem; font-size: var(--t-h1); }

.profile-head {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  padding: var(--s-5);
}
.profile-head__name { font-size: var(--t-h1); font-weight: 800; letter-spacing: -0.02em; }
.profile-head__meta { color: var(--c-text-2); font-size: var(--t-body); margin-top: 0.15rem; }

.note-list { display: grid; gap: var(--s-3); }
.note {
  padding: var(--s-4);
  background: var(--c-surface-2);
  border: 1px solid var(--c-line-soft);
  border-radius: var(--r-btn);
}
.note__head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-2);
}
.note__meta { font-size: var(--t-xs); color: var(--c-text-3); }
/* The controls on a note and a follow-up are secondary to the words: the
   hit area stays generous, the drawn box shrinks. */
.note__head .icon-btn,
.followup .icon-btn { width: 2.25rem; height: 2.25rem; }
.note__body { font-size: var(--t-sm); line-height: 1.5; color: var(--c-text-2); }

.followup {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--c-line-soft);
}
.followup:last-child { border-bottom: 0; }
.followup__what { flex: 1; font-size: var(--t-sm); }
.followup__when { font-size: var(--t-xs); color: var(--c-text-3); white-space: nowrap; }
.followup--due .followup__when { color: var(--c-amber); font-weight: 700; }

/* ==========================================================================
   POST — composer and posts list on the left, the preview beside them

   Scout's shape, deliberately: main column plus a rail. What goes in the rail
   is the thing the main column is FOR — the post as the page would show it,
   redrawn on every keystroke. The rail is not sticky: at the desktop sizes
   this build targets, preview plus connector panel is taller than the space
   under the sticky header, and pinning a block that does not fit is how the
   bottom of it becomes unreachable.
   ========================================================================== */

.post {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--rail-w);
  gap: var(--s-5);
  align-items: start;
}
.post__main { display: grid; gap: var(--s-5); min-width: 0; }
.post__rail { display: grid; gap: var(--s-5); align-content: start; }

/* Clicking Edit on a row scrolls the composer up to meet the operator. The
   header is sticky, so without this the panel's own title lands behind it and
   the edit appears to start halfway down a form. */
.post__compose { scroll-margin-top: calc(var(--header-h) + var(--s-5)); }

/* ---- Composer ---------------------------------------------------------- */

.compose { padding: var(--s-5); display: grid; gap: var(--s-5); }
.compose__caption { min-height: 9rem; }
.compose__count {
  font-size: var(--t-xs);
  color: var(--c-text-3);
  justify-self: end;
  font-variant-numeric: tabular-nums;
}

.compose__lot { display: grid; gap: var(--s-3); }
.compose__pull { display: grid; gap: var(--s-3); justify-items: start; }

/* The unit's picture wherever this screen shows one small — a row, the
   composer, a line in the picker. A landscape tile, because the silhouettes
   are landscape: in the square .thumb the app uses for parts, a 16:8 vehicle
   sits letterboxed at half the width and reads as a smudge. Same gradient as
   the card photo in Yard, so a vehicle looks like itself in both screens. */
.unit-thumb {
  flex: none;
  width: 6.5rem;
  aspect-ratio: 16 / 10;
  border-radius: 10px;
  border: 1px solid var(--c-line-soft);
  background: linear-gradient(160deg, #2b3036 0%, #1e2226 100%);
  display: grid;
  place-items: center;
  color: var(--c-text-2);
  overflow: hidden;
}
.unit-thumb--sm { width: 5rem; }

/* The unit pulled off the lot. The red edge is this app's "you are here"
   mark, used here for what it actually is: the live link between this post
   and a record standing in Yard. */
.compose__unit {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-3) var(--s-4);
  background: var(--c-surface-2);
  border: 1px solid var(--c-line);
  border-left: 3px solid var(--c-red);
  border-radius: var(--r-btn);
}
.compose__unitText { flex: 1; min-width: 0; }
.compose__unitName { font-size: var(--t-h3); font-weight: 700; letter-spacing: -0.01em; }
.compose__unitSub { font-size: var(--t-sm); color: var(--c-text-3); margin-top: 0.1rem; }
.compose__unit .price { font-size: var(--t-h3); }
/* Sold while it was attached: the number is history now, not an ask. */
.compose__unit .price--sold { color: var(--c-text-3); text-decoration: line-through; }
.compose__unitActions { display: flex; align-items: center; gap: var(--s-2); flex: none; }

/* A post pointing at something Yard no longer has. Amber, not red: nothing
   is broken, a record it referred to has moved on. */
.compose__gone {
  display: grid;
  gap: var(--s-3);
  justify-items: start;
  padding: var(--s-4);
  border: 1px solid rgba(217, 144, 42, 0.38);
  background: rgba(217, 144, 42, 0.08);
  border-radius: var(--r-btn);
  color: var(--c-text-2);
  font-size: var(--t-sm);
}

.compose__at { display: grid; gap: var(--s-2); margin-top: var(--s-3); }
.compose__at .input { width: auto; min-width: 22rem; justify-self: start; }

.compose__actions { display: flex; align-items: center; gap: var(--s-3); }

/* ---- The preview ------------------------------------------------------- */

.preview { padding: var(--s-5); display: grid; gap: var(--s-4); }
.preview__note { font-size: var(--t-xs); color: var(--c-text-3); line-height: 1.5; }

/* A post as the page would show it.
   Carrying no invented engagement figures on purpose: showing what WILL be
   published is honest, and a made-up "42 likes" underneath it is not. */
.fbpost {
  background: var(--c-surface-2);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  overflow: hidden;
}
.fbpost__head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-4) var(--s-3);
}
/* Bobby's own signage mark, contained inside the page tile — never cropped
   to fill it, never redrawn. */
.fbpost__avatar {
  flex: none;
  width: 3.25rem;
  height: 3.25rem;
  padding: 0.3rem;
  border-radius: 50%;
  background: var(--c-header);
  border: 1px solid var(--c-line);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.fbpost__avatar img { width: 100%; height: auto; object-fit: contain; }
.fbpost__who { min-width: 0; display: grid; gap: 0.1rem; }
.fbpost__page { font-size: var(--t-sm); font-weight: 800; letter-spacing: -0.01em; }
.fbpost__meta {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-xs);
  color: var(--c-text-3);
}
.fbpost__caption {
  padding: 0 var(--s-4) var(--s-4);
  font-size: var(--t-body);
  line-height: 1.5;
  /* Line breaks typed into the composer survive into the preview. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.fbpost__caption--empty { color: var(--c-text-3); font-style: italic; }
.fbpost__media {
  aspect-ratio: 16 / 10;
  background: linear-gradient(160deg, #2b3036 0%, #1e2226 100%);
  display: grid;
  place-items: center;
  color: var(--c-text-2);
  border-top: 1px solid var(--c-line-soft);
}
.fbpost__card {
  display: grid;
  gap: 0.15rem;
  padding: var(--s-4);
  background: var(--c-surface);
  border-top: 1px solid var(--c-line);
}
.fbpost__cardName { font-size: var(--t-h3); font-weight: 700; letter-spacing: -0.01em; }
.fbpost__cardSub {
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-text-3);
}
.fbpost__cardPrice {
  font-size: var(--t-h2);
  font-weight: 800;
  color: var(--c-green);
  letter-spacing: -0.02em;
  margin-top: 0.15rem;
}
/* Sold since it was attached. Same treatment Yard gives a sold card, for the
   same reason: the figure stays readable as history, and stops reading as an
   asking price. */
.fbpost__cardPrice--sold { color: var(--c-text-3); text-decoration: line-through; }
.fbpost__media--sold { filter: grayscale(1) brightness(0.7); }
.fbpost__cardNote {
  margin-top: 0.35rem;
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--c-amber);
}
.fbpost__gone {
  padding: var(--s-4);
  border-top: 1px solid var(--c-line-soft);
  font-size: var(--t-sm);
  color: var(--c-amber);
}

/* ---- The posts list ---------------------------------------------------- */

.post-row__caption {
  font-size: var(--t-body);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.005em;
}
.post-row__when {
  display: grid;
  justify-items: end;
  gap: 0.25rem;
  flex: none;
}
.post-row__time { font-size: var(--t-xs); color: var(--c-text-3); white-space: nowrap; }
/* The row that is open in the composer above, wearing the same red edge as
   every other "you are here" in this app. */
.post-row--editing { background: var(--c-surface-2); box-shadow: inset 3px 0 0 var(--c-red); }

/* ---- Pull from the lot (dialog) ---------------------------------------- */

.lot-pick {
  border: 1px solid var(--c-line);
  border-radius: var(--r-btn);
  overflow-x: hidden;
  overflow-y: auto;
  max-height: 34rem;
}
.lot-pick__row { padding: var(--s-3) var(--s-4); gap: var(--s-3); }
/* A <button> may only contain phrasing content, so the two lines of a row
   are spans — and spans are inline, which ran the name and the trim together
   on one line. The grid is what stacks them without putting a <div> inside a
   button. */
.lot-pick__row .row__main { display: grid; gap: 0.1rem; }
.lot-pick__row .row__title { font-size: var(--t-body); font-weight: 700; }
.lot-pick__row .row__sub { font-size: var(--t-xs); }
.lot-pick__row .price { font-size: var(--t-h3); }
