/* Bergstreme snag portal — matches bergstreme.co.za (Poppins, ink header, navy actions) */

:root {
  --ink: #121212;
  --navy: #08336C;
  --navy-deep: #062754;
  --text: #2E2E2E;
  --muted: #6B6B6B;
  --grey: #D6D3D1;
  --light: #F1F1F1;
  --sky: #62A5CF;
  --pale: #E2EDF4;
  --white: #FFFFFF;
  --danger: #B3261E;
  --danger-bg: #FBEDEC;
  --amber: #D9822B;
  --green: #2E8B57;
  --radius-card: 12px;
  --radius-input: 10px;
  --radius-pill: 30px;
  --shadow: 0 1px 2px rgba(18, 18, 18, 0.04), 0 4px 14px rgba(18, 18, 18, 0.06);
  --font: 'Poppins', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* Fallback only — app.js measures the real bar and overwrites this (see measureBar). */
  --bar-h: 120px;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--light);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

body.has-bar main { padding-bottom: calc(var(--bar-h) + 24px); }

img { max-width: 100%; display: block; }
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
[hidden] { display: none !important; }

.wrap {
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding-left: 20px;
  padding-right: 20px;
}

/* ---------- header ---------- */
.topbar {
  background: var(--ink);
  color: var(--white);
  padding-top: env(safe-area-inset-top, 0px);
  position: relative;
  z-index: 25;
}

.topbar__inner {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 64px;
}
.topbar__home { display: inline-flex; align-items: center; margin-right: auto; border-radius: 6px; }
.topbar__home:focus-visible { outline: 2px solid var(--sky); outline-offset: 4px; }
/* The Construction logo is squarer than the others; cap the height so the 64px bar holds all three. */
.topbar__logo { width: 150px; height: auto; max-height: 48px; object-fit: contain; object-position: left center; display: block; }
.topbar__tag {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
  white-space: nowrap;
}
/* Back: a real 44px target that reads as "go back", never as part of the logo. */
.topbar__back {
  display: inline-flex; align-items: center; gap: 2px;
  min-height: 44px; padding: 0 10px 0 4px; margin-left: -8px;
  border: 0; border-radius: var(--radius-pill);
  background: transparent; color: var(--white);
  font-size: 14px; font-weight: 500;
}
.topbar__back svg { width: 22px; height: 22px; }
.topbar__back:hover { background: rgba(255, 255, 255, 0.1); }
.topbar__back:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }
.topbar__back[hidden] { display: none; }
/* Who you are, and the way to the menu. The address is trimmed to its local part so the pill
   stays one line on a phone; the full address sits in the menu. */
.topbar__who {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; max-width: 42vw; padding: 0 12px;
  border: 1.5px solid rgba(255, 255, 255, 0.35); border-radius: var(--radius-pill);
  background: transparent; color: var(--white);
  font-size: 13px; font-weight: 500;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.topbar__who::after { content: '▾'; font-size: 10px; opacity: 0.7; }
.topbar__who:hover, .topbar__who[aria-expanded="true"] { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.6); }
.topbar__who:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }
.topbar__who[hidden] { display: none; }
@media (max-width: 479px) { .topbar__tag { display: none; } .topbar__back span { display: none; } .topbar__back { padding-right: 6px; } }
@media (max-width: 359px) { .topbar__logo { width: 120px; } }

/* the account menu */
.menu {
  position: absolute; right: max(20px, calc((100% - 560px) / 2 + 20px)); top: calc(100% - 6px);
  min-width: 240px; max-width: calc(100vw - 40px);
  background: var(--white); color: var(--text);
  border: 1px solid var(--grey); border-radius: var(--radius-card);
  box-shadow: 0 12px 32px rgba(18, 18, 18, 0.22);
  padding: 6px; z-index: 40;
  animation: rise-menu 0.14s ease;
}
.menu[hidden] { display: none; }
@keyframes rise-menu { from { transform: translateY(-4px); opacity: 0; } to { transform: none; opacity: 1; } }
.menu__who { padding: 10px 12px 8px; border-bottom: 1px solid var(--light); margin-bottom: 4px; display: flex; flex-direction: column; gap: 2px; }
.menu__lbl { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
#menu-email { font-weight: 600; color: var(--ink); font-size: 14px; overflow-wrap: anywhere; }
.menu__item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: 44px; padding: 8px 12px;
  border: 0; border-radius: 8px; background: transparent;
  color: var(--navy); font-weight: 500; font-size: 14px; text-align: left; text-decoration: none;
}
.menu__item:hover { background: var(--pale); }
.menu__item:focus-visible { outline: 2px solid var(--sky); outline-offset: -2px; }
.menu__item[hidden] { display: none; }
.menu__item--out { color: var(--muted); }
.menu__hint { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }

/* ---------- layout & type ---------- */
main { padding-top: 28px; padding-bottom: 48px; }

h1 {
  font-size: 26px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 8px;
}
.lede { margin: 0 0 22px; color: var(--muted); font-size: 15px; }
.muted { color: var(--muted); }
.small { font-size: 13px; }
p { margin: 0 0 12px; }

.stack > * + * { margin-top: 12px; }

/* ---------- cards ---------- */
.card {
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
  padding: 20px;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 26px;
  border-radius: var(--radius-pill);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.02em;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.08s ease, opacity 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:active { transform: scale(0.985); }
.btn--primary { background: var(--navy); color: var(--white); border-color: var(--navy); }
.btn--primary:hover { background: var(--navy-deep); border-color: var(--navy-deep); }
.btn--secondary { background: var(--white); color: var(--navy); border-color: var(--navy); }
.btn--secondary:hover { background: var(--pale); }
.btn--block { width: 100%; }
.btn:disabled { opacity: 0.45; cursor: default; transform: none; }
.btn:focus-visible, .chip:focus-visible, .linkbtn:focus-visible, .iconbtn:focus-visible,
.pcard:focus-visible, .snag__summary:focus-visible, .seg button:focus-visible, .tile:focus-visible,
.room__head:focus-visible, .dphoto button:focus-visible {
  outline: 2px solid var(--sky);
  outline-offset: 2px;
}

.linkbtn {
  background: none;
  border: 0;
  padding: 10px 0;
  min-height: 44px;
  color: var(--navy);
  font-weight: 500;
  font-size: 14px;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(8, 51, 108, 0.35);
}
.linkbtn:hover { text-decoration-color: var(--navy); }

.iconbtn {
  background: none;
  border: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}
.iconbtn:hover { background: var(--light); color: var(--danger); }
.iconbtn svg { width: 20px; height: 20px; }

/* ---------- forms ---------- */
.field { margin-bottom: 18px; }
.field:last-child { margin-bottom: 0; }
.label {
  display: block;
  font-weight: 500;
  font-size: 14px;
  color: var(--ink);
  margin-bottom: 8px;
}
.label .opt { font-weight: 400; color: var(--muted); }
.field-hint { margin: 6px 0 0; font-size: 13px; color: var(--muted); }

.input {
  width: 100%;
  min-height: 48px;
  padding: 11px 14px;
  font-size: 16px;
  border: 1.5px solid var(--grey);
  border-radius: var(--radius-input);
  background: var(--white);
  color: var(--text);
  outline: none;
  transition: border-color 0.15s ease;
  -webkit-appearance: none;
  appearance: none;
}
.input::placeholder { color: #9A9A9A; }
.input:focus { border-color: var(--navy); }
.input.is-invalid { border-color: var(--danger); }
textarea.input { resize: none; line-height: 1.45; min-height: 72px; overflow: hidden; }

.field-error { color: var(--danger); font-size: 13px; margin: 8px 0 0; font-weight: 500; }

/* The six-digit code. Wide letter-spacing so it can be checked against the email at a glance,
   and text-indent cancels the trailing space so the digits are actually centred. */
.input--code {
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: 8px;
  text-indent: 8px;
  text-align: center;
  min-height: 56px;
}
/* "Send it again" on the left, "Wrong address?" on the right — the two ways out of the code
   screen, which is the only screen a client can be stuck on. */
.altrow { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.signedin { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 15px; }

/* honeypot: hidden from humans, visible to bots */
.hp { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; opacity: 0; }

/* ---------- notices ---------- */
.notice {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--pale);
  color: var(--navy);
  border-radius: var(--radius-input);
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 500;
  margin: 14px 0 0;
}
.notice .spinner { flex: none; }

.alert {
  background: var(--danger-bg);
  color: var(--danger);
  border-radius: var(--radius-input);
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 500;
  margin: 0 0 14px;
}
.alert ul { margin: 6px 0 0; padding-left: 18px; font-weight: 400; }
.alert li + li { margin-top: 3px; }

.spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid rgba(8, 51, 108, 0.2);
  border-top-color: var(--navy);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- resume card ---------- */
.resume {
  border-color: var(--sky);
  background: var(--pale);
  margin-bottom: 20px;
}
.resume__title { font-weight: 600; color: var(--ink); margin: 0 0 2px; }
.resume__sub { margin: 0 0 12px; font-size: 14px; color: var(--muted); }
.resume__actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.resume__actions .btn { min-height: 44px; padding: 0 20px; font-size: 14px; }

/* ---------- project cards ---------- */
.pcard {
  width: 100%;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.pcard:hover { border-color: var(--navy); }
.pcard__main { flex: 1; min-width: 0; }
.pcard__name { font-weight: 600; color: var(--ink); font-size: 15px; }
.pcard__client { font-size: 14px; color: var(--text); margin-top: 1px; }
.pcard__meta { font-size: 13px; color: var(--muted); margin-top: 3px; }
.pcard__chev { flex: none; color: var(--grey); }
/* Landing: the two company tiles, then the three journeys. */
.ccard { justify-content: center; padding: 26px 20px; min-height: 120px; }
.ccard img { width: min(100%, 260px); height: auto; display: block; }
.ccard[aria-pressed="true"] { border-color: var(--navy); }
a.hcard { text-decoration: none; color: inherit; }
.hcard .pcard__chev { color: var(--navy); }
.badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 500;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--pale);
  color: var(--navy);
  vertical-align: middle;
  margin-left: 6px;
  letter-spacing: 0.02em;
}
.search { position: relative; margin-bottom: 14px; }
.search .input { padding-left: 42px; }
.search svg {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--muted); pointer-events: none;
}

/* ---------- project strip ---------- */
.strip {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 13px;
  color: var(--muted);
  margin: -8px 0 18px;
}
.strip > * { white-space: nowrap; }
.strip__proj { font-weight: 600; color: var(--navy); }
.strip .linkbtn { padding: 4px 0; min-height: 0; font-size: 13px; }
.strip__dot::before { content: '·'; }

/* ---------- snag cards ---------- */
.snag {
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: border-color 0.15s ease;
}
.snag.is-flagged { border-color: var(--danger); }
.snag.is-open { border-color: var(--navy); }

.snag__summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  min-height: 64px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.snag.is-open .snag__summary { display: none; }
.snag__sum-thumb {
  flex: none; width: 44px; height: 44px; border-radius: 8px;
  background: var(--pale); overflow: hidden;
  display: flex; align-items: center; justify-content: center; color: var(--navy);
}
.snag__sum-thumb img { width: 100%; height: 100%; object-fit: cover; }
.snag__sum-thumb svg { width: 20px; height: 20px; opacity: 0.6; }
.snag__sum-text { flex: 1; min-width: 0; }
.snag__sum-zone { font-weight: 600; font-size: 14px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.snag__sum-desc { font-size: 13px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.snag__sum-desc.is-todo { color: var(--amber); font-weight: 500; }
.snag__sum-chev { flex: none; color: var(--grey); width: 18px; height: 18px; }

.snag__body { display: none; padding: 16px 16px 18px; }
.snag.is-open .snag__body { display: block; }
.snag__head { display: flex; align-items: center; justify-content: space-between; margin: -6px -8px 8px 0; }
.snag__title { font-weight: 600; color: var(--ink); font-size: 15px; }
.snag__error { color: var(--danger); font-size: 13px; font-weight: 500; margin: 12px 0 0; }

/* photos */
.photos { margin-bottom: 18px; }
.tiles { display: flex; gap: 10px; flex-wrap: wrap; }
.tile {
  position: relative;
  width: 72px; height: 72px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--light);
  border: 1.5px solid var(--grey);
  padding: 0;
  flex: none;
}
.tile img { width: 100%; height: 100%; object-fit: cover; }
.tile--add {
  border-style: dashed;
  border-color: var(--navy);
  background: var(--white);
  color: var(--navy);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  font-size: 11px; font-weight: 500;
}
.tile--add svg { width: 22px; height: 22px; }
.tile--add:hover { background: var(--pale); }
.tile--busy { display: flex; align-items: center; justify-content: center; }
.tile__main {
  position: absolute; left: 4px; top: 4px;
  background: var(--navy); color: var(--white);
  font-size: 9px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 1px 6px; border-radius: var(--radius-pill);
}
.tile__size {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: rgba(18, 18, 18, 0.6); color: var(--white);
  font-size: 10px; text-align: center; padding: 1px 0;
}
.tile__rm {
  position: absolute; right: 2px; top: 2px;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(18, 18, 18, 0.7); color: var(--white);
  border: 0; display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.tile__rm svg { width: 12px; height: 12px; }
.tile__rm::after { content: ''; position: absolute; inset: -11px; } /* 44px hit target */
.hint { font-size: 12px; color: var(--muted); margin: 8px 0 0; }

/* chips */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  min-height: 36px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  background: var(--pale);
  color: var(--navy);
  border: 1.5px solid transparent;
  font-size: 13.5px;
  font-weight: 500;
  display: inline-flex; align-items: center;
  transition: background-color 0.12s ease, color 0.12s ease;
  -webkit-tap-highlight-color: transparent;
  position: relative;
}
.chip::after { content: ''; position: absolute; inset: -4px 0; } /* 44px hit target */
.chip:hover { background: #D3E3EE; }
.chip[aria-pressed="true"] { background: var(--navy); color: var(--white); }
.chips + .linkbtn { padding: 6px 0 0; min-height: 36px; }

/* segmented control */
.seg {
  display: flex;
  background: var(--light);
  border: 1.5px solid var(--grey);
  border-radius: var(--radius-pill);
  padding: 3px;
}
.seg button {
  flex: 1;
  min-height: 38px;
  border: 0;
  background: transparent;
  border-radius: var(--radius-pill);
  font-weight: 500;
  font-size: 14px;
  color: var(--muted);
  transition: background-color 0.12s ease, color 0.12s ease;
}
.seg button[aria-checked="true"] { background: var(--white); color: var(--navy); font-weight: 600; box-shadow: 0 1px 3px rgba(18, 18, 18, 0.12); }

/* disclosure */
.disc { border-top: 1px solid var(--light); margin-top: 4px; }
.disc summary {
  list-style: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  min-height: 44px;
  font-size: 14px; font-weight: 500; color: var(--navy);
}
.disc summary::-webkit-details-marker { display: none; }
.disc summary::after {
  content: '';
  width: 8px; height: 8px;
  border-right: 1.5px solid var(--navy); border-bottom: 1.5px solid var(--navy);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
  margin-right: 4px;
}
.disc[open] summary::after { transform: rotate(-135deg); }
.disc .chips { padding: 4px 0 8px; }

/* ---------- sticky action bar ---------- */
.actionbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  background: rgba(255, 255, 255, 0.94);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--grey);
  padding: 14px 0 calc(14px + env(safe-area-inset-bottom, 0px));
  z-index: 20;
}
.actionbar .wrap { display: flex; flex-direction: column; gap: 8px; }
.actionbar .linkbtn { min-height: 36px; padding: 4px 0; }

/* ---------- review ---------- */
.kv { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; font-size: 14px; }
.kv .k { color: var(--muted); }
.kv .v { font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
.rlist { padding: 4px 0; }
.rrow { display: flex; align-items: center; gap: 12px; padding: 12px 16px; }
.rrow + .rrow { border-top: 1px solid var(--light); }
.rrow__thumb {
  flex: none; width: 48px; height: 48px; border-radius: 8px; overflow: hidden;
  background: var(--pale); display: flex; align-items: center; justify-content: center; color: var(--navy);
}
.rrow__thumb img { width: 100%; height: 100%; object-fit: cover; }
.rrow__thumb svg { width: 20px; height: 20px; opacity: 0.6; }
.rrow__text { flex: 1; min-width: 0; }
.rrow__zone { font-weight: 600; font-size: 14px; color: var(--ink); }
.rrow__desc { font-size: 13px; color: var(--muted); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.rrow__meta { font-size: 12px; color: var(--muted); margin-top: 2px; }

.sendstatus { margin: 0 0 6px; }
.progress { height: 6px; background: var(--pale); border-radius: 3px; overflow: hidden; }
.progress__bar { height: 100%; width: 0; background: var(--navy); border-radius: 3px; transition: width 0.2s ease; }
.progress.is-indeterminate .progress__bar { width: 40%; animation: slide 1.2s ease-in-out infinite; }
@keyframes slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(260%); } }
.sendstatus p { margin: 8px 0 0; font-size: 13px; font-weight: 500; color: var(--navy); text-align: center; }

/* ---------- success ---------- */
.success { text-align: center; padding-top: 20px; }
.check {
  width: 96px; height: 96px; border-radius: 50%;
  background: var(--sky); color: var(--white);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 24px;
  animation: pop 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.3);
}
.check svg { width: 48px; height: 48px; }
@keyframes pop { from { transform: scale(0.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.success h1 { margin-bottom: 18px; }
.pills { list-style: none; padding: 0; margin: 0 0 20px; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.pills li {
  background: var(--white); border: 1.5px solid var(--sky); color: var(--navy);
  border-radius: var(--radius-pill); padding: 6px 14px; font-size: 14px; font-weight: 600; letter-spacing: 0.02em;
}
.status {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--pale); color: var(--navy); font-weight: 500; font-size: 14px;
  padding: 10px 16px; border-radius: 18px; margin: 4px 0 18px; text-align: left;
}
.status .spinner, .status svg { flex: none; }
.status.is-done { background: #E5F3EA; color: var(--green); }
.status.is-partial { background: #FCEFE3; color: var(--amber); }
.status svg { width: 18px; height: 18px; }

/* ---------- toast ---------- */
.toast {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--bar-h) + 12px);
  background: var(--ink); color: var(--white);
  border-radius: var(--radius-pill);
  padding: 10px 10px 10px 18px;
  display: flex; align-items: center; gap: 14px;
  font-size: 14px; font-weight: 500;
  box-shadow: 0 8px 24px rgba(18, 18, 18, 0.25);
  z-index: 30;
  max-width: calc(100% - 40px);
  animation: rise 0.2s ease;
}
body:not(.has-bar) .toast { bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
.toast button {
  background: rgba(255, 255, 255, 0.14); color: var(--white);
  border: 0; border-radius: var(--radius-pill);
  min-height: 36px; padding: 0 14px; font-weight: 600; font-size: 13px; letter-spacing: 0.02em;
}
@keyframes rise { from { transform: translate(-50%, 10px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }

/* ---------- utilities ---------- */
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.empty { text-align: center; color: var(--muted); font-size: 14px; padding: 24px 0; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
  .progress.is-indeterminate .progress__bar { width: 100%; opacity: 0.5; }
  .spinner { border-top-color: var(--navy); border-color: var(--navy); opacity: 0.6; }
}

@media (min-width: 600px) {
  main { padding-top: 40px; }
  h1 { font-size: 30px; }
  .card { padding: 24px; }
}

/* ---------- dashboard ---------- */
/* The read-only view: what Bergstreme has done with the snags on a project. It reuses .card,
   .strip, .seg, .chips, .search, .snag (open/closed) and .progress unchanged; only what follows
   is new, and all of it sits on the tokens above. */

.sum { margin-bottom: 16px; }
.sum__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; margin-bottom: 16px; }
.sumcard { text-align: center; }
.sumcard__n { display: block; font-size: 28px; font-weight: 600; color: var(--ink); line-height: 1.2; }
.sumcard__l { display: block; font-size: 12px; color: var(--muted); }
/* Navy, not amber: an outstanding snag is the normal state of a project being built, and the
   client should not be alarmed by their own report. Only "fixed" earns a colour that means
   something. */
.sumcard--reported .sumcard__n { color: var(--navy); }
.sumcard--fixed .sumcard__n { color: var(--green); }
.sum__note { margin: 8px 0 0; font-size: 13px; color: var(--muted); text-align: center; }
/* The one line on this card that is asking for something, so it is the one that is not grey. */
.sum__note--do { color: var(--green); font-weight: 600; }
/* Why this viewer cannot approve. Muted, not alarming: for staff and subbies this is normal. */
.sum__note--why { color: var(--muted); }
/* The staff preview banner. Deliberately loud — nobody should mistake it for the real thing. */
.notice--preview {
  margin: 0 0 16px;
  justify-content: space-between;
  gap: 12px;
  background: #FFF4D6;
  color: #6B4E00;
  border: 1px solid #E9C96A;
}
.notice--preview .linkbtn { flex: none; color: #6B4E00; }

.filters { margin-bottom: 12px; }
.filters__selects { display: flex; gap: 10px; margin-bottom: 12px; }
.sel { flex: 1 1 0; min-width: 0; display: block; }
.sel__lbl { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.sel__input {
  /* .input already clears the native appearance, so the chevron has to be drawn back on. */
  background-image: linear-gradient(45deg, transparent 50%, var(--navy) 50%),
                    linear-gradient(135deg, var(--navy) 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 1px), calc(100% - 14px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 38px;
}
.filters .search { margin-bottom: 12px; }
.togg { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--text); min-height: 32px; cursor: pointer; }
.togg input { width: 17px; height: 17px; accent-color: var(--navy); flex: none; }

.listtools { display: flex; justify-content: flex-end; margin-bottom: 4px; }
.listtools .linkbtn { font-size: 13px; }

/* ---- a room. Native <details>, so the keyboard and screen-reader behaviour is the browser's. */
.rooms { display: block; }
.room + .room { margin-top: 24px; }
.room__head {
  list-style: none;
  cursor: pointer;
  display: flex; align-items: baseline; gap: 12px;
  padding: 4px 2px 7px;
}
.room__head::-webkit-details-marker { display: none; }
.room__name { font-size: 16px; font-weight: 600; color: var(--ink); }
.room__count { margin-left: auto; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.room__chev {
  flex: none; width: 16px; height: 16px; color: var(--muted); align-self: center;
  transform: rotate(90deg); transition: transform 0.15s ease;
}
.room:not([open]) .room__chev { transform: rotate(0deg); }
/* The room's progress is the rule under its name — one mark doing two jobs. */
.room__bar { height: 3px; background: var(--grey); border-radius: var(--radius-pill); overflow: hidden; }
.room__fill { display: block; height: 100%; background: var(--green); }
.room__rows {
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
  margin-top: 10px;
  padding: 0 16px;
}
.room:not([open]) .room__rows { display: none; }

/* ---- a snag. Everything it has, always visible: there is nothing left worth a tap. */
.drow {
  padding: 14px 0 16px;
  /* ~one row tall, so a long project does not pay for laying out every row up front. */
  content-visibility: auto;
  contain-intrinsic-size: 0 220px;
}
.drow + .drow { border-top: 1px solid var(--light); }
.drow__desc { margin: 0 0 6px; font-size: 14.5px; font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
.drow__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: 12px; color: var(--muted); }
.drow__badge { flex: none; }
.badge--reported { background: var(--pale); color: var(--navy); }
.badge--fixed { background: #E5F3EA; color: var(--green); }
.drow__mine { color: var(--navy); font-weight: 500; }
.drow__action { margin-top: 10px; }
/* The form's .label is a 14px input label; here it is a caption over a sentence, so it steps back
   and lets the sentence itself be the thing being read. */
.drow__action .label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--muted); margin: 0;
}
.drow__action-text { margin: 2px 0 0; color: var(--text); overflow-wrap: anywhere; }
.drow__comment { margin-top: 10px; display: block; overflow-wrap: anywhere; }

/* ---- client approval. The one thing on this screen that writes, so it is the one thing allowed
   a green button — everything else here is a link or a filter. It sits below the comment and
   above the photos on a phone, and stays in the text column on a wide screen, because the
   question it asks ("is this actually fixed?") is answered by looking at the photos beside it. */
.approve { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--grey); }
.approve__btns { display: flex; flex-wrap: wrap; gap: 8px; }
.btn--small { min-height: 40px; padding: 0 16px; font-size: 13.5px; }
.btn--approve { background: var(--green); border-color: var(--green); color: var(--white); }
.btn--approve:hover { background: #267146; border-color: #267146; }
/* A snag nobody has fixed yet keeps its buttons, greyed, with the reason under them: a control
   that vanishes reads as a bug, and "why can't I approve this?" is a support call. */
.approve__why { margin: 8px 0 0; }
.approve__form { margin-top: 10px; }
.approve__label { font-size: 13px; }
.approve__formbtns { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.approve__done { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.approve__said {
  flex-basis: 100%;
  margin: 0; padding: 8px 12px;
  background: var(--danger-bg); color: var(--danger);
  border-radius: var(--radius-input);
  font-size: 13px; overflow-wrap: anywhere;
}
.approve__err { margin: 8px 0 0; color: var(--danger); font-weight: 500; }
/* Read-only: the row carries a decision but this viewer is not the one who makes it. */
.approve--readonly { opacity: 0.95; }
.approve__when { margin: 0; }
.badge--approved { background: #E5F3EA; color: var(--green); }
.badge--notapproved { background: var(--danger-bg); color: var(--danger); }
/* An optimistic row, while its write is in flight. The same posture the /manage grid takes. */
.approve.is-sending { opacity: 0.55; pointer-events: none; }

.room__tools { display: flex; justify-content: flex-end; margin-top: 8px; }
.linkbtn--go { color: var(--green); text-decoration-color: rgba(46, 139, 87, 0.35); }
.linkbtn--go:hover { text-decoration-color: var(--green); }
.listtools { gap: 16px; }

/* ---- the bulk confirm. A sheet on a phone, a centred card on a desktop; either way it lists
   what is about to be approved rather than asking the client to trust a number. */
.confirm {
  position: fixed; inset: 0; z-index: 45;
  background: rgba(18, 18, 18, 0.5);
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0;
}
.confirm__card {
  width: 100%; max-width: 560px;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  padding: 20px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  max-height: 82vh; overflow-y: auto;
}
.confirm__title { font-size: 18px; margin: 0 0 4px; color: var(--ink); }
.confirm__sub { margin: 0 0 12px; font-size: 14px; color: var(--muted); }
.confirm__list { margin: 0 0 8px; padding-left: 18px; font-size: 13.5px; color: var(--text); }
.confirm__list li + li { margin-top: 4px; }
.confirm__more { margin: 0 0 8px; }
.confirm__btns { display: flex; gap: 10px; margin-top: 16px; }
.confirm__btns .btn { flex: 1 1 0; }
@media (min-width: 640px) {
  .confirm { align-items: center; padding: 24px; }
  .confirm__card { border-radius: var(--radius-card); }
}

/* Always two columns, even for one photo: the defect always sits in the left slot and the repair
   in the right, so the pair lines up down the list instead of each row finding its own size. A
   photo here is a thumbnail into the lightbox, not the thing itself — full-bleed turns fourteen
   snags into a very long page. */
.dphotos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 12px; max-width: 360px; }
.dphoto { margin: 0; }
.dphoto button {
  display: block; width: 100%; padding: 0; border: 1.5px solid var(--grey);
  border-radius: 10px; overflow: hidden; background: var(--pale); aspect-ratio: 4 / 3;
}
.dphoto img { width: 100%; height: 100%; object-fit: cover; }
.dphoto__cap { font-size: 12px; color: var(--muted); margin-top: 4px; text-align: center; }
.dphoto__fallback { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--navy); }
.dphoto__fallback svg { width: 26px; height: 26px; opacity: 0.5; }

.lightbox {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(18, 18, 18, 0.94);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px 16px calc(24px + env(safe-area-inset-bottom, 0px));
}
.lightbox__img { max-width: 100%; max-height: 82vh; object-fit: contain; border-radius: 8px; }
.lightbox__cap { color: rgba(255, 255, 255, 0.8); font-size: 13px; margin: 12px 0 0; text-align: center; }
.lightbox__close {
  position: absolute; top: calc(12px + env(safe-area-inset-top, 0px)); right: 12px;
  color: var(--white); background: rgba(255, 255, 255, 0.14); border-radius: 50%;
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
}
.lightbox__close svg { width: 20px; height: 20px; }

/* The review screen is the one two-column layout in the app: a list of rooms with before/after
   photo pairs, which the 560px report-form column cannot hold. Scoped on the current screen, so
   the topbar and the sticky action bar widen with it and stay aligned with the list. */
@media (min-width: 900px) {
  body[data-current="dashboard"] .wrap { max-width: 820px; }
  body[data-current="dashboard"] .drow {
    display: grid; grid-template-columns: 1fr 300px; gap: 24px; align-items: start;
  }
  body[data-current="dashboard"] .dphotos { margin-top: 0; }
  .filters__selects { max-width: 420px; }
}
/* ---------- save state, on the snags action bar ---------- */
/* The only place the client is told whether their work is safe, so it sits in the bar that is
   always on screen rather than somewhere they have to scroll to. */
.savestate {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--muted);
  padding: 0 2px 8px;
  min-height: 20px;
}
.savestate__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ok, #2e7d52);
}
.savestate[data-kind='busy'] .savestate__dot { background: var(--grey); animation: pulse 1.2s ease-in-out infinite; }
.savestate[data-kind='warn'] { color: var(--danger, #b3261e); font-weight: 500; }
.savestate[data-kind='warn'] .savestate__dot { background: currentColor; }
.savestate .linkbtn { margin-left: auto; font-size: 13px; white-space: nowrap; }
@keyframes pulse { 50% { opacity: 0.35; } }

/* ---------- resume rows ---------- */
.rrow { padding: 0; display: flex; align-items: stretch; gap: 0; }
.rrow__pick {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: none;
  border: 0;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.rrow__pick .badge { flex: none; }
.rrow__drop { flex: none; padding: 0 14px; font-size: 13px; }

/* A lost photo is a note, not a failure: it must read differently from .snag__error, which
   blocks the review step. */
.snag__notice {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.check--saved { background: var(--pale); color: var(--navy); }
.lede.is-local { color: var(--muted); }

/* ---------- home: a journey that is not available, and the other-company hint ---------- */
.pcard.is-off { opacity: 0.55; cursor: default; }
.pcard.is-off:hover { border-color: var(--line); box-shadow: none; }
.pcard.is-off .pcard__chev { visibility: hidden; }
.pcard__note { font-size: 13px; color: var(--navy); margin-top: 6px; font-weight: 500; }
.home-other { margin-top: 18px; }
.home-other .linkbtn { display: inline; padding: 0; min-height: 0; }
.pcard__tag { flex: none; }

/* ---------- claim: erf number or full project name ---------- */
.claim-help { font-size: 13px; color: var(--muted); margin: 10px 0 0; }
