/* OCH brand, from the Brand Graphic Guidelines (Aug 2023).
   Green PMS 568 CP, navy PMS 540 CP, red PMS 179 CP, warm grey PMS 420 CP,
   Montserrat over Arial.

   The chrome is navy and the work is on paper. The one idea repeated
   everywhere is the green spine — the ▌ of the mark — which runs down the
   left of the form as the step rail and lights the step that still needs
   something. Only problems are allowed to shout: red is a block, amber is a
   warning, and nothing else is coloured. */
:root {
  --green:      #055A49;
  --green-deep: #04473A;
  --navy:       #002A4E;
  --navy-ink:   #BFD0DF;   /* text on navy */
  --red:        #F04937;
  --grey:       #D1D1CE;
  --paper:      #FBFAF7;
  --card:       #FFFFFF;
  --sunk:       #F3F2ED;
  --muted:      #5B6470;
  --green-soft: #E3EEEB;
  --warn-soft:  #FDEBE8;
  --warn-ink:   #B7301F;
  --amber:      #9A5B00;
  --amber-soft: #FFF1D6;
  --display:    Montserrat, Arial, Helvetica, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--navy);
  font: 15px/1.5 Arial, "Liberation Sans", Helvetica, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, legend, .mark, .btn, .places, .reading, .pill, .count { font-family: var(--display); }

/* ── The band ─────────────────────────────────────────────────────────────── */

.bar {
  display: flex; align-items: center; gap: 14px;
  padding: 0 18px; min-height: 52px;
  background: var(--navy); color: #fff;
  position: sticky; top: 0; z-index: 5;
}
.mark {
  font-weight: 700; font-size: 1rem; letter-spacing: .01em;
  display: inline-flex; align-items: center; gap: 9px;
  color: #fff; text-decoration: none; white-space: nowrap;
}
.mark i { width: 9px; height: 16px; background: var(--green); display: inline-block; border-radius: 1px; }
.spacer { flex: 1; }
.who { color: var(--navy-ink); font-size: .84rem; white-space: nowrap; }
.ref {
  font-variant-numeric: tabular-nums; font-size: .84rem; white-space: nowrap;
  color: var(--green); font-weight: 600;
}
.bar .ref { color: #8FD3BE; }

.places { display: flex; gap: 2px; align-self: stretch; }
.places a {
  display: inline-flex; align-items: center;
  font-size: .84rem; font-weight: 600; text-decoration: none;
  color: var(--navy-ink); padding: 0 11px; position: relative; white-space: nowrap;
}
.places a:hover { color: #fff; }
.places a.here { color: #fff; }
.places a.here::after {
  content: ""; position: absolute; left: 11px; right: 11px; bottom: 0;
  height: 3px; background: var(--green); border-radius: 2px 2px 0 0;
}
.bar .btn.ghost { color: #fff; border-color: rgba(255,255,255,.28); background: transparent; padding: 6px 11px; font-size: .82rem; }
.bar .btn.ghost:hover { background: rgba(255,255,255,.08); filter: none; }
.bar #signout { color: var(--navy-ink); border: 0; padding: 6px 4px; }
.bar #signout:hover { color: #fff; background: none; }

/* ── Two ways in ──────────────────────────────────────────────────────────── */
/* Guided mode is the default because a monthly user should not meet twelve
   fields cold; the form stays one click away for people who write these
   every week and know exactly what to change. */
.modes {
  display: flex; gap: 4px; padding: 10px 18px 0;
  background: var(--card); border-bottom: 1px solid var(--grey);
}
.mode {
  font: inherit; font-family: var(--display);
  font-size: .84rem; font-weight: 600; cursor: pointer;
  border: 1px solid transparent; border-bottom: 0;
  border-radius: 8px 8px 0 0; padding: 9px 15px;
  background: transparent; color: var(--muted);
  position: relative; top: 1px;
}
.mode:hover { color: var(--navy); }
.mode.on {
  background: var(--paper); color: var(--green);
  border-color: var(--grey); border-bottom: 1px solid var(--paper);
}
body.form-mode #guided { display: none; }

/* ── The two panes ────────────────────────────────────────────────────────── */
/* Desktop: the form and the live notice side by side, because a desk has room
   for both. Phone: one column with the preview underneath and a dock that
   says the preview exists — one codebase, two postures, not two front ends.
   The preview gets the larger share: it is the thing being checked, and at
   half width a finished notice read as half-finished. */
#main { display: grid; grid-template-columns: minmax(380px, 5fr) minmax(0, 7fr); }
.pane { padding: 18px; }
.form { display: flex; flex-direction: column; gap: 6px; border-right: 1px solid var(--grey); }
.preview {
  background: var(--sunk); display: flex; flex-direction: column; gap: 12px;
  position: sticky; top: 52px; align-self: start;
  height: calc(100vh - 52px);
}

/* ── The say-it box ───────────────────────────────────────────────────────── */
#guided {
  background: var(--card); border: 1px solid var(--grey); border-radius: 12px;
  padding: 14px 16px 16px; margin-bottom: 14px;
}
#guided legend { float: left; width: 100%; margin-bottom: 8px; color: var(--green); }
#guided .btn { align-self: flex-start; }
.field.big { font-size: 1.04rem; line-height: 1.5; }

/* ── The spine: steps down the form ───────────────────────────────────────── */
/* The order is the job — who, what, when, then the rest — and the number of
   the step that still needs something turns green. When nothing is missing,
   the rail is quiet and "Check" lights up over the preview instead. */
.step {
  position: relative; padding: 4px 0 18px 34px;
  border-left: 3px solid var(--grey); margin-left: 11px;
  display: flex; flex-direction: column; gap: 14px;
}
.step:last-of-type { padding-bottom: 6px; }
.step h2 {
  margin: 0; font-size: .74rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
  display: flex; align-items: center; gap: 10px;
}
.step h2 b {
  position: absolute; left: -14px; top: 2px;
  width: 25px; height: 25px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--paper); border: 3px solid var(--grey);
  font-size: .72rem; color: var(--muted); font-weight: 700;
}
.step.now { border-left-color: var(--green); }
.step.now h2 { color: var(--green); }
.step.now h2 b { background: var(--green); border-color: var(--green); color: #fff; }
.step.done h2 b { border-color: var(--green); color: var(--green); }
.step[hidden] { display: none; }

.fset { border: 0; padding: 0; margin: 0; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.fset.two { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: end; }
.fset.two label, .fset > label:not(.inline) {
  display: flex; flex-direction: column; gap: 6px;
  font-size: .8rem; color: var(--muted);
}
.fset[hidden] { display: none; }
legend {
  padding: 0; font-size: .72rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
}
.step .fset + .fset { margin-top: 2px; }
.field {
  width: 100%; font: inherit; padding: 10px 12px;
  border: 1px solid var(--grey); border-radius: 8px;
  background: var(--card); color: var(--navy);
}
.field:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }
.field:disabled { background: var(--sunk); color: var(--muted); }
textarea.field { resize: vertical; font-family: inherit; }
.hint { margin: 0; font-size: .8rem; color: var(--muted); }
.tally { margin: 0; font-size: .82rem; font-weight: 600; color: var(--green); }
.tally:empty { display: none; }

/* Search results: three kinds of answer in one list, told apart by a tag. */
.results, .chosen { list-style: none; margin: 0; padding: 0; }
.results:empty, .chosen:empty { display: none; }
.results {
  border: 1px solid var(--grey); border-radius: 8px;
  background: var(--card); max-height: 260px; overflow-y: auto;
}
.results li {
  padding: 9px 12px; cursor: pointer;
  border-top: 1px solid var(--grey);
  display: flex; align-items: baseline; gap: 9px;
}
.results li:first-child { border-top: 0; }
.results li:hover { background: var(--green-soft); }
.results .label { flex: 1; min-width: 0; }
.results .label small { display: block; color: var(--muted); font-size: .78rem; }
.tag {
  font-size: .64rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; border-radius: 3px; padding: 2px 6px;
  background: var(--sunk); color: var(--muted); flex: none;
}
.tag.building, .tag.community { background: var(--green-soft); color: var(--green); }

.chosen { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.chosen li {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--green-soft); color: var(--green);
  border-radius: 999px; padding: 5px 6px 5px 12px; font-size: .84rem;
}
.chosen b { font-weight: 600; }
.chosen span { opacity: .75; }
.chosen button {
  border: 0; background: none; color: inherit; cursor: pointer;
  font: inherit; font-size: 1.05rem; line-height: 1; padding: 0 5px;
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn {
  font: inherit; font-family: var(--display); font-weight: 600; font-size: .86rem;
  border-radius: 8px; padding: 9px 15px; cursor: pointer;
  border: 1px solid var(--green); background: var(--green); color: #fff;
  text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.btn.ghost { background: transparent; color: var(--navy); border-color: var(--grey); }
.btn.danger { background: transparent; color: var(--warn-ink); border-color: var(--warn-ink); }
.btn[disabled] { opacity: .4; cursor: not-allowed; }
.btn:not([disabled]):hover { filter: brightness(1.08); }
.btn:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }

/* ── The check pane ───────────────────────────────────────────────────────── */
/* The reading sentence is the headline: what the app understood, in one
   line, before anyone reads the sheet. The chips under the Build button say
   how it got there; this says where it arrived. */
.reading {
  margin: 0; font-size: 1.02rem; font-weight: 600; line-height: 1.4;
  color: var(--green);
}
.reading.quiet { color: var(--muted); font-weight: 500; }
.reading em { font-style: normal; color: var(--navy); }
.pvbar { display: flex; align-items: center; gap: 10px; }
.pvbar .check {
  font-family: var(--display); font-size: .74rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
  display: inline-flex; align-items: center; gap: 8px;
}
.pvbar .check b {
  width: 25px; height: 25px; border-radius: 50%; display: grid; place-items: center;
  border: 3px solid var(--grey); font-size: .72rem; color: var(--muted);
}
.pvbar .check.now { color: var(--green); }
.pvbar .check.now b { background: var(--green); border-color: var(--green); color: #fff; }

/* Findings: a block is red, a warning is amber, and each one is a way to the
   field it is about — "Still needed: a time" focuses the time. */
.findings { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.findings:empty { display: none; }
.findings li {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: 8px;
  font-size: .86rem; background: var(--card); color: var(--navy);
  border: 1px solid var(--grey); border-left: 4px solid var(--grey);
}
.findings li::before { content: "i"; font-weight: 700; flex: none; width: 1em; text-align: center; color: var(--muted); font-family: var(--display); }
.findings li.warn { border-left-color: var(--amber); background: var(--amber-soft); }
.findings li.warn::before { content: "!"; color: var(--amber); }
.findings li.block { border-left-color: var(--red); background: var(--warn-soft); color: var(--warn-ink); }
.findings li.block::before { content: "!"; color: var(--red); }
.findings li[data-field] { cursor: pointer; }
.findings li[data-field]:hover { filter: brightness(.97); }
/* The one finding the app can fix itself. */
.findings .fixit {
  margin-left: auto; flex: none; align-self: center; cursor: pointer;
  font: inherit; font-family: var(--display); font-size: .76rem; font-weight: 700;
  letter-spacing: .04em; padding: 5px 11px; border-radius: 999px;
  border: 1px solid currentColor; background: transparent; color: inherit;
  white-space: nowrap;
}
.findings .fixit:hover:not([disabled]) { background: rgba(255, 255, 255, .55); }
.findings .fixit[disabled] { opacity: .55; cursor: progress; }
.findings li[data-field]::after {
  content: "fix"; margin-left: auto; flex: none; font-size: .72rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; opacity: .7; align-self: center;
}

.sheetwrap { flex: 1; position: relative; min-height: 0; }
.sheet {
  width: 100%; height: 100%; border: 1px solid var(--grey);
  border-radius: 6px; background: #fff;
}
.sheet[hidden] { display: none; }
.empty {
  position: absolute; inset: 0; margin: 0;
  display: grid; place-items: center; text-align: center;
  padding: 32px; color: var(--muted); font-size: .9rem;
  border: 1px dashed var(--grey); border-radius: 6px;
}
.empty[hidden] { display: none; }

/* Where the notice got to. Only present once something has happened to it —
   an empty timeline on a draft would be a promise with nothing behind it. */
.trail {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
  font-size: .84rem;
}
.trail:empty { display: none; }
.trail li { display: flex; gap: 9px; align-items: baseline; }
.trail li::before {
  content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--green);
}
.trail b { font-weight: 600; }
.trail span { color: var(--muted); }
.trail li.next::before { background: none; }
.trail li.next a { color: var(--green); font-weight: 600; }

/* A compliance notice: what the tenant has to put right, and how long they
   have. Shown instead of a date and a window, because nobody is attending. */
.deficiencies { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px; }
.deficiencies:empty::after {
  content: "Nothing listed yet.";
  color: var(--muted); font-size: .86rem;
}
.deficiencies li {
  display: flex; align-items: center; gap: 10px;
  background: var(--card); border: 1px solid var(--grey);
  border-radius: 8px; padding: 9px 12px;
}
.deficiencies .what { flex: 1; min-width: 0; }
.deficiencies .what small { display: block; color: var(--muted); font-size: .78rem; }
.deficiencies .amount {
  font-variant-numeric: tabular-nums; font-weight: 600; color: var(--navy);
}
.deficiencies button {
  border: 0; background: none; color: var(--muted); cursor: pointer;
  font: inherit; font-size: 1.05rem; line-height: 1; padding: 0 4px;
}
label.inline {
  display: flex; align-items: center; gap: 10px;
  font-size: .8rem; color: var(--muted);
}
.field.short { width: 6rem; }

/* ── The phone dock ───────────────────────────────────────────────────────── */
/* On a phone the preview is below a long form. The dock is the one line that
   says what the notice has become, and the way down to check it. */
.dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 4;
  display: none; align-items: center; gap: 10px;
  padding: 10px 14px; background: var(--card);
  border-top: 1px solid var(--grey); box-shadow: 0 -6px 18px rgba(0, 42, 78, .08);
}
.dock p { margin: 0; flex: 1; min-width: 0; font-size: .84rem; font-weight: 600; color: var(--green);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-family: var(--display); }
.dock p.quiet { color: var(--muted); font-weight: 500; }

/* ── Pills, shared with the lists ─────────────────────────────────────────── */
.pill {
  display: inline-block; font-size: .72rem; font-weight: 600;
  letter-spacing: .04em; border-radius: 999px; padding: 3px 9px;
  background: var(--sunk); color: var(--muted); white-space: nowrap;
}
.pill.approved, .pill.queued { background: var(--green-soft); color: var(--green); }
.pill.printed, .pill.out     { background: #E7ECF2; color: var(--navy); }
.pill.delivered              { background: var(--green); color: #fff; }
.pill.cancelled, .pill.superseded { background: var(--warn-soft); color: var(--warn-ink); }

/* ── On a phone ───────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .bar { padding: 0 12px; gap: 8px; min-height: 48px; overflow-x: auto; }
  .bar .who { display: none; }
  .bar .ref { display: none; }
  .places a { padding: 0 8px; font-size: .8rem; }
  .bar .btn.ghost { padding: 5px 9px; font-size: .78rem; }

  /* One codebase, two postures. */
  #main { grid-template-columns: 1fr; }
  .form { border-right: 0; border-bottom: 1px solid var(--grey); padding-bottom: 24px; }
  .preview { position: static; height: auto; scroll-margin-top: 56px; }
  .fset.two { grid-template-columns: 1fr 1fr; }
  /* Letter paper is 11/8.5 tall. Match it so a full page fits rather than
     showing a strip and inviting the same "is it finished?" doubt. */
  /* The notice is laid out for letter paper. On a phone it is NOT reflowed to
     the screen — the footer, the QR and the signature are placed for paper
     and would run into each other — it is rendered at paper width (816px,
     8.5in at 96dpi) and scaled down to fit, so what you see is the sheet.
     app.js fitSheet() sets the scale and the height from the document. */
  .sheetwrap { min-height: 0; overflow: hidden; }
  /* Absolute, so the 816px frame does not widen the wrapper it is measured against. */
  .sheet { position: absolute; top: 0; left: 0; width: 816px; transform-origin: 0 0; height: 2100px; }
  .dock { display: flex; }
  body.docked { padding-bottom: 64px; }
  .modes { padding: 8px 12px 0; }
  .pane { padding: 14px 12px; }
}

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
