/* ==================================================================
   Bulk Scheduler — visual system

   Audience: the owner of a lawn / cleaning / plumbing / HVAC company,
   often on a phone in a truck cab, about to change 120 customers'
   appointments at once. The screen has one job: make it obvious what
   is about to happen and obvious that it can be taken back.

   Rules this file follows:
     - Colour NEVER carries meaning alone. Every status also has a
       distinct silhouette (square / ring / triangle).
     - The brand colour owns the action. Red is reserved for reporting
       something that went wrong — pressing the big button is not a
       thing that went wrong, so the big button is not red.
     - Numbers are monospaced and tabular so 120 and 1,560 line up.
     - No web fonts, no external requests of any kind.
   ================================================================== */

/* ---------------- tokens: complete light palette ---------------- */
:root {
  color-scheme: light;

  /* structure */
  --ink:        #17211E;  /* text — near-black with a green cast, like printing ink */
  --ink-2:      #5A6763;  /* secondary text — warm slate, never a dead grey */
  --paper:      #F2EFE8;  /* page ground — bone */
  --surface:    #FCFAF5;  /* cards */
  --surface-2:  #EEEAE0;  /* inset panels, table zebra */
  --rule:       #D8D1C4;  /* hairlines — warm, so they sit on the paper */
  --rule-firm:  #B9AF9C;

  /* brand — deep petrol. Work-shirt blue, not product-launch blue. */
  --brand:      #16414F;
  --brand-lift: #1E5769;  /* hover */
  --brand-wash: #E1E9EC;  /* tinted fill */
  --on-brand:   #FBF9F4;

  /* semantics — deliberately a different family from the brand, so
     "this is the action" and "this is what happened" never blur */
  --ok:         #2C6E4B;
  --ok-wash:    #E2ECE5;
  --caution:    #8A5A0B;
  --caution-wash:#F4EBDA;
  --stop:       #8E3122;
  --stop-wash:  #F4E3DF;

  --focus:      #B4531E;  /* focus ring — the one warm accent, used nowhere else */

  --font-ui:  ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-doc: ui-serif, Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-num: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --pad: clamp(16px, 4vw, 28px);
  --radius: 3px;   /* forms and tickets have corners, not pills */
}

/* dark: token values only, never a colour that exists nowhere else */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --ink:        #ECE7DB;
    --ink-2:      #9BA7A2;
    --paper:      #0F1513;
    --surface:    #18211E;
    --surface-2:  #212B27;
    --rule:       #2E3A35;
    --rule-firm:  #47554F;
    --brand:      #7FB6C4;
    --brand-lift: #9BCBD7;
    --brand-wash: #17313A;
    --on-brand:   #0C1518;
    --ok:         #74C295;
    --ok-wash:    #16301F;
    --caution:    #D9A24C;
    --caution-wash:#332510;
    --stop:       #E2846F;
    --stop-wash:  #381914;
    --focus:      #E08A4F;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --ink:        #ECE7DB;
  --ink-2:      #9BA7A2;
  --paper:      #0F1513;
  --surface:    #18211E;
  --surface-2:  #212B27;
  --rule:       #2E3A35;
  --rule-firm:  #47554F;
  --brand:      #7FB6C4;
  --brand-lift: #9BCBD7;
  --brand-wash: #17313A;
  --on-brand:   #0C1518;
  --ok:         #74C295;
  --ok-wash:    #16301F;
  --caution:    #D9A24C;
  --caution-wash:#332510;
  --stop:       #E2846F;
  --stop-wash:  #381914;
  --focus:      #E08A4F;
}

/* ------------------------------ base ------------------------------ */

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

:where(a) { color: var(--brand); }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* numbers, ids, dates, rules — always monospaced and tabular */
.num, .mono, td.n, .tally b, .rail-read b, .ledger time {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ----------------------------- top bar ---------------------------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px var(--pad);
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
}

.brand {
  font-family: var(--font-doc);
  font-size: 17px;
  letter-spacing: 0.01em;
  color: var(--brand);
}
.brand b { font-weight: 700; }
.brand span { color: var(--ink-2); font-weight: 400; }

.topbar-spacer { flex: 1; }

.account {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--ink-2);
  text-align: right;
}

.theme-toggle {
  border: 1px solid var(--rule-firm);
  background: transparent;
  color: var(--ink-2);
  border-radius: var(--radius);
  padding: 5px 9px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-2); }

/* ------------------------------ shell ----------------------------- */

main {
  max-width: 1040px;
  margin: 0 auto;
  padding: var(--pad) var(--pad) 96px;
}

/* ------------------------------ steps ----------------------------- */

.step {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  margin-bottom: 18px;
}

.step > header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 14px var(--pad);
  border-bottom: 1px solid var(--rule);
}

.step-no {
  flex: none;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  background: var(--brand);
  color: var(--on-brand);
  font-family: var(--font-num);
  font-size: 13px;
  align-self: center;
}

.step h2 {
  margin: 0;
  font-family: var(--font-doc);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.step h2 small {
  display: block;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 400;
  color: var(--ink-2);
  letter-spacing: 0;
}

.step > .body { padding: var(--pad); }

/* --------------------------- form controls ------------------------ */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px;
}

.field { display: block; }
.field > .lbl {
  display: block;
  font-size: 12px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: 6px;
}

select, input[type="date"], input[type="number"], input[type="text"] {
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--rule-firm);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 15px;
}
select[multiple] { font-family: var(--font-ui); padding: 4px; }
select[multiple] option { padding: 4px 6px; }

.stack { display: flex; flex-direction: column; gap: 12px; }

.check {
  display: flex; align-items: center; gap: 9px;
  font-size: 15px;
  cursor: pointer;
}
.check input { width: 18px; height: 18px; accent-color: var(--brand); flex: none; }

/* operation chooser — big enough for a thumb, reads as a set of switches */
.ops { display: grid; gap: 8px; margin-bottom: 18px; }

.op {
  display: flex; align-items: flex-start; gap: 11px;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--rule);
  border-radius: var(--radius);
  padding: 12px 14px;
  cursor: pointer;
  background: var(--surface);
}
.op:hover { border-color: var(--rule-firm); }
.op:has(input:checked) {
  border-color: var(--rule-firm);
  border-left-color: var(--brand);
  background: var(--brand-wash);
}
.op input { margin-top: 3px; accent-color: var(--brand); width: 17px; height: 17px; flex: none; }
.op .t { font-weight: 600; }
.op .d { display: block; font-size: 13px; color: var(--ink-2); font-weight: 400; }

.op-panel {
  display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-end;
  border-top: 1px dashed var(--rule);
  padding-top: 16px;
}
.op-panel .field { flex: 0 1 150px; }
.op-panel .field.wide { flex: 1 1 260px; }
.op-panel .hint { flex: 1 1 220px; font-size: 13px; color: var(--ink-2); }

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 18px;
  border: 1px solid var(--rule-firm);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}
.btn:hover { border-color: var(--ink-2); }
.btn[disabled] { opacity: 0.45; cursor: not-allowed; }

.btn-primary {
  background: var(--brand); border-color: var(--brand); color: var(--on-brand);
}
.btn-primary:hover { background: var(--brand-lift); border-color: var(--brand-lift); }

/* The consequential one. Weight comes from size, frame and a full-width
   footprint — not from an alarming colour. */
.btn-commit {
  width: 100%;
  padding: 17px 20px;
  font-size: 17px;
  letter-spacing: 0.01em;
  background: var(--brand);
  border: 1px solid var(--brand);
  box-shadow: 0 2px 0 0 var(--rule-firm);
  color: var(--on-brand);
  flex-direction: column;
  gap: 3px;
}
.btn-commit .sub {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 400;
  opacity: 0.82;
}
.btn-commit:hover { background: var(--brand-lift); border-color: var(--brand-lift); }

.btn-undo { border-color: var(--rule-firm); }

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

.verdict {
  font-family: var(--font-doc);
  font-size: clamp(21px, 3.4vw, 27px);
  line-height: 1.28;
  letter-spacing: -0.015em;
  margin: 0 0 4px;
}
.verdict b { color: var(--brand); font-weight: 700; }
.verdict .n {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
.verdict-note { color: var(--ink-2); font-size: 14px; margin: 0 0 20px; }

/* counts */
.tally {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 22px;
}
.tally > div {
  padding: 12px 14px;
  border-right: 1px solid var(--rule);
  background: var(--surface-2);
}
.tally > div:last-child { border-right: 0; }
.tally b { display: block; font-size: 25px; line-height: 1.1; font-weight: 700; }
.tally span {
  display: block; margin-top: 3px;
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2);
}

/* --------------------- before / after date rails ------------------ */

.rails {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 16px var(--pad);
  margin-bottom: 22px;
  background: var(--surface-2);
}
.rails > figcaption {
  font-size: 12px; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-2); margin-bottom: 14px;
}
.rails > figcaption em { font-style: normal; color: var(--ink); }

.rail-row { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.rail-label {
  flex: none; width: 58px;
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-2); text-align: right;
}
.rail-row.is-after .rail-label { color: var(--brand); font-weight: 700; }

.rail-track {
  position: relative;
  flex: 1;
  height: 26px;
  border-bottom: 1px solid var(--rule-firm);
}
.rail-track i {
  position: absolute; bottom: 0;
  width: 3px; height: 15px;
  margin-left: -1px;
  background: var(--ink-2);
}
.rail-row.is-after .rail-track i { height: 22px; background: var(--brand); }

.rail-scale {
  position: relative; height: 16px;
  margin-left: 70px;
}
.rail-scale span {
  position: absolute; top: 0;
  font-family: var(--font-num); font-size: 11px; color: var(--ink-2);
  transform: translateX(-2px);
}

.rail-read {
  display: flex; flex-wrap: wrap; gap: 6px 26px;
  margin: 14px 0 0 70px;
  font-size: 13px; color: var(--ink-2);
}
.rail-read b { color: var(--ink); font-weight: 600; }
.rail-read .to { color: var(--brand); }

.rail-foot {
  margin: 12px 0 0 70px;
  font-size: 12px;
  color: var(--ink-2);
  max-width: 62ch;
}

/* ------------------------------ ledger ---------------------------- */

.ledger-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 8px;
}
.ledger-head h3 {
  margin: 0; font-family: var(--font-doc); font-size: 16px; font-weight: 600;
}
.ledger-head .muted { font-size: 13px; color: var(--ink-2); }

.scroll-x { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: 14px; }
thead th {
  text-align: left; padding: 7px 10px;
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-2); font-weight: 600;
  border-bottom: 1px solid var(--rule-firm);
  white-space: nowrap;
}
tbody td { padding: 9px 10px; border-bottom: 1px solid var(--rule); vertical-align: top; }
tbody tr:nth-child(even) td { background: var(--surface-2); }

.ledger .who { font-weight: 600; }
.ledger .what { display: block; font-size: 12px; color: var(--ink-2); }
.ledger .from { color: var(--ink-2); }
.ledger .arrow { color: var(--rule-firm); padding: 0 2px; }
.ledger .to { color: var(--brand); font-weight: 600; }
.ledger td.n { text-align: right; white-space: nowrap; }

details { margin-top: 14px; }
details > summary {
  cursor: pointer; font-size: 13px; color: var(--ink-2);
  padding: 7px 0;
}
details > summary::marker { color: var(--rule-firm); }

/* --------------------------- notice blocks ------------------------ */
/* Colour + a left bar + a silhouette. Any one of the three is enough. */

.notice {
  border: 1px solid var(--rule);
  border-left: 4px solid var(--rule-firm);
  border-radius: var(--radius);
  background: var(--surface-2);
  padding: 14px 16px;
  margin: 18px 0;
  font-size: 14px;
}
.notice h4 {
  margin: 0 0 7px;
  font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase;
}
.notice p { margin: 0 0 8px; }
.notice p:last-child { margin-bottom: 0; }
.notice b { font-weight: 700; }

.notice-info    { border-left-color: var(--brand);   background: var(--brand-wash); }
.notice-info h4 { color: var(--brand); }
.notice-warn    { border-left-color: var(--caution); background: var(--caution-wash); }
.notice-warn h4 { color: var(--caution); }
.notice-stop    { border-left-color: var(--stop);    background: var(--stop-wash); }
.notice-stop h4 { color: var(--stop); }
.notice-ok      { border-left-color: var(--ok);      background: var(--ok-wash); }
.notice-ok h4   { color: var(--ok); }

/* ---------------------------- commit bar -------------------------- */

.commit {
  border: 2px solid var(--rule-firm);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 16px;
  margin-top: 20px;
}
.commit .caption {
  font-size: 13px; color: var(--ink-2); margin: 10px 0 0; text-align: left;
}

/* The acknowledgement.
   Inside .commit on purpose: on a phone .commit.is-live is the sticky footer,
   so the box and the button it unlocks scroll as one piece. Ticking something
   and then hunting for the button is the failure this layout rules out. */
.ack {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin: 0 0 14px;
  padding: 0 0 14px;
  border-bottom: 1px solid var(--rule);
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink);
  cursor: pointer;
}
.ack input {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--brand);
  cursor: pointer;
}
/* The whole row is the tap target, not just the 22px square. */
.ack span { padding-top: 1px; }
.ack:has(input:disabled) { opacity: 0.5; cursor: not-allowed; }
.ack input:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ------------------------- status silhouettes --------------------- */
/* square = landed · ring = skipped · triangle = refused              */

.mark { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.mark::before { content: ""; flex: none; display: block; }

.mark-ok::before   { width: 10px; height: 10px; background: var(--ok); }
.mark-skip::before { width: 10px; height: 10px; border: 2px solid var(--ink-2); border-radius: 50%; }
.mark-fail::before {
  width: 0; height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 11px solid var(--stop);
}
.mark-ok   { color: var(--ok); }
.mark-skip { color: var(--ink-2); }
.mark-fail { color: var(--stop); }

.result-line {
  display: flex; flex-wrap: wrap; gap: 10px 22px;
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 15px; margin-bottom: 6px;
}

.loading { color: var(--ink-2); font-size: 14px; }

/* ------------------------------ landing --------------------------- */

.landing { padding: clamp(24px, 6vw, 48px) var(--pad); }
.landing h1 {
  font-family: var(--font-doc);
  font-size: clamp(28px, 6vw, 42px);
  line-height: 1.12; letter-spacing: -0.02em;
  margin: 0 0 14px; max-width: 17ch;
}
.landing p { max-width: 56ch; color: var(--ink-2); margin: 0 0 12px; }
.landing .cta { margin-top: 22px; }
.landing ul {
  margin: 22px 0 0; padding: 0; list-style: none;
  display: grid; gap: 10px; max-width: 56ch;
}
.landing li { display: flex; gap: 10px; font-size: 15px; }
.landing li::before {
  content: ""; flex: none; margin-top: 7px;
  width: 9px; height: 9px; background: var(--brand);
}

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

@media (max-width: 720px) {
  /* Room for the sticky commit bar, which is now two rows tall: the
     acknowledgement sits inside it, above the button. */
  main { padding-bottom: 220px; }

  .step > header { padding: 12px 16px; }
  .step > .body { padding: 16px; }

  .rail-label { width: 44px; font-size: 10px; }
  .rail-scale, .rail-read, .rail-foot { margin-left: 56px; }

  /* In a truck cab the action must not be a scroll away. */
  .commit.is-live {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin: 20px -16px -16px;
    border-radius: 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    box-shadow: 0 -8px 20px -14px rgba(0, 0, 0, 0.5);
  }

  /* Thumb-sized on glass, and tighter above the button so both fit in the
     sticky strip without eating the schedule behind it. */
  .commit .ack {
    margin-bottom: 12px;
    padding-bottom: 12px;
    font-size: 13px;
  }
  .commit .ack input { width: 24px; height: 24px; }

  .ledger thead { display: none; }
  .ledger tbody tr {
    display: block;
    border-bottom: 1px solid var(--rule-firm);
    padding: 10px 0;
  }
  .ledger tbody tr:nth-child(even) td { background: transparent; }
  .ledger tbody td { display: block; border: 0; padding: 2px 0; }
  .ledger td.n { text-align: left; font-size: 12px; color: var(--ink-2); }
  .ledger td.n::before { content: "visits: "; }
}
