/* ═══════════════════════════════════════════════════════════════════════════
   Balenton — direction 04. The shared design system.

   One grammar across four surfaces. The only structural difference between them is where the
   navigation sits: a bar at the bottom where the thumb is, a column on the left where the cursor
   is. Everything below is the same set of components, re-flowed.

   EVERY class here is prefixed `b-`. The desk already owns `.row`, `.board`, `.bay` and others
   with different meanings, and a shared stylesheet that quietly redefines them would break the
   board the moment both are loaded. The prefix also makes the migration visible: anything
   unprefixed is still on the old system.

   THE GARAGE'S COLOUR is three variables, set by shop-theme.js from shops.brand_colour:
     --brand      the fill
     --brand-on   the text that sits ON that fill, flipped by luminance
     --brand-ink  the brand colour darkened enough to be legible AS text
   Nothing here hard-codes a hue. Noukoua is #FFED00; a blue garage is the same file.

   And #FFED00 is never type. It is 1.1:1 on white. It is a fill, with black on it.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── icons ───────────────────────────────────────────────────────────────── */
/* Stroke only, no fill, currentColor — so an icon is the colour of the text beside it and the
   brand colour reaches them for free. Sizes are a short list, not arbitrary numbers. */
.ic {
  width: 21px; height: 21px; display: block; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.ic-sm { width: 16px; height: 16px; stroke-width: 1.9; }
.ic-lg { width: 26px; height: 26px; stroke-width: 1.6; }

/* ── surfaces ────────────────────────────────────────────────────────────── */
.b-panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow, 0 1px 2px rgba(16,18,27,.04), 0 8px 24px rgba(16,18,27,.06));
  overflow: hidden; margin-bottom: 12px;
}
.b-panel > .b-top {
  padding: 12px 15px; display: flex; justify-content: space-between; align-items: center; gap: 10px;
  background: var(--brand); color: var(--brand-on, #000);
}
.b-panel > .b-top.k { background: #0E0E10; color: #fff; }
.b-panel > .b-top .k2 {
  font-size: 11px; font-weight: 850; letter-spacing: .08em; text-transform: uppercase;
  display: flex; align-items: center; gap: 7px; min-width: 0;
}
.b-panel > .b-top.k .k2 { color: var(--brand); }
.b-panel > .b-top .amt { font-size: 16px; font-weight: 900; white-space: nowrap; }
.b-panel .b-in { padding: 15px; }

.b-lbl { font-size: 10.5px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3); }
.b-sub { font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.b-tiny { font-size: 11.5px; color: var(--ink-3); }
.b-num { font-variant-numeric: tabular-nums; }

/* ── the car, and what it needs ──────────────────────────────────────────── */
/* The photo leads. In a two-car household it is the only thing that tells somebody which vehicle
   they are looking at without reading a line of text. */
.b-carhero { position: relative; background: #0E0E10; color: #fff; border-radius: 18px; overflow: hidden; }
.b-carhero .shot {
  display: block; width: 100%; height: auto;
  filter: drop-shadow(0 16px 22px rgba(0, 0, 0, .55));
}
.b-carhero .band {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 13px 15px;
  background: linear-gradient(to top, rgba(0,0,0,.92) 36%, rgba(0,0,0,0));
}
.b-carhero .vname { font-size: 18px; font-weight: 850; letter-spacing: -.4px; }
.b-carhero .vmeta { font-size: 12px; color: rgba(255,255,255,.68); margin-top: 2px; }
.b-carhero .plate {
  position: absolute; top: 12px; right: 12px;
  background: var(--brand); color: var(--brand-on, #000);
  font-weight: 850; letter-spacing: 1.4px; font-size: 12.5px;
  padding: 4px 11px; border-radius: 5px; border: 2px solid #0E0E10;
}
.b-carhero .pick { position: absolute; top: 14px; left: 12px; display: flex; gap: 5px; }
.b-carhero .pick i { width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,.3); display: block; }
.b-carhero .pick i.on { background: var(--brand); width: 17px; border-radius: 3px; }
/* Nothing to render for this car: a black box with no picture reads as a loading failure. */
.b-carhero.nophoto { min-height: 120px; display: grid; place-items: center; }

/* A service line — used for what a car needs, and for anything else that is
   icon · title · detail · value. */
.b-svc { display: flex; align-items: center; gap: 11px; padding: 12px 15px; border-top: 1px solid var(--line-2); }
.b-svc:first-child { border-top: 0; }
.b-svc .bx {
  width: 34px; height: 34px; flex: 0 0 34px; border-radius: 10px;
  display: grid; place-items: center; background: var(--line-2); color: var(--ink-2);
}
.b-svc.due .bx { background: var(--brand); color: var(--brand-on, #000); }
.b-svc .g { flex: 1; min-width: 0; }
.b-svc .t { font-size: 14px; font-weight: 720; letter-spacing: -.15px; }
.b-svc .s { font-size: 11.5px; color: var(--ink-3); margin-top: 1px; }
.b-svc .amt { font-size: 14px; font-weight: 800; white-space: nowrap; }

.b-row { display: flex; align-items: center; gap: 12px; padding: 13px 15px; border-top: 1px solid var(--line-2); }
.b-row:first-child { border-top: 0; }
.b-row .bx { width: 38px; height: 38px; flex: 0 0 38px; border-radius: 11px; display: grid; place-items: center; background: var(--line-2); color: var(--ink-2); }
.b-row .g { flex: 1; min-width: 0; }
.b-row .t { font-size: 14.5px; font-weight: 700; letter-spacing: -.15px; }
.b-row .s { font-size: 12px; color: var(--ink-3); margin-top: 1px; }

/* ── chips and buttons ───────────────────────────────────────────────────── */
.b-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 750; padding: 3px 9px; border-radius: 30px; white-space: nowrap;
}
.b-chip.ok { background: var(--ok-bg); color: var(--ok); }
.b-chip.warn { background: var(--warn-bg); color: var(--warn); }
.b-chip.bad { background: var(--urgent-bg, #FEF3F2); color: var(--urgent-ink, #B42318); }
.b-chip.info { background: var(--info-bg); color: var(--info-ink, var(--info)); }
.b-chip.grey { background: var(--line-2); color: var(--ink-2); }
.b-chip.b { background: var(--brand); color: var(--brand-on, #000); }

.b-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 13px; border-radius: 12px; border: 0;
  font: inherit; font-size: 15px; font-weight: 750; cursor: pointer;
  background: #0E0E10; color: #fff;
}
.b-btn:hover { background: #26282E; }
.b-btn.o { background: var(--panel); border: 1.5px solid var(--line); color: var(--ink); }
.b-btn.o:hover { border-color: var(--brand-line, var(--brand)); color: var(--brand-ink, var(--ink)); }
.b-btn.b { background: var(--brand); color: var(--brand-on, #000); }
.b-btn:disabled { opacity: .45; cursor: not-allowed; }
.b-btn.auto { width: auto; }

/* ── the countdown ───────────────────────────────────────────────────────── */
/* Tabular numerals, or the line jitters sideways once a second as digit widths change. */
.b-cd { display: flex; gap: 6px; }
.b-cd div { flex: 1; text-align: center; border-radius: 10px; padding: 8px 2px; background: var(--line-2); }
.b-cd .v { font-size: 21px; font-weight: 850; letter-spacing: -.5px; line-height: 1; font-variant-numeric: tabular-nums; }
.b-cd .u { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; opacity: .6; margin-top: 3px; }
.b-panel > .b-top.k + .b-in .b-cd div { background: var(--line-2); }

/* ── phone shell: the bar goes to the thumb ──────────────────────────────── */
.b-app { display: flex; flex-direction: column; min-height: 100vh; }
@supports (min-height: 100dvh) { .b-app { min-height: 100dvh; } }

.b-mast { display: flex; align-items: center; gap: 11px; padding: 10px 16px 12px; }
.b-mast .mark { width: 36px; height: 36px; border-radius: 10px; background: #0E0E10; flex: 0 0 36px; overflow: hidden; }
.b-mast .mark img { width: 100%; height: 100%; object-fit: cover; display: block; }
.b-mast .gname { font-size: 15.5px; font-weight: 800; letter-spacing: -.25px; line-height: 1.15; }
.b-mast .gsub { font-size: 11.5px; color: var(--ink-3); font-weight: 550; }
.b-mast .sp { margin-left: auto; display: flex; align-items: center; gap: 10px; color: var(--ink-3); }

.b-body { flex: 1; }
.b-body > .b-panel, .b-body > .b-carwrap { margin-left: 16px; margin-right: 16px; }

/* One column per tab, counted rather than hardcoded.
   This said repeat(4, 1fr) while the bar has carried FIVE buttons — Accueil, Véhicules,
   Rendez-vous, Documents, Compte — so Compte wrapped onto a second row on every phone, and
   client.js never hid one to make the four fit. On a portal whose own comment says it is read
   on a phone in a waiting room, that is the first thing a customer sees. grid-auto-flow:column
   takes its count from the children, so adding a sixth tab cannot reintroduce this. */
.b-tabbar {
  position: sticky; bottom: 0; z-index: 20;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  background: var(--panel); border-top: 1px solid var(--line);
  padding: 9px 6px calc(9px + env(safe-area-inset-bottom));
}
.b-tabbar button {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: none; border: 0; font: inherit; cursor: pointer; color: var(--ink-4); padding: 2px 0;
}
.b-tabbar .t { font-size: 10px; font-weight: 750; }
.b-tabbar button.on { color: var(--ink); }
.b-tabbar button.on::after {
  content: ''; width: 16px; height: 3px; border-radius: 2px; background: var(--brand); margin-top: -2px;
}

/* ── wide shell: the bar becomes a column ────────────────────────────────── */
.b-wide { display: flex; min-height: 100vh; }
@supports (min-height: 100dvh) { .b-wide { min-height: 100dvh; } }

.b-side {
  flex: 0 0 228px; background: var(--panel); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; padding: 15px 11px;
  position: sticky; top: 0; height: 100vh;
}
@supports (height: 100dvh) { .b-side { height: 100dvh; } }
/* Dark rail: the mechanic's tablet is mounted under bay lights where white glares, and the
   owner's screen uses it so you know which one you are on without reading the header. */
.b-side.k { background: #0E0E10; border-right-color: #22242A; }
.b-side.k .gname { color: #fff; } .b-side.k .gsub { color: #7E828C; }
.b-side.mini { flex: 0 0 74px; align-items: center; }

.b-side .brand { display: flex; align-items: center; gap: 10px; padding: 4px 7px 17px; }
.b-side.mini .brand { padding: 4px 0 17px; }
.b-side .mark { width: 36px; height: 36px; border-radius: 10px; background: #0E0E10; flex: 0 0 36px; overflow: hidden; }
.b-side .mark img { width: 100%; height: 100%; object-fit: cover; display: block; }
.b-side nav { display: flex; flex-direction: column; gap: 2px; }
.b-side a {
  display: flex; align-items: center; gap: 11px; padding: 10px 11px; border-radius: 11px;
  text-decoration: none; color: var(--ink-2); font-size: 13.5px; font-weight: 650; cursor: pointer;
  background: color-mix(in srgb, var(--brand, transparent) 7%, transparent);
}
.b-side.k a { color: #A5A8B2;
  background: color-mix(in srgb, var(--brand-rail, #1B1D22) 8%, #141519); }
.b-side.mini a { justify-content: center; padding: 11px 0; width: 48px; }
/* The same standard as the desk rail, on the other two surfaces: the colour is worn at REST,
   not only under the mouse, and the three rungs stay apart — a wash at rest, a stronger tint on
   hover, a solid fill for the page you are on. Light sidebar: --brand-50 is the pale wash and
   --brand-ink the brand taken down far enough to read on it. Dark sidebar (.k, the bay tablet):
   --brand-rail, lifted instead. Same intent, opposite arithmetic.
   The rest colour mixes toward TRANSPARENT on the light sidebar rather than a named background,
   because .b-side sits on two different panel colours depending on the surface and a hardcoded
   base would show as a seam on one of them. */
.b-side a:hover { background: var(--brand-50, var(--line-2)); color: var(--brand-ink, inherit); }
.b-side.k a:hover { background: color-mix(in srgb, var(--brand-rail, #1B1D22) 22%, #141519);
  color: var(--brand-rail, #fff); }
.b-side a.on { background: #0E0E10; color: #fff; }
.b-side.k a.on { background: var(--brand); color: var(--brand-on, #000); }
.b-side a .count { margin-left: auto; }
.b-side .grp { font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4); padding: 14px 11px 6px; }
.b-side.k .grp { color: #5E626B; }
.b-side .foot { margin-top: auto; padding: 10px 7px 2px; border-top: 1px solid var(--line-2); }
.b-side.k .foot { border-top-color: #22242A; }
.b-side .who { display: flex; align-items: center; gap: 9px; font-size: 13px; font-weight: 650; }
.b-side.k .who { color: #D5D8DE; }
.b-side .av { width: 30px; height: 30px; border-radius: 9px; background: var(--brand); color: var(--brand-on, #000); display: grid; place-items: center; font-size: 12px; font-weight: 850; flex: 0 0 30px; }

.b-main { flex: 1; min-width: 0; }
.b-topbar {
  display: flex; align-items: center; gap: 13px; padding: 14px 24px;
  border-bottom: 1px solid var(--line); background: var(--panel);
  position: sticky; top: 0; z-index: 10;
}
.b-topbar h3 { font-size: 18px; font-weight: 850; letter-spacing: -.4px; margin: 0; }
.b-topbar .sp { margin-left: auto; display: flex; gap: 8px; align-items: center; }
.b-pill {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 700;
  color: var(--ink-2); border: 1px solid var(--line); border-radius: 9px; padding: 7px 12px;
  background: var(--panel); cursor: pointer; font-family: inherit;
}
.b-pill:hover { border-color: var(--brand-line, var(--brand)); }
.b-pill.b { background: var(--brand); border-color: var(--brand-line, var(--brand)); color: var(--brand-on, #000); }

.b-wrap { padding: 20px 24px 34px; }
.b-grid2 { display: grid; grid-template-columns: 1.3fr .8fr; gap: 17px; align-items: start; }
.b-stack { display: flex; flex-direction: column; gap: 0; }
.b-stack > .b-panel { margin-bottom: 15px; }

.b-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 13px; margin-bottom: 16px; }
.b-kpi { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 14px; box-shadow: var(--shadow); }
.b-kpi .k { font-size: 10.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); display: flex; align-items: center; gap: 6px; }
.b-kpi .v { font-size: 25px; font-weight: 850; letter-spacing: -.9px; margin-top: 7px; font-variant-numeric: tabular-nums; }
.b-kpi .d { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }

.b-tbl { width: 100%; border-collapse: collapse; }
.b-tbl th { font-size: 10.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); text-align: left; padding: 9px 13px; border-bottom: 1px solid var(--line); }
.b-tbl td { padding: 11px 13px; border-bottom: 1px solid var(--line-2); font-size: 13.5px; }
.b-tbl tr:last-child td { border-bottom: 0; }
.b-tbl .r { text-align: right; font-weight: 750; font-variant-numeric: tabular-nums; }

.b-empty { color: var(--ink-3); font-size: 14px; padding: 26px 16px; text-align: center; }

/* ── where the shell flips ───────────────────────────────────────────────── */
/* Below 820px the column would eat a third of the screen, so it goes to the bottom. This is the
   ONLY structural difference between the phone and the desktop. */
@media (max-width: 820px) {
  .b-side { display: none; }
  .b-wide { display: block; min-height: 0; }
  .b-topbar { padding: 12px 16px; }
  .b-wrap { padding: 14px 16px 24px; }
  .b-grid2 { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .b-kpis { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 821px) {
  .b-tabbar { display: none; }
}

/* The tools backdrop set in app.css shows through the gaps between panels — which is the whole
   point of it. Panels are opaque so text stays legible; the space around them is where the shop
   shows through. Nothing here paints a background over the page. */

/* ── one element, two shells ─────────────────────────────────────────────── */
/* The masthead mark belongs in the top bar on a phone and in the rail on a desktop. Rather than
   render it twice and risk them diverging, both exist and one is hidden. */
.b-only-phone { display: none; }
@media (max-width: 820px) {
  .b-only-phone { display: block; }
  .b-only-wide { display: none; }
  .b-topbar .mark { width: 32px; height: 32px; border-radius: 9px; overflow: hidden; background: #0E0E10; flex: 0 0 32px; }
  .b-topbar .mark img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .b-topbar h3 { font-size: 16px; }
}

/* ── a card that goes somewhere ──────────────────────────────────────────── */
/* Clickable things have to look clickable, and be reachable without a mouse. The chevron in the
   markup says where it goes; this says you may. */
.b-click { cursor: pointer; transition: border-color .12s, transform .12s; }
.b-click:hover { border-color: var(--brand-line, var(--brand)); }
.b-kpi.b-click:hover { transform: translateY(-1px); }
.b-click:focus-visible { outline: 2px solid var(--brand-line, var(--brand)); outline-offset: 2px; }
.b-click .ic { flex: 0 0 auto; }

/* The chevron on a KPI sits at the end of its detail line, quiet until hovered. */
.b-kpi.b-click .d { display: flex; align-items: center; gap: 5px; }
.b-kpi.b-click .d .ic { width: 13px; height: 13px; margin-left: auto; opacity: .45; }
.b-kpi.b-click:hover .d .ic { opacity: 1; color: var(--brand-ink, var(--ink)); }

.b-row.b-click > .ic:last-child { color: var(--ink-4); }
.b-row.b-click:hover > .ic:last-child { color: var(--brand-ink, var(--ink)); }

/* ── the assistant ───────────────────────────────────────────────────────── */
/* A sheet, not a page. A customer opens it with a question and closes it again; making it a
   destination would mean deciding to "go to the assistant", which nobody does. */
.asst { position: fixed; inset: 0; z-index: 9500; display: flex; align-items: flex-end; justify-content: center; }
.asst-scrim { position: absolute; inset: 0; background: rgba(12, 10, 18, .5); }
body.asst-open { overflow: hidden; }

.asst-card {
  position: relative; display: flex; flex-direction: column;
  width: min(560px, 100vw); height: min(78vh, 720px);
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: 20px 20px 0 0;
  box-shadow: 0 -10px 50px rgba(0, 0, 0, .35); overflow: hidden;
}
@supports (height: 100dvh) { .asst-card { height: min(78dvh, 720px); } }
@media (min-width: 821px) {
  .asst { align-items: center; }
  .asst-card { border-radius: 20px; }
}

.asst-head { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.asst-mark {
  width: 38px; height: 38px; flex: 0 0 38px; border-radius: 12px;
  background: var(--brand); color: var(--brand-on, #000); display: grid; place-items: center;
}
.asst-title { font-size: 16px; font-weight: 800; letter-spacing: -.2px; }
.asst-sub { font-size: 12px; color: var(--ink-3); }
.asst-x {
  margin-left: auto; background: none; border: 0; cursor: pointer; color: var(--ink-3);
  padding: 8px; border-radius: 9px; transform: rotate(90deg);
}
.asst-x:hover { background: var(--line-2); color: var(--ink); }

.asst-log { flex: 1; overflow: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.asst-msg { display: flex; }
.asst-msg .b {
  max-width: 85%; padding: 10px 13px; border-radius: 14px;
  font-size: 14.5px; line-height: 1.5; white-space: normal;
}
.asst-msg.assistant .b { background: var(--line-2); border-bottom-left-radius: 5px; }
.asst-msg.me { justify-content: flex-end; }
.asst-msg.me .b { background: #0E0E10; color: #fff; border-bottom-right-radius: 5px; }
.asst-msg.pending .b { color: var(--ink-3); font-style: italic; }
.asst-msg.err .b { background: var(--urgent-bg, #FEF3F2); color: var(--urgent-ink, #B42318); }

.asst-sugg { display: flex; gap: 7px; padding: 0 16px 12px; overflow-x: auto; }
.asst-sugg::-webkit-scrollbar { display: none; }
.asst-sugg button {
  flex: 0 0 auto; font: inherit; font-size: 12.5px; font-weight: 650; cursor: pointer;
  padding: 8px 13px; border-radius: 30px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink-2);
}
.asst-sugg button:hover { border-color: var(--brand-line, var(--brand)); color: var(--ink); }

.asst-bar {
  display: flex; gap: 9px; padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line); background: var(--panel-2, var(--panel));
}
.asst-bar input {
  flex: 1; font: inherit; font-size: 15px; padding: 12px 14px;
  border-radius: 12px; border: 1px solid var(--line); background: var(--panel); color: var(--ink);
  min-width: 0;
}
.asst-bar input:focus { outline: 0; border-color: var(--brand-line, var(--brand)); box-shadow: 0 0 0 3px var(--brand-50); }
.asst-send {
  flex: 0 0 auto; width: 48px; border: 0; border-radius: 12px; cursor: pointer;
  background: var(--brand); color: var(--brand-on, #000); display: grid; place-items: center;
}

/* The way in. Above the bottom bar on a phone, bottom-right on a desktop. */
.asst-fab {
  position: fixed; right: 16px; z-index: 40;
  bottom: calc(86px + env(safe-area-inset-bottom));
  width: 54px; height: 54px; border-radius: 18px; border: 0; cursor: pointer;
  background: var(--brand); color: var(--brand-on, #000);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .22); display: grid; place-items: center;
}
.asst-fab:hover { transform: translateY(-1px); }
.asst-fab .ic { width: 24px; height: 24px; }
@media (min-width: 821px) { .asst-fab { bottom: 24px; right: 24px; } }

/* ── who is here, and which bay is actually empty ──────────────────────────── */
/* The dot is the fastest read on the page: green = here and free, amber = here and under a car,
   hollow = gone home. Colour is never the only signal — every row also carries a worded chip,
   because a yellow garage has already spent its colour budget elsewhere. */
.teamdot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 9px; }
.teamdot.live { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-bg); }
.teamdot.idle { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-bg); }
.teamdot.off  { background: transparent; border: 1.5px solid var(--line); }

/* Share of the time somebody has been here that is on a work order. The one number on this
   screen an owner cannot get any other way. */
.teambar { height: 4px; border-radius: 3px; background: var(--line-2); margin: 4px 0 2px; overflow: hidden; }
.teambar i { display: block; height: 100%; background: var(--ok); border-radius: 3px; }

/* The bays. A grid rather than a list: the shop is a row of bays, so the screen should look like
   the building. Twelve at Noukoua, so it wraps instead of scrolling sideways. */
.baygrid {
  display: grid; gap: 10px; padding: 14px 15px;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
}
.baycell {
  border: 1px solid var(--line); border-radius: 11px; padding: 10px 11px;
  background: var(--panel-2); cursor: pointer; min-height: 78px;
  transition: border-color .12s, transform .08s;
}
.baycell:hover { border-color: var(--brand-line, var(--brand)); transform: translateY(-1px); }
.baycell:focus-visible { outline: 2px solid var(--brand-line, var(--brand)); outline-offset: 2px; }
/* The names here are checked, not chosen. index.html loads atelier.css and ui.css together, so
   they share one namespace, and atelier.css declares both `.job` (absolutely positioned, for the
   schedule board) and `.bay-n` (a 22px badge) as bare rules. Each one, used here, matched these
   elements and brought its own geometry: .job drew twelve full-height lines down the dashboard,
   .bay-n squeezed the bay name into 22px so it wrapped mid-label. Scoping the selector does not
   help — the other file's bare rule still matches. Run `node classcheck.mjs` before inventing a
   class name. */
.baycell .bc-name { font-size: 13px; font-weight: 850; letter-spacing: -.2px; }
.baycell .bc-who { font-size: 11.5px; color: var(--ink-2); font-weight: 650; margin-top: 2px; }
.baycell .bc-state { font-size: 11px; color: var(--ink-3); margin-top: 2px; }

/* Free bays are what somebody is looking for, so they get the left edge. Unstaffed counts as
   free: the bay can take a car, it just needs somebody put in it. */
.baycell.free      { border-left: 3px solid var(--ok); }
.baycell.unstaffed { border-left: 3px dashed var(--line); }
.baycell.busy      { border-left: 3px solid var(--warn); }
/* The one worth interrupting for: yesterday's car is still in it and today's schedule shows
   nothing, which is exactly how a second car gets sent to the same bay. */
.baycell.held_over {
  border-left: 3px solid var(--urgent-ink, #B42318);
  background: var(--urgent-bg, #FEF3F2);
}

@media (max-width: 760px) {
  .baygrid { grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); gap: 8px; }
  .baycell { min-height: 70px; padding: 9px 10px; }
}

/* ── assigning a bay ───────────────────────────────────────────────────────── */
.bp-scrim {
  position: fixed; inset: 0; z-index: 90; display: flex; align-items: center;
  justify-content: center; padding: 24px; background: rgba(12, 14, 20, .5);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.bp {
  width: min(720px, 100%); max-height: calc(100vh - 48px); overflow: auto;
  background: var(--panel); border-radius: 16px; box-shadow: 0 24px 64px rgba(0, 0, 0, .3);
}
.bp-head { position: relative; padding: 15px 18px; background: #14161c; color: #fff; }
.bp-h1 { font-size: 16px; font-weight: 840; letter-spacing: -.3px; display: flex;
  align-items: center; gap: 8px; }
.bp-h1 svg { color: var(--brand); }
.bp-h2 { font-size: 12px; opacity: .74; margin-top: 3px; }
.bp-x { position: absolute; top: 12px; right: 13px; width: 30px; height: 30px; border: 0;
  border-radius: 8px; background: rgba(255, 255, 255, .12); color: #fff; font-size: 19px;
  line-height: 1; cursor: pointer; }
.bp-x:hover { background: rgba(255, 255, 255, .22); }

/* The held-over warning belongs here and not only on the board: this is the moment somebody is
   about to send a second car into a bay that still has yesterday's in it. */
.bp-warn { display: flex; gap: 9px; align-items: flex-start; padding: 11px 18px;
  background: var(--urgent-bg, #FEF3F2); color: var(--urgent-ink, #B42318);
  font-size: 12px; font-weight: 650; }
.bp-warn svg { flex: 0 0 auto; margin-top: 1px; }

.bp-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px 16px; }
.pc { position: relative; border: 1.5px solid var(--line); border-radius: 12px; padding: 11px 12px;
  background: var(--panel); cursor: pointer; transition: border-color .12s, background .12s; }
.pc:hover { border-color: var(--brand-line, var(--brand)); }
.pc:focus-visible { outline: 2px solid var(--brand-line, var(--brand)); outline-offset: 2px; }
/* The chosen card, not merely the hovered one — this survives a re-render. */
.pc.on { border-color: var(--brand-line, var(--brand)); background: var(--brand-50, #fffde3);
  box-shadow: inset 0 0 0 1.5px var(--brand-line, var(--brand)); }
.pc.off { opacity: .55; }
.pc-rib { font-size: 9.5px; font-weight: 850; letter-spacing: .5px; text-transform: uppercase;
  color: var(--ink-4); margin-bottom: 6px; }
.pc-rib.best { color: var(--ok); }
.pc-rib.busy { color: var(--warn); }
.pc-rib.stale { color: var(--urgent-ink, #B42318); }
.pc-top { display: flex; align-items: center; gap: 10px; }
.pc-av { width: 42px; height: 42px; border-radius: 50%; flex: 0 0 42px; color: #fff;
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; }
.pc-n { font-size: 13.5px; font-weight: 780; line-height: 1.2; }
.pc-r { font-size: 10.5px; color: var(--ink-3); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pc-m { display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  font-size: 10.5px; color: var(--ink-3); margin-top: 7px; }
.pc-m b { font-size: 12px; color: var(--ink); font-variant-numeric: tabular-nums; }

.bp-span { display: flex; flex-wrap: wrap; gap: 7px; padding: 12px 16px;
  border-top: 1px solid var(--line-2); background: var(--panel-2); }
.bp-span b { width: 100%; font-size: 10.5px; font-weight: 800; letter-spacing: .5px;
  text-transform: uppercase; color: var(--ink-3); }
.bp-sp { font: inherit; font-size: 12px; font-weight: 720; padding: 6px 11px; border-radius: 8px;
  border: 1.5px solid var(--line); background: var(--panel); color: var(--ink); cursor: pointer; }
.bp-sp.on { background: var(--brand); border-color: var(--brand-line, var(--brand));
  color: var(--brand-on, #000); font-weight: 830; }
.bp-foot { display: flex; gap: 9px; align-items: center; padding: 13px 16px;
  border-top: 1px solid var(--line); }

@media (max-width: 620px) {
  .bp-scrim { padding: 0; align-items: flex-end; }
  .bp { max-height: 92vh; border-radius: 16px 16px 0 0; }
  .bp-cards { grid-template-columns: 1fr; }
}

/* ── a member's face ───────────────────────────────────────────────────────── */
/* Shared by the desk, the bay tablet and the customer portal, so the same person looks the same
   everywhere. Sized inline by the caller, because the same face appears at 21px in a result row
   and 46px on a profile. */
.b-face {
  border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  object-fit: cover; vertical-align: middle; background: var(--line-2);
}
/* The initials fallback. Never an empty circle — that reads as a picture that failed to load,
   and most members will never upload one. */
.b-face-i { color: #fff; font-weight: 800; letter-spacing: .3px; }

/* Choosing one. The whole thing is the target, because on a tablet a small pencil icon in a
   corner is a miss waiting to happen. */
.b-facepick { position: relative; display: inline-block; cursor: pointer; border: 0; padding: 0;
  background: none; }
.b-facepick::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--brand-line, var(--brand)); opacity: 0; transition: opacity .12s;
}
.b-facepick:hover::after, .b-facepick:focus-visible::after { opacity: 1; }
.b-facepick .hint {
  position: absolute; left: 50%; bottom: -20px; transform: translateX(-50%);
  font-size: 10.5px; font-weight: 700; color: var(--ink-3); white-space: nowrap;
}

/* ── the two lookups at the top of the dashboard ───────────────────────────── */
/* Side by side above the figures: a client is looked up twenty times a day, the figures are read
   once in the morning. Each result list opens under the field that produced it, so using one
   does not clear the other. */
.b-find { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 16px; }
.b-findlab {
  display: block; font-size: 10.5px; font-weight: 800; letter-spacing: .5px;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 5px;
}
.b-findin {
  width: 100%; font: inherit; font-size: 14px; padding: 11px 13px; border-radius: 10px;
  border: 1.5px solid var(--line); background: var(--panel); color: var(--ink);
}
.b-findin:focus {
  outline: none; border-color: var(--brand-line, var(--brand)); box-shadow: 0 0 0 3px var(--brand-100);
}
/* Floated over what follows rather than pushing it down: the figures should not jump every time
   somebody types a letter. */
.b-findres {
  position: absolute; z-index: 20; margin-top: 6px; width: 100%;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow, 0 10px 30px rgba(0,0,0,.12)); overflow: hidden; max-height: 340px;
  overflow-y: auto;
}
.b-find > div { position: relative; min-width: 0; }

@media (max-width: 760px) {
  .b-find { grid-template-columns: 1fr; gap: 11px; }
}

/* A heading inside a list, naming what the rows beneath it have in common. Quieter than a panel
   header: it divides, it does not announce. */
.b-grp {
  font-size: 10px; font-weight: 850; letter-spacing: .6px; text-transform: uppercase;
  color: var(--ink-4); padding: 11px 15px 4px; background: var(--panel-2);
  border-top: 1px solid var(--line-2);
}
.b-panel > .b-grp:first-of-type { border-top: 0; }
