/* ==========================================================================
   VRS — Vehicle Rental System
   Base theme. The :root color tokens here are DEFAULTS ONLY — they are
   overridden at runtime by views/partials/theme-vars.ejs from dbo.Settings,
   so branding is admin-configurable without touching this file.
   ========================================================================== */

:root {
  /* Taken from the ALiN mark: chrome lettering on near-black, with red as the
     spark. Red is rationed on purpose — it marks the brand, the one primary
     action on a screen, and where you are. Everything else that used to be red
     is steel, which is what chrome looks like in shadow. A console read for
     eight hours cannot be red all over. */
  --c-primary:      #14161b;   /* near-black graphite — chrome, sidebar, headers */
  --c-secondary:    #262b34;   /* raised graphite — gradient partner             */
  --c-accent:       #c81e28;   /* ALiN red — brand, primary action, you-are-here */
  --c-accent-soft:  #e5424b;   /* the mark's glow — hover only                   */
  --c-success:      #1f8f63;
  /* Deeper than the accent on purpose: a warning must not read as a button. */
  --c-danger:       #9d1017;

  --c-ink:          #16181d;
  --c-ink-soft:     #565c66;
  --c-ink-faint:    #878d97;
  --c-line:         #e3e5ea;
  --c-line-soft:    #eff1f4;
  --c-surface:      #ffffff;
  --c-canvas:       #f4f5f7;
  --c-canvas-warm:  #faf6f6;   /* the faintest red cast, not pink              */
  --c-chrome:       #c9ced6;   /* the silver in the wordmark                    */

  /* The working interactive color. Brushed steel rather than a second brand
     color, so links, charts, progress and focus rings carry the interface
     without competing with the red. Structural, so unlike the six brand
     colors above these are not admin-configurable. */
  --c-steel:        #44546a;
  --c-steel-soft:   #7d8ea3;
  --c-steel-tint:   #edf0f4;
  --c-warning:      #a8710d;   /* attention that is not an error               */

  --radius:     10px;
  --radius-sm:  7px;
  --radius-lg:  16px;

  --shadow-sm: 0 1px 2px rgba(20, 22, 27, .07), 0 1px 3px rgba(20, 22, 27, .05);
  --shadow:    0 2px 4px rgba(20, 22, 27, .06), 0 6px 16px rgba(20, 22, 27, .08);
  --shadow-lg: 0 10px 34px rgba(20, 22, 27, .16);

  --font-head: 'Sora', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-body: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;

  --sidebar-w: 254px;
  --topbar-h:  60px;
}

/* ---------------------------------------------------------------- base --- */
* { box-sizing: border-box; }

body {
  font-family: var(--font-body);
  background: var(--c-canvas);
  color: var(--c-ink);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  margin: 0;
}

h1, h2, h3, h4, h5, h6, .font-head {
  font-family: var(--font-head);
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--c-primary);
}

a { color: var(--c-secondary); text-decoration: none; }
a:hover { color: var(--c-steel); }

.text-muted-2 { color: var(--c-ink-faint) !important; }
.text-accent  { color: var(--c-accent) !important; }   /* brand red — sparingly */
.text-steel   { color: var(--c-steel) !important; }
.mono { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

/* The signature detail: a thin red rule that reappears across the chrome,
   echoing the speed streak in the mark. Used sparingly so it reads as brand,
   not decoration. */
.rule-accent {
  height: 3px;
  background: linear-gradient(90deg, var(--c-accent) 0%, var(--c-accent-soft) 42%, transparent 100%);
  border: 0;
  margin: 0;
  opacity: .95;
}

/* ------------------------------------------------------------- sidebar --- */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: linear-gradient(180deg, var(--c-primary) 0%, var(--c-secondary) 100%);
  color: #cfdae4;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  z-index: 30;
}

.sidebar-brand {
  padding: 18px 18px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, .09);
  display: flex;
  align-items: center;
  gap: 11px;
}
.sidebar-brand .bm { flex: 0 0 auto; }
.sidebar-brand .bt { min-width: 0; }
.sidebar-brand .bt strong {
  display: block;
  font-family: var(--font-head);
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  letter-spacing: .01em;
  line-height: 1.2;
  overflow-wrap: break-word;
}
.sidebar-brand .bt span {
  display: block;
  font-size: 10.5px;
  color: #9aa1ab;
  text-transform: uppercase;
  letter-spacing: .09em;
  margin-top: 2px;
}

.sidebar-nav { padding: 12px 10px 24px; flex: 1; }

.nav-section {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: #6f8ba5;
  padding: 16px 10px 6px;
  font-weight: 600;
}

.sidebar a.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 11px;
  border-radius: var(--radius-sm);
  color: #c7ccd4;
  font-size: 13.5px;
  font-weight: 500;
  margin-bottom: 1px;
  position: relative;
  transition: background .13s ease, color .13s ease;
}
.sidebar a.nav-item:hover { background: rgba(255, 255, 255, .07); color: #fff; }
.sidebar a.nav-item.active {
  background: rgba(255, 255, 255, .10);
  color: #fff;
}
/* Active marker keeps the red brand thread going down the rail */
.sidebar a.nav-item.active::before {
  content: '';
  position: absolute;
  left: -10px; top: 6px; bottom: 6px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--c-accent);
}
.sidebar a.nav-item svg { flex: 0 0 17px; opacity: .85; }
.sidebar a.nav-item.active svg { opacity: 1; }
.nav-item .badge-count {
  margin-left: auto;
  background: var(--c-steel-soft);
  color: #101318;
  font-size: 10.5px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 20px;
}

.sidebar-foot {
  padding: 12px 16px 16px;
  border-top: 1px solid rgba(255, 255, 255, .08);
  font-size: 11px;
  color: #7f95ab;
}

/* -------------------------------------------------------------- topbar --- */
.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  height: var(--topbar-h);
  background: var(--c-surface);
  border-bottom: 1px solid var(--c-line);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 22px;
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar .page-title {
  font-family: var(--font-head);
  font-size: 16.5px;
  font-weight: 600;
  margin: 0;
}
.topbar .page-sub { font-size: 12px; color: var(--c-ink-faint); margin: 0; }

.user-chip {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 4px 10px 4px 4px;
  border: 1px solid var(--c-line);
  border-radius: 30px;
  background: #fff;
}

/* ------------------------------------------------------ notification bell --- */
/* One bell for staff and customers; the middleware decides which rows are
   theirs. The badge counts unread messages; the hollow mark means nothing new
   to read but work still sitting there. */
.bell-wrap { flex: 0 0 auto; }
.bell {
  position: relative;
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--c-line); border-radius: 9px;
  background: #fff; color: var(--c-ink-soft); cursor: pointer;
}
.bell:hover { border-color: var(--c-chrome); color: var(--c-primary); }
.bell[aria-expanded="true"] { border-color: var(--c-accent); color: var(--c-accent); }
.bell-dot {
  position: absolute; top: -5px; right: -5px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center;
  border-radius: 9px; border: 2px solid #fff;
  background: var(--c-accent); color: #fff;
  font-size: 9.6px; font-weight: 700; line-height: 1;
}
.bell-dot-quiet {
  min-width: 9px; width: 9px; height: 9px; padding: 0;
  background: var(--c-warning); top: -2px; right: -2px;
}

.bell-menu {
  width: min(360px, calc(100vw - 24px));
  padding: 0; overflow: hidden;
  border: 1px solid var(--c-line); border-radius: var(--radius);
  box-shadow: 0 14px 38px rgba(20, 22, 27, .16);
}
.bell-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 13px; border-bottom: 1px solid var(--c-line);
  font-size: 12.4px; font-weight: 700; color: var(--c-primary);
  background: var(--c-canvas);
}
.bell-mark {
  border: 0; background: none; padding: 0;
  font-size: 11.4px; font-weight: 600; color: var(--c-steel); cursor: pointer;
}
.bell-mark:hover { color: var(--c-accent); text-decoration: underline; }

/* The work, above the history. It is the only row here that is not just news. */
.bell-action {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px; text-decoration: none;
  background: var(--c-canvas-warm);
  border-bottom: 1px solid var(--c-line);
}
.bell-action:hover { background: #f7ecec; }
.bell-action-n {
  flex: 0 0 auto; display: grid; place-items: center;
  min-width: 24px; height: 24px; padding: 0 6px;
  border-radius: 7px; background: var(--c-accent); color: #fff;
  font-size: 12px; font-weight: 700;
}
.bell-action-body { min-width: 0; }
.bell-action-body strong { display: block; font-size: 12.8px; color: var(--c-primary); }
.bell-action-lines { display: block; font-size: 11.4px; color: var(--c-ink-soft); margin-top: 1px; }

.bell-item {
  display: block; padding: 10px 13px 10px 22px;
  text-decoration: none; position: relative;
  border-bottom: 1px solid var(--c-line-soft);
}
.bell-item:hover { background: var(--c-canvas); }
.bell-item.is-new::before {
  content: ''; position: absolute; left: 10px; top: 15px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--c-accent);
}
.bell-item-subject {
  display: block; font-size: 12.6px; font-weight: 600; color: var(--c-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bell-item-meta { display: block; font-size: 11px; color: var(--c-ink-faint); margin-top: 1px; }
.bell-item-failed { color: var(--c-warning); font-weight: 600; }
.bell-empty { padding: 20px 13px; text-align: center; font-size: 12.4px; color: var(--c-ink-faint); }
.bell-foot {
  display: block; padding: 10px 13px; text-align: center;
  font-size: 12px; font-weight: 600; color: var(--c-steel);
  text-decoration: none; background: var(--c-canvas);
}
.bell-foot:hover { color: var(--c-accent); }

/* ------------------------------------------------- the full notification list --- */
.nfy {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; text-decoration: none;
  border-bottom: 1px solid var(--c-line-soft);
}
.nfy:last-child { border-bottom: 0; }
.nfy:hover { background: var(--c-canvas); }
.nfy-main { flex: 1; min-width: 0; }
/* Unread until it has been opened, not until the page has been looked at. */
.nfy-dot { flex: 0 0 7px; width: 7px; height: 7px; border-radius: 50%; background: transparent; }
.nfy.is-new { background: var(--c-canvas-warm); }
.nfy.is-new:hover { background: #f7ecec; }
.nfy.is-new .nfy-dot { background: var(--c-accent); }
.nfy.is-new .nfy-subject { color: var(--c-primary); }
.nfy-subject { font-size: 13.2px; font-weight: 600; color: var(--c-ink-soft); }
.nfy.is-new .nfy-subject { font-weight: 700; }
.nfy-message {
  font-size: 12.2px; color: var(--c-ink-soft); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nfy-meta { font-size: 11.2px; color: var(--c-ink-faint); margin-top: 3px; }
.nfy-sent   { color: var(--c-success); }
.nfy-failed { color: var(--c-warning); font-weight: 600; }
.nfy-go { flex: 0 0 auto; color: var(--c-ink-faint); font-size: 15px; }
.nfy:hover .nfy-go { color: var(--c-accent); }
.avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: linear-gradient(140deg, var(--c-secondary), var(--c-primary));
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 11.5px;
  font-weight: 700;
  font-family: var(--font-head);
  letter-spacing: .02em;
}
.avatar.av-accent { background: linear-gradient(140deg, var(--c-steel-soft), var(--c-steel)); color: #fff; }

.content { padding: 22px; flex: 1; }

/* --------------------------------------------------------------- cards --- */
.card {
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  background: var(--c-surface);
  box-shadow: var(--shadow-sm);
}
.card-header {
  background: #fff;
  border-bottom: 1px solid var(--c-line-soft);
  padding: 13px 17px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 14px;
  color: var(--c-primary);
  display: flex;
  align-items: center;
  gap: 9px;
  border-radius: var(--radius) var(--radius) 0 0;
}
.card-body { padding: 17px; }

/* Stat tiles — color-coded left accent, subtle lift on hover */
.stat {
  position: relative;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  padding: 15px 16px 14px 18px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform .15s ease, box-shadow .15s ease;
  height: 100%;
}
.stat:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.stat::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--c-steel);
}
.stat.s-green::before  { background: var(--c-success); }
.stat.s-amber::before  { background: var(--c-warning); }
.stat.s-red::before    { background: var(--c-danger); }
.stat.s-blue::before   { background: #2f6fb0; }
.stat.s-violet::before { background: #6b52b8; }
.stat.s-slate::before  { background: var(--c-ink-faint); }

.stat .k {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--c-ink-faint);
  font-weight: 600;
  display: block;
}
.stat .v {
  font-family: var(--font-head);
  font-size: 25px;
  font-weight: 700;
  color: var(--c-primary);
  line-height: 1.15;
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.stat .m { font-size: 11.5px; color: var(--c-ink-soft); margin-top: 1px; }

/* A tile that is also a link to the list it counts. It has to look clickable
   without becoming a link-blue block, so the affordance is the cursor, a firmer
   lift on hover and a small chevron that appears with it. */
a.stat {
  display: block;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
a.stat:hover { border-color: var(--c-steel); }
a.stat:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
a.stat .k::after {
  content: '→';
  float: right;
  font-size: 12px;
  letter-spacing: 0;
  color: var(--c-ink-faint);
  opacity: 0;
  transform: translateX(-3px);
  transition: opacity .15s ease, transform .15s ease;
}
a.stat:hover .k::after, a.stat:focus-visible .k::after { opacity: 1; transform: translateX(0); }
a.stat:hover .v { color: var(--c-accent); }

/* -------------------------------------------------------------- tables --- */
.table { font-size: 13.2px; margin-bottom: 0; }
.table > thead > tr > th {
  background: var(--c-canvas);
  border-bottom: 1px solid var(--c-line);
  color: var(--c-ink-soft);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  padding: 9px 12px;
  white-space: nowrap;
}
.table > tbody > tr > td { padding: 10px 12px; vertical-align: middle; border-color: var(--c-line-soft); }
.table-hover > tbody > tr:hover > td { background: var(--c-canvas-warm); }
.table-fixed-head { max-height: 620px; overflow-y: auto; }

.table-wrap { overflow-x: auto; }

.ref {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: .01em;
  color: var(--c-secondary);
  white-space: nowrap;
}

/* ------------------------------------------------------------- badges ---- */
.st {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .045em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 20px;
  white-space: nowrap;
  border: 1px solid transparent;
  line-height: 1.5;
}
.st-gray   { background: #eef1f5; color: #5c6b7a; border-color: #dfe5ec; }
.st-blue   { background: #e7f0fa; color: #205a92; border-color: #cfe0f2; }
.st-indigo { background: #ecebfa; color: #453b9c; border-color: #dcd9f3; }
.st-teal   { background: #e2f5f1; color: #12695a; border-color: #c9ebe3; }
.st-green  { background: #e3f5ec; color: #146a4d; border-color: #c8ebda; }
.st-amber  { background: #fdf1dd; color: #8a5a09; border-color: #f6e0bb; }
.st-orange { background: #fdeadf; color: #9a4413; border-color: #f7d5c2; }
.st-violet { background: #f0eafa; color: #533a94; border-color: #e2d7f3; }
.st-red    { background: #fceaea; color: #a02b23; border-color: #f5d2cf; }

/* -------------------------------------------------------------- forms ---- */
.form-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--c-ink-soft);
  text-transform: uppercase;
  letter-spacing: .05em;
  margin-bottom: 4px;
}
.form-control, .form-select {
  font-size: 13.5px;
  border-color: var(--c-line);
  border-radius: var(--radius-sm);
  padding: 7px 11px;
}
/* A select draws its chevron as a background image pinned to the right edge,
   and Bootstrap keeps it clear by reserving 2.25rem of right padding. The
   shorthand above sets all four sides, so that reservation was lost and any
   option long enough to reach the arrow ran underneath it — "Any size" in the
   seats filter being the one that showed. Given back here rather than by
   dropping the shorthand, so the other three sides stay as designed. */
.form-select { padding-right: 2.1rem; }
.form-control:focus, .form-select:focus {
  border-color: var(--c-steel);
  box-shadow: 0 0 0 3px rgba(68, 84, 106, .16);
}
.form-control::placeholder { color: #a9b6c4; }
.input-hint { font-size: 11.5px; color: var(--c-ink-faint); margin-top: 3px; }

/* ------------------------------------------------------------ buttons ---- */
.btn {
  font-size: 13.2px;
  font-weight: 600;
  border-radius: var(--radius-sm);
  padding: 7px 14px;
  letter-spacing: .005em;
}
.btn-primary {
  background: var(--c-primary);
  border-color: var(--c-primary);
}
.btn-primary:hover, .btn-primary:focus {
  background: var(--c-secondary);
  border-color: var(--c-secondary);
}
.btn-accent {
  background: var(--c-accent);
  border-color: var(--c-accent);
  color: #fff;
}
.btn-accent:hover, .btn-accent:focus {
  background: var(--c-accent-soft);
  border-color: var(--c-accent-soft);
  color: #fff;
}

/* The primary action inside a light card. Graphite carries the same weight as
   the red without spending the brand color twice in one view — one red per
   region is the rule. */
.btn-chrome {
  background: var(--c-primary);
  border-color: var(--c-primary);
  color: #fff;
}
.btn-chrome:hover, .btn-chrome:focus {
  background: var(--c-secondary);
  border-color: var(--c-secondary);
  color: #fff;
}
.btn-outline-dark2 {
  border: 1px solid var(--c-line);
  color: var(--c-ink-soft);
  background: #fff;
}
.btn-outline-dark2:hover { border-color: var(--c-ink-faint); color: var(--c-primary); background: #fff; }
.btn-sm { font-size: 12.2px; padding: 4px 10px; }

/* ------------------------------------------------------------ progress --- */
.wf-track {
  height: 5px;
  background: var(--c-line-soft);
  border-radius: 4px;
  overflow: hidden;
}
.wf-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--c-steel), var(--c-steel-soft));
  border-radius: 4px;
  transition: width .3s ease;
}
.wf-fill.done { background: linear-gradient(90deg, var(--c-success), #35b384); }
.wf-fill.cancelled { background: var(--c-danger); }

/* Vertical lifecycle timeline on the reservation case file */
.timeline { list-style: none; margin: 0; padding: 0 0 0 22px; position: relative; }
.timeline::before {
  content: '';
  position: absolute;
  left: 6px; top: 6px; bottom: 6px;
  width: 2px;
  background: var(--c-line);
}
.timeline li { position: relative; padding: 0 0 15px 4px; }
.timeline li::before {
  content: '';
  position: absolute;
  left: -21px; top: 5px;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: #fff;
  border: 2.5px solid var(--c-line);
}
.timeline li.done::before   { border-color: var(--c-success); background: var(--c-success); }
.timeline li.current::before{ border-color: var(--c-steel); background: var(--c-steel); box-shadow: 0 0 0 4px rgba(68,84,106,.20); }
.timeline .t-title { font-weight: 600; font-size: 13px; color: var(--c-primary); }
.timeline .t-meta  { font-size: 11.5px; color: var(--c-ink-faint); }

/* -------------------------------------------------- vehicle result card -- */
.veh-card {
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  background: #fff;
  overflow: hidden;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.veh-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: #d3dde7; }
.veh-photo {
  height: 152px;
  background: linear-gradient(150deg, #2a2e37 0%, #101216 100%);
  display: grid;
  place-items: center;
  position: relative;
}
.veh-photo img { width: 100%; height: 100%; object-fit: cover; }
.veh-photo .cat-chip {
  position: absolute;
  top: 10px; left: 10px;
  background: rgba(255, 255, 255, .94);
  color: var(--c-primary);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  padding: 3px 8px;
  border-radius: 4px;
}
.veh-body { padding: 13px 15px 15px; flex: 1; display: flex; flex-direction: column; }
.veh-title { font-family: var(--font-head); font-weight: 600; font-size: 14.5px; color: var(--c-primary); margin: 0; }
.veh-plate { font-size: 11.5px; color: var(--c-ink-faint); letter-spacing: .04em; }
.veh-specs { display: flex; flex-wrap: wrap; gap: 7px; margin: 9px 0 11px; }
.veh-specs span {
  font-size: 11px;
  background: var(--c-canvas);
  border: 1px solid var(--c-line-soft);
  color: var(--c-ink-soft);
  padding: 2px 7px;
  border-radius: 4px;
}
.veh-rate { margin-top: auto; padding-top: 10px; border-top: 1px dashed var(--c-line); }
.veh-rate .amt {
  font-family: var(--font-head);
  font-size: 19px;
  font-weight: 700;
  color: var(--c-primary);
}
.veh-rate .per { font-size: 11.5px; color: var(--c-ink-faint); }

/* Free for part of the requested window: shown, but plainly not on offer for
   those dates. Muted rather than hidden — the point is that it exists and is
   free on the days listed on the card. */
.veh-partial { background: var(--c-canvas); border-style: dashed; }
.veh-partial:hover { transform: none; box-shadow: none; border-color: var(--c-line); }
.veh-partial .veh-photo img { filter: grayscale(.85); opacity: .62; }
.veh-partial .veh-title, .veh-partial .veh-specs span { color: var(--c-ink-soft); }
.veh-photo .veh-flag {
  position: absolute;
  top: 10px; right: 10px;
  background: rgba(32, 36, 43, .86);
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  padding: 3px 8px;
  border-radius: 4px;
}
.veh-free-head {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--c-ink-faint); margin: 0 0 6px;
}
.veh-free-dates { display: flex; flex-wrap: wrap; gap: 5px; margin: 0 0 7px; }
.veh-free-chip {
  font-size: 11.5px;
  background: #e3f5ec;
  border: 1px solid #c8ebda;
  color: #1d6b4a;
  padding: 2px 8px;
  border-radius: 4px;
  white-space: nowrap;
}
.veh-free-note { font-size: 11.5px; color: var(--c-ink-faint); margin: 0; }

/* ------------------------------------------------- submitting / uploading -- */
/* The button says what is happening while it happens, so nobody presses it a
   second time wondering whether the first one took. */
.btn-spin {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 7px;
  vertical-align: -1px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin .6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn-spin { animation-duration: 2.4s; }
}
.btn:disabled, .btn[disabled] { cursor: progress; }
form[aria-busy="true"] { cursor: progress; }

/* What was chosen for a file input, and whether it can be sent. */
.file-note { font-size: 11.4px; color: var(--c-ink-faint); margin-top: 4px; }
.file-note.is-bad { color: var(--c-danger); font-weight: 600; }

/* A key/value list packed a little tighter, for a summary inside a strip
   rather than a panel of its own. */
.kv.kv-tight { font-size: 12.7px; row-gap: 4px; }

/* ---------------------------------------------------- needs-action rows --- */
/* One line per thing waiting on us, under the customer it belongs to. */
.na-row {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 11px 15px;
  border-top: 1px solid var(--c-line-soft);
}
.na-row:first-child { border-top: 0; }
.na-body { flex: 1; min-width: 0; }
.na-title { font-size: 13px; font-weight: 600; color: var(--c-primary); }
.na-meta  { font-size: 11.6px; color: var(--c-ink-faint); margin-top: 1px; }
.na-tag {
  flex: 0 0 auto;
  margin-top: 1px;
  font-size: 9.6px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  padding: 3px 7px;
  border-radius: 4px;
  border: 1px solid var(--c-line);
  background: var(--c-canvas);
  color: var(--c-ink-soft);
  min-width: 74px;
  text-align: center;
}
.na-tag-account { background: #eef2f7; border-color: #cfdbe8; color: #44546a; }
.na-tag-doc     { background: #fdf1dd; border-color: #f6e0bb; color: #8a5a09; }
.na-tag-booking { background: #e3f5ec; border-color: #c8ebda; color: #146a4d; }
.na-tag-payment { background: #fceaea; border-color: #f5d2cf; color: #a02b23; }
@media (max-width: 575.98px) {
  .na-row { flex-wrap: wrap; }
  .na-row .btn { margin-left: auto; }
}

/* ------------------------------- transactions waiting on us, per customer --- */
/* One customer, whatever of the three steps is still open, and a bar saying
   which one is next. Used by the dashboard panel and the full Needs Action
   page from the same partial, so the two always agree. */
.vq { border-top: 1px solid var(--c-line); }
.vq:first-child { border-top: 0; }
.vq-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 11px 15px 0;
}
.vq-name { font-size: 13.4px; font-weight: 600; color: var(--c-primary); text-decoration: none; }
.vq-name:hover { color: var(--c-accent); }
.vq-code { font-size: 11.4px; }

.vq-steps {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 7px 15px 9px;
}
.vq-stepn {
  font-size: 10.6px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--c-ink-faint); flex: 0 0 auto;
}
.vq-stages { display: flex; gap: 6px; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
.vq-stage {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600;
  padding: 3px 9px 3px 4px;
  border: 1px solid var(--c-line); border-radius: 999px;
  color: var(--c-ink-faint); background: var(--c-surface);
}
.vq-dot {
  display: inline-grid; place-items: center;
  width: 17px; height: 17px; border-radius: 50%;
  font-size: 10px; font-weight: 700;
  background: var(--c-line-soft); color: var(--c-ink-faint);
}
.vq-stage.is-done { color: var(--c-success); border-color: #c8ebda; background: #f2fbf6; }
.vq-stage.is-done .vq-dot { background: var(--c-success); color: #fff; }
.vq-stage.is-now  { color: var(--c-accent); border-color: #f0c9cb; background: var(--c-canvas-warm); }
.vq-stage.is-now .vq-dot { background: var(--c-accent); color: #fff; }

.vq-rows { border-top: 1px solid var(--c-line-soft); }
.vq-row {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 10px 15px;
  border-top: 1px solid var(--c-line-soft);
}
.vq-row:first-child { border-top: 0; }
.vq-row .na-title a { color: inherit; text-decoration: none; }
.vq-row .na-title a:hover { color: var(--c-accent); }
/* A row whose step has not come round yet. Readable, plainly not actionable. */
.vq-row.is-locked { background: var(--c-canvas); }
.vq-row.is-locked .na-title { color: var(--c-ink-soft); }
/* Verify / Reject, and the document Preview / Download pair. */
.vq-acts { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.vq-cashier { font-size: 11.4px; color: var(--c-ink-faint); }
/* ------------------------------------------ where the vehicle is, as a filter --- */
/* The old Rentals page, folded into the bookings list. A booking and a rental
   were never two things — one record at different points — so these select a
   part of the one list rather than opening a second screen. */
.rent-stages { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 14px; }
.rent-stage {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px;
  border: 1px solid var(--c-line); background: var(--c-surface);
  font-size: 12.4px; font-weight: 600; color: var(--c-ink-soft);
  text-decoration: none; white-space: nowrap;
}
.rent-stage:hover { border-color: var(--c-chrome); color: var(--c-primary); }
.rent-stage.is-active {
  background: var(--c-primary); border-color: var(--c-primary); color: #fff;
}
.rent-stage-n {
  display: inline-grid; place-items: center;
  min-width: 17px; height: 17px; padding: 0 5px;
  border-radius: 9px; background: var(--c-line-soft); color: var(--c-ink-soft);
  font-size: 10.2px; font-weight: 700; line-height: 1;
}
.rent-stage.is-active .rent-stage-n { background: rgba(255, 255, 255, .22); color: #fff; }
.rent-stage.is-late { border-color: #f0c9cb; color: var(--c-danger); }
.rent-stage.is-late .rent-stage-n { background: var(--c-danger); color: #fff; }
.rent-stage.is-late.is-active { background: var(--c-danger); border-color: var(--c-danger); color: #fff; }
@media (max-width: 575.98px) {
  .rent-stages { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ------------------------------------------------------------- hub tabs --- */
/* One page per area of work. Seven sidebar items for six lists made the menu
   the busiest thing on the screen and hid the fact that each group belongs
   together; these are the same lists, gathered under one heading. */
.hub {
  display: flex; gap: 4px; flex-wrap: wrap;
  margin: 0 0 16px;
  padding: 4px;
  border: 1px solid var(--c-line); border-radius: var(--radius);
  background: var(--c-canvas);
}
.hub-tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 600; color: var(--c-ink-soft);
  text-decoration: none; white-space: nowrap;
}
.hub-tab svg { flex: 0 0 auto; opacity: .75; }
.hub-tab:hover { background: var(--c-surface); color: var(--c-primary); }
.hub-tab.is-active {
  background: var(--c-surface); color: var(--c-primary);
  box-shadow: 0 1px 2px rgba(20, 22, 27, .1);
}
.hub-tab.is-active svg { opacity: 1; color: var(--c-accent); }
.hub-n {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; background: var(--c-accent); color: #fff;
  font-size: 10.4px; font-weight: 700; line-height: 1;
}
@media (max-width: 575.98px) {
  /* One row that scrolls sideways rather than three stacked lines pushing the
     list itself off the screen — which is what this change was meant to fix. */
  .hub { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .hub-tab { padding: 7px 10px; font-size: 12.4px; }
  .hub-tab span:not(.hub-n) { white-space: nowrap; }
}

/* A vehicle's calendar shown over the search results rather than instead of them. */
.calfrag-head { font-size: 13.2px; color: var(--c-primary); margin: 0 0 10px; }
.calfrag-plate { font-size: 11.6px; color: var(--c-ink-faint); margin-left: 6px; }
.calfrag-foot { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--c-line); }
.calfrag-loading { font-size: 12.6px; color: var(--c-ink-faint); text-align: center; padding: 26px 0; margin: 0; }

/* --------------------------------------------------- documents and forms --- */
/* An executed document — signed, issued, or recording something that happened —
   reads differently from a blank form or a draft. They used to be one list of
   plain links, which made a signed agreement look like stationery. */
.doclist { display: flex; flex-direction: column; }
.doc-row {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 15px; text-decoration: none;
  font-size: 12.9px; color: var(--c-ink-soft);
  border-left: 3px solid transparent;
}
.doc-row:hover { background: var(--c-canvas); color: var(--c-accent); }
.doc-mark {
  flex: 0 0 auto; width: 16px; height: 16px;
  display: grid; place-items: center;
  border-radius: 50%; font-size: 10px; font-weight: 700;
  background: var(--c-line-soft); color: transparent;
}
.doc-label { flex: 1; min-width: 0; }
.doc-state {
  flex: 0 0 auto; font-size: 10.4px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--c-ink-faint);
}
.doc-row.is-done {
  color: var(--c-primary); font-weight: 600;
  border-left-color: var(--c-success);
  background: #f7fcf9;
}
.doc-row.is-done:hover { background: #eef9f3; color: var(--c-accent); }
.doc-row.is-done .doc-mark { background: var(--c-success); color: #fff; }
.doc-row.is-done .doc-state { color: var(--c-success); font-weight: 700; }

/* A damage mark's own row: description, an optional close-up, and Remove. */
.dmap-fields { flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.dmap-fields .form-control { flex: 1 1 190px; min-width: 0; }
.dmap-photo {
  flex: 0 0 auto; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px;
  border: 1px dashed var(--c-line); border-radius: var(--radius-sm);
  background: var(--c-surface);
  font-size: 11.6px; color: var(--c-ink-soft);
  max-width: 190px;
}
.dmap-photo:hover { border-color: var(--c-accent); color: var(--c-accent); }
.dmap-photo.has-file { border-style: solid; border-color: #c8ebda; background: #f2fbf6; color: var(--c-success); font-weight: 600; }
.dmap-photo input[type=file] { display: none; }
.dmap-photo-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dmap-photo-opt { color: var(--c-ink-faint); font-weight: 400; }
.dmap-shot { flex: 0 0 auto; display: block; line-height: 0; }
.dmap-shot img {
  width: 34px; height: 34px; object-fit: cover;
  border: 1px solid var(--c-line); border-radius: var(--radius-sm);
}
.dmap-shot:hover img { border-color: var(--c-accent); }
@media (max-width: 575.98px) {
  .dmap-photo { max-width: 100%; }
}

/* -------------------------------------- "your reservation is made" dialog --- */
.paid-tick {
  width: 58px; height: 58px; margin: 0 auto;
  display: grid; place-items: center;
  border-radius: 50%; background: #eaf7f0; color: var(--c-success);
}
.paid-note {
  text-align: left; font-size: 12.8px; line-height: 1.65;
  color: var(--c-ink-soft);
  background: var(--c-canvas); border: 1px solid var(--c-line);
  border-left: 3px solid var(--c-accent);
  border-radius: var(--radius-sm); padding: 11px 13px;
}
.paid-note strong { display: block; color: var(--c-primary); margin-bottom: 2px; }

/* ------------------------------------------------ show / hide a password --- */
.pw-wrap { position: relative; }
.pw-wrap .form-control { padding-right: 42px; }
.pw-eye {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 40px; display: grid; place-items: center;
  border: 0; background: none; padding: 0;
  color: var(--c-ink-faint); cursor: pointer;
}
.pw-eye:hover { color: var(--c-primary); }
.pw-eye.is-on { color: var(--c-accent); }
/* Struck through while the password is visible — the same icon meaning the
   opposite thing is how these end up ambiguous. */
.pw-eye.is-on::after {
  content: ''; position: absolute;
  width: 20px; height: 1.6px; background: currentColor;
  transform: rotate(-45deg); border-radius: 1px;
}

/* ------------------------------------------------ a field the server refused --- */
/* Bootstrap's .is-invalid expects its own validation flow; this is the same
   class driven by the server, so the colour is stated rather than inherited. */
.form-control.is-invalid,
.form-select.is-invalid {
  border-color: var(--c-danger);
  background-color: #fdf6f6;
  box-shadow: 0 0 0 3px rgba(157, 16, 23, .10);
}
.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
  border-color: var(--c-danger);
  box-shadow: 0 0 0 3px rgba(157, 16, 23, .18);
}

/* An optional charge on the return form: a decision, then an amount. */
.charge-opt {
  border: 1px solid var(--c-line); border-radius: var(--radius-sm);
  padding: 10px 12px; background: var(--c-canvas);
  height: 100%;
}
.charge-opt .form-check-label { font-size: 13px; font-weight: 600; color: var(--c-primary); }
.charge-opt .input-hint { margin-top: 5px; }
.charge-opt input:disabled { background: var(--c-line-soft); color: var(--c-ink-faint); }

/* A document still attached from the last attempt at the sign-up form. */
.doc-held {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-bottom: 6px; padding: 6px 10px;
  border: 1px solid #c8ebda; border-radius: var(--radius-sm);
  background: #f2fbf6; color: var(--c-success);
  font-size: 12.2px; font-weight: 600;
}
.doc-held-name { color: var(--c-primary); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.doc-held-size { color: var(--c-ink-faint); font-weight: 500; }

.vq-count { font-size: 13px; color: var(--c-ink-soft); margin: 0 0 12px; }
.vq-count strong { color: var(--c-primary); }
.vq-note { color: var(--c-steel); }
.vq-blocking { color: var(--c-warning); font-weight: 600; }
.vq-ok   { color: var(--c-success); font-weight: 600; }
.vq-warn { color: var(--c-warning); font-weight: 600; }
.vq-bad  { color: var(--c-danger);  font-weight: 600; }
.vq-more {
  padding: 10px 15px; font-size: 12.1px; color: var(--c-ink-soft);
  border-top: 1px solid var(--c-line); background: var(--c-canvas);
}
@media (max-width: 575.98px) {
  .vq-row { flex-wrap: wrap; }
  .vq-acts { width: 100%; justify-content: flex-end; }
  .vq-steps { gap: 6px; }
}

/* --------------------------------------------- the booking, folded away --- */
/* Shown on the sign-up form: one line by default, the whole rental a click
   away. Present for reassurance, not for attention. */
.bsummary {
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  background: var(--c-canvas);
  margin-bottom: 14px;
}
.bsummary-head {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 13px;
  font-size: 12.4px;
  color: var(--c-ink-soft);
}
.bsummary-head::-webkit-details-marker { display: none; }
.bsummary-icon { flex: 0 0 auto; color: var(--c-steel); }
.bsummary-line {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bsummary-line strong { color: var(--c-primary); }
.bsummary-toggle {
  flex: 0 0 auto;
  font-size: 11.4px;
  font-weight: 700;
  color: var(--c-accent);
}
.bsummary[open] > .bsummary-head { border-bottom: 1px solid var(--c-line-soft); }
.bsummary[open] > .bsummary-head .bsummary-toggle { color: var(--c-ink-faint); }
.bsummary-body { padding: 11px 13px 13px; background: #fff; border-radius: 0 0 var(--radius) var(--radius); }
.bsummary-body .kv { margin-bottom: 10px; }

/* On a phone the one line cannot hold vehicle, dates and length, and the dates
   are the half that got cut. Two lines rather than an ellipsis — the point of
   the summary is that the booking stays visible while the form is filled in. */
@media (max-width: 575.98px) {
  .bsummary-head { align-items: flex-start; padding: 9px 11px; }
  .bsummary-icon { margin-top: 2px; }
  .bsummary-line { white-space: normal; overflow: visible; line-height: 1.5; }
  .bsummary-line strong { display: block; }
  .bsummary-toggle { margin-top: 1px; }
}

/* ------------------------------------------------------ booking progress -- */
/* How far through the booking somebody is: the count in words, a bar, and the
   four stages named under it. */
.bsteps {
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  padding: 13px 16px 11px;
  margin-bottom: 14px;
}
.bsteps-head {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin-bottom: 8px;
}
.bsteps-count {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-ink-faint);
}
.bsteps-now {
  font-family: var(--font-head);
  font-size: 14.5px;
  font-weight: 600;
  color: var(--c-primary);
}
.bsteps-track {
  height: 6px;
  border-radius: 4px;
  background: var(--c-canvas);
  border: 1px solid var(--c-line-soft);
  overflow: hidden;
}
.bsteps-fill {
  height: 100%;
  background: var(--c-accent);
  border-radius: 4px;
  transition: width .3s ease;
}
.bsteps-list {
  display: flex;
  list-style: none;
  margin: 7px 0 0;
  padding: 0;
  gap: 6px;
}
.bstep {
  flex: 1 1 0;
  min-width: 0;
  font-size: 11.2px;
  text-align: center;
  color: var(--c-ink-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bstep.is-done { color: var(--c-success); }
.bstep.is-now  { color: var(--c-accent); font-weight: 700; }
.bsteps-note { font-size: 11.6px; color: var(--c-ink-faint); margin: 7px 0 0; }
@media (max-width: 480px) {
  .bstep { font-size: 10.4px; }
  .bsteps-now { font-size: 13.2px; }
}

/* ------------------------------------------------- collapsible filters ---- */
/* The availability filters fold to one line once they have been used, so the
   results are what is on screen rather than the form that found them. */
.filter-panel > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 15px;
  font-size: 12.6px;
  color: var(--c-ink-soft);
}
.filter-panel > summary::-webkit-details-marker { display: none; }
.filter-panel[open] > summary {
  border-bottom: 1px solid var(--c-line-soft);
  color: var(--c-ink-faint);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  padding-bottom: 9px;
}
/* Open, the line above the form is a heading, not a restatement of what is
   already in the fields below it. */
.filter-panel[open] > summary .filter-summary-text { display: none; }
.filter-panel[open] > summary::before { content: 'Availability search'; }
.filter-summary-text {
  flex: 1;
  min-width: 0;
  color: var(--c-ink);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* "Change" when folded, "Hide" when open. The word in the markup is the one
   that shows if this stylesheet never arrives, so it is the useful one. */
.filter-summary-action {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 0;
}
.filter-summary-action::before {
  content: 'Change';
  font-size: 12px;
  font-weight: 700;
  color: var(--c-accent);
}
.filter-panel[open] > summary .filter-summary-action::before {
  content: 'Hide';
  font-size: 11px;
  color: var(--c-ink-faint);
}

/* --------------------------------------------------------- money rows ---- */
.money-table { width: 100%; font-size: 13.2px; }
.money-table td { padding: 5px 0; }
.money-table td:last-child { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.money-table tr.sep td { border-top: 1px solid var(--c-line); padding-top: 9px; }
.money-table tr.total td {
  border-top: 2px solid var(--c-primary);
  padding-top: 9px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 15px;
  color: var(--c-primary);
}
.money-table tr.muted td { color: var(--c-ink-faint); }
.money-table tr.credit td:last-child { color: var(--c-success); }
.money-table tr.due td:last-child { color: var(--c-danger); }

/* ------------------------------------------------------- misc / utility -- */
.empty {
  text-align: center;
  padding: 44px 20px;
  color: var(--c-ink-faint);
}
.empty svg { opacity: .32; margin-bottom: 10px; }
.empty h6 { color: var(--c-ink-soft); font-family: var(--font-head); }

.kv { display: grid; grid-template-columns: 148px 1fr; gap: 5px 14px; font-size: 13.2px; }
.kv dt { color: var(--c-ink-faint); font-weight: 500; }
.kv dd { margin: 0; color: var(--c-ink); font-weight: 500; }

.section-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--c-ink-faint);
  font-weight: 700;
  margin: 0 0 9px;
}

.alert { border-radius: var(--radius-sm); font-size: 13.3px; border-width: 1px; padding: 10px 14px; }
.tabs-line { border-bottom: 1px solid var(--c-line); display: flex; gap: 2px; margin-bottom: 16px; }
.tabs-line a {
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--c-ink-soft);
  border-bottom: 2.5px solid transparent;
  margin-bottom: -1px;
}
.tabs-line a:hover { color: var(--c-primary); }
.tabs-line a.active { color: var(--c-accent); border-bottom-color: var(--c-accent); }

/* --------------------------------------------------------- auth screen --- */
/* minmax(0, 1fr), never a bare 1fr. A bare `1fr` is `minmax(auto, 1fr)`, and
   `auto` will not shrink a track below its content's minimum width — so one
   wide child (a long vehicle line, a three-stage progress bar) stretched the
   whole column past the viewport and clipped everything else off the right.
   The page did not even report a horizontal scrollbar; the content was simply
   wider than the screen and unreachable. */
.auth-wrap { min-height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.auth-visual {
  background:
    radial-gradient(1100px 520px at 12% -12%, rgba(200, 30, 40, .16) 0%, transparent 56%),
    linear-gradient(160deg, var(--c-secondary) 0%, var(--c-primary) 74%);
  color: #fff;
  padding: 52px 56px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
  overflow: hidden;
}
.auth-visual h1 {
  color: #fff;
  font-size: 33px;
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.025em;
  max-width: 13ch;
}
.auth-visual p.lead-sm { color: #adc0d1; font-size: 14.5px; max-width: 44ch; }
.auth-points { list-style: none; padding: 0; margin: 26px 0 0; }
.auth-points li {
  display: flex; gap: 11px; align-items: flex-start;
  color: #c3d2df; font-size: 13.4px; margin-bottom: 12px;
}
.auth-points li svg { flex: 0 0 17px; margin-top: 2px; color: var(--c-chrome); }
.auth-form-side {
  display: grid; place-items: center; padding: 40px 28px; background: var(--c-surface);
  min-width: 0;                 /* same reason as the track above */
}
.auth-card { width: 100%; max-width: 388px; min-width: 0; }

/* The sign-up form is twenty fields long, not four. An even split left a
   half-screen of empty dark panel beside a narrow ribbon of form, so the
   brand side is capped and the card given room to breathe. */
.auth-wrap-wide { grid-template-columns: minmax(0, 38%) minmax(0, 62%); }
.auth-wrap-wide .auth-card { max-width: 620px; }
.auth-wrap-wide .auth-visual { padding: 44px 40px; }
@media (max-width: 1280px) {
  .auth-wrap-wide { grid-template-columns: minmax(0, 34%) minmax(0, 66%); }
}

@media (max-width: 900px) {
  .auth-wrap, .auth-wrap-wide { grid-template-columns: minmax(0, 1fr); }
  .auth-visual { display: none; }
}

/* --------------------------------------------- the sign-up form on a phone --
   Twenty fields, filled in once, usually on the smallest screen the site sees.
   The desktop padding alone was costing about a sixth of the width. */
@media (max-width: 575.98px) {
  .auth-wrap, .auth-wrap-wide { min-height: 100%; }
  .auth-form-side { padding: 18px 14px 34px; align-items: start; }
  .auth-card, .auth-wrap-wide .auth-card { max-width: none; }

  /* A heading that wraps to three lines is a heading that pushed the first
     field below the fold. */
  .auth-card h2 { font-size: 20px; line-height: 1.25; }
  .auth-card > p { font-size: 12.8px; }

  /* Paired fields stack; the gutter between them would only shrink both. */
  .auth-card .row.g-2 > [class*="col-"] { margin-bottom: 2px; }

  /* 16px or iOS zooms the whole page in on focus and leaves it there, which
     is the single worst thing that happens on a long form. */
  .auth-card .form-control,
  .auth-card .form-select { font-size: 16px; padding: 10px 12px; }
  .auth-card .form-label { font-size: 11.4px; }
  .auth-card .input-hint { font-size: 11.4px; }

  /* A file input shows its own button and a file name; at 16px it overflows. */
  .auth-card input[type="file"] { font-size: 13px; padding: 8px 10px; }

  .auth-card .section-title { margin-top: 16px !important; }

  /* Thumb-sized, and it stays put while the page scrolls under it. */
  .auth-card form > button[type="submit"] {
    position: sticky; bottom: 10px;
    padding: 13px 16px; font-size: 15px;
    box-shadow: 0 6px 18px rgba(20, 22, 27, .18);
  }
}

/* ------------------------------------------------------------- public ---- */
.public-nav {
  background: rgba(16, 18, 22, .97);
  backdrop-filter: blur(7px);
  border-bottom: 1px solid rgba(255, 255, 255, .09);
  position: sticky;
  top: 0;
  z-index: 40;
}
.public-nav a.pn-link { color: #c7ccd4; font-size: 13.5px; font-weight: 500; padding: 6px 12px; border-radius: 6px; }
.public-nav a.pn-link:hover { color: #fff; background: rgba(255, 255, 255, .07); }

.hero {
  background:
    radial-gradient(940px 460px at 82% -18%, rgba(200, 30, 40, .15) 0%, transparent 58%),
    linear-gradient(158deg, var(--c-secondary) 0%, var(--c-primary) 72%);
  color: #fff;
  padding: 58px 0 78px;
  position: relative;
}
.hero h1 {
  color: #fff;
  font-size: 42px;
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.1;
  max-width: 16ch;
}
.hero p.sub { color: #b3c4d3; font-size: 15.5px; max-width: 56ch; }

/* The banner above the availability search. Tighter than the full-height hero
   it replaced, so it keeps the brand and the promise without pushing the
   search — the reason anybody is on the page — below the fold. */
.hero-slim { padding: 34px 0 30px; }
.hero-slim h1 { font-size: 33px; max-width: 20ch; margin: 0 0 10px; }
.hero-slim p.sub { font-size: 14px; margin: 0; max-width: 62ch; }
@media (max-width: 900px) {
  .hero-slim { padding: 26px 0 22px; }
  .hero-slim h1 { font-size: 25px; }
  .hero-slim p.sub { font-size: 13.2px; }
}
@media (max-width: 576px) {
  .hero-slim h1 { font-size: 21px; }
  .hero-slim p.sub { font-size: 12.8px; }
}

.search-panel {
  background: #fff;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 19px 20px;
  margin-top: -46px;
  position: relative;
  z-index: 5;
  border: 1px solid var(--c-line);
}

/* --------------------------------------------------------------- print --- */
.print-sheet {
  max-width: 800px;
  margin: 24px auto;
  background: #fff;
  padding: 40px 46px;
  border: 1px solid var(--c-line);
  box-shadow: var(--shadow);
  font-size: 12.6px;
  color: #1b2733;
}
.print-sheet h1, .print-sheet h2 { letter-spacing: -.01em; }
.doc-title {
  font-family: var(--font-head);
  font-size: 17px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
  text-align: center;
  margin: 22px 0 4px;
  color: var(--c-primary);
}
.doc-sub { text-align: center; font-size: 11.5px; color: var(--c-ink-faint); margin-bottom: 20px; }
.print-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; }
.print-org strong { font-family: var(--font-head); font-size: 15.5px; color: var(--c-primary); display: block; }
.print-org span { font-size: 11.3px; color: var(--c-ink-soft); display: block; line-height: 1.5; }
.print-sheet table.grid { width: 100%; border-collapse: collapse; font-size: 12.2px; margin: 10px 0 16px; }
.print-sheet table.grid th, .print-sheet table.grid td { border: 1px solid #c9d3dd; padding: 6px 9px; text-align: left; }
.print-sheet table.grid th { background: #eef2f6; font-weight: 600; font-size: 11.4px; text-transform: uppercase; letter-spacing: .04em; }
.print-sheet table.grid td.num, .print-sheet table.grid th.num { text-align: right; font-variant-numeric: tabular-nums; }
.sig-row { display: flex; gap: 40px; margin-top: 38px; }
.sig-box { flex: 1; }
.sig-line { border-top: 1px solid #4b5b6b; padding-top: 5px; margin-top: 44px; font-size: 11.6px; }
/* A signatory's name is set in capitals on every document, the way it is on the
   deed. Doing it here rather than at each of the twenty-odd places a name is
   printed means none of them can be missed or drift. A ruled blank stays as
   underscores — uppercasing does nothing to those. */
.sig-line strong { display: block; font-size: 12.4px; text-transform: uppercase; }
.doc-note { font-size: 10.8px; color: var(--c-ink-faint); line-height: 1.6; margin-top: 22px; border-top: 1px dashed var(--c-line); padding-top: 11px; }
.terms-body { font-size: 11.6px; line-height: 1.72; }
.terms-body h6 { font-family: var(--font-head); font-size: 12.2px; margin: 15px 0 4px; color: var(--c-primary); }
.checkbox-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px 22px; font-size: 12px; }
.checkbox-grid span::before { content: '☐ '; font-size: 13px; }
.checkbox-grid span.on::before { content: '☑ '; }

/* ---------------------------------------------------------------- deed ---
   The Car Rental Agreement is a Philippine notarial instrument, not a form.
   It reads as continuous prose with the particulars typed onto ruled lines, so
   the styling here is deliberately plain: justified body text, a capitalized
   lead-in for each covenant, and every particular the system already knows
   printed on the rule where the blank would have been. */
/* Cambria, matching the downloadable PDF: the deed is a printed instrument and
   is set in a serif, not in the interface face used everywhere else. */
.deed, .deed-ack, .deed-notarial, .deed-sigs, .deed-annex {
  font-family: Cambria, 'Times New Roman', Georgia, serif;
}
.deed { font-size: 12.4px; line-height: 1.85; text-align: justify; }
.deed p { margin: 0 0 11px; }
.deed .lead-in { font-weight: 700; text-transform: uppercase; letter-spacing: .02em; }
.deed .center { text-align: center; }
.deed .party { margin-left: 26px; }
.deed .and { text-align: center; font-weight: 600; margin: 4px 0 10px; }
/* A particular the system filled in — printed on the rule, as if typed. */
.deed .v { font-weight: 700; border-bottom: 1px solid #1b2733; padding: 0 4px 1px; }
/* A particular only the parties can settle at the counter — left ruled. */
.deed .blank {
  display: inline-block;
  min-width: 150px;
  border-bottom: 1px solid #1b2733;
  vertical-align: baseline;
}
.deed .blank.sm { min-width: 62px; }
.deed .blank.lg { min-width: 250px; }
.deed table.deed-cols { width: 100%; border-collapse: collapse; font-size: 12.3px; margin: 6px 0 13px; }
.deed table.deed-cols th { text-align: left; font-weight: 700; padding: 3px 8px 3px 0; border-bottom: 1px solid #1b2733; }
.deed table.deed-cols td { padding: 5px 8px 5px 0; vertical-align: top; }
.deed table.deed-cols td.num, .deed table.deed-cols th.num { text-align: right; font-variant-numeric: tabular-nums; }
.deed ol.deed-list { padding-left: 22px; margin: 0 0 11px; text-align: justify; }
.deed ol.deed-list li { margin-bottom: 8px; }
.deed-ack { margin-top: 30px; font-size: 12.2px; line-height: 1.8; }
.deed-ack .ack-title {
  font-family: var(--font-head);
  font-weight: 700;
  text-align: center;
  letter-spacing: .12em;
  margin: 16px 0 12px;
}
.deed-notarial { margin-top: 24px; font-size: 12.2px; line-height: 2; }
/* Owner, renter, and the two attesting witnesses. */
.deed-sigs { display: flex; gap: 40px; margin-top: 30px; }
.deed-sigs > div { flex: 1; }
.deed-sig-slot { min-height: 66px; display: flex; align-items: flex-end; }
.deed-sig-name {
  border-top: 1px solid #1b2733;
  padding-top: 4px;
  font-size: 12.3px;
  font-weight: 700;
  text-transform: uppercase;
}
.deed-sig-role {
  display: block;
  font-size: 11.4px;
  color: var(--c-ink-soft);
  text-transform: none;
  font-weight: 400;
}
@media (max-width: 575.98px) {
  .deed { text-align: left; }
  .deed-sigs { flex-direction: column; gap: 16px; }
}

/* ----------------------------------------------------------- remittance ---
   Where the money goes. Two cards, each pairing the account details a customer
   types with the QR they scan; the QR is optional because the number alone is
   enough to pay. */
.remit { display: grid; gap: 10px; }
.remit-card {
  border: 1px solid var(--c-line);
  border-radius: 10px;
  background: var(--c-steel-tint);
  overflow: hidden;
}
.remit-head {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--c-line);
  background: #fff;
}
.remit-tag {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: #fff; padding: 3px 8px; border-radius: 5px;
}
.remit-tag-gcash { background: #0d6efd; }
.remit-tag-bank  { background: var(--c-accent); }
.remit-name { font-size: 13px; font-weight: 600; color: var(--c-primary); }
.remit-body { display: flex; align-items: center; gap: 14px; padding: 11px 12px; }
.remit-body > .min-width-0 { flex: 1; }
.remit-label {
  font-size: 10.6px; text-transform: uppercase; letter-spacing: .08em; color: var(--c-ink-faint);
}
.remit-value { font-size: 17px; font-weight: 700; color: var(--c-primary); letter-spacing: .02em; }
.remit-qr {
  width: 104px; height: 104px; flex: 0 0 104px;
  object-fit: contain; background: #fff;
  border: 1px solid var(--c-line); border-radius: 8px; padding: 4px;
}
.remit-qr-empty {
  display: grid; place-items: center; text-align: center;
  font-size: 10.5px; line-height: 1.4; color: var(--c-ink-faint);
  border-style: dashed;
  padding: 6px;
}
/* The same empty slot as a link, for the administrator who can actually fill it. */
a.remit-qr-empty { text-decoration: none; }
a.remit-qr-empty:hover { border-color: var(--c-accent); color: var(--c-accent); }
/* The thumbnail is a button, not a link: enlarging opens a preview over the
   page rather than a new tab, so a part-filled payment form is never left
   behind. Reset the button chrome so it still reads as a picture. */
.remit-qr-link {
  flex: 0 0 auto;
  display: block;
  text-align: center;
  text-decoration: none;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: zoom-in;
}
.remit-qr-link .remit-qr { display: block; }
.remit-qr-link:hover .remit-qr { border-color: var(--c-accent); }
.remit-qr-cap {
  display: block;
  margin-top: 3px;
  font-size: 10px;
  color: var(--c-ink-faint);
}
.remit-note { font-size: 11.6px; color: var(--c-ink-soft); margin: 2px 0 0; line-height: 1.6; }

/* --- Enlarged QR ---------------------------------------------------------
   Sits above a Bootstrap modal (backdrop 1050, dialog 1055), because the
   payment form it is opened from is itself a dialog. */
.qr-zoom {
  position: fixed; inset: 0; z-index: 2000;
  display: grid; place-items: center;
  padding: 16px;
  background: rgba(12, 14, 18, .78);
  opacity: 0; transition: opacity .18s ease;
  overscroll-behavior: contain;
}
.qr-zoom.show { opacity: 1; }
.qr-zoom-panel {
  background: #fff; border-radius: 12px;
  width: min(420px, 100%);
  max-height: 100%;
  display: flex; flex-direction: column;
  box-shadow: 0 18px 48px rgba(0, 0, 0, .38);
  transform: translateY(6px); transition: transform .18s ease;
}
.qr-zoom.show .qr-zoom-panel { transform: none; }
.qr-zoom-head {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 12px 11px 14px;
  border-bottom: 1px solid var(--c-line);
}
.qr-zoom-label {
  font-size: 13px; font-weight: 600; color: var(--c-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qr-zoom-x {
  margin-left: auto; flex: 0 0 auto;
  width: 30px; height: 30px; line-height: 1;
  border: 0; border-radius: 7px; background: none;
  font-size: 22px; color: var(--c-ink-faint); cursor: pointer;
}
.qr-zoom-x:hover { background: var(--c-canvas); color: var(--c-ink); }
/* The QR itself must stay square and unblurred — it is going to be scanned. */
.qr-zoom-body { padding: 14px; overflow: auto; background: #fff; }
.qr-zoom-body img {
  display: block; width: 100%; height: auto; max-width: 360px; margin: 0 auto;
  image-rendering: -webkit-optimize-contrast;
}
.qr-zoom-foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 14px; border-top: 1px solid var(--c-line);
}
.qr-zoom-hint { font-size: 11.4px; color: var(--c-ink-soft); flex: 1 1 150px; line-height: 1.5; }
.qr-zoom-foot .btn { margin-left: auto; }
@media (max-width: 575.98px) {
  .remit-body { flex-direction: column; align-items: flex-start; }
  .remit-qr { width: 128px; height: 128px; flex-basis: auto; }
}

@media print {
  body { background: #fff; }
  .no-print, .sidebar, .topbar, .public-nav { display: none !important; }
  .print-sheet { box-shadow: none; border: 0; margin: 0; padding: 0; max-width: none; }
  .content { padding: 0; }
  a { color: inherit; text-decoration: none; }
  .st { border: 1px solid #aaa !important; }
}

/* ==========================================================================
   RESPONSIVE
   Phone-first adjustments layered over the desktop rules above. Breakpoints
   match Bootstrap's so utility classes (d-none d-md-block, col-*) and these
   rules never disagree: 1200 xl, 992 lg, 768 md, 576 sm.
   ========================================================================== */

/* Nothing may force the page wider than the viewport. Flex/grid children need
   min-width:0, or long unbroken strings (emails, reference numbers) push the
   layout sideways instead of wrapping. */
html, body { max-width: 100%; overflow-x: hidden; }
.app-main, .content, .card, .card-body, .stat { min-width: 0; }
/* Bootstrap 5.3 ships no min-width utility, but the layouts use this class to
   let a flex child shrink so its text can ellipsis instead of shoving the
   buttons beside it off the row. */
.min-width-0 { min-width: 0; }
img, svg, table { max-width: 100%; }
.veh-photo img { max-width: none; }          /* object-fit needs to overflow */
/* break-word, not anywhere: long tokens (emails, refs) wrap, ordinary words are
   left alone. `anywhere` shatters "Mitsubishi" across four lines. */
.kv dd, .table td, .table th { overflow-wrap: break-word; }

/* Wide content scrolls inside its own box, never the page. The right-edge
   shading is the only cue a touch user gets that there is more to the side. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  background:
    linear-gradient(to right, var(--c-surface) 30%, rgba(255,255,255,0)) left / 28px 100% no-repeat,
    linear-gradient(to left,  var(--c-surface) 30%, rgba(255,255,255,0)) right / 28px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, rgba(20,22,27,.14), transparent) left / 12px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(20,22,27,.14), transparent) right / 12px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
}

/* ----------------------------------------------- ≤1200: tighten gutters --- */
@media (max-width: 1200px) {
  :root { --sidebar-w: 226px; }
  .content { padding: 18px; }
}

/* ------------------------------ ≤992: sidebar becomes an off-canvas drawer - */
@media (max-width: 992px) {
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: min(284px, 82vw);
    flex-basis: min(284px, 82vw);
    height: 100dvh;                     /* dvh survives mobile browser chrome */
    transform: translateX(-102%);
    transition: transform .24s ease;
    z-index: 1045;                      /* above Bootstrap's backdrop (1040) */
    will-change: transform;
  }
  .sidebar.open { transform: translateX(0); box-shadow: var(--shadow-lg); }

  .drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(9, 17, 24, .55);
    opacity: 0;
    visibility: hidden;
    transition: opacity .24s ease, visibility .24s ease;
    z-index: 1040;
  }
  .drawer-backdrop.show { opacity: 1; visibility: visible; }
  body.drawer-open { overflow: hidden; }   /* stop the page scrolling behind */

  .sidebar-close { display: grid !important; }
  .content { padding: 15px; }
  .hero { padding: 44px 0 62px; }
  .hero h1 { font-size: 31px; }
  .hero p.sub { font-size: 14.5px; }
}

/* ------------------------------------------------ ≤768: phones / tablets -- */
@media (max-width: 768px) {
  .topbar { height: auto; min-height: var(--topbar-h); padding: 8px 14px; gap: 10px; }
  .topbar .page-title {
    font-size: 15px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .topbar .page-sub { display: none; }     /* the title alone carries context */

  .content { padding: 13px; }
  .card-body { padding: 14px; }
  .card-header { padding: 11px 14px; font-size: 13.4px; flex-wrap: wrap; row-gap: 8px; }
  /* Filter controls parked in a card header need their own line on a phone */
  .card-header .form-control, .card-header .form-select { max-width: none !important; width: 100%; }

  /* Label/value pairs read better stacked than squeezed into two columns */
  .kv { grid-template-columns: 1fr; gap: 2px 0; }
  .kv dt { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; margin-top: 8px; }
  .kv dd { margin-bottom: 2px; }

  /* Tab strips scroll sideways rather than wrapping into a ragged block */
  .tabs-line {
    overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tabs-line::-webkit-scrollbar { display: none; }
  .tabs-line a { white-space: nowrap; }

  /* Filter bars stack; nothing sits awkwardly half-width on a phone */
  .d-flex.gap-2 > .form-control,
  .d-flex.gap-2 > .form-select { max-width: none !important; }

  .stat { padding: 13px 14px 12px 15px; }
  .stat .v { font-size: 21px; }

  .search-panel { margin-top: -26px; padding: 15px 14px; border-radius: var(--radius); }
  .hero { padding: 36px 0 54px; }
  .hero h1 { font-size: 26px; line-height: 1.15; }

  .auth-form-side { padding: 26px 18px; }

  /* Printable documents: keep the paper look, lose the paper margins */
  .print-sheet { margin: 12px 8px; padding: 20px 16px; font-size: 12.2px; }
  .print-head { flex-direction: column; gap: 10px; }
  .print-head > div:last-child { text-align: left !important; }
  .doc-title { font-size: 15px; letter-spacing: .06em; }
  .sig-row { flex-direction: column; gap: 8px; }
  .sig-line { margin-top: 34px; }
  .checkbox-grid { grid-template-columns: 1fr; }

  .timeline { padding-left: 18px; }
  .veh-photo { height: 168px; }

  /* A dense table squeezed into 375px turns every cell into a word ladder.
     Give it a floor width so columns stay legible and the wrapper scrolls
     instead. Lists that carry a mobile summary line opt out via .table-tight,
     because they hide their secondary columns and genuinely do fit. */
  .table-wrap > .table:not(.table-tight) { min-width: 660px; }
  .mobile-only { display: block !important; }
}

/* The mobile summary line inside a list's first cell — the essential facts from
   the columns that are hidden at this width. */
.mobile-only { display: none; }

/* -------------------------------------------------- ≤576: small phones ---- */
@media (max-width: 576px) {
  .content { padding: 10px; }
  .card { border-radius: var(--radius-sm); }
  .card-body { padding: 12px; }

  /* Action rows: full-width, thumb-sized, stacked in workflow order */
  .card-body > .d-flex.flex-wrap.gap-2 > .btn,
  .card-body > .d-flex.flex-wrap.gap-2 > form,
  .card-body > .d-flex.flex-wrap.gap-2 > form > .btn { width: 100%; }
  .card-body > .d-flex.flex-wrap.gap-2 > .btn.ms-auto { margin-left: 0 !important; }

  .modal-dialog { margin: 8px; }
  .modal-body { padding: 14px; }
  .modal-footer .btn { flex: 1 1 auto; }

  .hero h1 { font-size: 23px; }
  .hero p.sub { font-size: 13.6px; }
  .public-nav a.pn-link { padding: 6px 8px; }

  .table > thead > tr > th { font-size: 9.6px; padding: 8px 9px; }
  .table > tbody > tr > td { padding: 9px 9px; }

  .print-sheet { margin: 8px 4px; padding: 16px 12px; }
  .auth-card { max-width: none; }
}

/* ------------------------------------- touch devices: bigger hit targets -- */
@media (hover: none) and (pointer: coarse) {
  .btn { padding: 9px 15px; }
  .btn-sm { padding: 8px 13px; font-size: 12.6px; }
  .form-control, .form-select { padding: 10px 12px; font-size: 16px; } /* 16px stops iOS zoom-on-focus */
  /* Same shorthand, same lost reservation for the chevron — and worse here,
     because 16px text reaches the arrow sooner. */
  .form-select { padding-right: 2.25rem; }
  .sidebar a.nav-item { padding: 11px 12px; }
  .tabs-line a { padding: 11px 14px; }
  .table > tbody > tr > td { padding: 12px; }
  tr.row-link:hover > td { background: inherit; }   /* no sticky hover state */
}

/* Landscape phones are short — let the drawer scroll rather than clip */
@media (max-height: 480px) and (max-width: 992px) {
  .sidebar { overflow-y: auto; }
  .sidebar-foot { display: none; }
}

/* ------------------------------------------------- clickable table rows --
   Whole-row navigation on transaction lists. The row still contains a real
   link (the reference number), so keyboard and screen-reader users keep a
   proper target — this only adds a larger mouse hit area. */
tr.row-link { cursor: pointer; }
tr.row-link:hover > td { background: var(--c-canvas-warm); }
tr.row-link:focus-visible {
  outline: 2px solid var(--c-steel);
  outline-offset: -2px;
}

/* --------------------------------------------- inspection photo evidence --
   Thumbnail strips for the release and return inspection sets. Fixed-height
   tiles so a mixed portrait/landscape batch off a phone still lines up. */
.photo-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
.photo-strip img,
.photo-strip .photo-tile {
  width: 92px;
  height: 68px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--c-line);
  background: var(--c-canvas-warm);
  display: block;
}
.photo-strip a { line-height: 0; }
.photo-strip a:hover img { border-color: var(--c-steel); }
.photo-strip .photo-cap {
  font-size: 10.5px;
  color: var(--c-ink-faint);
  width: 100%;
}
@media print {
  .photo-strip img, .photo-strip .photo-tile { width: 118px; height: 86px; }
}

/* --------------------------------------------------- photograph credit --
   Fleet photographs are used under CC BY / CC BY-SA, which oblige us to name
   the photographer wherever the picture appears. Small and unobtrusive, but
   always on the image — never tucked away on a separate page only. */
.veh-photo { position: relative; }
.photo-credit {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  max-width: 100%;
  padding: 3px 8px;
  font-size: 9.6px;
  line-height: 1.5;
  letter-spacing: .01em;
  color: rgba(255, 255, 255, .82);
  background: rgba(8, 16, 22, .58);
  border-top-left-radius: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: auto;
}
.photo-credit a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, .32);
}
.photo-credit a:hover { color: #fff; border-bottom-color: rgba(255, 255, 255, .8); }

/* On a card the picture is small; keep the credit from crowding the plate */
.veh-card .photo-credit { font-size: 9px; padding: 2px 6px; }

@media print {
  .photo-credit { color: #333; background: none; position: static; display: block; }
}

/* ------------------------------------------------------ document viewer --
   Preview dialog for an uploaded customer document. Sized to the viewport so a
   reviewer sees a whole page of a scanned form without scrolling the dialog. */
.doc-viewer-body {
  padding: 0;
  background: var(--c-canvas-warm);
  min-height: 220px;
}
.doc-viewer-frame {
  display: block;
  width: 100%;
  height: min(72vh, 860px);
  border: 0;
  background: var(--c-canvas-warm);
}
.doc-viewer-image {
  display: block;
  max-width: 100%;
  max-height: min(72vh, 860px);
  margin: 0 auto;
  object-fit: contain;
  background: #fff;
}
.doc-viewer-loading,
.doc-viewer-fallback {
  padding: 46px 24px;
  text-align: center;
  font-size: 13px;
  color: var(--c-ink-faint);
}
.doc-viewer-fallback p { margin: 0 0 6px; }
.doc-viewer-fallback p:last-child { margin-bottom: 0; }

@media (max-width: 768px) {
  .doc-viewer-frame { height: 62vh; }
  .doc-viewer-image { max-height: 62vh; }
}

/* --------------------------------------------- real photographs in cards --
   The fleet now carries actual photographs, whose aspect ratios vary. The
   card's picture area is a grid with centered items, and a centered grid item
   sizes to its own content rather than stretching — so a tall photo used to
   spill past the bottom of the card. Pin the image to the box instead. */
.veh-photo { overflow: hidden; }
.veh-photo > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ----------------------------------------------------------- signature pad --
   Signing a rental agreement on screen. The ruled baseline and the wide, short
   box are what tell someone this is a place to sign rather than a place to
   draw — nobody needs an instruction for a signature line on paper. */
.sig-pad {
  position: relative;
  height: 132px;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-sm);
  background: #fff;
  overflow: hidden;
  touch-action: none;            /* or a phone scrolls instead of signing */
}
.sig-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  cursor: crosshair;
  display: block;
}
.sig-baseline {
  position: absolute;
  left: 22px; right: 22px; bottom: 34px;
  height: 1px;
  background: var(--c-line);
  pointer-events: none;
}
.sig-hint {
  position: absolute;
  left: 0; right: 0; bottom: 12px;
  text-align: center;
  font-size: 11.5px;
  color: var(--c-ink-faint);
  pointer-events: none;
}

/* A signature already on file, on the case file and the printed agreement */
.sig-image {
  display: block;
  max-width: 230px;
  max-height: 64px;
  object-fit: contain;
}
@media print {
  .sig-image { max-width: 200px; max-height: 56px; }
}

/* ==========================================================================
   Vehicle availability calendar
   Shown on the quotation page so a customer can see, before asking, which
   dates a unit is free. Colors come from the shared tokens - a booked day
   reads as the same red used for refusals elsewhere, a free day as the same
   green used for success, so the legend needs no explaining.
   ========================================================================== */
/* One month at a time, with arrows either side of its name. */
/* Capped, not full-bleed: the cells are square, so letting the grid stretch to
   a wide sidebar gave 69px date squares. Bounded and centered keeps them about
   40px whatever the column does. */
.cal           { width: 100%; max-width: 310px; margin: 0 auto; }
.cal-nav       { display: flex; align-items: center; justify-content: space-between;
                 gap: 8px; margin: 0 0 10px; }
.cal-nav-label { font-size: 13px; font-weight: 600; color: var(--c-ink);
                 letter-spacing: .2px; text-align: center; flex: 1 1 auto; }
.cal-arrow     { flex: 0 0 auto; width: 28px; height: 28px; line-height: 1;
                 font-size: 17px; border-radius: 6px; cursor: pointer;
                 border: 1px solid var(--c-line); background: var(--c-surface);
                 color: var(--c-ink-soft); }
.cal-arrow:hover:not(:disabled) { border-color: var(--c-accent); color: var(--c-accent); }
.cal-arrow:disabled { opacity: .38; cursor: default; }
.cal-month     { width: 100%; }
.cal-note      { font-size: 11.2px; color: var(--c-ink-faint); margin: 9px 0 0; line-height: 1.5; }
.cal-grid      { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-dow       { font-size: 10px; font-weight: 600; color: var(--c-ink-faint);
                 text-align: center; padding-bottom: 3px; letter-spacing: .4px; }
.cal-day       { position: relative; aspect-ratio: 1; display: flex; align-items: center;
                 justify-content: center; font-size: 12.2px; border-radius: 5px;
                 border: 1px solid var(--c-line-soft); background: var(--c-surface);
                 color: var(--c-ink); cursor: default; }
.cal-day.is-free    { background: #e3f5ec; border-color: #c8ebda; color: #146a4d; font-weight: 600; }
.cal-day.is-booked  { background: #fceaea; border-color: #f5d2cf; color: #a02b23; }
.cal-day.is-blocked { background: #fdf1dd; border-color: #f6e0bb; color: #8a5a09; }
/* Half free, half taken - split the swatch rather than pick a side and lie. */
.cal-day.is-partial { background: linear-gradient(135deg, #fceaea 0 48%, #e3f5ec 52% 100%);
                      border-color: #f0ddd8; color: #6b4a33; font-weight: 600; }
/* Asked for but not confirmed. Reads as "someone is interested" rather than
   "taken" - a request holds nothing until staff confirm it. */
.cal-day.is-requested { background: #eef2f7; border-color: #cfdbe8; color: #44546a;
                        font-weight: 600; font-style: italic; }
.cal-day.is-past    { background: var(--c-canvas); border-color: var(--c-line-soft);
                      color: var(--c-chrome); }
.cal-day.is-pad     { border: 0; background: transparent; }
/* A date the customer can actually take. The affordance is the cursor and a
   hover ring; the chosen range is filled so the selection reads at a glance. */
.cal-day.is-pickable { cursor: pointer; }
.cal-day.is-pickable:hover { outline: 2px solid var(--c-accent); outline-offset: -2px; }
.cal-day.is-pickable:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 1px; }
.cal-day.is-chosen  { background: var(--c-accent); border-color: var(--c-accent);
                      color: #fff; font-weight: 700; }
.cal-day.is-between { background: #fbe3e4; border-color: #f3c9cb; color: #8a2b30; }
.cal-readout        { font-size: 12px; font-weight: 600; color: var(--c-accent);
                      text-align: center; margin: 8px 0 0; min-height: 16px; }

/* ==========================================================================
   Booking requirements — the checklist that is also the upload form
   ========================================================================== */
.req-row    { display: flex; gap: 11px; align-items: flex-start; padding: 12px 15px; }
.req-sep    { border-top: 1px solid var(--c-line-soft); }
.req-mark   { flex: 0 0 20px; margin-top: 1px; }
.req-dot    { display: inline-block; width: 16px; height: 16px; border-radius: 50%;
              border: 2px solid var(--c-line); margin-top: 1px; }
.req-upload { display: flex; gap: 7px; align-items: flex-end; flex-wrap: wrap; margin-top: 7px; }
.req-upload input[type="file"] { flex: 1 1 190px; min-width: 0; }
.req-expiry { flex: 0 0 auto; }
.req-expiry .form-label { margin-bottom: 2px; }
@media (max-width: 575.98px) {
  .req-upload input[type="file"] { flex: 1 1 100%; }
}
/* Sending in a newer copy of something already on file. Folded away so a
   satisfied requirement still reads as done. */
.req-replace          { margin-top: 6px; }
.req-replace summary  { font-size: 11.6px; color: var(--c-accent); cursor: pointer; width: fit-content; }
.req-replace summary:hover { text-decoration: underline; }
.req-replace[open] summary { margin-bottom: 2px; }
/* A date field that is really a button. It stands in for the datetime input
   beside it, which keeps the value but would otherwise open the browser's own
   date picker on top of ours. Styled as the input it replaces. */
.cal-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  text-align: left;
  cursor: pointer;
}
.cal-field[hidden] { display: none; }
.cal-field svg { flex: 0 0 auto; color: var(--c-ink-faint); }
.cal-field:hover { border-color: var(--c-steel); }
.cal-field:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 1px; }

/* Which end of the range the next click sets. */
.cal-hint {
  margin: 10px 0 0;
  font-size: 12.2px;
  font-weight: 600;
  color: var(--c-accent);
  text-align: center;
}

/* Why a date in the calendar cannot be taken, said where it was clicked. */
.cal-warn {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--c-danger);
  background: #fceaea;
  border: 1px solid #f5d2cf;
  border-radius: 6px;
  padding: 7px 10px;
}
.cal-warn[hidden] { display: none; }
/* The handover time, chosen alongside the date it belongs to. */
.cal-time {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--c-line-soft);
}
.cal-time .form-label  { margin: 0; flex: 0 0 auto; }
.cal-time .form-select { flex: 0 0 auto; width: auto; }
.cal-time .input-hint  { margin: 0; }

.cal-legend    { display: flex; flex-wrap: wrap; gap: 13px; margin-top: 13px;
                 font-size: 11.6px; color: var(--c-ink-soft); }
.cal-legend i  { width: 11px; height: 11px; border-radius: 3px; display: inline-block;
                 margin-right: 5px; vertical-align: -1px; border: 1px solid var(--c-line); }

/* Alternative dates offered when the requested range will not work. */
.alt-list      { list-style: none; margin: 9px 0 0; padding: 0; }
.alt-item      { display: flex; align-items: center; justify-content: space-between;
                 gap: 10px; padding: 9px 11px; border: 1px solid var(--c-line);
                 border-radius: 7px; background: var(--c-surface); margin-bottom: 7px; }
.alt-item:hover{ border-color: var(--c-accent); }
.alt-when      { font-size: 12.6px; font-weight: 600; color: var(--c-ink); }
.alt-meta      { font-size: 11.2px; color: var(--c-ink-faint); margin-top: 1px; }

/* ==========================================================================
   Pre / post rental inspection
   ========================================================================== */
.insp-table td, .insp-table th { vertical-align: middle; padding: 5px 8px; }
.insp-table th { font-size: 11px; text-transform: uppercase; letter-spacing: .4px;
                 color: var(--c-ink-faint); font-weight: 600; }
.insp-choice   { display: flex; gap: 4px; flex-wrap: wrap; }
.insp-opt      { position: relative; }
.insp-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.insp-opt span { display: inline-block; font-size: 11.4px; font-weight: 600; padding: 3px 9px;
                 border-radius: 5px; border: 1px solid var(--c-line); background: var(--c-surface);
                 color: var(--c-ink-soft); cursor: pointer; user-select: none; }
.insp-opt input:focus-visible + span { outline: 2px solid var(--c-accent); outline-offset: 1px; }
.insp-ok        input:checked + span { background: #e3f5ec; border-color: #c8ebda; color: #146a4d; }
.insp-attention input:checked + span { background: #fdf1dd; border-color: #f6e0bb; color: #8a5a09; }
.insp-defect    input:checked + span { background: #fceaea; border-color: #f5d2cf; color: #a02b23; }
.insp-na        input:checked + span { background: #eef1f5; border-color: #dfe5ec; color: #5c6b7a; }

/* Vehicle diagram — marks are placed by percentage so the same data prints. */
.dmap-views    { display: flex; flex-wrap: wrap; gap: 14px; }
.dmap-view     { margin: 0; flex: 0 0 auto; }
.dmap-view figcaption { font-size: 10.6px; text-transform: uppercase; letter-spacing: .4px;
                        color: var(--c-ink-faint); font-weight: 600; margin-bottom: 3px; text-align: center; }
.dmap-canvas   { position: relative; border: 1px solid var(--c-line); border-radius: 8px;
                 background: var(--c-surface); padding: 4px; cursor: crosshair; }
.dmap-canvas svg { display: block; height: 150px; width: auto; }
.dmap-marks    { position: absolute; inset: 0; }
.dmap-dot      { position: absolute; transform: translate(-50%, -50%); width: 20px; height: 20px;
                 border-radius: 50%; border: 2px solid #ffffff; background: var(--c-accent);
                 color: #ffffff; font-size: 11px; font-weight: 700; line-height: 1; cursor: pointer;
                 box-shadow: 0 1px 3px rgba(0,0,0,.3); padding: 0;
                 display: flex; align-items: center; justify-content: center; }
.dmap-list     { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.dmap-row      { display: flex; align-items: center; gap: 8px; }
/* The description takes the room that is going; the number and the Remove
   button are fixed. Without this the input keeps its intrinsic width and
   leaves most of the row empty. */
.dmap-row input { flex: 1 1 auto; min-width: 0; }
/* Taking a mark off has to be findable, so it is a labelled button beside the
   description rather than a small target on the drawing. */
.dmap-remove {
  flex: 0 0 auto;
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  color: var(--c-ink-soft);
  border-radius: 6px;
  font-size: 11.6px;
  font-weight: 600;
  padding: 4px 10px;
  cursor: pointer;
}
.dmap-remove:hover { border-color: var(--c-danger); color: var(--c-danger); background: #fdf1f0; }
.dmap-remove:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 1px; }
.dmap-undo {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding: 8px 11px;
  border: 1px solid var(--c-line); border-left: 3px solid var(--c-warning);
  border-radius: 7px; background: var(--c-canvas-warm);
  font-size: 12.2px; color: var(--c-ink-soft);
}
.dmap-undo span { flex: 1; min-width: 0; }
/* An author `display` beats the browser's own [hidden] rule whatever the
   specificity, so the attribute has to be honoured explicitly here. */
.dmap-undo[hidden] { display: none; }
.dmap-n        { flex: 0 0 22px; height: 22px; border-radius: 50%; background: var(--c-accent);
                 color: #fff; font-size: 11.5px; font-weight: 700; display: flex;
                 align-items: center; justify-content: center; }

@media print {
  .dmap-canvas { cursor: default; }
  .dmap-canvas svg { height: 116px; }
  .dmap-remove, .dmap-undo { display: none !important; }
  .insp-opt span { padding: 1px 6px; font-size: 10px; }
  /* A numbered mark that the printer drops is a mark that is not on the signed
     sheet, so the fill is forced rather than left to the browser's ink saving. */
  .dmap-dot, .dmap-n { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .dmap-view, .insp-print-table tr { break-inside: avoid; page-break-inside: avoid; }
}

/* Printed checklist — boxes to tick on a blank form, results on a filled one. */
.insp-print-table td, .insp-print-table th { padding: 3px 7px; font-size: 11px; }
.insp-print-box { letter-spacing: .5px; white-space: nowrap; }
.insp-print-res { font-weight: 700; }
.insp-print-res.r-defect    { color: #a02b23; }
.insp-print-res.r-attention { color: #8a5a09; }
.insp-print-res.r-ok        { color: #146a4d; }
.insp-print-res.r-na        { color: #5c6b7a; }
