/* app.css — houseinfo DM design system.
   Reskinned 2026-07-14 to "CALM COURIER" (DM/untitled.pen, direction A + A1):
   greige canvas #F4F3F1 + warm ink #1C1B1A, borderless white cards (radius 24,
   soft diffuse shadows), display = Inter Tight LIGHT (300) sentence case,
   body = Inter 400/500. Yellow #FFD200 means "houseinfo acts / live": the
   primary button (ALWAYS yellow with ink text — never black), search-go,
   live dots, the current tracker node. Selected chips = dark ink fill.
   NO black buttons anywhere (user rule). Serif italic (Instrument Serif) is
   reserved for marketing surfaces (login/landing) and never used in-app.
   Web idioms only: text back-links, in-flow cards/buttons, labeled actions.
   Single light theme. Variable/class names are unchanged from the previous
   systems so page-level styles keep working; only the values changed. */

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Inter+Tight:wght@300;400;500;600&display=swap");

:root {
  /* fonts — Inter body, Inter Tight display; split kept for compatibility */
  --font:       "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: "Inter Tight", "Inter", ui-sans-serif, system-ui, sans-serif;   /* display (LIGHT) */
  --font-data:  "Inter", ui-sans-serif, system-ui, sans-serif;   /* numbers (tabular) */

  /* surfaces — greige canvas, borderless white cards */
  --bg:#F4F3F1; --card:#FFFFFF; --card-2:#F0EEE9; --card-hover:#FAF9F7;
  --border:#E5E2DC; --border-strong:#D6D2C9;

  /* text — warm ink + greige ramp */
  --ink:#1C1B1A; --ink-2:#5A564F; --ink-3:#8A867F; --ink-4:#B7B2A9;

  /* yellow = "houseinfo acts / live" — always ink text/marks on yellow */
  --accent:#FFD200; --accent-soft:#FFF1B8; --accent-ink:#1C1B1A;
  --accent-glow:rgba(255,210,0,0.40);

  /* the single primary action = YELLOW (never black — user rule) */
  --action:#FFD200; --action-ink:#1C1B1A; --action-hover:#F2C700;

  /* merge-token highlight in letters (amber on pale yellow) */
  --variable:#8A6D00; --variable-soft:#FFF1B8;
  /* functional states — sparing */
  --warn:#B57F00; --warn-soft:#FCF3D7;
  --ok:#2E9E5B;   --ok-soft:#E7F5EC;
  --err:#E5484D;  --err-soft:#FCECEC;

  --radius:12px; --radius-sm:10px; --radius-lg:24px;
  --shadow-card:0 10px 30px rgba(0,0,0,0.07);
  --shadow-input:0 3px 8px rgba(0,0,0,0.06);
  --shadow-cta:0 10px 24px rgba(255,210,0,0.35);
  --shadow-glow:0 0 0 4px var(--accent-glow);
  --ease-out:cubic-bezier(0.22,1,0.36,1);
  --ease-spring:cubic-bezier(0.34,1.56,0.64,1);
  --bg-outer:#EDEBE7;   /* area outside the phone frame on desktop */
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font); font-size: 15px; line-height: 1.55; color: var(--ink);
  background: var(--bg-outer); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

/* numbers/prices align in columns */
[data-num], .num, .money { font-family: var(--font-data); font-variant-numeric: tabular-nums lining-nums; font-feature-settings: "tnum" 1, "lnum" 1; }

.phone {
  max-width: 440px; margin: 24px auto; min-height: calc(100vh - 48px);
  background: var(--bg);
  border-radius: 26px; overflow: hidden;
  box-shadow: 0 24px 70px rgba(0,0,0,0.18), 0 0 0 1px rgba(0,0,0,0.05);
  display: flex; flex-direction: column;
}
@media (max-width: 480px) { .phone { margin: 0; border-radius: 0; min-height: 100vh; box-shadow: none; } }

/* ── top bar ─────────────────────────────────────────────── */
.top { display: flex; align-items: center; gap: 12px; padding: 15px 18px 13px; border-bottom: 0; background: var(--bg); position: sticky; top: 0; z-index: 5; }
.brand { display: flex; align-items: center; gap: 8px; font-family: var(--font); font-weight: 600; letter-spacing: -0.01em; font-size: 16px; }
/* The canonical mark (owner, 2026-08-06): yellow square, ink "hi" — the same
   drawing as the landing nav and the favicon. The inverse ink-square "h" is
   RETIRED; see BRAND.html §1. */
.brand-mark { width: 26px; height: 26px; border-radius: 8px; background: var(--accent); display: grid; place-items: center; color: var(--accent-ink); font-size: 12px; font-weight: 600; }
.top-spacer { flex: 1; }
.suburb-pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); color: var(--ink-2); font-size: 12.5px; font-weight: 500; }
.suburb-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); border: 1px solid rgba(32,32,32,0.25); animation: pp-pulse 1.6s var(--ease-out) infinite; }
.avatar { width: 34px; height: 34px; border-radius: 50%; background: #E9E7E3; border: 0; color: var(--ink); display: grid; place-items: center; font-size: 12px; font-weight: 600; cursor: pointer; }
.iconbtn { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--border); background: var(--card); display: grid; place-items: center; cursor: pointer; color: var(--ink-2); }
.iconbtn:hover { border-color: var(--border-strong); color: var(--ink); }
.iconbtn svg, .brand svg, .searchbar svg, .mag svg { display: block; }
.iconbtn:empty { display: none; }   /* retired theme toggle mounts nothing */

.body { flex: 1; overflow-y: auto; padding: 18px 18px 44px; }
.greet { color: var(--ink-3); font-size: 13.5px; margin: 2px 0 4px; }
.greet b { color: var(--ink); font-weight: 600; }

/* ── type — display = Inter Tight LIGHT, sentence case ───── */
.serif-title { font-family: var(--font-serif); font-weight: 300; letter-spacing: -0.01em; line-height: 1.12; }
h1.page { font-family: var(--font-serif); font-weight: 300; font-size: 30px; letter-spacing: -0.02em; line-height: 1.15; margin: 6px 0 16px; }

.sec-label { display: flex; align-items: baseline; justify-content: space-between; font-family: var(--font); font-size: 12px; letter-spacing: 0; color: var(--ink-3); font-weight: 500; margin: 26px 4px 10px; }
.sec-label .more { color: var(--ink); cursor: pointer; letter-spacing: 0; text-transform: none; font-family: var(--font); font-size: 12.5px; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.sec-label .count { color: var(--ink-2); background: var(--card-2); border-radius: 999px; padding: 1px 8px; font-size: 11px; letter-spacing: 0; font-weight: 600; }

/* the Trust Rule primitive — every number cites its source + freshness */
.source-cap { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-data); font-size: 11px; font-weight: 500; letter-spacing: 0.01em; color: var(--ink-3); }
.source-cap b { color: var(--ink-2); font-weight: 600; }
.source-cap.fresh { color: var(--ink-2); } .source-cap.fresh b { color: var(--ink); }
.source-cap .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); border: 1px solid rgba(32,32,32,0.3); animation: pp-pulse 1.6s var(--ease-out) infinite; flex: none; }

.live-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px 4px 9px; border-radius: 999px; background: var(--card-2); border: 0; font-size: 12px; font-weight: 500; letter-spacing: 0; color: var(--ink); }
.live-badge .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); animation: pp-pulse 1.6s var(--ease-out) infinite; }

.card { background: var(--card); border: 0; border-radius: var(--radius-lg); box-shadow: var(--shadow-card); padding: 18px; }
.card.pad0 { padding: 0; overflow: hidden; }

/* rounded-pixel grid decoration (quantized gradient — see DESIGN.md).
   Rules: ONE per screen; empty/marketing/celebration surfaces only — never
   behind data or forms. Tint via classes (default yellow = action/brand,
   .grey = neutral chrome, .ok = Delivered/success only). Host element needs
   position:relative + overflow:hidden. */
.pxgrid { position: absolute; top: 0; right: 0; width: 232px; height: 232px; color: var(--accent); pointer-events: none; }
.pxgrid.grey { color: var(--ink); opacity: 0.5; }
.pxgrid.ok { color: var(--ok); opacity: 0.75; }

/* ── buttons — the primary action is YELLOW (never black) ── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 48px; padding: 0 18px; border-radius: var(--radius); border: 1px solid transparent; font-family: var(--font); font-weight: 600; font-size: 14.5px; letter-spacing: 0.005em; cursor: pointer; transition: transform var(--ease-spring) 120ms, background 120ms var(--ease-out), border-color 120ms, box-shadow 120ms; }
.btn:active { transform: scale(0.97); }
.btn.block { width: 100%; }
.btn-primary { background: var(--action); color: var(--action-ink); }
.btn-primary:hover { background: var(--action-hover); box-shadow: var(--shadow-cta); }
.btn-ghost { background: var(--card); color: var(--ink); border-color: transparent; box-shadow: var(--shadow-input); font-weight: 500; }
.btn-ghost:hover { background: var(--card-hover); box-shadow: var(--shadow-card); }
.btn[disabled] { opacity: 0.45; cursor: default; box-shadow: none; }
.spinner { width: 15px; height: 15px; border: 2px solid rgba(28,27,26,0.22); border-top-color: var(--action-ink); border-radius: 50%; animation: spin 0.7s linear infinite; }
.spin-ink { border-color: var(--border-strong); border-top-color: var(--ink); }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── status pills / chips ────────────────────────────────── */
.status-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; letter-spacing: 0; padding: 5px 11px; border-radius: 999px; background: var(--card-2); color: var(--ink); }
.status-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.status-pill.live .dot { animation: pp-pulse 1.6s var(--ease-out) infinite; }
.status-pill.ok { background: var(--ok-soft); color: var(--ok); } .status-pill.ok .dot { background: var(--ok); }
.status-pill.warn { background: var(--warn-soft); color: var(--warn); } .status-pill.warn .dot { background: var(--warn); }

.chip { display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 15px; border: 0; box-shadow: var(--shadow-input); border-radius: 999px; background: var(--card); font-family: var(--font); font-size: 13px; font-weight: 500; color: var(--ink-3); cursor: pointer; transition: background 120ms var(--ease-out), box-shadow 120ms, color 120ms; user-select: none; }
.chip:hover { color: var(--ink-2); box-shadow: var(--shadow-card); }
.chip.on { background: var(--ink); box-shadow: none; color: #FFFFFF; font-weight: 600; }
.chip .n { opacity: 0.7; font-family: var(--font-data); font-variant-numeric: tabular-nums; }
.chips { display: flex; gap: 8px; flex-wrap: wrap; }

/* ── inputs ──────────────────────────────────────────────── */
.field { display: flex; align-items: center; gap: 8px; padding: 0 14px; border-radius: var(--radius); background: var(--card); border: 1px solid var(--border); transition: box-shadow 120ms, border-color 120ms; }
.field:focus-within { border-color: var(--ink); box-shadow: var(--shadow-glow); }
.field input, .field select { flex: 1; border: 0; background: transparent; outline: none; padding: 13px 0; font-size: 15px; color: var(--ink); }
select.plain, .range input, .mockcard input { color: var(--ink); }
.searchbar { display: flex; align-items: center; gap: 10px; padding: 15px 10px 15px 20px; border-radius: 999px; background: var(--card); border: 0; box-shadow: var(--shadow-card); cursor: text; transition: box-shadow 120ms; }
.searchbar:focus-within { box-shadow: var(--shadow-card), var(--shadow-glow); }
.searchbar .mag { color: var(--ink-4); display: inline-flex; }
.searchbar input { flex: 1; border: 0; background: transparent; outline: none; font-size: 15px; color: var(--ink); }
.searchbar input::placeholder, .field input::placeholder { color: var(--ink-4); }

.money { font-family: var(--font-data); font-weight: 700; letter-spacing: -0.01em; }
.money .nzd { font-family: var(--font); font-size: 0.5em; color: var(--ink-3); font-weight: 600; margin-left: 3px; }
.pulse-accent { animation: pulseAccent 260ms ease; }
@keyframes pulseAccent { 0% { color: var(--variable); } 100% { color: var(--ink); } }

.banner { display: none; align-items: flex-start; gap: 8px; font-size: 13px; padding: 10px 12px; border-radius: var(--radius-sm); }
.banner:empty { display: none !important; }
.banner.err { display: flex; background: var(--err-soft); color: var(--err); }
.banner.info { display: flex; background: var(--accent-soft); color: var(--ink-2); }
.banner.ok { display: flex; background: var(--ok-soft); color: var(--ok); }
.banner.warn { display: flex; background: var(--warn-soft); color: var(--warn); }
.banner a { text-decoration: underline; font-weight: 600; color: var(--ink); }

/* ── fulfilment tracker — done=ink dot, current=yellow ring pulse ── */
.track { position: relative; display: flex; justify-content: space-between; margin: 8px 6px 0; }
.track::before { content: ''; position: absolute; top: 7px; left: 8px; right: 8px; height: 2px; background: #EBE8E2; border-radius: 999px; }
.track .fill { position: absolute; top: 7px; left: 8px; height: 2px; background: var(--border-strong); border-radius: 999px; z-index: 1; transition: width 500ms var(--ease-out); }
.tnode { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 6px; flex: 1; }
.tnode .k { width: 16px; height: 16px; border-radius: 50%; background: var(--card); border: 3px solid #DDD9D1; }
.tnode.done .k { background: var(--ink); border-color: var(--ink); }
.tnode.cur .k { background: var(--card); border: 4px solid var(--accent); animation: pp-pulse 1.6s var(--ease-out) infinite; }
.tnode .l { font-family: var(--font-data); font-size: 9.5px; font-weight: 500; color: var(--ink-4); text-align: center; }
.tnode.done .l, .tnode.cur .l { color: var(--ink-2); }

.muted { color: var(--ink-3); }
.hide { display: none !important; }
.center { text-align: center; }
.row { display: flex; align-items: center; justify-content: space-between; }
.divider { height: 1px; background: var(--border); margin: 14px 0; }
.kv { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 2px solid var(--card-2); font-size: 13.5px; }
.kv:last-child { border-bottom: none; }
.kv .k { color: var(--ink-3); flex: none; }
.kv .v { font-weight: 600; text-align: right; min-width: 0; overflow-wrap: anywhere; }

.lead { display: flex; align-items: center; gap: 12px; padding: 13px 15px; border-bottom: 2px solid var(--card-2); }
.lead:last-child { border-bottom: none; }
.lead-av { width: 34px; height: 34px; border-radius: 50%; background: var(--card-2); border: 0; color: var(--ink); display: grid; place-items: center; font-family: var(--font-data); font-size: 12px; font-weight: 600; flex-shrink: 0; }
.lead-body { flex: 1; min-width: 0; }
.lead-name { font-weight: 600; font-size: 14px; }
.lead-ctx { color: var(--ink-3); font-size: 12.5px; margin-top: 1px; }

.overlay { position: fixed; inset: 0; background: rgba(32,32,32,0.45); display: grid; place-items: center; z-index: 50; opacity: 0; pointer-events: none; transition: opacity 160ms; }
.overlay.show { opacity: 1; pointer-events: auto; }
.sheet { background: var(--card); border: 1px solid var(--border); border-radius: 18px; width: min(400px, 92vw); max-height: 86vh; overflow-y: auto; box-shadow: var(--shadow-card); }

/* avatar dropdown (mountUserMenu in app.js) */
.menu { position: absolute; top: 52px; right: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-card); padding: 6px; z-index: 20; min-width: 178px; }
.menu button { display: block; width: 100%; text-align: left; padding: 9px 12px; border: 0; background: transparent; border-radius: var(--radius-sm); font-size: 13.5px; font-weight: 500; cursor: pointer; }
.menu button:hover { background: var(--card-2); }
.menu .menu-div { height: 1px; background: var(--border); margin: 5px 4px; }

/* the LIVE pulse — yellow ring on live dots / current tracker node */
@keyframes pp-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(255,210,0,0.55); }
  70%  { box-shadow: 0 0 0 7px rgba(255,210,0,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,210,0,0); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}
::selection { background: var(--accent); color: var(--ink); }
