/* ============================================================
   Base — reset, element defaults, focus, utilities

   The brand face is linked from each document's <head>, not
   @import-ed here. An @import cannot start until this file has
   been fetched and parsed, so the font request sat third in a
   chain: base.css, then the Google stylesheet, then the woff2.
   A <link> in the head starts it in parallel with the CSS.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color-scheme: light;
  background: var(--canvas);
}

body {
  min-width: 320px;
  font-family: var(--font-sans);
  font-size: var(--t-base);
  line-height: var(--lh-base);
  color: var(--ink);
  background: var(--canvas);
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  color: var(--ink);
}

p { line-height: var(--lh-base); }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
img, svg { display: block; max-width: 100%; }
svg { flex-shrink: 0; }
table { border-collapse: collapse; width: 100%; }
th { text-align: left; font-weight: var(--fw-semibold); }

button, input, select, textarea { font: inherit; color: inherit; }
button {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: inherit;
  -webkit-tap-highlight-color: transparent;
}
input::placeholder, textarea::placeholder { color: var(--ink-muted); }

:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}
/* Inside the dark rail the ring has to lift off the slate instead
   of sinking into it. */
.shell :focus-visible { outline-color: var(--focus-ondark); }

::selection { background: var(--accent-soft); color: var(--ink); }

/* ---- Scrollbars ---- */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: var(--r-pill);
  border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); background-clip: content-box; }
.shell *::-webkit-scrollbar-thumb { background: var(--shell-line); background-clip: content-box; }

/* ============================================================
   View transitions

   Switching between the list, the calendar and the map morphs the
   open houses from one shape into another rather than cutting, so
   you keep hold of the one you were looking at.
   ============================================================ */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 240ms;
  animation-timing-function: var(--ease-out);
}

/* ============================================================
   Utilities
   ============================================================ */

.tnum { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.inline { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.stack { display: flex; flex-direction: column; gap: var(--s3); }
.right { margin-left: auto; }
.grow { flex: 1 1 auto; min-width: 0; }

.overline {
  font-size: var(--t-micro);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-over);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.muted { color: var(--ink-muted); }
.small { font-size: var(--t-sm); }
.num { font-variant-numeric: tabular-nums; }

/* ============================================================
   Motion budget

   Entrances animate transform only, never opacity from zero. An
   entrance with `from { opacity: 0 }` and a filled animation hides
   its content permanently wherever the animation clock does not
   advance: a throttled tab, low power mode, some assistive
   tooling. That failure blanked seven calendar blocks here once.
   ============================================================ */
@keyframes rise-in { from { transform: translateY(8px); } to { transform: translateY(0); } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes menu-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes pop-in { from { transform: scale(0.9); } to { transform: scale(1); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
