/* =====================================================================
 * JIM — Jobs, Inventory, Materials (Fence Masters)
 *
 * Design intent: an operations console, not a web page. Dark rail for
 * navigation so the eye ignores it, near-white workspace, one confident
 * accent, and colour reserved almost entirely for things that are wrong.
 * Every control stays at least 44px so it works with work gloves on.
 * ===================================================================== */

/* ------------------------------------------------------------ tokens */
:root {
  /* neutrals — cool grey, slight blue cast */
  --n-0:   #ffffff;
  --n-25:  #fbfcfd;
  --n-50:  #f5f7fa;
  --n-100: #eceff4;
  --n-150: #e2e7ee;
  --n-200: #d3dae4;
  --n-300: #b4bfcd;
  --n-400: #8b99ac;
  --n-500: #67768b;
  --n-600: #4e5c70;
  --n-700: #3a4657;
  --n-800: #263140;
  --n-900: #16202c;
  --n-950: #0d151e;

  --ink:      var(--n-900);
  --ink-2:    var(--n-600);
  --ink-3:    var(--n-500);
  --line:     var(--n-150);
  --line-soft:var(--n-100);
  --bg:       var(--n-50);
  --panel:    var(--n-0);
  --panel-2:  var(--n-25);

  /* one accent, used sparingly */
  --accent:     #1a63c4;
  --accent-2:   #1553a8;
  --accent-ink: #ffffff;
  --accent-bg:  #e9f1fd;
  --accent-line:#bcd5f5;

  /* navigation rail */
  --rail:      #16202c;
  --rail-2:    #1e2b3a;
  --rail-ink:  #c3cedd;
  --rail-ink-2:#7f8ea3;

  /* semantic — these are the only loud colours */
  --ok:      #0f7a44;   --ok-bg:   #e4f6ec;  --ok-line:  #a8e0c1;
  --warn:    #92580a;   --warn-bg: #fdf2dc;  --warn-line:#f0d59b;
  --bad:     #b02417;   --bad-bg:  #fdeceb;  --bad-line: #f4bcb6;
  --info:    #1a5fb4;   --info-bg: #e9f1fd;  --info-line:#bcd5f5;

  --radius-sm: 6px;
  --radius:    9px;
  --radius-lg: 13px;

  --sh-1: 0 1px 2px rgba(22,32,44,.05);
  --sh-2: 0 1px 3px rgba(22,32,44,.07), 0 4px 12px -2px rgba(22,32,44,.06);
  --sh-3: 0 12px 44px -8px rgba(13,21,30,.28), 0 4px 12px -4px rgba(13,21,30,.14);

  --tap: 44px;
  --rail-w: 236px;
  --ease: cubic-bezier(.4, 0, .2, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --n-0:   #151e29;
    --n-25:  #18222e;
    --n-50:  #0f1721;
    --n-100: #1e2a37;
    --n-150: #26333f;
    --n-200: #2f3d4c;
    --n-300: #42525f;
    --n-400: #6b7c8d;
    --n-500: #8d9dae;
    --n-600: #adbbc9;
    --n-700: #c9d4df;
    --n-800: #e0e7ee;
    --n-900: #eef3f8;
    --n-950: #ffffff;

    --line:      #26333f;
    --line-soft: #1e2a37;
    --bg:        #0b1219;
    --panel:     #151e29;
    --panel-2:   #18222e;

    --accent:     #4f9ae8;
    --accent-2:   #6cb0f5;
    --accent-ink: #08131f;
    --accent-bg:  #14273c;
    --accent-line:#2b4f78;

    --rail:      #0d151e;
    --rail-2:    #16202c;
    --rail-ink:  #c3cedd;
    --rail-ink-2:#6d7d92;

    --ok:   #4ec585;  --ok-bg:   #102e1e;  --ok-line:  #1e5638;
    --warn: #e0a63f;  --warn-bg: #2f2510;  --warn-line:#5b451a;
    --bad:  #ff8177;  --bad-bg:  #331512;  --bad-line: #61281f;
    --info: #6fadf3;  --info-bg: #14273c;  --info-line:#2b4f78;

    --sh-1: 0 1px 2px rgba(0,0,0,.4);
    --sh-2: 0 1px 3px rgba(0,0,0,.5), 0 4px 12px -2px rgba(0,0,0,.4);
    --sh-3: 0 12px 44px -8px rgba(0,0,0,.7), 0 4px 12px -4px rgba(0,0,0,.5);
  }
}

/* ------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text",
               "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  font-feature-settings: "cv05" 1, "ss01" 1;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-weight: 640; letter-spacing: -.012em; line-height: 1.25; }
h1 { font-size: 1.5rem;  letter-spacing: -.022em; }
h2 { font-size: 1.08rem; }
h3 { font-size: .95rem; }
p  { margin: 0 0 .7rem; }
p:last-child { margin-bottom: 0; }
a  { color: var(--accent); text-underline-offset: 2px; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--n-200); border-radius: 99px;
  border: 3px solid var(--bg); background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--n-300); background-clip: padding-box; }

/* ------------------------------------------------------------ layout */
.app { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 40;
  background: var(--rail); color: #fff;
  display: flex; align-items: center; gap: .8rem;
  padding: .7rem 1rem;
  padding-top: max(.7rem, env(safe-area-inset-top));
}
.topbar .brand {
  font-weight: 680; font-size: 1rem; letter-spacing: -.01em;
  white-space: nowrap; line-height: 1.15;
  display: flex; align-items: center; gap: .6rem; min-width: 0;
}
.topbar .brand small {
  font-weight: 450; font-size: .7rem;
  color: var(--rail-ink-2); letter-spacing: .01em;
  overflow: hidden; text-overflow: ellipsis;
}
/* JIM, set off from the Fence Masters lockup by a hairline. */
.topbar .brand-name {
  display: flex; flex-direction: column; min-width: 0;
  padding-left: .7rem; border-left: 1px solid var(--rail-2);
}
.topbar .brand-name b {
  font-size: 1.02rem; font-weight: 720; letter-spacing: .06em; line-height: 1.1;
}
.topbar .brand-name small { display: block; }

/* Knockout lockup — sits straight on the rail, no plate. */
.brand-logo { display: block; width: 132px; height: auto; flex: none; }
.topbar .spacer { flex: 1; }
.topbar .who {
  font-size: .74rem; color: var(--rail-ink-2); text-align: right;
  line-height: 1.3; letter-spacing: .04em; text-transform: uppercase;
}
.topbar .who b {
  display: block; font-weight: 600; color: var(--rail-ink);
  font-size: .84rem; letter-spacing: 0; text-transform: none;
}

.demo-flag {
  background: var(--warn-bg); color: var(--warn);
  border-bottom: 1px solid var(--warn-line);
  font-size: .78rem; font-weight: 560; letter-spacing: .005em;
  padding: .5rem 1rem; text-align: center;
}

/* Bottom tab bar on phones.
   The nav lives inside .topbar in the DOM (it belongs to the rail on
   desktop), so it has to be FIXED to escape that flex row on narrow
   screens — sticky would leave it stranded in the header. */
.nav {
  display: flex; background: var(--panel);
  border-top: 1px solid var(--line);
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 45;
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: 0 -1px 3px rgba(22,32,44,.06);
}
.nav button {
  position: relative; flex: 1; min-height: 56px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: none; border: 0; cursor: pointer; font-family: inherit;
  color: var(--ink-3); font-size: .63rem; font-weight: 620;
  letter-spacing: .015em; padding: .3rem .15rem;
  transition: color .15s var(--ease);
}
.nav button .ico { display: flex; align-items: center; justify-content: center; height: 20px; }
.nav button .ico svg { width: 19px; height: 19px; }
.nav button > span:not(.ico):not(.pip) { white-space: nowrap; }
.nav .lbl-long  { display: none; }
.nav .lbl-short { display: inline; }
.nav button[aria-current="page"] { color: var(--accent); }
.nav button .pip {
  position: absolute; top: 6px; left: 50%; margin-left: 4px;
  background: var(--bad); color: #fff; border-radius: 99px;
  font-size: .6rem; min-width: 16px; height: 16px; padding: 0 4px;
  display: grid; place-items: center; font-weight: 700;
  font-variant-numeric: tabular-nums; box-shadow: 0 0 0 2px var(--panel);
}

.main {
  flex: 1; width: 100%; max-width: 1220px; margin: 0 auto;
  /* leave room for the fixed bottom tab bar */
  padding: 1.1rem 1rem calc(64px + 1.5rem + env(safe-area-inset-bottom));
}

/* left rail on desktop */
@media (min-width: 920px) {
  .app { flex-direction: row; }
  .topbar {
    flex-direction: column; align-items: stretch;
    width: var(--rail-w); flex: 0 0 var(--rail-w);
    min-height: 100vh; height: 100vh; overflow-y: auto;
    padding: 1.15rem .7rem 1rem; gap: 0;
    border-right: 1px solid rgba(255,255,255,.06);
  }
  .topbar .brand {
    padding: .1rem .55rem 0; margin-bottom: 1.5rem;
    flex-direction: column; align-items: flex-start; gap: .5rem;
  }
  .brand-logo { width: 176px; }
  /* Stacked on the rail, so the vertical divider makes no sense here. */
  .topbar .brand-name { padding-left: 0; border-left: 0; }
  .topbar .who {
    text-align: left; order: 5; padding: .7rem .55rem 0;
    border-top: 1px solid rgba(255,255,255,.07); margin-top: .6rem;
  }
  .topbar .spacer { order: 4; }
  .topbar > .btn { order: 6; margin-top: .55rem; }

  .nav {
    position: static; flex-direction: column; gap: 2px;
    background: none; border: 0; padding: 0; box-shadow: none;
  }
  .nav button {
    flex: none; flex-direction: row; justify-content: flex-start; gap: .68rem;
    min-height: 40px; border-radius: var(--radius);
    color: var(--rail-ink); font-size: .875rem; font-weight: 520;
    letter-spacing: -.002em; padding: .45rem .55rem;
  }
  .nav button .ico { width: 20px; height: 20px; }
  .nav button .ico svg { width: 18px; height: 18px; }
  .nav .lbl-long  { display: inline; }
  .nav .lbl-short { display: none; }
  .nav button:hover { background: rgba(255,255,255,.055); color: #fff; }
  .nav button[aria-current="page"] {
    background: var(--rail-2); color: #fff; font-weight: 620;
    box-shadow: inset 2px 0 0 var(--accent-2);
  }
  .nav button .pip {
    position: static; margin: 0 0 0 auto; box-shadow: none;
    background: rgba(255,255,255,.13); color: #fff;
  }
  .nav button[aria-current="page"] .pip { background: var(--bad); }

  .body-col { flex: 1; min-width: 0; display: flex; flex-direction: column; height: 100vh; overflow-y: auto; }
  .main { padding: 1.7rem 2.2rem 4rem; }
}

/* ------------------------------------------------------- page header */
.page-head { margin-bottom: 1.25rem; }
.page-head .sub { color: var(--ink-3); font-size: .875rem; margin-top: .15rem; }

/* -------------------------------------------------------------- card */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--sh-1);
  padding: 1.05rem 1.15rem;
  margin-bottom: 1rem;
}
.card.flush { padding: 0; overflow: hidden; }
.card.flush .card-head { padding: 1rem 1.15rem; margin: 0; border-bottom: 1px solid var(--line); }

.card-head {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-bottom: .9rem;
}
.card-head > h1, .card-head > h2, .card-head > h3 { margin: 0; }
.card-head .spacer { flex: 1 1 auto; }

/* ------------------------------------------------------------- tiles */
.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: .7rem; margin-bottom: 1.15rem;
}
.tile {
  position: relative; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--sh-1);
  padding: .8rem .9rem .85rem;
  text-align: left; font-family: inherit; color: inherit;
  cursor: pointer; display: block; width: 100%;
  transition: box-shadow .16s var(--ease), border-color .16s var(--ease), transform .1s var(--ease);
}
.tile:hover { box-shadow: var(--sh-2); border-color: var(--n-200); }
.tile:active { transform: translateY(1px); }
.tile .n {
  font-size: 2rem; font-weight: 660; line-height: 1;
  letter-spacing: -.035em; font-variant-numeric: tabular-nums;
  margin-bottom: .3rem;
}
.tile .l {
  font-size: .76rem; font-weight: 640; color: var(--ink-2);
  letter-spacing: .015em; text-transform: uppercase;
}
.tile::after {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 3px; background: transparent;
}
/* the tile currently being used as a filter */
.tile.is-on {
  border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), var(--sh-2);
}
.tile.alert::after { background: var(--bad); }
.tile.alert .n    { color: var(--bad); }
.tile.warn::after { background: var(--warn); }
.tile.warn .n     { color: var(--warn); }
.tile.good::after { background: var(--ok); }
.tile.good .n     { color: var(--ok); }
.tile.info::after { background: var(--accent); }

/* A second rank of tiles inside a card — the backlog breakdown. Smaller,
   because it's detail under a heading, not the headline itself. */
.tiles-sm { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); margin-bottom: 0; }
.tiles-sm .tile   { padding: .65rem .7rem .7rem; box-shadow: none; }
.tiles-sm .tile .n { font-size: 1.5rem; margin-bottom: .2rem; }
.tiles-sm .tile .l { font-size: .7rem; }

/* ------------------------------------------------------------ badges */
.badge {
  display: inline-flex; align-items: center; gap: .34rem;
  font-size: .715rem; font-weight: 620; letter-spacing: .012em;
  padding: .18rem .5rem; border-radius: var(--radius-sm);
  background: var(--n-100); color: var(--ink-2);
  border: 1px solid transparent; white-space: nowrap; line-height: 1.5;
}
.badge.ok   { background: var(--ok-bg);   color: var(--ok);   border-color: var(--ok-line); }
.badge.warn { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-line); }
.badge.bad  { background: var(--bad-bg);  color: var(--bad);  border-color: var(--bad-line); }
.badge.info { background: var(--info-bg); color: var(--info); border-color: var(--info-line); }
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

/* ----------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  min-height: var(--tap); padding: .5rem 1rem;
  border-radius: var(--radius); border: 1px solid var(--line);
  background: var(--panel); color: var(--ink);
  font: inherit; font-size: .875rem; font-weight: 580; letter-spacing: -.003em;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  box-shadow: var(--sh-1);
  transition: background .14s var(--ease), border-color .14s var(--ease),
              box-shadow .14s var(--ease), transform .08s var(--ease);
}
.btn:hover:not(:disabled) { background: var(--n-50); border-color: var(--n-200); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }

.btn.primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
  box-shadow: 0 1px 2px rgba(26,99,196,.28);
}
.btn.primary:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); }
.btn.danger { color: var(--bad); border-color: var(--bad-line); background: var(--bad-bg); }
.btn.danger:hover:not(:disabled) { background: var(--bad); color: #fff; border-color: var(--bad); }
.btn.ghost  { background: none; border-color: transparent; box-shadow: none; color: var(--ink-2); }
.btn.ghost:hover:not(:disabled) { background: var(--n-100); border-color: transparent; color: var(--ink); }
.btn.sm { min-height: 34px; padding: .25rem .65rem; font-size: .8rem; border-radius: var(--radius-sm); }
.btn.block { width: 100%; }

.topbar .btn {
  background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.13);
  color: var(--rail-ink); box-shadow: none;
}
.topbar .btn:hover:not(:disabled) { background: rgba(255,255,255,.13); color: #fff; }

.btn-row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

/* ------------------------------------------------------------- forms */
label.f { display: block; margin-bottom: .85rem; }
label.f > span {
  display: block; font-size: .78rem; font-weight: 620; color: var(--ink-2);
  margin-bottom: .3rem; letter-spacing: .005em;
}
label.f > span .req { color: var(--bad); }
label.f .hint {
  display: block; font-weight: 430; color: var(--ink-3);
  font-size: .74rem; margin-top: .18rem; line-height: 1.4;
}

input[type=text], input[type=date], input[type=number], input[type=email],
input[type=password], input[type=tel], input[type=search], select, textarea {
  width: 100%; min-height: var(--tap);
  padding: .5rem .65rem;
  border: 1px solid var(--n-200); border-radius: var(--radius);
  background: var(--panel); color: var(--ink);
  font: inherit; font-size: .92rem;
  transition: border-color .14s var(--ease), box-shadow .14s var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--n-400); }
textarea { min-height: 84px; resize: vertical; line-height: 1.5; padding-top: .6rem; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%2367768b' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .6rem center;
  padding-right: 2rem;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
input[type=checkbox] { width: 19px; height: 19px; min-height: 0; accent-color: var(--accent); cursor: pointer; }

.grid2 { display: grid; grid-template-columns: 1fr; gap: 0 .9rem; }
.grid3 { display: grid; grid-template-columns: 1fr; gap: 0 .9rem; }
@media (min-width: 620px) {
  .grid2 { grid-template-columns: 1fr 1fr; }
  .grid3 { grid-template-columns: repeat(3, 1fr); }
}

.toolbar { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-bottom: .85rem; }
.toolbar input[type=search] { flex: 1 1 230px; min-width: 0; }
.toolbar select { flex: 0 1 auto; width: auto; min-width: 140px; }

.chips { display: flex; gap: .38rem; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--line); background: var(--panel); color: var(--ink-2);
  border-radius: 99px; padding: .3rem .78rem; font: inherit;
  font-size: .81rem; font-weight: 580; cursor: pointer; min-height: 34px;
  box-shadow: var(--sh-1);
  transition: background .14s var(--ease), color .14s var(--ease), border-color .14s var(--ease);
}
.chip:hover { border-color: var(--n-300); color: var(--ink); }
.chip[aria-pressed="true"] {
  background: var(--ink); border-color: var(--ink); color: var(--panel);
}

/* -------------------------------------------------------- job rows */
.joblist { display: grid; gap: .5rem; }

.jobrow {
  position: relative; display: block; width: 100%; text-align: left;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .78rem .9rem .78rem 1.05rem;
  cursor: pointer; font: inherit; color: inherit; box-shadow: var(--sh-1);
  transition: box-shadow .16s var(--ease), border-color .16s var(--ease);
}
.jobrow::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-radius: var(--radius) 0 0 var(--radius); background: var(--n-200);
}
.jobrow:hover { box-shadow: var(--sh-2); border-color: var(--n-200); }
.jobrow.s-at-risk::before     { background: var(--bad); }
.jobrow.s-in-progress::before { background: var(--accent); }
.jobrow.s-not-started::before { background: var(--n-300); }
.jobrow.s-on-hold::before     { background: var(--warn); }
.jobrow.s-completed::before   { background: var(--ok); }
.jobrow.s-cancelled::before   { background: var(--n-200); }
.jobrow.s-completed, .jobrow.s-cancelled { opacity: .68; }

.jobrow .r1 { display: flex; align-items: baseline; gap: .45rem; flex-wrap: wrap; }
.jobrow .num {
  font-weight: 680; font-variant-numeric: tabular-nums;
  font-size: .875rem; letter-spacing: -.01em;
}
.jobrow .cust { font-weight: 570; }
.jobrow .proj { color: var(--ink-3); font-size: .875rem; }
.jobrow .meta { font-size: .8rem; color: var(--ink-3); margin-top: .28rem; }
.jobrow .r2 { display: flex; gap: .35rem; flex-wrap: wrap; margin-top: .5rem; align-items: center; }

/* The latest note, inline on the row. Clamped to one line: it's a peek at
   what's going on, not the whole story — that's what the Notes tab is for. */
.jobrow .rownote {
  display: block; margin-top: .34rem; padding-left: .55rem;
  border-left: 2px solid var(--n-200);
  font-size: .8rem; color: var(--ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.jobrow .rownote-who { color: var(--ink-3); }

/* A table cell that is really a button. Looks like text until you point
   at it, so a dense table doesn't turn into a wall of links. */
.linkcell {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
}
.linkcell:hover .strong { color: var(--accent); text-decoration: underline; }

/* ------------------------------------------------------- job notes */
.note-add { margin-bottom: 1.1rem; }
.note-add textarea { min-height: 4.4rem; }

.notelog { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.note {
  background: var(--panel-2, var(--bg)); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .6rem .75rem;
}
.note-head {
  display: flex; align-items: baseline; gap: .5rem; margin-bottom: .3rem;
}
.note-head b { font-size: .85rem; }
.note-head .spacer, .note-head .note-del { margin-left: auto; }
.note-body { font-size: .9rem; line-height: 1.5; white-space: pre-wrap; }
.note-body.muted { color: var(--ink-3); }

/* Latest note on the job overview — same shape, called out with a rule. */
.latest-note {
  margin-top: 1rem; padding: .7rem .85rem;
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--radius); background: var(--panel);
}
.latest-note .note-head { margin-bottom: .35rem; }
.latest-note .note-head button { margin-left: auto; }

/* ------------------------------------------------------ empty state */
.empty { text-align: center; padding: 2.4rem 1rem; color: var(--ink-3); }
.empty .big { font-size: 2rem; margin-bottom: .55rem; opacity: .85; }
.empty h3 { color: var(--ink); margin-bottom: .3rem; }
.empty p { font-size: .875rem; max-width: 42ch; margin: 0 auto; }

/* ------------------------------------------------------------ tables */
.tablewrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel);
}
.card > .tablewrap { box-shadow: none; }
table.data {
  width: 100%; border-collapse: separate; border-spacing: 0;
  font-size: .875rem;
  /* Scroll the wrapper rather than crushing columns. Long material names
     like "8 Wheel Trolley (Cantilever Gate)" wrap to four lines otherwise. */
  min-width: 560px;
}
table.data th, table.data td {
  padding: .6rem .75rem; text-align: left;
  border-bottom: 1px solid var(--line-soft); vertical-align: middle;
}
/* first column is always the name/label — give it room to breathe */
table.data th:first-child, table.data td:first-child { min-width: 200px; }
table.data th:first-child:empty, table.data td:has(> input[type=checkbox]) { min-width: 0; }

/* Narrow tables (2-3 columns) shouldn't be forced into a scroll. */
table.data.compact { min-width: 0; }
table.data.compact th:first-child, table.data.compact td:first-child { min-width: 0; }
table.data thead th {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); font-weight: 700; white-space: nowrap;
  background: var(--panel-2); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 2;
}
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Centred numeric column. Used where a cell holds an editable box rather
   than plain text — a right-aligned header above a fixed-width input reads
   as misaligned, because the box never reaches the column edge. */
table.data td.ctr, table.data th.ctr { text-align: center; font-variant-numeric: tabular-nums; }
table.data td.ctr input { margin: 0 auto; text-align: center; }
table.data tbody tr { transition: background .1s var(--ease); }
table.data tbody tr:hover { background: var(--panel-2); }
table.data input[type=number], table.data input[type=date], table.data input[type=text] {
  min-height: 34px; padding: .2rem .45rem; font-size: .85rem; border-radius: var(--radius-sm);
}
/* A table with no <thead> — the picker lists. Its group banner must stick
   to the very top, not 32px down where a header row would have been,
   otherwise it hangs over the first item and hides it. */
table.data.no-head tr.grouprow td { top: 0; }

/* Group banner. The colspan must match the real column count or the grey
   stops halfway across and looks like a rendering fault. */
tr.grouprow td {
  background: var(--n-100); font-weight: 700; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .06em; color: var(--ink-2);
  padding-top: .4rem; padding-bottom: .4rem;
  position: sticky; top: 32px; z-index: 1;
}
tr.grouprow:hover td { background: var(--n-100); }
/* the first-column min-width would otherwise pin the banner's own width */
tr.grouprow td:first-child { min-width: 0; }

/* ---------------------------------------------------- crew schedule */
/* `.tablewrap` sets overflow-x, which makes it the scroll container — so a
   sticky `top` inside resolves against a box that never scrolls vertically
   and the header never sticks. Giving the wrapper its own height makes it
   scroll in both directions, and then the day row pins properly. */
.sched-wrap {
  max-height: calc(100vh - 300px);
  min-height: 260px;
  overflow: auto;
  overscroll-behavior: contain;
}
@media (max-width: 919px) {
  .sched-wrap { max-height: calc(100vh - 340px); }
}

table.data.sched { min-width: 780px; table-layout: fixed; }
table.data.sched th, table.data.sched td { padding: .3rem; vertical-align: top; }
table.data.sched th:first-child, table.data.sched td:first-child { width: 148px; min-width: 148px; }
table.data.sched th:not(:first-child) { width: auto; }

/* Day row pins to the top; installer column pins to the left; the corner
   cell has to beat both or it gets overrun in one direction. */
table.data.sched thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--panel-2);
  box-shadow: inset 0 -1px 0 var(--line);
}
table.data.sched .stick {
  position: sticky; left: 0; z-index: 2;
  background: var(--panel); border-right: 1px solid var(--line);
  padding-left: .7rem;
}
table.data.sched thead .stick { z-index: 5; background: var(--panel-2); }
table.data.sched tbody tr:hover .stick { background: var(--panel-2); }
table.data.sched th.today { background: var(--accent-bg); color: var(--accent); }
table.data.sched td.cell.today { background: color-mix(in srgb, var(--accent-bg) 55%, transparent); }
table.data.sched td.cell { height: 62px; }

/* a booking, or an empty slot waiting for one */
.slot {
  display: flex; flex-direction: column; justify-content: center;
  width: 100%; min-height: 54px; gap: 1px;
  border-radius: var(--radius-sm); border: 1px solid transparent;
  font: inherit; text-align: left; cursor: pointer; overflow: hidden;
  padding: .3rem .45rem; line-height: 1.25;
  transition: filter .12s var(--ease), border-color .12s var(--ease);
}
.slot + .slot { margin-top: 3px; }
.slot.half { min-height: 25px; padding: .1rem .4rem; flex-direction: row; align-items: center; gap: .3rem; }

.slot.job {
  background: hsl(var(--jh) 62% 93%);
  border-color: hsl(var(--jh) 52% 82%);
  color: hsl(var(--jh) 72% 26%);
}
.slot.job:hover { filter: brightness(.97); border-color: hsl(var(--jh) 55% 65%); }
.slot .txt { font-weight: 660; font-size: .78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slot .sub {
  font-size: .7rem; opacity: .8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-weight: 500;
}
.slot .tag {
  font-size: .6rem; font-weight: 800; letter-spacing: .05em;
  background: hsl(var(--jh) 60% 82%); color: hsl(var(--jh) 75% 22%);
  border-radius: 3px; padding: 0 .22rem; flex: none;
}

.slot.empty {
  background: none; border: 1px dashed var(--n-200); color: var(--n-400);
  align-items: center; justify-content: center; font-size: .9rem; font-weight: 600;
}
.slot.empty:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-bg); }
.slot.empty.half { min-height: 25px; font-size: .62rem; letter-spacing: .04em; }
.slot.wide { min-height: 40px; flex-direction: row; align-items: center; gap: .45rem; flex-wrap: wrap; }
.slot.wide .sub { flex-basis: 100%; }

@media (prefers-color-scheme: dark) {
  .slot.job {
    background: hsl(var(--jh) 42% 20%);
    border-color: hsl(var(--jh) 40% 32%);
    color: hsl(var(--jh) 75% 84%);
  }
  .slot.job:hover { filter: brightness(1.18); }
  .slot .tag { background: hsl(var(--jh) 45% 32%); color: hsl(var(--jh) 80% 88%); }
}

/* day view rows */
.dayrow {
  display: flex; gap: .8rem; align-items: flex-start;
  padding: .7rem .9rem; border-bottom: 1px solid var(--line-soft);
}
.dayrow:last-child { border-bottom: 0; }
.dayrow .who { flex: 0 0 34%; min-width: 110px; padding-top: .2rem; }
.dayrow .what { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }

/* ------------------------------------------- editable number cell */
/* The tick only appears once the value differs from what it was, so a row
   sitting untouched stays clean but an unsaved change is impossible to
   miss. Blur still saves; this is the visible reassurance. */
.editcell { display: inline-flex; align-items: center; gap: .25rem; }
.editcell-go {
  width: 0; padding: 0; border: 0; overflow: hidden;
  background: var(--ok); color: #fff; border-radius: var(--radius-sm);
  font-size: .8rem; font-weight: 800; line-height: 1; cursor: pointer;
  opacity: 0; transition: width .12s var(--ease), opacity .12s var(--ease);
  flex: none; height: 30px;
}
/* Classes sit on the elements they style, not on an ancestor — see the
   note in editableNumber(). */
.editcell-go.is-on { width: 30px; opacity: 1; }
input.is-unsaved {
  border-color: var(--warn) !important;
  box-shadow: 0 0 0 2px var(--warn-bg) !important;
}

/* Briefly marks the row you just changed, so the new figure is visible
   rather than something to go looking for. */
@keyframes flashRow {
  0%, 60% { background: var(--ok-bg); box-shadow: inset 3px 0 0 var(--ok); }
  100%    { background: transparent; box-shadow: none; }
}
tbody tr.flash td, .sc.flash { animation: flashRow 2.2s var(--ease); }
.sc.flash { box-shadow: inset 3px 0 0 var(--ok); }

/* ------------------------------------------- phone inventory cards */
.countlist { display: flex; flex-direction: column; }

.cc, .sc { border-bottom: 1px solid var(--line-soft); padding: .8rem 1rem; }
.cc:last-child, .sc:last-child { border-bottom: 0; }

.cc { display: grid; grid-template-columns: 1fr auto auto; gap: .6rem; align-items: end; }
.cc-main { min-width: 0; }
.cc-name { font-weight: 640; font-size: .92rem; line-height: 1.3; }
.cc-sub  { font-size: .76rem; color: var(--ink-3); margin-top: .1rem; }
.cc-lab  {
  font-size: .62rem; font-weight: 750; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: .2rem;
}
.cc-val { font-weight: 680; font-variant-numeric: tabular-nums; font-size: 1rem; }
.cc-val.warnval { color: var(--warn); }
.cc-now { text-align: center; min-width: 54px; }
.cc-in  { min-width: 96px; }
.cc-in input { width: 96px; text-align: center; font-size: 1.05rem; font-weight: 640; }
.cc-delta { font-size: .72rem; font-weight: 650; margin-top: .2rem; text-align: center; min-height: 1em; }

.sc-head { display: flex; gap: .6rem; align-items: flex-start; justify-content: space-between; }
.sc-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: .7rem .9rem; margin-top: .7rem;
}
.sc-cell { min-width: 0; }
.sc-foot {
  display: flex; justify-content: space-between; gap: .5rem; flex-wrap: wrap;
  margin-top: .7rem; font-size: .74rem; color: var(--ink-3);
}

/* ------------------------------------------------------------ modals */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(13,21,30,.52); backdrop-filter: blur(3px);
  display: flex; align-items: flex-end; justify-content: center;
  animation: fadeIn .16s var(--ease);
}
@media (min-width: 700px) { .modal-backdrop { align-items: center; padding: 2rem 1.25rem; } }
@keyframes fadeIn { from { opacity: 0; } }
@keyframes slideUp { from { transform: translateY(14px); opacity: 0; } }

.modal {
  background: var(--panel); width: 100%; max-width: 700px;
  max-height: 93vh; max-height: 93dvh; overflow-y: auto;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--sh-3);
  animation: slideUp .2s var(--ease);
  padding-bottom: env(safe-area-inset-bottom);
}
@media (min-width: 700px) { .modal { border-radius: var(--radius-lg); max-height: 86vh; } }
.modal.wide { max-width: 1000px; }

.modal-head {
  position: sticky; top: 0; z-index: 3; background: var(--panel);
  display: flex; align-items: flex-start; gap: .6rem;
  padding: 1rem 1.15rem .8rem; border-bottom: 1px solid var(--line);
}
.modal-head h2 { flex: 1; font-size: 1.05rem; padding-top: .1rem; }
.modal-body { padding: 1.15rem; }
.modal-foot {
  position: sticky; bottom: 0; z-index: 3; background: var(--panel);
  display: flex; gap: .5rem; justify-content: flex-end; flex-wrap: wrap;
  padding: .8rem 1.15rem; border-top: 1px solid var(--line);
}
.modal-foot .spacer { flex: 1; }
.x {
  border: 0; background: none; font-size: 1.5rem; line-height: 1;
  color: var(--ink-3); cursor: pointer; padding: .15rem .45rem;
  border-radius: var(--radius-sm); flex: none;
}
.x:hover { background: var(--n-100); color: var(--ink); }

/* -------------------------------------------------------------- tabs */
.tabs {
  display: flex; gap: .1rem; border-bottom: 1px solid var(--line);
  margin-bottom: 1.15rem; overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
  border: 0; background: none; font: inherit;
  font-weight: 580; font-size: .875rem; color: var(--ink-3);
  padding: .6rem .8rem; cursor: pointer; white-space: nowrap;
  border-bottom: 2px solid transparent; margin-bottom: -1px; min-height: 42px;
  transition: color .14s var(--ease), border-color .14s var(--ease);
}
.tabs button:hover { color: var(--ink); }
.tabs button[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); font-weight: 640; }

/* ------------------------------------------------------ key / value */
.kv {
  display: grid; grid-template-columns: minmax(108px, auto) 1fr;
  gap: .5rem .9rem; font-size: .9rem; margin: 0;
}
.kv dt { color: var(--ink-3); font-size: .78rem; font-weight: 600; padding-top: .06rem; }
.kv dd { margin: 0; }

/* ---------------------------------------------------------- timeline */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
  padding: .1rem 0 .95rem 1.05rem; border-left: 2px solid var(--line);
  position: relative;
}
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before {
  content: ''; position: absolute; left: -5px; top: .42rem;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--panel); border: 2px solid var(--accent);
}
.timeline .when {
  font-size: .76rem; color: var(--ink-3); font-weight: 620;
  letter-spacing: .01em;
}
.timeline .what { margin-top: .12rem; font-size: .9rem; }
.timeline .who { font-size: .76rem; color: var(--ink-3); margin-top: .2rem; }

/* ------------------------------------------------------------- notes */
.note {
  border: 1px solid var(--accent-line); border-left-width: 3px;
  background: var(--accent-bg); color: var(--ink);
  padding: .68rem .85rem; border-radius: var(--radius);
  font-size: .865rem; margin-bottom: 1rem; line-height: 1.5;
}
.note.warn { border-color: var(--warn-line); background: var(--warn-bg); }
.note.bad  { border-color: var(--bad-line);  background: var(--bad-bg); }
.note.ok   { border-color: var(--ok-line);   background: var(--ok-bg); }
.note b { font-weight: 660; }

/* ------------------------------------------------------------- toast */
#toast {
  position: fixed; left: 50%; bottom: 78px;
  transform: translateX(-50%) translateY(14px);
  background: var(--n-900); color: var(--n-0);
  padding: .62rem 1.1rem; border-radius: 99px;
  font-size: .865rem; font-weight: 570;
  box-shadow: var(--sh-3); opacity: 0; pointer-events: none;
  transition: opacity .2s var(--ease), transform .2s var(--ease);
  z-index: 200; max-width: 90vw; text-align: center;
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
#toast.bad { background: var(--bad); color: #fff; }
@media (min-width: 920px) { #toast { bottom: 26px; } }

/* -------------------------------------------------------------- auth */
.auth-wrap { max-width: 392px; margin: 0 auto; padding: 8vh 1.1rem 2rem; }
.auth-wrap .card { padding: 1.6rem 1.5rem; box-shadow: var(--sh-2); }
.auth-logo { text-align: center; margin-bottom: 1.4rem; }
.auth-logo picture { display: block; }
.auth-logo img { width: 232px; max-width: 78%; height: auto; margin: 0 auto .5rem; display: block; }
.auth-logo h1 { font-size: 1.25rem; margin: .55rem 0 .12rem; }
.auth-logo p { color: var(--ink-3); font-size: .85rem; margin: 0; }

/* ---------------------------------------------------------- dropzone */
.dropzone {
  border: 1.5px dashed var(--n-300); border-radius: var(--radius-lg);
  padding: 2rem 1rem; text-align: center; color: var(--ink-3);
  background: var(--panel-2); cursor: pointer;
  transition: border-color .16s var(--ease), background .16s var(--ease), color .16s var(--ease);
}
.dropzone:hover { border-color: var(--accent); color: var(--accent); }
.dropzone.over { border-color: var(--accent); color: var(--accent); background: var(--accent-bg); }
.dropzone .big { font-size: 2rem; margin-bottom: .35rem; }

/* ------------------------------------------------------------- misc */
.spin {
  display: inline-block; width: 14px; height: 14px;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: sp .65s linear infinite; vertical-align: -2px;
}
@keyframes sp { to { transform: rotate(360deg); } }

.progress {
  height: 5px; border-radius: 99px; background: var(--n-150);
  overflow: hidden; min-width: 54px;
}
.progress > i { display: block; height: 100%; background: var(--accent); border-radius: 99px; }
.progress.ok   > i { background: var(--ok); }
.progress.warn > i { background: var(--warn); }
.progress.bad  > i { background: var(--bad); }

.muted   { color: var(--ink-3); }
.small   { font-size: .8rem; }
.nowrap  { white-space: nowrap; }
.right   { text-align: right; }
.mt      { margin-top: 1rem; }
.mb0     { margin-bottom: 0; }
.tabular { font-variant-numeric: tabular-nums; }
.strong  { font-weight: 640; }
.sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

@media print {
  .topbar, .nav, .toolbar, .modal-foot, .btn, .chips { display: none !important; }
  .card { box-shadow: none; border: 1px solid #ccc; break-inside: avoid; }
  .body-col, .main { height: auto; overflow: visible; }
  body { background: #fff; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
