/* Advantage Appliances
 *
 * Two people use this: Glenys at a desk, Alexander on a phone in someone's
 * kitchen. So: high contrast, big touch targets, dense where it helps and
 * roomy where it matters, and status shown as colour AND words, never colour
 * alone. Colour-coding was asked for repeatedly in 2006 and half-delivered;
 * this does it properly.
 */

:root {
  --ink:        #14181f;
  --ink-2:      #3d4653;
  --ink-3:      #6b7686;
  --line:       #dfe3ea;
  --line-2:     #eef1f5;
  --bg:         #f6f7f9;
  --surface:    #ffffff;
  --surface-2:  #fafbfc;

  --brand:      #1d4ed8;
  --brand-ink:  #17389c;
  --brand-soft: #eaf0ff;

  --red:        #b42318;
  --red-soft:   #fdeceb;
  --amber:      #a45c00;
  --amber-soft: #fdf3e2;
  --green:      #08704a;
  --green-soft: #e6f4ee;
  --purple:     #6b2fbd;
  --purple-soft:#f2ecfd;
  --slate:      #52606d;
  --slate-soft: #eef1f4;

  --radius:     10px;
  --radius-sm:  7px;
  --shadow:     0 1px 2px rgba(20,24,31,.06), 0 1px 3px rgba(20,24,31,.04);
  --shadow-lg:  0 4px 16px rgba(20,24,31,.10);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -0.01em; }
h1 { font-size: 22px; }
h2 { font-size: 17px; }
h3 { font-size: 14px; color: var(--ink-2); }

/* --- layout ------------------------------------------------------------- */

.topbar {
  background: var(--ink);
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 40;
}
.topbar-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 52px;
  flex-wrap: wrap;
}
.brand {
  color: #fff; font-weight: 700; letter-spacing: -0.02em;
  margin-right: 12px; font-size: 15px; white-space: nowrap;
}
.brand:hover { text-decoration: none; }
.brand small { display: block; font-size: 10px; font-weight: 500; opacity: .55; letter-spacing: .06em; text-transform: uppercase; }

.navlink {
  color: rgba(255,255,255,.72);
  padding: 7px 11px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 550;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 7px;
}
.navlink:hover { background: rgba(255,255,255,.10); color: #fff; text-decoration: none; }
.navlink.on { background: rgba(255,255,255,.16); color: #fff; }
.navspacer { flex: 1; }

.badge {
  background: var(--red); color: #fff;
  font-size: 11px; font-weight: 700;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
}
.badge.quiet { background: rgba(255,255,255,.22); }

main { max-width: 1280px; margin: 0 auto; padding: 20px 16px 64px; }
main.narrow { max-width: 760px; }

.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 18px; flex-wrap: wrap;
}
.page-head .sub { color: var(--ink-3); font-size: 13px; margin-top: 3px; }

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: 1fr 1fr; }
.grid-main { grid-template-columns: minmax(0, 1fr) 340px; align-items: start; }
@media (max-width: 900px) {
  .grid-2, .grid-main { grid-template-columns: 1fr; }
}

/* --- cards -------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.card + .card { margin-top: 16px; }
.card-head {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-2);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.card-head h2, .card-head h3 { margin: 0; }
.card-body { padding: 16px; }
.card-body.tight { padding: 10px 16px; }

/* --- chips -------------------------------------------------------------- */

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12px; font-weight: 650;
  line-height: 1.7;
  white-space: nowrap;
}
.chip-blue   { background: var(--brand-soft); color: var(--brand-ink); }
.chip-amber  { background: var(--amber-soft); color: var(--amber); }
.chip-green  { background: var(--green-soft); color: var(--green); }
.chip-red    { background: var(--red-soft);   color: var(--red); }
.chip-purple { background: var(--purple-soft);color: var(--purple); }
.chip-grey   { background: var(--line-2);     color: var(--ink-3); }
.chip-slate  { background: var(--slate-soft); color: var(--slate); }
.chip-black  { background: var(--ink); color: #fff; }
.chip.big { font-size: 13px; padding: 4px 12px; }

/* --- buttons ------------------------------------------------------------ */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 14px;
  min-height: 38px;
  min-width: 76px;               /* stops "Save" -> "Saving" resizing the button */
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.btn:hover { background: var(--surface-2); border-color: #cfd6e0; text-decoration: none; }
.btn:disabled, .btn[disabled] { opacity: .55; cursor: default; }
.btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-ink); border-color: var(--brand-ink); }
.btn-danger { color: var(--red); border-color: #f0c9c5; background: var(--red-soft); }
.btn-danger:hover { background: #fbdedb; }
.btn-ghost { border-color: transparent; background: transparent; color: var(--ink-2); min-width: 0; }
.btn-ghost:hover { background: var(--line-2); }
.btn-sm { padding: 4px 10px; min-height: 30px; font-size: 13px; min-width: 0; }
.btn-lg { padding: 12px 18px; min-height: 48px; font-size: 15px; }
.btn-block { width: 100%; }

.btn-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* --- forms -------------------------------------------------------------- */

label { display: block; font-size: 12px; font-weight: 650; color: var(--ink-2); margin-bottom: 4px; }
label.inline { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 500; margin: 0; }

/* Match by exclusion, not by listing the types we want.
   An <input> with no type attribute behaves as text but does NOT match
   input[type=text] - that is an attribute selector, not a behaviour one. Every
   bare <input name="..."> in this app was falling through to the browser
   default: 21px tall, 170px wide, sitting out of line with the select beside
   it. Excluding the handful that must keep their native look is the only
   version of this rule that cannot silently miss a field again. */
.input,
input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]):not([type=hidden]),
select, textarea {
  width: 100%;
  padding: 8px 11px;
  min-height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font: inherit; font-size: 14px;
  color: var(--ink);
}
input::placeholder, textarea::placeholder { color: var(--ink-3); }
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--brand);
  outline-offset: -1px;
  border-color: var(--brand);
}
textarea { min-height: 76px; resize: vertical; line-height: 1.5; }
input[type=checkbox], input[type=radio] { width: auto; min-height: 0; accent-color: var(--brand); }

.field { margin-bottom: 12px; }
.field-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.field-row > * { flex: 1; min-width: 0; }
.field-row .grow-2 { flex: 2; }
/* A button sharing a row with labelled fields. It has no label of its own, so
   without this it floats to the top of the row and misses the line the inputs
   sit on. */
.field-action { flex: 0 0 auto; }

.hint { font-size: 12px; color: var(--ink-3); margin-top: 3px; }
.err  { font-size: 12px; color: var(--red); margin-top: 3px; font-weight: 600; }

.alert {
  padding: 11px 14px; border-radius: var(--radius-sm);
  font-size: 14px; margin-bottom: 14px;
  border: 1px solid transparent;
}
.alert-error { background: var(--red-soft); color: var(--red); border-color: #f3cfcb; }
.alert-warn  { background: var(--amber-soft); color: var(--amber); border-color: #f2ddba; }
.alert-info  { background: var(--brand-soft); color: var(--brand-ink); border-color: #cddcfd; }

/* --- tables ------------------------------------------------------------- */

table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-3); padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
td { padding: 9px 12px; border-bottom: 1px solid var(--line-2); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr.clickable:hover { background: var(--surface-2); cursor: pointer; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table-wrap { overflow-x: auto; }

/* A red left edge marks a row where money is owed. Always paired with the
   amount in text - the colour is a shortcut, not the message. */
tr.owing td:first-child { box-shadow: inset 3px 0 0 var(--red); }

/* --- lists -------------------------------------------------------------- */

.rows { display: flex; flex-direction: column; }
.row {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-2);
  transition: opacity 150ms ease, background 120ms ease;
}
.row:last-child { border-bottom: 0; }
.row:hover { background: var(--surface-2); }
.row-main { flex: 1; min-width: 0; }
.row-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.row-title { font-weight: 600; }
.row-meta { font-size: 13px; color: var(--ink-3); margin-top: 2px; }
.row.owing { box-shadow: inset 3px 0 0 var(--red); }

.empty {
  padding: 34px 16px; text-align: center; color: var(--ink-3); font-size: 14px;
}
.empty strong { display: block; color: var(--ink-2); font-size: 15px; margin-bottom: 4px; }

/* --- stat cards --------------------------------------------------------- */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 13px 15px; box-shadow: var(--shadow);
  display: block; color: inherit;
}
.stat:hover { text-decoration: none; border-color: #cfd6e0; }
.stat .n { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; }
.stat .k { font-size: 12px; color: var(--ink-3); font-weight: 600; margin-top: 2px; }
.stat.alarm .n { color: var(--red); }
.stat.warn .n { color: var(--amber); }

/* --- key/value ---------------------------------------------------------- */

.kv { display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; font-size: 14px; }
.kv dt { color: var(--ink-3); font-size: 13px; }
.kv dd { margin: 0; }

.money-line {
  display: flex; gap: 18px; align-items: baseline; flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
}
.money-line b { font-size: 17px; }
.money-line .due { color: var(--red); font-weight: 700; }
.money-line .settled { color: var(--green); font-weight: 650; }

/* --- misc --------------------------------------------------------------- */

.muted { color: var(--ink-3); }
.small { font-size: 13px; }
.tiny  { font-size: 12px; }
.mono  { font-family: var(--mono); font-size: 13px; }
.nowrap { white-space: nowrap; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: 8px; } .mt-2 { margin-top: 16px; }
.mb-1 { margin-bottom: 8px; } .mb-2 { margin-bottom: 16px; }
.flex { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.between { justify-content: space-between; }
.pre-wrap { white-space: pre-wrap; word-break: break-word; }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 0; }
.tab {
  padding: 9px 14px; font-size: 14px; font-weight: 600; color: var(--ink-3);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.on { color: var(--brand-ink); border-bottom-color: var(--brand); }

.timeline { font-size: 13px; }
.timeline .ev { padding: 7px 0; border-bottom: 1px solid var(--line-2); }
.timeline .ev:last-child { border-bottom: 0; }
.timeline .when { color: var(--ink-3); font-size: 12px; }

/* --- photos -------------------------------------------------------------- */

.photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }
.photo {
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--line-2);
  aspect-ratio: 4 / 3;
}
.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 14px 8px 5px;
  font-size: 12px; color: #fff; line-height: 1.3;
  background: linear-gradient(to top, rgba(0,0,0,.72), transparent);
  pointer-events: none;
}
.photo-actions {
  position: absolute; top: 0; right: 0;
  padding: 5px;
  opacity: 0; transition: opacity 120ms ease;
}
.photo:hover .photo-actions, .photo:focus-within .photo-actions { opacity: 1; }
/* On a touch screen there is no hover, so the control is always there. */
@media (hover: none) { .photo-actions { opacity: 1; } }
.photo-del {
  border: 0; border-radius: 5px; cursor: pointer;
  width: 30px; height: 30px; padding: 0; line-height: 1;
  font-size: 17px; font-weight: 700;
  background: rgba(255,255,255,.9); color: var(--red);
}
.photo-del:hover { background: #fff; }

.dropzone {
  border: 2px dashed var(--line);
  border-radius: var(--radius-sm);
  padding: 18px 14px;
  text-align: center;
  transition: border-color 120ms ease, background 120ms ease;
}
.dropzone:hover { border-color: #b9c4d4; }
.dropzone.upload-drop-active { border-color: var(--brand); background: var(--brand-soft); }
.dropzone-hint { font-size: 13px; color: var(--ink-3); margin-bottom: 9px; }
.upload-buttons { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; }
/* A label styled as a button, wrapping a hidden file input. The native control
   cannot be styled and looked like a leftover from another application. */
.upload-buttons label.btn { margin-bottom: 0; }
.upload-progress { text-align: left; }
.upload-progress-track {
  height: 6px; border-radius: 3px; background: var(--line-2); overflow: hidden;
}
.upload-progress-bar {
  height: 100%; width: 0%; background: var(--brand);
  border-radius: 3px; transition: width 140ms ease;
}
.upload-progress-text {
  display: block; font-size: 12px; color: var(--ink-3); margin-top: 6px;
}

.saved-tick { color: var(--green); font-size: 12px; font-weight: 650; }

/* Search results keep a floor so the page does not jump as they arrive. */
#results { min-height: 260px; }
#queue-list { min-height: 200px; }

/* --- the technician's day ----------------------------------------------- */

.day-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 15px; margin-bottom: 12px;
}
.day-card h2 { font-size: 17px; }
.day-card .addr { font-size: 15px; color: var(--ink-2); margin: 5px 0 9px; }
.day-card .problem {
  background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: var(--radius-sm); padding: 9px 11px;
  font-size: 15px; margin: 10px 0;
}
.day-actions { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.day-actions .btn { min-width: 0; }

/* Sized off the container, not the viewport. This control lives in a 340px
   side rail on a wide screen, so a viewport media query gave it four columns
   with no room for them and "Awaiting parts" wrapped to two lines, leaving one
   button half again as tall as its neighbours. */
.segmented {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  align-items: stretch;
}
.segmented .btn { min-width: 0; width: 100%; }

/* --- toasts ------------------------------------------------------------- */

#toasts {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
  z-index: 100; display: flex; flex-direction: column; gap: 8px;
  pointer-events: none; width: min(420px, calc(100vw - 32px));
}
.toast {
  padding: 11px 15px; border-radius: var(--radius-sm);
  background: var(--ink); color: #fff; font-size: 14px; font-weight: 550;
  box-shadow: var(--shadow-lg);
  animation: rise 180ms ease;
}
.toast-error   { background: var(--red); }
.toast-success { background: var(--green); }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }

/* --- login -------------------------------------------------------------- */

.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: var(--ink);
}
.login-card {
  background: var(--surface); border-radius: 14px; padding: 30px;
  width: 100%; max-width: 380px; box-shadow: var(--shadow-lg);
}
.login-card h1 { font-size: 21px; margin-bottom: 3px; }

/* --- mobile ------------------------------------------------------------- */

@media (max-width: 640px) {
  body { font-size: 16px; }
  main { padding: 14px 12px 60px; }
  .topbar-inner { padding: 0 12px; min-height: 48px; }
  .navlink { padding: 6px 9px; font-size: 13px; }
  .card-body { padding: 13px; }
  .row { padding: 12px 13px; }
  /* Touch targets get bigger, not smaller, on a phone. */
  .btn { min-height: 44px; }
  .btn-sm { min-height: 36px; }
  th, td { padding: 9px 8px; }
  /* Stacked, and stretched back to full width: the row aligns to flex-end so
     buttons sit on the same line as the inputs beside them, and in a column
     that would push every field against the right edge instead. */
  .field-row { flex-direction: column; gap: 0; align-items: stretch; }
  .field-row .field-action { margin-bottom: 12px; }
  /* Title and its buttons stack rather than fight for one line. */
  .page-head { flex-direction: column; align-items: stretch; gap: 10px; }
}

/* --- print -------------------------------------------------------------- */

@media print {
  .topbar, .no-print, #toasts { display: none !important; }
  body { background: #fff; font-size: 12pt; }
  main { max-width: none; padding: 0; }
  .card { border: 1px solid #000; box-shadow: none; break-inside: avoid; }
  .job-card-print { font-size: 12pt; }
  .job-card-print h1 { font-size: 20pt; }
  a { color: #000; text-decoration: none; }
}
