/* holmesre.com — Layer 2: BASE
   Reset, element defaults, typography roles, layout primitives, buttons, motion primitives.
   Uses tokens only. Knows nothing about a header, a tile, or a listing.
   v7: section headings are sentence case and left-aligned against a plat hairline; a
   monospace role carries every figure, label and source on the site. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: var(--weight-body) var(--fs-body)/var(--lh-body) var(--font-body);
  -webkit-font-smoothing: antialiased;
}
img, picture, video, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
[hidden] { display: none !important; }
dl, dd, figure, blockquote { margin: 0; }
ul[role="list"], ol[role="list"] { list-style: none; margin: 0; padding: 0; }

/* ---- typography roles (class = role, never = size) ---- */
/* display-1 is the only caps display left: the hero name over the photograph. */
.display-1 { font: var(--weight-display) var(--fs-display-1)/var(--lh-display) var(--font-display); letter-spacing: var(--track-display-wide); text-transform: uppercase; margin: 0; }
/* display-2 is sentence case in v7. A section title is a line of a legal description,
   not a banner: it sets flush left and the copy under it hangs off the same edge. */
.display-2 { font: var(--weight-display) var(--fs-display-2)/var(--lh-tight) var(--font-display); letter-spacing: var(--track-display); margin: 0 0 var(--s-4); text-wrap: balance; }
.display-3 { font: var(--weight-display) var(--fs-display-3)/1.25 var(--font-display); font-style: italic; letter-spacing: .04em; margin: 0; text-wrap: balance; }
.eyebrow  { font: var(--weight-body) var(--fs-label)/1.4 var(--font-body); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-muted); margin: 0 0 var(--s-3); }
.lede     { font-size: var(--fs-lede); color: var(--ink-muted); max-width: var(--measure); margin: 0; }
.small    { font-size: var(--fs-small); }
.caption  { font-size: var(--fs-caption); color: var(--ink-muted); }
.label    { font: var(--weight-body) var(--fs-label-small)/1.6 var(--font-body); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-muted); }
.micro    { font: var(--weight-body) var(--fs-micro)/1.4 var(--font-body); letter-spacing: .14em; text-transform: uppercase; }
.prose p  { color: var(--ink-muted); max-width: 34em; margin: 0 0 var(--s-4); }
.on-inverse { color: var(--ink-on-inverse); }
.on-inverse .eyebrow { color: var(--accent-on-inverse); }
.on-inverse .lede, .on-inverse .prose p { color: var(--ink-on-inverse-muted); }

/* ---- the appraiser's hand: one monospace role, four sizes ----
   Figures, dates, prices, acres and sources all set in the same face. This is the
   site's decoration: he is paid to be exact, so the exact things get their own type. */
.num      { font-family: var(--font-mono); font-weight: var(--weight-mono); font-variant-numeric: tabular-nums; letter-spacing: var(--track-mono); }
.num-lg   { font: var(--weight-mono) var(--fs-figure)/1 var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.num-label{ font: var(--weight-mono) var(--fs-label-small)/1.5 var(--font-mono); letter-spacing: var(--track-mono-label); text-transform: uppercase; color: var(--ink-muted); }
.num-src  { font: var(--weight-mono) var(--fs-micro)/1.5 var(--font-mono); letter-spacing: .1em; color: var(--ink-quiet); }
.num-src a { color: inherit; text-decoration-color: var(--line); text-underline-offset: 2px; }
.num-src a:hover { color: var(--accent-ink); }

/* ---- layout primitives ---- */
.wrap   { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
@media (max-width: 760px) { .wrap { padding-inline: var(--gutter-mobile); } }
.section { padding-block: var(--section-y); }
.section-tight { padding-block: var(--section-y-tight); }
.section-alt { background: var(--bg-alt); }
.section-inverse { background: var(--bg-inverse); color: var(--ink-on-inverse); }
.center { text-align: center; }
.stack > * + * { margin-top: var(--s-4); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap-tiles); }
@media (max-width: 860px) { .grid-3 { grid-template-columns: 1fr; } }
.row-between { display: flex; justify-content: space-between; align-items: center; gap: var(--s-4); flex-wrap: wrap; }
.scroll-x { overflow-x: auto; }

/* Skip link: off-screen until focused, then the first thing in the tab order. */
.skip { position: absolute; left: -9999px; top: 0; z-index: calc(var(--z-overlay) + 1); background: var(--bg); color: var(--ink); padding: var(--s-3) var(--s-5); text-decoration: none; }
.skip:focus { left: 0; }

/* ---- the plat hairline ----
   A section head sets against a hairline running down its left edge, the way a
   description hangs off the margin of a plat. Copy is inset from the rule, never on it. */
.head { border-left: var(--border) solid var(--line-hair); padding-left: var(--rule-inset); max-width: var(--measure); }
.head .eyebrow { color: var(--accent-ink); }
.head--inverse { border-left-color: var(--line-on-inverse); }
.head--inverse .eyebrow { color: var(--accent-on-inverse); }

/* ---- buttons: one shape, three fills ---- */
.btn {
  display: inline-block; cursor: pointer; text-decoration: none; background: transparent;
  font: var(--weight-body-strong) var(--fs-label)/1 var(--font-body);
  letter-spacing: var(--track-button); text-transform: uppercase;
  padding: 15px 30px; border: var(--border) solid currentColor; border-radius: var(--radius);
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}
.btn-light { color: var(--white); border-color: var(--white); }
.btn-light:hover { background: rgba(255,255,255,.12); }
.btn-dark { color: var(--ink); border-color: var(--ink); }
.btn-dark:hover { background: var(--ink); color: var(--bg); }
.btn-accent { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-accent:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-bare { border: 0; padding: 0; background: transparent; }

/* ---- form controls used on dark grounds ---- */
.input-inverse { font: var(--fs-small) var(--font-body); padding: 14px; color: var(--white); background: rgba(255,255,255,.08); border: var(--border) solid rgba(255,255,255,.6); border-radius: var(--radius); }
.input-inverse::placeholder { color: var(--ink-on-inverse-muted); }

/* ---- motion primitives ---- */
/* Reveal: visible at rest. Only when JS is present and motion allowed does .pre park it low. */
.rv { transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease); }
@media (prefers-reduced-motion: no-preference) { .js .rv.pre { opacity: 0; transform: translateY(var(--reveal-offset)); } }
/* Drift: slow Ken Burns for a hero image. Stand-in for a muted drone loop. */
.drift { transform-origin: 55% 45%; animation: drift var(--dur-hero-drift) ease-in-out infinite alternate; }
@keyframes drift { from { transform: scale(1); } to { transform: scale(var(--hero-drift-scale)); } }
/* Zoom-on-hover for photo tiles */
.zoom img { transition: transform var(--dur-slow) var(--ease); }
.zoom:hover img { transform: scale(var(--tile-zoom)); }
@media (prefers-reduced-motion: reduce) { .drift { animation: none; } .zoom img { transition: none; } .rv { transition: none; } }
