/* base.css — reset, custom properties, typography, layout primitives.
   Shared by every view (the valuation result, the dev/district/KB pages):
   nothing in here is specific to one screen. See result.css for the
   estimate card/range plot/adjustments/comparables, and pages.css for the
   development, district and KB views.

   Palette: cool off-white ground, deep slate ink, one instrument-blue
   primary. --amber is reserved EXCLUSIVELY for caveats and confidence (see
   result.css's .cav-warning/.conf-badge and .prop-estimate.conf-medium) —
   if something below reads as amber, that is a bug. Warnings that are not
   about the estimate's trustworthiness (a build error, a preview banner)
   use --rose instead, so amber keeps one meaning everywhere it appears. */

:root {
  color-scheme: light;
  --bg: #f6f7fb;
  --surface: #ffffff;
  --surface-hover: #eef0f6;
  --border: #dde1ea;
  --border-strong: #c2c8d6;
  --text: #1b2333;
  --text-muted: #5b6478;
  --accent: #2f5fdb;
  --accent-soft: #e8edfc;
  --accent2: #2f5fdb;
  --green: #0f8a5f;
  --amber: #b7791f;
  --rose: #c8384f;
  --rose-soft: #fdecef;
  --sky: #2f5fdb;
  --track: #eceff5;
  --radius: 12px;
  --shadow: 0 1px 3px rgba(20,26,43,.08), 0 1px 2px rgba(20,26,43,.04);
  --shadow-hover: 0 6px 20px rgba(20,26,43,.10);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ---- Shell ---- */
.wrap { max-width: 62rem; margin: 0 auto; padding: 1.25rem 1.1rem 3rem; }

.view-header { margin-bottom: 2rem; }
.view-header h1 { font-size: clamp(1.6rem, 3vw, 2.1rem); font-weight: 700; color: var(--text); }
.subtitle { color: var(--text-muted); font-size: .95rem; margin-top: .35rem; }

.section-note { font-size: .8rem; color: var(--text-muted); margin: -.3rem 0 .8rem; line-height: 1.5; }
.section-note b { color: var(--text); }

.prop-h3 { font-size: .95rem; margin: 1.25rem 0 .5rem; }
/* Muted one-line caption, used both beside the estimate (evidence window,
   lease note) and on the dev/district pages (sale count, "no data"). */
.prop-why { font-size: .8rem; color: var(--text-muted); margin-top: .5rem; }

.prop-about-open { margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid var(--border); }
/* Not a caveat about the estimate — a build/deploy status. Kept off amber
   on purpose (see the file banner above) so amber stays a single, reliable
   signal wherever it appears. */
.build-badge { display: inline-block; font-size: .72rem; padding: .15rem .5rem; border-radius: 6px;
  background: var(--surface-hover); color: var(--text-muted); margin-top: .5rem; }
.build-badge.preview, .build-badge.stale { background: var(--rose-soft); color: #9c2942; }

/* property.js's showFailure() AND pages.js's renderPageFailure() both write
   this exact markup, so the two read identically regardless of which
   container they land in. A lookup failure, not a data caveat — rose, not
   amber (see file banner above). */
.prop-error { background: var(--rose-soft); color: #9c2942; padding: .9rem 1.1rem; border-radius: var(--radius); font-size: .9rem; }

/* A loading state shared by every lookup entry point (postal, block, dev
   page, district page) — one visual so "something is happening" never looks
   different depending on which fetch is in flight. Do NOT use
   class="muted" for a loading state — no rule anywhere matches it, and it
   renders as unstyled body text with no signal that anything is happening. */
.prop-loading {
  display: flex; align-items: center; gap: .6rem;
  padding: 1rem 1.1rem; margin-top: .5rem;
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: var(--radius); background: var(--surface);
  color: var(--text); font-size: .95rem;
}
.prop-loading::before {
  content: ''; flex-shrink: 0;
  width: 1rem; height: 1rem; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--accent);
  animation: prop-spin .7s linear infinite;
}
@keyframes prop-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .prop-loading::before { animation: none; border-top-color: var(--border); }
}

/* Generic table primitive: property.js's own adjustments/comparables
   tables, and pages.js's per-project sale table, all share it. Its own
   scroll container because the comparables table's 8 columns do not fit a
   380px screen — the alternative is the whole page scrolling sideways,
   which moves the layout instead of the one thing that is too wide. Every
   column here is a number in a column, hence tabular-nums throughout. */
.year-tbl { display: block; overflow-x: auto; width: 100%; border-collapse: collapse; font-size: .85rem; }
.year-tbl th, .year-tbl td { text-align: right; padding: .4rem .6rem; border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.year-tbl th:first-child, .year-tbl td:first-child { text-align: left; }
.year-tbl th { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }

/* Required by the Singapore Open Data Licence wherever URA, HDB or
   data.gov.sg data is shown — conspicuous, names the dataset and source,
   states the access date, links to the licence. Shared by attribution.js's
   hdbAttribution()/privateAttribution()/priceIndexAttribution(), called
   from both the result view (property.js) and the dev/district pages
   (pages.js). */
.prop-attrib {
  margin-top: 1.25rem; padding-top: .75rem; border-top: 1px solid var(--border);
  font-size: .85rem; color: var(--text);
}
.prop-attrib a { color: var(--accent); }

/* The "this is an estimate, not a valuation" line attribution.js's
   valuationDisclaimer() prepends everywhere a number is shown. Sits with the
   number, not tucked in the footer — a disclaimer nobody reads protects
   nobody, and the point is that the reader understands what they are
   holding. */
.prop-disclaimer { font-size: .8rem; color: var(--text-muted); margin: .5rem 0 1.25rem;
  padding-left: .75rem; border-left: 2px solid var(--border); line-height: 1.5; }

/* ---- Footer ---- */
footer {
  padding: 2rem 0 0; margin-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--text-muted); font-size: .85rem;
}

.build-line { font-size: .78rem; margin-top: .3rem; }
.build-line.live  { color: var(--text-muted); }
.build-line.preview {
  color: #9c2942; font-weight: 600;
  background: var(--rose-soft); padding: .45rem .7rem;
  border-radius: 8px; display: inline-block;
}
.build-line a { color: inherit; text-decoration: underline; }
