/* Guest Haus Launch Control — internal register.
 *
 * Tokens transcribed from design-reference/tokens.md. Declared once here as
 * custom properties so every later screen reads from the same values rather
 * than repeating hex codes, which is how a palette drifts.
 *
 * The owner register (sage background, serif body, larger radii) lands in
 * Phase 7 and gets its own block rather than overriding these.
 */

:root {
  /* Brand */
  --ink: #241B12;
  --rust: #54281A;
  --forest: #2E382D;
  --sage: #9BA592;
  --clay: #BF9C73;
  --cream: #E3D6C1;
  --gold: #B58A4C;

  /* Internal surfaces */
  --bg: #F5EFE2;
  --surface: #FFFDF6;
  --surface-raised: #FBF7EC;
  --surface-tint: #F1E9D4;
  --border: #E6DCC4;
  --border-soft: #EFE6D0;
  --border-strong: #D8CDB4;

  /* Text */
  --text: #241B12;
  --text-secondary: #7A6E58;
  --text-muted: #8A7E68;
  --text-faint: #A79B85;

  --r-sm: 5px;
  --r-md: 7px;
  --r-lg: 8px;
  --r-xl: 10px;
  --r-pill: 999px;

  --gutter: 28px;
  --content-max: 1180px;
}

* { box-sizing: border-box; }

/* `hidden` is only `display: none` at user-agent specificity, so any class
 * that sets a display — .save-status, .add-row — silently outranks it and the
 * element stays on screen. Caught twice by looking at the page; this is the
 * fix that stops it happening a third time. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: Rubik, system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

body.centered {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

h1 {
  font-family: 'Libre Baskerville', Georgia, serif;
  font-weight: 400;
  font-size: 30px;
  margin: 0 0 20px;
}

a { color: var(--rust); text-decoration: none; }
a:hover { color: var(--forest); text-decoration: underline; }
::selection { background: var(--cream); }

/* Flat and print-like: the drawer is the only shadowed element in the whole
 * design, and it does not exist yet. */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 24px 28px;
}

.appbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px var(--gutter);
  background: var(--surface-raised);
  border-bottom: 1px solid var(--border);
}

.page {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 32px var(--gutter) 80px;
}

.wordmark { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.wordmark-name {
  font-family: 'Libre Baskerville', Georgia, serif;
  font-size: 18px;
  white-space: nowrap;
}
.wordmark-org {
  font-size: 10px;
  letter-spacing: 2.5px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Auth ---------------------------------------------------------------- */

.auth { width: 100%; max-width: 380px; }
.auth .wordmark { margin-bottom: 24px; }

.field { display: block; margin-bottom: 16px; }

.label {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  color: var(--text-faint);
  margin-bottom: 6px;
}

input[type="email"],
input[type="password"],
input[type="text"],
input[type="url"],
input[type="date"] {
  width: 100%;
  padding: 9px 11px;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
}

input:focus-visible,
button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.button-primary {
  width: 100%;
  padding: 10px 16px;
  margin-top: 4px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: #F3EEE0;
  background: var(--forest);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  cursor: pointer;
}

.button-ghost {
  padding: 6px 14px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--rust);
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  cursor: pointer;
}

.error {
  margin: 0 0 16px;
  padding: 9px 12px;
  font-size: 13px;
  color: var(--rust);
  background: #EAD8D1;
  border-radius: var(--r-md);
}

/* Rows ---------------------------------------------------------------- */

.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 0;
  border-bottom: 1px solid var(--border-soft);
}
.row:last-child { border-bottom: none; }
.row:first-child { padding-top: 0; }

.row-title { font-size: 14px; font-weight: 500; }
.row-meta { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

.row-progress { display: flex; align-items: center; gap: 10px; }
.track {
  width: 160px;
  height: 8px;
  background: #EBE1C9;
  border-radius: 4px;
  overflow: hidden;
}
.fill { height: 100%; background: var(--rust); border-radius: 4px; }
.pct { font-size: 13px; font-weight: 600; min-width: 36px; text-align: right; }

.muted { color: var(--text-muted); }
.empty p { margin: 0 0 8px; }
.empty p:last-child { margin-bottom: 0; }

/* The prototype switched layouts on a prop; real breakpoints start here.
 * 900px is the desktop/mobile split named in the build plan. */
@media (max-width: 900px) {
  :root { --gutter: 16px; }
  .page { padding-top: 24px; }
  h1 { font-size: 26px; }
  .row { flex-direction: column; align-items: flex-start; gap: 8px; }
  .track { width: 100%; }
  .row-progress { width: 100%; }

  /* The org tag is the first thing to go: at 375px the wordmark and the
   * sign-out control together do not fit, and the wordmark is the one that
   * has to stay legible. */
  .wordmark-org { display: none; }
  .appbar { padding: 10px var(--gutter); }
  /* Every tappable thing on a phone clears 44px. These are used one-handed,
   * standing up, often in a hurry. */
  .tab { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; }
  .button-primary { min-height: 44px; }
  /* The wordmark links home. The sign-out button already sets the bar's
   * height, so this costs no vertical space. */
  a.wordmark { min-height: 44px; align-items: center; }
  /* 44px minimum touch target — this is used one-handed in a house. */
  .button-ghost { min-height: 44px; }
  .hide-narrow { display: none; }
}

/* Portfolio, forms and settings ----------------------------------------- */

.page.narrow { max-width: 720px; }

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.page-head h1 { margin-bottom: 4px; }

.subline { margin: 0; font-size: 13px; color: var(--text-muted); }
.crumb { margin: 0 0 12px; font-size: 13px; }
.footnote { margin-top: 20px; font-size: 12px; color: var(--text-faint); }
.hint { margin: 0; font-size: 12px; color: var(--text-muted); }

h2 {
  font-family: 'Libre Baskerville', Georgia, serif;
  font-weight: 400;
  font-size: 20px;
  margin: 0;
}

a.wordmark { text-decoration: none; color: inherit; }
a.wordmark:hover { text-decoration: none; }

.button-primary.inline { width: auto; margin-top: 0; text-decoration: none; display: inline-block; }
a.button-ghost, a.button-primary { text-decoration: none; display: inline-block; }
a.button-ghost:hover, a.button-primary:hover { text-decoration: none; }

.tabs { display: flex; gap: 4px; margin-bottom: 16px; }
.tab {
  padding: 6px 16px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 500;
  color: var(--rust);
}
.tab:hover { text-decoration: none; background: var(--surface-tint); }
.tab-on { background: var(--forest); color: #F3EEE0; }
.tab-on:hover { background: var(--forest); }

.card.list { padding: 8px 24px; overflow: hidden; }

.launch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  /* Padded inward rather than by the card, so the hover background and the
   * click area reach the full width of the row. */
  padding: 16px 24px;
  margin: 0 -24px;
  border-bottom: 1px solid var(--border-soft);
}
.launch-row:last-child { border-bottom: none; }

.launch-main { min-width: 0; }
.launch-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.launch-side { display: flex; align-items: center; gap: 16px; flex: none; }

.chip-type {
  padding: 2px 9px;
  border-radius: var(--r-pill);
  background: #EDE1C8;
  color: #7A5B33;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.5px;
}

.row-dates, .row-flags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.chip-date {
  padding: 2px 9px;
  border-radius: var(--r-pill);
  background: var(--surface-tint);
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 500;
}
/* Amber, not red: a date that is not set yet is a prompt, not a failure. */
.chip-flag {
  padding: 2px 9px;
  border-radius: var(--r-pill);
  border: 1px solid #D9C3A2;
  color: #8A6A3F;
  font-size: 11px;
  font-weight: 500;
}

.row-link { font-size: 13px; white-space: nowrap; }
.row-link-quiet { color: var(--text-muted); }
.row-link-quiet:hover { color: var(--rust); }

/* The whole row opens the launch, not just the name.
 *
 * Done with a stretched pseudo-element rather than by wrapping the row in an
 * anchor: the row also contains a link to Settings, and an anchor inside an
 * anchor is invalid and behaves unpredictably. The ::after covers the row and
 * sits below the Settings link, which is raised above it.
 */
.launch-row { position: relative; }

/* Deliberately flat. No hover background, no colour change, no highlight on
 * tap — the row is a surface you touch and it navigates, not a button that
 * responds first. Safari draws its own pale rounded box around a tapped link
 * by default, sized to the text rather than the row, which made the title
 * read as a chip; transparent turns that off.
 *
 * The title itself carries no background, padding or radius for the same
 * reason: it should look like the text it is. The tap target is the whole
 * row via the stretched ::after, so the link needs no padding of its own.
 */
/* :hover spelled out rather than left to the cascade. There is a generic
 * `a:hover` earlier in this file at the same specificity, so this currently
 * wins on source order alone — which would quietly reverse the day someone
 * moves a block. Naming the state costs one line and removes the question. */
a.row-title-link,
a.row-title-link:hover,
a.row-title-link:active {
  color: var(--text);
  text-decoration: none;
  background: transparent;
  -webkit-tap-highlight-color: transparent;
}
.launch-row { -webkit-tap-highlight-color: transparent; }

a.row-title-link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* Kept on purpose, and it is not a tap or hover effect: :focus-visible fires
 * for keyboard navigation only, never for a touch or a mouse click. Without
 * it someone tabbing through the portfolio cannot see where they are. Say the
 * word and it goes, but it costs nothing on a phone. */
a.row-title-link:focus-visible::after {
  outline: 2px solid var(--gold);
  outline-offset: -2px;
}

/* Above the stretched area, so it still goes to Settings. */
.row-link { position: relative; z-index: 2; }

.crumb-sep { color: var(--text-faint); margin: 0 6px; }

/* Forms ------------------------------------------------------------------ */

.stack > * + * { margin-top: 18px; }
.stack .field { margin-bottom: 0; }
/* A tight positive gap, not a negative one. The negative margin worked at
 * desktop field heights and overlapped the input on mobile, where the 44px
 * touch targets are taller. */
.stack .hint { margin-top: 6px; }
.stack h2 { margin-top: 26px; }
.stack h2:first-child { margin-top: 0; }

/* Not the `margin` shorthand: `.stack > * + *` sets margin-top for the stack
 * rhythm, and `fieldset.field` outranks it on specificity, so a shorthand here
 * silently collapses the gap above every fieldset. */
fieldset.field {
  border: none;
  padding: 0;
  margin-left: 0;
  margin-right: 0;
  margin-bottom: 0;
}
fieldset.field legend { padding: 0; }

.field-row { display: flex; gap: 16px; }
.field-row .field { flex: 1; min-width: 0; }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }

/* The radio itself is hidden but still focusable and still the thing the
 * keyboard and screen reader operate — the chip is only its appearance. */
.chip-radio { position: relative; display: inline-flex; }
.chip-radio input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.chip-radio span {
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  color: var(--text-secondary);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
}
.chip-radio input:checked + span {
  background: var(--forest);
  border-color: transparent;
  color: #F3EEE0;
}
.chip-radio input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 1px; }

.chip-button {
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
}
.chip-button.chip-on { background: var(--forest); border-color: transparent; color: #F3EEE0; }

.actions { display: flex; justify-content: flex-end; align-items: center; gap: 10px; }
.actions-left { justify-content: flex-start; }

.input-with-link { display: flex; align-items: center; gap: 10px; }
.input-with-link input { flex: 1; min-width: 0; }
.open-link { font-size: 12px; white-space: nowrap; }

.owner-link { display: flex; gap: 10px; align-items: center; }
.owner-link input {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  color: var(--text-secondary);
}

.notice {
  margin: 0 0 16px;
  padding: 9px 12px;
  font-size: 13px;
  color: #3E4A3C;
  background: #DDE3D6;
  border-radius: var(--r-md);
}

/* Confirmations ---------------------------------------------------------- */

.card.confirm {
  border-color: #DCC69E;
  background: #FBF3E2;
  margin-bottom: 20px;
}
.card.confirm h2 { margin-bottom: 8px; }
.card.confirm p { margin: 0 0 16px; font-size: 13px; color: #6B4A23; }

.button-danger {
  padding: 8px 16px;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  background: var(--rust);
  color: #F3EEE0;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.button-danger-ghost {
  padding: 6px 14px;
  border-radius: var(--r-md);
  border: 1px solid #D9C3B8;
  background: transparent;
  color: var(--rust);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.danger-zone { border-color: #E6D3CB; }

@media (max-width: 900px) {
  .page-head { flex-direction: column; align-items: stretch; }
  .launch-row { flex-direction: column; align-items: stretch; gap: 12px; }
  .launch-side { justify-content: space-between; }
  /* Thumb-sized targets: this is the screen someone opens standing in a
   * hallway deciding which house they are working on. */
  /* No padding: the whole row is the target, so the title does not need to
   * be one, and padding on it was part of what made it read as a chip. */
  a.row-title-link { font-size: 16px; line-height: 1.4; }
  .row-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
    padding: 0 8px;
  }
  .field-row { flex-direction: column; gap: 18px; }
  .card.list { padding: 8px 16px; }
  /* The row bleeds out to the card's edge so the whole width is clickable.
   * The negative margin has to match the card's padding at this breakpoint —
   * the desktop value of 24px overflows a card padded to 16px. */
  .launch-row { padding: 16px; margin: 0 -16px; }
  .card { padding: 20px 16px; }
  .owner-link { flex-direction: column; align-items: stretch; }
  /* Touch targets: this gets used one-handed in a house with bad signal. */
  .chip-radio span, .chip-button, .button-danger, .button-danger-ghost { min-height: 44px; display: inline-flex; align-items: center; }
  input[type="text"], input[type="date"], input[type="url"], input[type="email"], input[type="password"] { min-height: 44px; }
}

/* Launch detail ---------------------------------------------------------- */

.launch-title h1 { margin: 0; }
.page-head .subline + .subline { margin-top: 2px; }

.progress-panel {
  display: flex;
  gap: 32px;
  align-items: flex-start;
  margin-bottom: 24px;
}
.progress-figure { flex: none; min-width: 120px; }
.stat { display: block; font-size: 40px; font-weight: 600; line-height: 1; }
.stat-sub { display: block; margin-top: 6px; font-size: 12px; color: var(--text-muted); }
.progress-bars { flex: 1; min-width: 0; }

/* Segmented per phase, widths proportional to each phase's weight — so the
 * bar shows where the work actually is, not five equal fifths. */
.segmented { display: flex; gap: 2px; margin-bottom: 20px; }
.seg { height: 8px; background: #EBE1C9; border-radius: 4px; overflow: hidden; min-width: 8px; }
.seg-fill { height: 100%; background: var(--rust); border-radius: 4px; }
.seg-fill.seg-na {
  width: 100% !important;
  background: repeating-linear-gradient(45deg, #DED3B8 0 4px, #EBE1C9 4px 8px);
}

.phase-rail { display: grid; gap: 10px; }
.phase { display: grid; grid-template-columns: 14px 1fr auto; gap: 10px; align-items: center; }
.phase-dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--surface); border: 2px solid #CFC3A8;
}
.phase-done .phase-dot { background: var(--forest); border-color: var(--forest); }
.phase-active .phase-dot { border: 3px solid var(--gold); }
.phase-na .phase-dot { border-style: dashed; }
.phase-name { font-size: 13px; font-weight: 500; }
.phase-todo .phase-name, .phase-na .phase-name { color: var(--text-muted); }
.phase-sub { font-size: 12px; color: var(--text-muted); }

.phase-heading {
  font-family: Rubik, sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 2px;
  color: var(--text-faint);
  margin: 28px 0 10px;
}

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

.card.step { padding: 0; margin-bottom: 8px; border-radius: var(--r-lg); }
.step-na { opacity: 0.62; }

.step-head {
  display: grid;
  grid-template-columns: 28px 1fr auto 16px;
  gap: 12px;
  align-items: center;
  width: 100%;
  padding: 14px 18px;
  background: transparent;
  border: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.step-num {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-faint);
  text-align: center;
}
.step-headline { min-width: 0; }
.step-name { display: block; font-size: 14px; font-weight: 500; }
.step-sub { display: block; margin-top: 2px; font-size: 12px; color: var(--text-muted); }
.step-pillbox { display: flex; align-items: center; gap: 8px; }
.chev { font-size: 11px; color: var(--text-faint); transition: transform .15s; }
.step-open .chev { transform: rotate(180deg); }

.manual-mark {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: #8A6A3F;
  border: 1px dashed #D9C3A2;
  border-radius: var(--r-pill);
  padding: 2px 8px;
  white-space: nowrap;
}

.pill {
  padding: 4px 12px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 600;
  border: 1px solid transparent;
  white-space: nowrap;
}
.pill-complete { background: var(--forest); color: #F3EEE0; }
.pill-in_progress { background: #EDDFC3; color: #6B4A23; border-color: #DCC69E; }
.pill-not_started { color: var(--text-muted); border-color: #D8CDB6; }
.pill-na { color: var(--text-faint); border-color: #D8CDB6; border-style: dashed; }

.step-body { padding: 4px 18px 18px; border-top: 1px solid var(--border-soft); }
.step-body > * + * { margin-top: 16px; }
.step-note {
  margin: 14px 0 0;
  font-style: italic;
  font-size: 12.5px;
  color: var(--text-muted);
}
.lock-note {
  margin: 0;
  padding: 8px 11px;
  font-size: 12.5px;
  color: #6B4A23;
  background: #FBF3E2;
  border-radius: var(--r-md);
}

.status-row .chips, .flow .chips { margin-top: 6px; margin-bottom: 6px; }
.inline-field { max-width: 280px; }
.chip-danger-on { background: var(--rust); border-color: transparent; color: #F3EEE0; }

.linkish {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  color: var(--rust);
  text-decoration: underline;
  cursor: pointer;
}

/* Checklist -------------------------------------------------------------- */

.sub-heading {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  color: var(--text-faint);
  margin: 16px 0 6px;
}
.checklist > .sub-heading:first-child { margin-top: 0; }

.sub { display: flex; align-items: flex-start; gap: 10px; padding: 3px 0; }
.sub-indent { margin-left: 28px; }

.tickbox {
  flex: none;
  width: 18px; height: 18px;
  margin-top: 1px;
  border-radius: var(--r-sm);
  border: 1px solid #C9BCA0;
  background: var(--surface);
  color: #F3EEE0;
  font-size: 11px;
  line-height: 15px;
  text-align: center;
  padding: 0;
  cursor: pointer;
}
.tickbox.ticked { background: var(--forest); border-color: var(--forest); }
.tickbox:disabled { border-style: dashed; cursor: not-allowed; opacity: 0.6; }

.sub-text { flex: 1; font-size: 13px; min-width: 0; }
.ticked ~ .sub-text { color: #9A8F79; text-decoration: line-through; text-decoration-color: #C9BCA0; }
.sub-text.editing {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 3px;
  text-decoration: none;
  color: var(--text);
}

/* Row actions stay out of the way until the row is touched or focused. */
.sub-actions { display: flex; gap: 2px; opacity: 0; transition: opacity .12s; }
.sub:hover .sub-actions, .sub:focus-within .sub-actions { opacity: 1; }
.icon-button {
  border: none;
  background: none;
  padding: 2px 6px;
  font-size: 13px;
  line-height: 1;
  color: var(--text-faint);
  cursor: pointer;
}
.icon-button:hover { color: var(--rust); }

.checklist-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
}
.checklist-actions .spacer { flex: 1; }
.button-ghost.small, .button-primary.small { padding: 5px 11px; font-size: 12px; }

.add-row { display: flex; gap: 8px; margin-top: 10px; }
.add-row input { flex: 1; min-width: 0; }

textarea {
  width: 100%;
  padding: 9px 11px;
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  resize: vertical;
}

/* Save indicator --------------------------------------------------------- */
/* Bottom-left so it never sits under a thumb reaching for the checklist. */

.save-status {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-radius: var(--r-pill);
  font-size: 12.5px;
  font-weight: 500;
  box-shadow: 0 4px 16px rgba(36, 27, 18, 0.12);
}
/* Scroll room under the page while the banner is up, so no row is stuck
 * behind it. The 80px is the page's own bottom padding. */
body.has-save-banner .page {
  padding-bottom: calc(80px + var(--save-banner-space, 0px));
}

.save-ok { background: #DDE3D6; color: #3E4A3C; }
.save-busy { background: var(--surface-tint); color: var(--text-secondary); }
.save-error { background: #EAD8D1; color: var(--rust); }
.save-error .linkish { color: var(--rust); }

@media (max-width: 900px) {
  .progress-panel { flex-direction: column; gap: 20px; }
  .progress-figure { display: flex; align-items: baseline; gap: 12px; }
  .stat-sub { margin-top: 0; }
  .step-head { grid-template-columns: 22px 1fr auto; padding: 12px 14px; gap: 8px; }
  .step-head .chev { display: none; }
  .step-pillbox { flex-direction: column; align-items: flex-end; gap: 4px; }
  .step-body { padding: 4px 14px 16px; }
  .inline-field { max-width: none; }

  /* 44px rows and 24px boxes: this is the screen someone actually ticks
   * against, standing in a room holding a phone. */
  .sub { padding: 6px 0; min-height: 44px; align-items: center; }
  .tickbox { width: 24px; height: 24px; border-radius: 7px; font-size: 13px; line-height: 21px; }
  .sub-text { font-size: 14px; }
  .sub-actions { opacity: 1; }
  .icon-button { padding: 10px 8px; }
  .save-status { left: 12px; right: 12px; bottom: 12px; justify-content: center; }
}

/* Punch list ------------------------------------------------------------- */

.stat-row { display: flex; gap: 28px; flex-wrap: wrap; padding: 18px 24px; }
.stat-cell { display: flex; flex-direction: column; gap: 2px; }
.stat-n { font-size: 22px; font-weight: 600; line-height: 1.2; }
.stat-money { font-size: 20px; }
.stat-l { font-size: 10px; font-weight: 600; letter-spacing: 1.5px; color: var(--text-faint); }
.stat-wide { margin-left: auto; text-align: right; }
.stat-wide .stat-cell, .stat-wide { align-items: flex-end; }
/* The caveats sit with the number, not in a footnote — an unquoted item is
 * missing money, and a total that hides that is a total that understates. */
.stat-caveat { margin-top: 3px; font-size: 11.5px; color: var(--text-muted); }

.filters { padding: 14px 18px; margin-top: 12px; }
.filters-top { display: flex; gap: 8px; align-items: center; }
.filters-top input[type="search"] { flex: 1; min-width: 0; }
.filters-body { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
/* Desktop shows the dropdowns whatever the details element thinks. */
.filters-summary { display: none; }
.filters-wrap { margin: 0; }
select {
  padding: 8px 10px;
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
}
input[type="search"] {
  padding: 8px 11px;
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
}

.bulk-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding: 10px 18px;
  background: var(--surface-tint);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 500;
}

.punch-table { padding: 0; margin-top: 12px; overflow: hidden; }

.punch-head, .punch-row {
  display: grid;
  grid-template-columns: 34px 22px minmax(0, 1fr) 116px 104px 96px 118px 108px;
  gap: 10px;
  align-items: center;
  padding: 10px 18px;
}
.punch-head {
  background: var(--surface-raised);
  border-bottom: 1px solid var(--border);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  color: var(--text-faint);
}
.punch-row {
  position: relative;
  border-bottom: 1px solid #F1E9D6;
  -webkit-tap-highlight-color: transparent;
}
/* Above the stretched area, so selecting a row does not open it. */
.punch-row .col-check { position: relative; z-index: 2; }
.punch-row:last-child { border-bottom: none; }
.punch-row.row-selected { background: #F7F0DD; }
.punch-row.row-checked { background: #F3EBD6; }
.punch-row.status-done { background: #E7ECDF; }
/* Declined is settled and not coming back — greyed and struck, so it reads as
 * closed rather than as an item nobody has got to. */
.punch-row.status-declined { opacity: 0.45; }
.punch-row.status-declined .punch-title { text-decoration: line-through; text-decoration-color: #B3A78E; }

/* The whole row opens the item, the same way the portfolio works.
 *
 * Stretched pseudo-element rather than wrapping the row in an anchor: the row
 * also holds a selection checkbox, and an anchor around a button swallows the
 * button's clicks. The ::after covers the row; the checkbox is raised above.
 *
 * Deliberately flat — no hover, no tap highlight. Safari otherwise draws a
 * pale box around the title text, which makes it read as a chip rather than a
 * row you can touch.
 */
a.col-title {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
a.col-title:hover, a.col-title:active { color: inherit; text-decoration: none; }
a.col-title::after { content: ''; position: absolute; inset: 0; z-index: 1; }
a.col-title:focus-visible::after { outline: 2px solid var(--gold); outline-offset: -2px; }
.punch-title {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.punch-meta { font-size: 11px; color: var(--text-muted); }
.col-room, .col-type, .col-owner {
  font-size: 12.5px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.col-cost { font-size: 12.5px; text-align: right; white-space: nowrap; }
.col-nec { text-align: center; }
.nec-dot { font-size: 13px; line-height: 1; }
.nec-necessary { color: var(--rust); }
.nec-recommended { color: var(--text-faint); }

/* The eight statuses, from tokens.md. Neutral warms through the clay family
 * as work is committed, then forest when done; rust only for declined. */
.punch-pill-identified { color: #8A7E68; border-color: #D8CDB6; }
.punch-pill-quoted { background: #F1E9D4; color: #7A6E58; }
.punch-pill-sent_to_owner { color: #8A6A3F; border-color: #D9C3A2; }
.punch-pill-approved { background: #DDE3D6; color: #3E4A3C; }
.punch-pill-declined { background: #EAD8D1; color: #54281A; }
.punch-pill-scheduled { color: #5C6B58; border-color: #B8C2AE; }
.punch-pill-in_progress { background: #E5CFA6; color: #5F421D; }
.punch-pill-done { background: #2E382D; color: #F3EEE0; }

/* Drawer ----------------------------------------------------------------- */
/* The only shadowed element in the design. */

.drawer-scrim {
  position: fixed;
  inset: 0;
  background: rgba(36, 27, 18, 0.18);
  z-index: 19;
}
.drawer {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 440px;
  max-width: 95vw;
  z-index: 20;
  padding: 20px 26px 40px;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -16px 0 40px rgba(36, 27, 18, 0.12);
  overflow-y: auto;
  transition: width .18s ease;
}
.drawer.drawer-wide { width: 760px; }
.drawer > * + * { margin-top: 16px; }
.drawer .field { margin-bottom: 0; }
.drawer-head { display: flex; align-items: center; gap: 10px; }
.drawer-head .spacer { flex: 1; }
/* The label only earns its place on mobile, where the drawer covers the whole
 * screen and there is otherwise nothing saying what you are looking at. */
.drawer-heading { display: none; }
.drawer-close {
  border: none;
  background: none;
  padding: 4px 8px;
  font-size: 20px;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
}
.drawer-close:hover { color: var(--rust); }
.drawer-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--border-soft);
}

@media (max-width: 900px) {
  .stat-row { gap: 16px 24px; padding: 16px; }
  .stat-wide { margin-left: 0; text-align: left; align-items: flex-start; width: 100%; }
  .filters-top { flex-direction: column; align-items: stretch; }
  .filters-body { flex-direction: column; align-items: stretch; margin-top: 12px; }
  .filters input, .filters select, .filters button, .filters a { width: 100%; min-height: 44px; }
  .filters-summary {
    display: block;
    margin-top: 12px;
    padding: 10px 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--rust);
    cursor: pointer;
  }
  .filters-wrap:not([open]) .filters-body { display: none; }

  /* The table becomes cards: eight columns do not survive 375px, and the
   * phone is where this list is actually worked. */
  .punch-head { display: none; }
  .punch-table { padding: 8px; background: transparent; border: none; }
  .punch-row {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas:
      "check title"
      "check meta"
      "check pills";
    gap: 4px 10px;
    padding: 14px;
    margin-bottom: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
  }
  /* The button fills the whole 44px target rather than sitting inside a
   * larger padded cell. A padded cell left dead corners: above the row's
   * stretched link so they blocked opening, outside the button so they did
   * not select either — a region that did nothing at all.
   *
   * The visible mark is drawn inset with a border, so a 44px target does not
   * mean a heavy 44px square in the corner of every card. */
  .punch-row .col-check {
    grid-area: check;
    align-self: start;
    position: relative;
    z-index: 2;
    margin: -10px 0 0 -10px;
  }
  .punch-row .col-check .tickbox {
    width: 44px;
    height: 44px;
    border: none;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0;
  }
  .punch-row .col-check .tickbox::before {
    content: '';
    width: 26px;
    height: 26px;
    border: 1.5px solid #C9BCA0;
    border-radius: 7px;
    background: var(--surface);
  }
  .punch-row .col-check .tickbox.ticked::before {
    background: var(--forest);
    border-color: var(--forest);
  }
  /* The glyph, not two rotated gradients. The gradient version rendered as a
   * chevron rather than a tick, which is the sort of thing that looks fine in
   * the CSS and wrong on the screen. */
  .punch-row .col-check .tickbox.ticked::after {
    content: '✓';
    position: absolute;
    color: #F3EEE0;
    font-size: 15px;
    line-height: 1;
  }
  .punch-row .col-check .tickbox { position: relative; }
  .punch-row .col-nec { display: none; }
  .punch-row .col-title { grid-area: title; }
  .punch-title { white-space: normal; font-size: 14px; }
  .punch-row .col-room { grid-area: meta; font-size: 12px; }
  .punch-row .col-type, .punch-row .col-owner { display: none; }
  .punch-row .col-status { grid-area: pills; justify-self: start; margin-top: 4px; }
  .punch-row .col-cost { grid-area: pills; justify-self: end; text-align: right; margin-top: 4px; }

  .bulk-bar { position: sticky; top: 8px; z-index: 5; flex-wrap: wrap; }

  /* Full screen on a phone, so it has to clear the notch and the status bar —
   * top: 0 alone put the close button under them. The header then sticks, so
   * the way out stays reachable however far down the form you are. */
  .drawer {
    width: 100%;
    max-width: none;
    padding: 0 16px calc(40px + env(safe-area-inset-bottom, 0px));
  }
  .drawer.drawer-wide { width: 100%; }
  .drawer-head [data-drawer-wider] { display: none; }
  .drawer-heading {
    display: block;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 1.5px;
    color: var(--text-faint);
  }
  .drawer-head {
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0 -16px;
    padding: calc(10px + env(safe-area-inset-top, 0px)) 16px 10px;
    background: var(--surface);
    border-bottom: 1px solid var(--border-soft);
  }
  .drawer > * + * { margin-top: 16px; }
  .drawer-close { padding: 10px 12px; font-size: 24px; min-height: 44px; min-width: 44px; }
}

/* Photos and comments ---------------------------------------------------- */

.drawer-section { border-top: 1px solid var(--border-soft); padding-top: 16px; }

.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 8px;
  margin-top: 8px;
}
.photo-grid:empty { display: none; }

.photo { position: relative; margin: 0; }
.photo img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  display: block;
  background: var(--surface-tint);
}
.photo-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border: none;
  border-radius: 50%;
  background: rgba(36, 27, 18, 0.62);
  color: #F3EEE0;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s;
}
.photo:hover .photo-remove, .photo:focus-within .photo-remove { opacity: 1; }

.photo-add { display: inline-block; margin-top: 10px; cursor: pointer; }
.photo-add .button-ghost { display: inline-block; }
.hint-error { color: var(--rust); font-weight: 500; }
.hint-warn { color: #8A6A3F; }

.comments { margin-top: 8px; }
.comment {
  padding: 10px 0;
  border-bottom: 1px solid var(--border-soft);
}
.comment:last-child { border-bottom: none; }
.comment-head { display: flex; align-items: baseline; gap: 8px; }
.comment-author { font-size: 13px; font-weight: 500; }
.comment-when { font-size: 11.5px; color: var(--text-muted); flex: 1; }
.comment-body {
  margin: 4px 0 0;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
}
.comment .icon-button { opacity: 0; }
.comment:hover .icon-button, .comment:focus-within .icon-button { opacity: 1; }

.comment-compose { position: relative; margin-top: 12px; }
.comment-compose .actions { margin-top: 8px; justify-content: space-between; }

/* Anchored to the composer rather than the caret: a caret-following menu on a
 * wrapping textarea is a lot of arithmetic for very little. */
.mention-menu {
  position: absolute;
  left: 0;
  bottom: 100%;
  margin-bottom: 4px;
  z-index: 5;
  min-width: 180px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  box-shadow: 0 6px 20px rgba(36, 27, 18, 0.12);
}
.mention-option {
  display: block;
  width: 100%;
  padding: 7px 10px;
  border: none;
  border-radius: var(--r-sm);
  background: transparent;
  font-family: inherit;
  font-size: 13px;
  text-align: left;
  color: var(--text);
  cursor: pointer;
}
.mention-active { background: var(--forest); color: #F3EEE0; }

@media (max-width: 900px) {
  .photo-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  /* Always visible: there is no hover on a phone. */
  .photo-remove { opacity: 1; width: 28px; height: 28px; font-size: 16px; }
  .comment .icon-button { opacity: 1; }
  .photo-add .button-ghost { width: 100%; text-align: center; min-height: 44px; }
  .mention-option { min-height: 44px; }
}

/* Photo staging ---------------------------------------------------------- */
/* Photos wait here until they are sent, so several camera trips become one
 * upload. Visually distinct from the uploaded grid — a pending photo is not
 * a saved photo, and the difference should be obvious at a glance. */

.photo-staging {
  margin-top: 10px;
  padding: 10px;
  background: var(--surface-tint);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
}
.photo-staging .photo-grid { margin-top: 0; }

.photo-pending img {
  border-style: dashed;
  opacity: 0.85;
}

.staging-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 10px;
}

@media (max-width: 900px) {
  .staging-actions { flex-direction: column; align-items: stretch; }
  .staging-actions button { width: 100%; min-height: 44px; }
  /* Always visible on touch — a pending photo you cannot remove is worse
   * than one you have to upload. */
  .photo-pending .photo-remove { opacity: 1; }
}

/* A thumbnail that failed to load, which is not the same thing as a photo
 * that failed to upload — the bytes are in the bucket either way. */
.photo-broken img { opacity: 0.35; }
.photo-retry {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  padding: 4px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  font-family: inherit;
  font-size: 11px;
  font-weight: 500;
  color: var(--rust);
  cursor: pointer;
}

/* ---------------------------------------------------------------------------
   Supply wizard
   --------------------------------------------------------------------------- */

/* The rail is a progress indicator and a jump target both: someone correcting
   one answer should not have to walk the other seven. Horizontal and
   scrollable rather than the vertical .phase-rail, because eight short labels
   read better across than down and the phone has one thumb. */
.wizard-rail {
  display: flex;
  gap: 6px;
  margin: 0 0 20px;
  padding: 0 0 6px;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
}
.wizard-rail::-webkit-scrollbar { display: none; }
.wizard-rail li { flex: 0 0 auto; }

.rail-step {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  cursor: pointer;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
.rail-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  font-size: 11px;
  border-radius: var(--r-pill);
  background: var(--surface-tint);
  color: var(--text-secondary);
}
.rail-step.is-done { color: var(--text-secondary); border-color: var(--border-strong); }
.rail-step.is-done .rail-number { background: var(--sage); color: #FFFDF6; }
.rail-step.is-current {
  color: #F3EEE0;
  background: var(--forest);
  border-color: var(--forest);
}
.rail-step.is-current .rail-number { background: rgba(255, 253, 246, 0.22); color: #F3EEE0; }

.wizard-panel h2 { margin-top: 0; }

/* Tabs only appear on a compound. A single unit gets no chrome for a choice
   it does not have. */
.unit-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.unit-tab {
  padding: 6px 14px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.unit-tab.is-active { color: #F3EEE0; background: var(--rust); border-color: var(--rust); }

.grid-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 14px;
}
.field.compact { margin: 0; }

.pullouts { display: grid; gap: 10px; margin-bottom: 12px; }
.pullout-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.pullout-row select,
.pullout-row input[type="text"] {
  padding: 8px 10px;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
}
.pullout-row input[type="text"] { flex: 1 1 160px; }

.check { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }

/* Multi-select chips. The single-select .chip-radio already exists; these
   differ only in that several can be on at once. */
.chip-check {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.chip-check input { position: absolute; opacity: 0; pointer-events: none; }
.chip-check span {
  display: inline-block;
  padding: 7px 14px;
  font-size: 13px;
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
}
.chip-check input:checked + span {
  color: #F3EEE0;
  background: var(--forest);
  border-color: var(--forest);
}
.chip-check input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px; }

.review { display: grid; gap: 10px; margin: 0 0 20px; }
.review > div {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 12px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--border-soft);
}
.review dt { font-size: 12px; color: var(--text-muted); }
.review dd { margin: 0; font-size: 14px; }

.warnings {
  padding: 14px 16px;
  margin-bottom: 20px;
  background: #FBF3E2;
  border: 1px solid #DCC69E;
  border-radius: var(--r-lg);
}
.warnings h3 { margin: 0 0 8px; }
.warnings ul { margin: 0; padding-left: 18px; }
.warnings li { font-size: 13px; color: var(--text-secondary); margin-bottom: 4px; }

.confirm-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }

.wizard-generate { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.wizard-nav {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 20px;
}
.wizard-nav .button-primary,
.wizard-nav .button-ghost { width: auto; margin-top: 0; }
.wizard-position { font-size: 12px; color: var(--text-muted); margin-right: auto; }
.wizard-status { font-size: 12px; color: var(--text-muted); }
.wizard-status.is-error { color: var(--rust); font-weight: 500; }

@media (max-width: 640px) {
  .wizard-nav { position: sticky; bottom: 0; padding: 12px 0; background: var(--bg); }
  .review > div { grid-template-columns: 1fr; gap: 2px; }
  .grid-fields { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
}

/* The confirm buttons are the destructive pair, and they get tapped on a
   phone standing in someone's kitchen. .button-ghost is 30px tall, which is
   under the 44px touch minimum — fine for a desktop toolbar, not for
   "Recalculate" next to "Cancel" where the wrong one destroys typed work. */
.confirm-actions button {
  min-height: 44px;
  padding-left: 18px;
  padding-right: 18px;
}

/* .page-head stacks on a narrow screen, and a flex column stretches its
   children — which turned the "View the list" link into a full-width box that
   reads as a card rather than a button. */
.page-head .button-ghost { align-self: start; width: auto; }

/* The wizard nav is sticky on a phone, so anything revealed near the bottom
   opens behind it. This reserves its height when the confirm is scrolled into
   view, so the destructive button is never the part that ends up covered. */
[data-confirm] { scroll-margin-bottom: 96px; }

@media (max-width: 640px) {
  /* And room to scroll the last card clear of the nav entirely. */
  .wizard { padding-bottom: 76px; }
}

/* Per-step tools — the supply list entry point on the Supplies step. Sits
   between the step's fields and its checklist, because it is the thing that
   step is actually for. */
.step-tool {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 14px 0 4px;
}
.step-tool .button-primary { width: auto; margin-top: 0; }
.step-tool .hint { margin: 0; }

/* ---------------------------------------------------------------------------
   Supply list
   ---------------------------------------------------------------------------
   Values here come from design-reference/Supply List.dc.html rather than from
   the shared tokens where the two differ. The prototype is the approved
   design; several of its greys and fills are one step off the token palette
   and copying the token instead is how the screen drifted the first time. */

.supply-page { max-width: 1220px; }

/* --- Header card --------------------------------------------------------- */

.supply-header { padding: 22px 26px; }

.supply-header-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
  flex-wrap: wrap;
}

.supply-header-titles h1 {
  margin: 0;
  font-family: 'Libre Baskerville', Georgia, serif;
  font-weight: 400;
  font-size: 24px;
  color: #241B12;
}
.supply-address { margin: 5px 0 0; font-size: 12.5px; color: #8A7E68; }
.supply-specs {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: #7A6E58;
  max-width: 640px;
}

.supply-header-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  flex: none;
}
.supply-header-buttons { display: flex; gap: 8px; }
.supply-header-buttons .button-primary,
.supply-header-buttons .button-ghost {
  width: auto;
  margin-top: 0;
  padding: 7px 14px;
  font-size: 12.5px;
  border-radius: var(--r-md);
}
.supply-export-note {
  margin: 0;
  font-size: 10.5px;
  color: #B3A78E;
  max-width: 220px;
  text-align: right;
}

/* Warnings are rust-tinted. The observation colour (#FBF3E2) is a different
   thing and using it here made a warning look like a note. */
.supply-warnings {
  margin-top: 16px;
  padding: 12px 16px;
  background: #F3E2D9;
  border: 1px solid #E0C4B5;
  border-radius: var(--r-lg);
}
.supply-warnings p {
  display: flex;
  gap: 8px;
  align-items: baseline;
  margin: 0;
  padding: 2px 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #6B4A3A;
}
.warn-mark { font-size: 11px; color: #B58A4C; }

.supply-chips {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid #EFE6D0;
}
.stat-chip {
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: #F1E9D4;
  color: #7A6E58;
  font-size: 11.5px;
  font-weight: 600;
}
.stat-chip.is-short { background: #F3E2D9; color: #54281A; }
.stat-chip.is-observed { background: #FBF3E2; color: #8A6A3F; }

.supply-fresh { margin: 12px 0 0; font-size: 12.5px; color: #8A7E68; }

/* --- Mobile head --------------------------------------------------------- */

.supply-mobile-head { display: none; }

/* --- Section chips ------------------------------------------------------- */
/* Completion, not scroll position: while walking a house the useful thing is
   what is left, not where you are. */

.section-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 22px 0 0;
  padding: 0;
}
.section-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-radius: var(--r-pill);
  border: 1px solid #D8CDB4;
  background: #FFFDF6;
  color: #54281A;
  font-size: 11.5px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
.section-chip.is-complete { border-color: #9BA592; background: #E7ECDF; color: #3E4A3C; }
.chip-count { opacity: 0.75; }

/* --- Sections ------------------------------------------------------------ */

.supply-section { margin-top: 22px; scroll-margin-top: 20px; }

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 0 4px 8px;
}
.section-title {
  font-size: 11px;
  letter-spacing: 2px;
  font-weight: 600;
  color: #54281A;
  text-transform: uppercase;
}
.section-count { font-size: 11px; color: #8A7E68; }

.section-card { padding: 0; overflow: hidden; border-radius: var(--r-xl); }

/* --- The grid ------------------------------------------------------------ */
/* Six columns: item, required, one per unit, need to order, derivation,
   observation. The observation is a column and not a drawer — someone typing
   a note while holding a tape measure should not have to open anything. */

.supply-grid { --unit-count: 1; }

.grid-head,
.grid-row {
  display: grid;
  grid-template-columns:
    minmax(0, 1.5fr) 76px repeat(var(--unit-count), 96px) 96px minmax(0, 1.1fr) minmax(0, 1.4fr);
  gap: 12px;
  align-items: center;
  padding: 9px 18px;
}

.grid-head {
  background: #FBF7EC;
  border-bottom: 1px solid #EBE1C9;
}
.grid-head span {
  font-size: 10px;
  letter-spacing: 1.2px;
  color: #A79B85;
  font-weight: 600;
}
.grid-head .num { text-align: right; }

.grid-row { border-bottom: 1px solid #F1E9D6; }
.grid-row:last-child { border-bottom: none; }

.cell-item { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.item-name { font-size: 13px; font-weight: 500; color: #241B12; }
.confirm-mark { font-size: 10px; color: #B58A4C; font-weight: 600; }
.mobile-req { display: none; }

.cell-req { font-size: 13px; font-weight: 600; color: #2E382D; text-align: right; }
.cell-req.is-dash { color: #C9BCA0; }

/* The wrapper exists for the phone, where the per-unit fields sit side by
   side. display:contents keeps them as real grid columns here. */
.onhand-group { display: contents; }
.cell-onhand { text-align: right; }
.unit-label { display: none; }

.on-hand {
  width: 100%;
  padding: 7px 9px;
  font-family: inherit;
  font-size: 12.5px;
  text-align: right;
  color: #241B12;
  background: #FBF7EC;
  border: 1px solid #E3D9C2;
  border-radius: 6px;
  outline: none;
  min-width: 0;
}
.on-hand:focus-visible { border-color: var(--gold); }

.cell-need { font-size: 12.5px; font-weight: 600; text-align: right; }
.cell-need .is-dash { color: #C9BCA0; }
.cell-need .needs { color: #54281A; }
.cell-need .covered { color: #5C6B58; }

.cell-deriv {
  font-size: 11.5px;
  line-height: 1.5;
  color: #A79B85;
  font-style: italic;
}

/* The observation earns a warm fill once it has something in it, so a row
   carrying a note is visible while scrolling past. */
.observation {
  width: 100%;
  padding: 7px 9px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 400;
  color: #54281A;
  background: transparent;
  border: 1px solid #EFE6D0;
  border-radius: 6px;
  outline: none;
  min-width: 0;
}
.observation.has-value { border-color: #DCC69E; background: #FBF3E2; font-weight: 500; }
.observation-mobile,
.observation-toggle { display: none; }

/* --- Additions ----------------------------------------------------------- */

.additions-card { padding: 16px 20px; }
.additions-empty { margin: 0; font-size: 12.5px; color: #B3A78E; }
.additions-hint { display: none; }

.additions { list-style: none; margin: 0; padding: 0; }
.additions li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid #F1E9D6;
  font-size: 13px;
  color: #312A1E;
}
.additions li.is-pending { opacity: 0.55; }
.addition-mark { font-size: 11px; color: #B58A4C; }
.addition-text { flex: 1; }
.addition-remove {
  border: none;
  background: transparent;
  color: #B3A78E;
  font-size: 14px;
  cursor: pointer;
  padding: 2px 6px;
}

.addition-add { display: flex; gap: 8px; margin-top: 12px; max-width: 520px; }
.addition-add input {
  flex: 1;
  min-width: 0;
  padding: 8px 11px;
  font-family: inherit;
  font-size: 12.5px;
  color: #241B12;
  background: #FBF7EC;
  border: 1px solid #D8CDB4;
  border-radius: var(--r-md);
  outline: none;
}
.addition-add .button-primary {
  width: auto;
  margin-top: 0;
  padding: 8px 14px;
  font-size: 12.5px;
  border-radius: var(--r-md);
}

/* The sticky bar is the phone's way of adding something. On a desktop the
   field sits in the additions card where it can simply be seen. */
.supply-sticky { display: none; }

/* --- Sticky bar ---------------------------------------------------------- */

.supply-sticky {
  position: sticky;
  bottom: 0;
  margin-top: 22px;
  background: #FBF7EC;
  border-top: 1px solid #E3D9C2;
  padding: 12px 16px;
}
.sticky-add { display: flex; gap: 8px; margin-bottom: 10px; }
.sticky-add input {
  flex: 1;
  min-width: 0;
  padding: 12px;
  font-family: inherit;
  font-size: 14px;
  color: #241B12;
  background: #FFFDF6;
  border: 1px solid #D8CDB4;
  border-radius: var(--r-lg);
  outline: none;
}
.sticky-add .button-primary { width: auto; margin-top: 0; padding: 12px 16px; border-radius: var(--r-lg); }
.sticky-row { display: flex; align-items: center; gap: 10px; }
.sticky-status { flex: 1; font-size: 11.5px; color: #8A7E68; }
.supply-sticky .button-ghost {
  width: auto;
  padding: 10px 14px;
  border-radius: var(--r-lg);
  font-size: 12.5px;
}

/* --- Below 1000px the table stops being a table ---------------------------
   Not 820. At 820 the six-column grid leaves the derivation column 122px,
   which wraps "4 per queen/full/pull-out · 2 per twin" onto four lines, and
   the item column 166px, which does the same to the longer kitchen names.
   Cards start earlier rather than shipping a squeezed table. */

@media (max-width: 1000px) {
  .supply-header { display: none; }

  .supply-mobile-head { display: block; }
  .mobile-head-top { display: flex; justify-content: space-between; align-items: baseline; }
  .mobile-property { font-family: 'Libre Baskerville', Georgia, serif; font-size: 19px; }
  .mobile-saved { font-size: 11px; color: #5C6B58; font-weight: 500; }
  .mobile-progress { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
  .mobile-track {
    flex: 1;
    height: 6px;
    background: #EBE1C9;
    border-radius: 3px;
    overflow: hidden;
  }
  .mobile-fill { height: 100%; background: #54281A; border-radius: 3px; }
  .mobile-count { font-size: 11.5px; color: #8A7E68; }

  .section-chips { margin-top: 12px; }

  /* Serif, rust, and a heavier rule than the desktop label. */
  .supply-section { margin-top: 26px; scroll-margin-top: 12px; }
  .section-head {
    padding: 0 0 7px;
    border-bottom: 2px solid #E3D9C2;
  }
  .section-title {
    font-family: 'Libre Baskerville', Georgia, serif;
    font-size: 17px;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: #54281A;
  }
  .section-count { flex: none; }

  .section-card { background: none; border: none; border-radius: 0; overflow: visible; }
  .grid-head { display: none; }

  /* Each row becomes its own card. The left edge turns sage once the row has
     been counted, so what is left shows at a glance while scrolling. */
  .grid-row {
    display: flex;
    flex-direction: column;
    /* The desktop rule centres cells in their grid track. In a column flex
       that centres them horizontally, which is not what it means here. */
    align-items: stretch;
    padding: 14px 16px;
    margin-top: 10px;
    background: #FFFDF6;
    border: 1px solid #E8DEC7;
    border-left: 3px solid #E8DEC7;
    border-radius: var(--r-xl);
  }
  .grid-row.is-filled { border-left-color: #9BA592; }

  .cell-item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    flex-wrap: nowrap;
  }
  .item-name { font-size: 14.5px; }

  /* Required moves into a pill beside the name; the desktop column goes. */
  .cell-req { display: none; }
  .mobile-req {
    display: inline-block;
    flex: none;
    padding: 3px 10px;
    border-radius: var(--r-pill);
    border: 1px solid #E3D9C2;
    background: transparent;
    color: #A79B85;
    font-size: 10.5px;
    font-weight: 600;
    white-space: nowrap;
  }
  .mobile-req.is-calc { background: #EDE1C8; border-color: transparent; color: #7A5B33; }

  /* The prototype reads item, derivation, inputs, need, observation. The
     desktop column order is different, so it is set explicitly here rather
     than left to the order the markup happens to be in. */
  .cell-item { order: 1; }
  .cell-deriv { order: 2; display: block; margin-top: 2px; font-size: 11px; }
  .onhand-group { order: 3; display: flex; gap: 8px; margin-top: 10px; }
  .cell-need { order: 4; }
  .cell-obs { order: 5; }

  .cell-onhand { flex: 1; min-width: 0; display: block; text-align: left; }
  .unit-label {
    display: block;
    margin-bottom: 4px;
    font-size: 9.5px;
    letter-spacing: 1px;
    color: #A79B85;
    font-weight: 600;
  }
  .on-hand {
    padding: 12px;
    font-size: 15px;
    text-align: left;
    border-radius: var(--r-lg);
    border-color: #D8CDB4;
  }

  .cell-need { display: block; margin-top: 8px; font-size: 13px; text-align: left; }
  .cell-need .is-dash { display: none; }

  .cell-obs { display: block; }
  .observation { display: none; }
  .observation-mobile {
    display: block;
    width: 100%;
    min-height: 56px;
    margin-top: 10px;
    padding: 10px 12px;
    font-family: inherit;
    font-size: 13.5px;
    line-height: 1.5;
    color: #241B12;
    background: #FBF3E2;
    border: 1px solid #DCC69E;
    border-radius: var(--r-lg);
    outline: none;
    resize: vertical;
  }
  .observation-mobile[hidden] { display: none; }
  .observation-toggle {
    display: inline-block;
    margin-top: 8px;
    padding: 8px 12px;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    color: #54281A;
    background: transparent;
    border: 1px dashed #C9BCA0;
    border-radius: var(--r-lg);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  .additions-card { padding: 0; background: none; border: none; }
  .additions-empty { display: none; }
  .additions-hint { display: block; margin: 4px 0 0; font-size: 11.5px; color: #8A7E68; }
  .addition-add { display: none; }

  .additions li {
    gap: 10px;
    margin-top: 8px;
    padding: 12px 14px;
    background: #FFFDF6;
    border: 1px solid #E8DEC7;
    border-left: 3px solid #B58A4C;
    border-radius: var(--r-lg);
    font-size: 14px;
    line-height: 1.4;
  }
  .addition-mark { display: none; }
  .addition-remove { font-size: 16px; padding: 4px 8px; }

  .supply-sticky { display: block; }

  /* Room to scroll the last card clear of the sticky bar. */
  .supply-page { padding-bottom: 110px; }
  .supply-sticky {
    margin: 0 calc(var(--gutter) * -1);
    padding: 12px 16px 26px;
  }
}

/* ---------------------------------------------------------------------------
   People
   --------------------------------------------------------------------------- */

.appbar-nav { margin-right: auto; margin-left: 22px; display: flex; gap: 16px; }
.appbar-nav a {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
}
.appbar-nav a:hover { color: var(--rust); }

.people { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 8px; }

.person {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.3fr) auto;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
}
/* Greyed, not hidden. They are still part of the record. */
.person.is-inactive { opacity: 0.62; }

.person-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.person-name { font-size: 14px; font-weight: 500; color: var(--text); }
.person-email {
  font-size: 12px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
}

.person-state { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.person-detail { font-size: 11.5px; color: var(--text-muted); }

.state-pill {
  align-self: start;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 600;
}
.state-pill.is-on { background: #DDE3D6; color: #3E4A3C; }
.state-pill.is-off { border: 1px dashed var(--border-strong); color: var(--text-faint); }
.state-pill.is-pending { background: #EDDFC3; color: #6B4A23; }

.person-actions { display: flex; justify-content: flex-end; }
.person-actions .button-ghost,
.person-actions .button-danger-ghost { width: auto; min-height: 40px; }
.person-you { font-size: 11.5px; color: var(--text-faint); }

.people-note { margin: 0 0 10px; }
.people-note[data-error] { color: var(--rust); font-weight: 500; }

@media (max-width: 640px) {
  .person { grid-template-columns: 1fr; gap: 10px; }
  .person-actions { justify-content: flex-start; }
  .person-actions .button-ghost,
  .person-actions .button-danger-ghost { min-height: 44px; }
  .appbar-nav { margin-left: 12px; }
}

.invite-card { margin-bottom: 20px; }
.invite-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) auto;
  align-items: end;
  gap: 12px;
}
.invite-form .field { margin: 0; }
.invite-form .button-primary { width: auto; margin: 0; min-height: 40px; }
.invite-result { margin: 12px 0 0; word-break: break-all; }
.invite-result.is-error { color: var(--rust); font-weight: 500; }

@media (max-width: 640px) {
  .invite-form { grid-template-columns: 1fr; }
  .invite-form .button-primary { width: 100%; min-height: 44px; }
}

/* The invite and reset pages stand alone — no app bar, no navigation. */
.auth-page { max-width: 460px; padding-top: 64px; }
.auth-card { padding: 28px; }
.auth-title { margin: 0 0 4px; font-size: 20px; font-weight: 400; }
.auth-org { font-size: 10px; letter-spacing: 2.5px; color: var(--text-muted); margin-left: 6px; }

.login-forgot { margin: 12px 0 0; text-align: center; }
.person-actions { gap: 8px; }
