/*
  Who's Watching West Hartford: design system
  Aesthetic: civic-archival. A public-records project or a serious local
  newsroom explainer, not a campaign site. Light theme only.

  This file is the shared reference for every later page. Reuse the
  component classes documented in each section below rather than inventing
  new ones.
*/

/* ---------------------------------------------------------------------
   Tokens
--------------------------------------------------------------------- */
:root {
  /* color */
  --color-paper: #faf8f5;
  --color-paper-raised: #ffffff;
  --color-ink: #1a1a1a;
  --color-ink-muted: #4a4540;
  --color-gray-warm: #6b6459;
  --color-gray-warm-light: #e8e3db;
  --color-rule: #d8d1c4;
  --color-accent: #2d4a5c;
  --color-accent-dark: #1f3542;
  --color-data: #9c3d2e;
  --color-focus: #2d4a5c;
  --color-paper-tint: #fcfaf6;

  /* type */
  --font-display: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-body: "Source Sans 3", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;

  /* rhythm */
  --measure: 68ch;
  --line-body: 1.65;
  --radius: 4px;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --rail-width: 18rem;
  --shell-max: 72rem;
}

/* ---------------------------------------------------------------------
   Reset & base
--------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: var(--line-body);
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }

a {
  color: var(--color-accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

a:hover { color: var(--color-accent-dark); }

:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  color: var(--color-ink);
  margin-top: 0;
}

h1 { font-size: clamp(1.9rem, 4vw + 1rem, 2.9rem); }
h2 { font-size: clamp(1.4rem, 2vw + 1rem, 1.9rem); margin-top: var(--space-4); }
h3 { font-size: 1.25rem; margin-top: var(--space-3); }

p { margin: 0 0 var(--space-2); }

ul, ol { padding-left: 1.3em; }

hr {
  border: none;
  border-top: 1px solid var(--color-rule);
  margin: var(--space-4) 0;
}

table {
  border-collapse: collapse;
  width: 100%;
}

th, td {
  text-align: left;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--color-rule);
  vertical-align: top;
}

th { font-family: var(--font-body); font-weight: 600; }

/* wide elements (tables, embedded map) scroll inside their own box, never
   the page body. On the map page these sit directly in main#content,
   outside .page, so they are free to use the full shell width (up to
   --shell-max) instead of being boxed inside the --measure reading
   column; the padding on main#content keeps them off the viewport edge
   at every width, including mobile, where they naturally fill the full
   measure like everything else. */
.table-scroll, .map-frame {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--color-rule);
  border-radius: var(--radius);
  width: min(100%, calc(var(--measure) + 8rem));
  max-width: none;
  margin: var(--space-3) auto;
}

/* the caption belongs to the frame above it, so it takes the same width */
.map-legend-note {
  max-width: min(100%, calc(var(--measure) + 8rem));
  margin-left: auto;
  margin-right: auto;
}

/* five columns crushed into 550px is not a table; give it a real
   minimum so .table-scroll's scroll is genuine */
.table-scroll table {
  min-width: 44rem;
}

@media (min-width: 1100px) {
  .table-scroll, .map-frame { width: 100%; }
  .map-legend-note { max-width: none; }
}

/* ---------------------------------------------------------------------
   Skip link
--------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--color-ink);
  color: #fff;
  padding: 0.75em 1.25em;
  border-radius: 0 0 var(--radius) 0;
}

.skip-link:focus {
  left: 0;
}

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

/* ---------------------------------------------------------------------
   Site header / nav
   Classes: .site-header, .site-header__inner, .site-header__wordmark,
            .site-header__wordmark-line, .site-nav, .site-nav__list,
            .site-nav__link
--------------------------------------------------------------------- */
.site-header {
  background: var(--color-paper-raised);
  border-bottom: 1px solid var(--color-rule);
}

.site-header__inner {
  max-width: 72rem;
  margin: 0 auto;
  padding: var(--space-2) var(--space-3);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
}

.site-header__wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--color-ink);
  text-decoration: none;
  line-height: 1.15;
}

.site-header__wordmark-line {
  display: block;
  color: var(--color-accent);
}

.site-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
}

.site-nav__link {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--color-ink-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  padding-bottom: 2px;
}

.site-nav__link:hover {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}

.site-nav__link.is-current {
  color: var(--color-accent);
  font-weight: 700;
  border-bottom-color: var(--color-accent);
}

/* ---------------------------------------------------------------------
   Page / home wrappers

   The reading column never grows past --measure (roughly 70 characters):
   widening it further would hurt readability, not help it. What changes at
   desktop widths is where the *rest* of the shell puts its width. A page
   with a Sources section (every content page but designed to scale to any
   future one) becomes a two-column shell above 1100px: the reading column
   holds its measure on the left, and the Sources list, the single most
   important piece of apparatus on this site, sits in a dedicated rail
   beside it rather than trailing far below a wide empty margin. The whole
   shell is centered, so there is no more "column pinned left, void on the
   right." Below 1100px, and on the map page (whose own wide elements are
   handled separately below), the shell is a single centered column.
--------------------------------------------------------------------- */
main#content {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: var(--space-4) var(--space-3) var(--space-5);
}

.page, .home {
  max-width: var(--measure);
  width: 100%;
  margin: 0 auto;
  container-type: inline-size;
  container-name: reading;
}

@media (min-width: 1100px) {
  main#content.has-sources.template-page,
  main#content.has-sources.template-home {
    display: grid;
    grid-template-columns: minmax(0, var(--measure)) minmax(15rem, var(--rail-width));
    justify-content: center;
    align-items: start;
    column-gap: var(--space-4);
  }

  main#content.has-sources.template-page > .sources,
  main#content.has-sources.template-home > .sources {
    margin-top: 0;
  }
}

.page-header { margin-bottom: var(--space-4); }

.page-description {
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--color-ink-muted);
}

/* ---------------------------------------------------------------------
   Hero
   Classes: .hero, .hero__statement, .hero__lead
--------------------------------------------------------------------- */
.hero {
  margin-bottom: var(--space-4);
  max-width: var(--measure);
}

.hero__statement {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.5vw + 0.8rem, 1.7rem);
  font-weight: 600;
  color: var(--color-ink);
}

.hero__lead {
  font-size: 1.05rem;
  color: var(--color-ink-muted);
}

/* ---------------------------------------------------------------------
   Stat tile
   Classes: .stat-tile-row, .stat-tile, .stat-tile__number,
            .stat-tile__label, .stat-tile__cite

   Two single-figure tiles sit side by side. A tile carrying a comparison
   (35 reported against 26 mapped) is not a third peer: it gets its own
   full-width band, so the discrepancy reads as a comparison instead of
   as a compressed tile with wrapping numbers. Marked up with
   .stat-tile--split.
--------------------------------------------------------------------- */
.stat-tile-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  margin: var(--space-4) 0;
  max-width: none;
}

@container reading (min-width: 26rem) {
  .stat-tile-row {
    grid-template-columns: repeat(2, 1fr);
  }
  .stat-tile--split {
    grid-column: 1 / -1;
  }
}

.stat-tile {
  background: var(--color-paper-raised);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius);
  padding: var(--space-3);
}

.stat-tile__number,
.stat-figure__number {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw + 1rem, 2.75rem);
  font-weight: 700;
  color: var(--color-data);
  line-height: 1;
  margin: 0 0 0.4rem;
  font-variant-numeric: tabular-nums;
}

/* a single figure should never break across lines; the two-up row gives
   even "420,645" and "$500,000" room to sit on one */
.stat-tile__number { white-space: nowrap; }

.stat-tile__label,
.stat-figure__label {
  font-size: 0.95rem;
  color: var(--color-ink-muted);
  margin: 0;
  text-wrap: pretty;
}

.stat-tile__cite {
  margin-left: 0.15em;
}

/* the comparison band */
.stat-tile--split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}

.stat-tile__versus {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1rem;
  color: var(--color-gray-warm);
  margin: 0;
  border-top: 1px solid var(--color-rule);
  padding-top: 0.6rem;
}

@container reading (min-width: 26rem) {
  .stat-tile--split {
    grid-template-columns: 1fr auto 1fr;
    column-gap: var(--space-3);
    align-items: start;
  }
  .stat-tile__versus {
    align-self: stretch;
    border-top: 0;
    border-left: 1px solid var(--color-rule);
    padding: 0.75rem 0 0 var(--space-3);
  }
}

/* ---------------------------------------------------------------------
   Document card
   Classes: .doc-card, .doc-card__badge, .doc-card__body, .doc-card__title,
            .doc-card__summary, .doc-card__meta, .doc-card__link
--------------------------------------------------------------------- */
.doc-card {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  padding: var(--space-2);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius);
  background: var(--color-paper-raised);
  margin-bottom: var(--space-2);
  max-width: none;
}

.doc-card__badge {
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius);
  background: var(--color-accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.doc-card__title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 0.2rem;
}

.doc-card__summary {
  margin: 0 0 0.35rem;
  color: var(--color-ink-muted);
}

.doc-card__meta {
  font-size: 0.85rem;
  color: var(--color-gray-warm);
  margin: 0;
}

/* ---------------------------------------------------------------------
   Timeline
   Classes: .timeline, .timeline__entry, .timeline__date, .timeline__body

   Restrained, dating only. The date is the thing readers scan, so it
   becomes the entry's own serif line, with a hairline running out to the
   margin: a docket, which is what this page is. The spine drops to a
   hairline and the filled dot becomes a small open square sitting on it,
   which reads as archival rather than as a bulleted list. Entries are
   separated by a rule, so the page has a rhythm at a glance.

   .timeline__points is for the rare entry that records a whole meeting:
   one line per exchange, the speaker's name picked out in .timeline__who.
--------------------------------------------------------------------- */
.timeline {
  list-style: none;
  margin: var(--space-4) 0;
  padding: 0 0 0 var(--space-3);
  border-left: 1px solid var(--color-rule);
}

.timeline__entry {
  padding: 0 0 var(--space-4);
}

.timeline__entry + .timeline__entry {
  border-top: 1px solid var(--color-gray-warm-light);
  padding-top: var(--space-3);
}

.timeline__entry:last-child {
  padding-bottom: 0;
}

.timeline__date {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
  margin: 0 0 var(--space-2);
}

/* the rule that runs out to the margin */
.timeline__date::after {
  content: "";
  height: 1px;
  background: var(--color-rule);
}

/* the marker, tied to the date's own line so it stays aligned whatever
   padding the entry carries */
.timeline__date::before {
  content: "";
  position: absolute;
  left: calc((var(--space-3) + 4.5px) * -1);
  top: 0.5em;
  width: 7px;
  height: 7px;
  background: var(--color-paper);
  border: 1.5px solid var(--color-accent);
}

.timeline__body { margin: 0; }
.timeline__body p { margin: 0 0 var(--space-2); text-wrap: pretty; }
.timeline__body p:last-child { margin-bottom: 0; }

.timeline__points {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
}

.timeline__points > li {
  text-wrap: pretty;
}

.timeline__points > li + li {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-gray-warm-light);
}

.timeline__who {
  font-weight: 700;
  color: var(--color-ink);
}

/* ---------------------------------------------------------------------
   Pull quote
   Classes: .pull-quote, .pull-quote__text, .pull-quote__attribution,
            plus the modifier .pull-quote--statute (added automatically by
            build.py when the attribution reads like a statute citation).

   A person speaking and a law being quoted need to read differently at a
   glance. The default (a person, e.g. a chief or a committee member) is
   set as informal, spoken speech: italic, a plain accent rule, a name and
   title underneath. The --statute variant, and a plain Markdown
   blockquote (used for the same purpose where a page just writes `>`),
   both read as an excerpted document: upright type, a labeled box, no
   italics, because a statute is not being "said."
--------------------------------------------------------------------- */
.pull-quote {
  border-left: 3px solid var(--color-accent);
  margin: var(--space-4) 0;
  padding: 0.25rem 0 0.25rem var(--space-3);
  max-width: none;
}

.pull-quote__text {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-style: italic;
  color: var(--color-ink);
  margin: 0 0 0.4rem;
}

.pull-quote__attribution {
  font-size: 0.9rem;
  color: var(--color-gray-warm);
}

.pull-quote__attribution::before { content: "- "; }

.pull-quote--statute,
blockquote {
  border-left: 3px solid var(--color-ink-muted);
  background: var(--color-gray-warm-light);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--space-2) var(--space-3);
  max-width: none;
}

.pull-quote--statute::before,
blockquote::before {
  content: "Statutory text";
  display: block;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-ink-muted);
  margin-bottom: 0.5rem;
}

.pull-quote--statute .pull-quote__text {
  font-style: normal;
  font-size: 1.1rem;
}

.pull-quote--statute .pull-quote__attribution {
  color: var(--color-ink-muted);
  font-weight: 600;
}

blockquote {
  margin: var(--space-4) 0;
}

blockquote p {
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--color-ink);
  margin: 0;
}

/* ---------------------------------------------------------------------
   Question and answer block
   Classes: .qa, .qa__question, .qa__n, .qa__answer

   Generated by mark_qa() in build.py from the quoted question headings
   the Questions page already uses: no content convention to remember, no
   content edits. The h2 stays an h2, so the document outline, existing
   deep links and the axe results do not change; the Qn chip is decorative
   and marked aria-hidden by the build.

   The first item carries a heavier top rule so the run of questions reads
   as one apparatus rather than as loose sections.
--------------------------------------------------------------------- */
.qa {
  border-top: 1px solid var(--color-rule);
  padding-top: var(--space-3);
  margin-top: var(--space-4);
}

.qa:first-of-type {
  border-top-width: 2px;
  border-top-color: var(--color-ink);
}

.qa__question {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.75rem;
  align-items: baseline;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1.2vw + 0.9rem, 1.55rem);
  font-weight: 600;
  line-height: 1.25;
  margin: 0 0 var(--space-2);
  scroll-margin-top: var(--space-3);
  text-wrap: pretty;
}

.qa__n {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent);
  background: var(--color-gray-warm-light);
  border-radius: 3px;
  padding: 0.3em 0.45em;
}

.qa__answer > p:last-child { margin-bottom: 0; }
.qa__answer p { text-wrap: pretty; }

/* ---------------------------------------------------------------------
   "What we know / what we do not know" block
   Classes: .know-block, .know-block__col, .know-block__title,
            .know-block__list

   One bordered frame, two stacked bands, with a shared hanging label
   column. The contrast survives on the labels (slate against data red)
   and on the tint of the second band, and every line gets the full
   measure. The two bands align into a small table, which is the right
   look for a records site.
--------------------------------------------------------------------- */
.know-block {
  border: 1px solid var(--color-rule);
  border-radius: var(--radius);
  background: var(--color-paper-raised);
  overflow: hidden;
  margin: var(--space-4) 0;
  max-width: none;
}

.know-block__col {
  padding: var(--space-3);
}

.know-block__col + .know-block__col {
  border-top: 1px solid var(--color-rule);
}

.know-block__col--unknown {
  background: var(--color-paper-tint);
}

.know-block__title {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.4;
  color: var(--color-accent);
  margin: 0 0 var(--space-2);
}

.know-block__col--unknown .know-block__title {
  color: var(--color-data);
}

.know-block__list {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

.know-block__list li {
  text-wrap: pretty;
}

.know-block__list li + li {
  margin-top: 0.7em;
  padding-top: 0.7em;
  border-top: 1px solid var(--color-gray-warm-light);
}

@container reading (min-width: 30rem) {
  .know-block__col {
    display: grid;
    grid-template-columns: 8.5rem 1fr;
    column-gap: var(--space-3);
  }
  .know-block__title {
    margin-bottom: 0;
  }
}

/* ---------------------------------------------------------------------
   Inline citation superscript
   Class: .cite (applied by build.py to a <sup><a>). This is the most
   important interface element on the site, so it needs an unmistakable
   affordance (a visible chip, not just colored text too small to notice)
   and a comfortable click/tap target despite being set in small type.
--------------------------------------------------------------------- */
.cite {
  font-size: 0.7em;
  line-height: 0;
}

.cite a {
  display: inline-block;
  color: var(--color-accent);
  background: var(--color-gray-warm-light);
  text-decoration: none;
  font-weight: 700;
  border-radius: 3px;
  padding: 0.3em 0.4em;
  margin: 0 0.05em;
}

.cite a:hover,
.cite a:focus-visible {
  color: #fff;
  background: var(--color-accent);
}

/* ---------------------------------------------------------------------
   Sources section
   Classes: .sources, .sources__list, .sources__item, .sources__title,
            .sources__meta, .sources__links, .sources__note
--------------------------------------------------------------------- */
.sources {
  margin-top: var(--space-5);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-rule);
  max-width: none;
}

.sources__list {
  list-style: decimal;
  padding-left: 1.4em;
  margin: 0;
}

.sources__item {
  margin-bottom: var(--space-3);
  padding: 0.1em 0.25em;
  scroll-margin-top: var(--space-3);
  border-radius: var(--radius);
}

/* the destination a reader lands on after clicking a citation superscript
   needs its own visible state, so the jump is never disorienting */
.sources__item:target {
  background: var(--color-gray-warm-light);
  outline: 2px solid var(--color-data);
  outline-offset: 3px;
}

.sources__title {
  font-weight: 600;
  margin: 0 0 0.15rem;
}

.sources__meta {
  color: var(--color-gray-warm);
  font-size: 0.9rem;
  margin: 0 0 0.15rem;
}

.sources__links {
  font-size: 0.9rem;
  margin: 0 0 0.15rem;
}

.sources__note {
  font-size: 0.9rem;
  color: var(--color-ink-muted);
  margin: 0;
}

/* ---------------------------------------------------------------------
   Footer
   Classes: .site-footer, .site-footer__inner, .site-footer__built,
            .site-footer__corrections
--------------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--color-rule);
  background: var(--color-paper-raised);
}

.site-footer__inner {
  max-width: 72rem;
  margin: 0 auto;
  padding: var(--space-3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  font-size: 0.85rem;
  color: var(--color-gray-warm);
}

.site-footer__inner p { margin: 0; }

/* ---------------------------------------------------------------------
   Print
--------------------------------------------------------------------- */
@media print {
  .site-header, .skip-link { display: none; }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  main#content {
    max-width: none;
    padding: 0;
  }

  a { color: #000; text-decoration: underline; }

  a[href^="http"]::after,
  a[href^="/docs/"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #333;
  }

  .stat-tile, .doc-card, .know-block,
  .pull-quote, .pull-quote--statute, blockquote {
    border: 1px solid #999;
    background: none;
    break-inside: avoid;
  }

  .know-block__col { border: 0; }
  .know-block__col + .know-block__col { border-top: 1px solid #999; }
  .know-block__col--unknown { background: none; }

  .stat-tile--split .stat-tile__versus {
    border-color: #999;
  }

  .timeline { border-left: 1px solid #999; }
  .timeline__entry { break-inside: avoid; }
  .timeline__date::before { border-color: #000; background: #fff; }
  .timeline__date::after { background: #999; }
  .timeline__points > li + li { border-top: 1px solid #ccc; }

  .qa { break-before: auto; }
  .qa__question { break-after: avoid; }
  .qa__n { background: none; color: #000; padding: 0; }

  .table-scroll, .map-frame, .map-legend-note { width: auto; max-width: none; }
  .table-scroll table { min-width: 0; }

  .pull-quote--statute::before, blockquote::before { color: #333; }

  .cite a {
    background: none;
    color: #000;
    padding: 0;
    text-decoration: underline;
  }

  .site-footer {
    border-top: 1px solid #999;
  }

  /* an interactive Leaflet map is dead weight on paper (no tiles, no
     interaction); the table right below it carries the same data and
     needs no JavaScript, so that is what a resident hands to a council
     member */
  .map-frame, .map-legend-note, noscript {
    display: none;
  }
}

/* ---------------------------------------------------------------------
   Small-screen guarantees (no horizontal scroll at 360px)
--------------------------------------------------------------------- */
@media (max-width: 400px) {
  main#content { padding-left: var(--space-2); padding-right: var(--space-2); }
  .site-header__inner { padding-left: var(--space-2); padding-right: var(--space-2); }
  .site-footer__inner { padding-left: var(--space-2); padding-right: var(--space-2); }
}

/* ---------------------------------------------------------------------
   Street View gallery (map page)
   Classes: .sv-gallery, .sv-card, .sv-card__badge, .sv-card__title,
            .sv-card__meta, .sv-card__flag, .sv-card__actions,
            .sv-card__link, .sv-card__button, .sv-card__unavailable,
            .sv-card__frame-slot

   Sits directly in main#content, a sibling of .page (same placement as
   .map-frame and .table-scroll above), so it gets the full shell width
   rather than being boxed into the --measure reading column.
--------------------------------------------------------------------- */
.sv-gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
  width: min(100%, calc(var(--measure) + 8rem));
  margin: var(--space-3) auto var(--space-4);
}

@media (min-width: 640px) {
  .sv-gallery { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1100px) {
  .sv-gallery {
    width: 100%;
    grid-template-columns: repeat(3, 1fr);
  }
}

.sv-card {
  border: 1px solid var(--color-rule);
  border-radius: var(--radius);
  background: var(--color-paper-raised);
  padding: var(--space-2);
}

.sv-card__badge {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-gray-warm);
  margin: 0 0 0.3rem;
}

.sv-card__title {
  font-family: var(--font-display);
  font-weight: 600;
  margin: 0 0 0.3rem;
}

.sv-card__meta {
  font-size: 0.85rem;
  color: var(--color-ink-muted);
  margin: 0 0 0.3rem;
}

.sv-card__flag {
  display: block;
  font-style: italic;
  color: var(--color-gray-warm);
}

.sv-card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: var(--space-1);
}

.sv-card__link {
  font-size: 0.85rem;
}

.sv-card__button {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  color: #fff;
  background: var(--color-accent);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius);
  padding: 0.4rem 0.8rem;
  cursor: pointer;
}

.sv-card__button:hover {
  background: var(--color-accent-dark);
  border-color: var(--color-accent-dark);
}

.sv-card__unavailable {
  font-size: 0.85rem;
  color: var(--color-gray-warm);
  font-style: italic;
  margin: var(--space-1) 0 0;
}

.sv-card__frame-slot iframe {
  display: block;
  margin-top: var(--space-2);
  width: 100%;
  max-width: 100%;
}

@media print {
  /* an embedded panorama is dead weight on paper, and the "Open street
     view" button does nothing without a click; the plain Street View
     link on each card already prints its own URL via the existing
     a[href^="http"]::after rule, so that is what survives on paper */
  .sv-card__button, .sv-card__frame-slot iframe {
    display: none;
  }
}

/* Dining-specific additions to the shared West Hartford AI design system. */

.page-kicker,
.page-as-of {
  color: var(--color-gray-warm);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.page-kicker { margin-bottom: var(--space-1); }
.page-as-of { margin-top: var(--space-2); }
.text-muted, .section-heading p, .hours-today { color: var(--color-ink-muted); }

.content-section { margin-top: var(--space-5); }
.section-heading { border-bottom: 1px solid var(--color-rule); margin-bottom: var(--space-2); }
.section-heading h2 { margin-bottom: 0.2rem; }
.section-heading p { font-size: 0.9rem; margin-bottom: var(--space-1); }
.empty-state { color: var(--color-ink-muted); font-style: italic; padding: var(--space-2) 0; }

.status-pill {
  display: inline-block;
  border: 1px solid var(--color-accent);
  border-radius: 999px;
  color: var(--color-accent-dark);
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.2;
  padding: 0.2rem 0.5rem;
  white-space: nowrap;
}

.status-pill--warning { background: var(--color-gray-warm-light); }
.status-pill--opened, .open-state[data-state="open"] { background: var(--color-accent); color: var(--color-paper-raised); }
.status-pill--closed, .open-state[data-state="closed"] { border-color: var(--color-data); color: var(--color-data); }
.open-state[data-state="unknown"] { border-color: var(--color-gray-warm); color: var(--color-gray-warm); }

.numeric,
.momentum-table,
.rating-figure,
.page-as-of { font-variant-numeric: tabular-nums; }
.numeric { text-align: right; white-space: nowrap; }
.change-up { color: var(--color-accent); font-weight: 700; }
.change-down { color: var(--color-data); font-weight: 700; }
.dining-table th { white-space: nowrap; }

.momentum-gate {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: minmax(9rem, 0.6fr) 1.4fr;
  align-items: start;
}
.momentum-gate h2 { margin-top: 0; }
.momentum-gate small { color: var(--color-gray-warm); font-family: var(--font-body); font-size: 0.4em; }

.permit-summary {
  gap: var(--space-1);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: var(--space-3) 0;
}
.permit-summary .stat-tile { padding: var(--space-2); }
.permit-summary .stat-tile__number { font-size: 1.8rem; }
.permit-summary .stat-tile__label { font-size: 0.8rem; line-height: 1.25; }

.roster-controls {
  align-items: end;
  background: var(--color-paper-raised);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius);
  display: grid;
  gap: var(--space-2);
  grid-template-columns: minmax(12rem, 1fr) auto auto;
  margin-bottom: var(--space-2);
  padding: var(--space-2);
}
/* The `hidden` attribute only works if nothing gives the element a display.
   .doc-card sets `display: flex`, which silently beat it: the roster filter
   computed the right count ("13 showing") while every one of the 141 rows
   stayed on screen, so filtering looked implemented and did nothing.
   Neutralise it once, globally, rather than per component. */
[hidden] { display: none !important; }
.roster-filter label { display: block; font-size: 0.85rem; font-weight: 700; }
.roster-filter input {
  border: 1px solid var(--color-gray-warm);
  border-radius: var(--radius);
  font: inherit;
  min-height: 2.4rem;
  padding: 0.3rem 0.5rem;
  width: 100%;
}
.roster-toggle { align-items: center; display: flex; font-weight: 600; gap: 0.4rem; min-height: 2.4rem; }
.roster-toggle input { height: 1.1rem; margin: 0; width: 1.1rem; }
.roster-count { color: var(--color-ink-muted); margin: 0; min-width: 5.5rem; text-align: right; }
.roster { border: 1px solid var(--color-rule); border-radius: var(--radius); overflow: hidden; }
.roster-row.doc-card { border: 0; border-radius: 0; margin: 0; padding: 0.65rem 0.75rem; }
.roster-row + .roster-row { border-top: 1px solid var(--color-rule); }
.roster-row .doc-card__body {
  align-items: center;
  display: grid;
  flex: 1;
  gap: var(--space-1) var(--space-2);
  grid-template-columns: minmax(11rem, 1.25fr) minmax(12rem, 1fr) auto;
  min-width: 0;
}
.hours-today { font-size: 0.9rem; line-height: 1.3; margin: 0; }
.roster-status { display: flex; flex-wrap: wrap; gap: 0.35rem; justify-content: flex-end; }

.profile-grid { display: grid; gap: var(--space-4); }
.facts { margin: 0; }
.facts > div { border-bottom: 1px solid var(--color-rule); padding: var(--space-1) 0; }
.facts dt { color: var(--color-gray-warm); font-size: 0.85rem; font-weight: 700; }
.facts dd { margin: 0; overflow-wrap: anywhere; }
.rating-summary { border: 1px solid var(--color-rule); border-radius: var(--radius); padding: var(--space-3); background: var(--color-paper-raised); }
.rating-figure { color: var(--color-data); font-family: var(--font-display); font-size: 2.75rem; font-weight: 700; line-height: 1; margin-bottom: var(--space-1); }
.hours-list { list-style: none; margin: 0; padding: 0; }
.hours-list li { border-bottom: 1px solid var(--color-rule); display: flex; justify-content: space-between; gap: var(--space-2); padding: var(--space-1) 0; }
.hours-list span:first-child { color: var(--color-gray-warm); }

@media (min-width: 760px) {
  .profile-grid { grid-template-columns: minmax(0, 1.5fr) minmax(15rem, 0.5fr); }
  .directory { columns: 2 18rem; column-gap: var(--space-3); }
  .directory .doc-card { break-inside: avoid; }
}

@media (max-width: 540px) {
  .permit-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .momentum-gate { grid-template-columns: 1fr; }
  .roster-controls { align-items: start; grid-template-columns: 1fr auto; }
  .roster-filter { grid-column: 1 / -1; }
  .roster-count { align-self: center; }
  .roster-row .doc-card__body { grid-template-columns: 1fr auto; }
  .roster-identity, .hours-today { grid-column: 1; }
  .roster-status { grid-column: 2; grid-row: 1 / span 2; }
  .hours-list li { display: block; }
  .hours-list span { display: block; }
}

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

/* base.css boxes .page inside --measure (68ch), which is right for a prose
   explainer but wrong here: every Dining page is a data table, not a reading
   column, so the pipeline's fourth column was clipped mid-word at 1280px.
   base.css's own answer is that wide elements live outside .page; rather than
   restructure every page around that, data pages opt out of the reading
   measure entirely and use the shell width. Tables keep their own scroll. */
.page--wide { max-width: var(--shell-max); }
.page--wide .table-scroll { width: 100%; }
.dining-table { width: 100%; }

/* Provenance travels with each row of the merged activity feed: a liquor
   permit and a Google listing are different kinds of evidence, and the reader
   has to be able to tell which one produced a line. */
.event-source {
  border: 1px solid var(--color-rule);
  border-radius: 3px;
  color: var(--color-gray-warm);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-right: 0.15rem;
  padding: 0.05rem 0.3rem;
  text-transform: uppercase;
  white-space: nowrap;
}

.feed-note {
  color: var(--color-ink-muted);
  font-size: 0.9rem;
  margin-top: var(--space-2);
  max-width: 62ch;
}

/* A place absent from Google is an observation, never a closure claim, so the
   notice is informational rather than an alarm. */
.notice {
  background: var(--color-gray-warm-light);
  border-left: 3px solid var(--color-gray-warm);
  margin: var(--space-3) 0;
  padding: var(--space-2) var(--space-3);
}
.notice p { margin: 0; max-width: 62ch; }
.notice--dormant strong { display: block; }

/* Collections ---------------------------------------------------------
   A directory of 300 pages needs a browse spine.  With no photography and
   no prose, the count IS the visual: "Pizza 20" beside "Thai 5" tells you
   the shape of the town faster than a sentence could. */
.collection-grid {
  display: grid;
  gap: var(--space-1);
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
}
.collection-tile {
  align-items: baseline;
  background: var(--color-paper-raised);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius);
  display: flex;
  gap: 0.5rem;
  padding: var(--space-2);
  text-decoration: none;
}
.collection-tile:hover { border-color: var(--color-accent); }
.collection-tile__count {
  color: var(--color-accent-dark);
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  line-height: 1;
}
.collection-tile__label { color: var(--color-ink); font-weight: 600; }

/* Rules, not boxes.  248 bordered cards read as a filing system; a ruled
   list reads as a menu, and it is what lets the long lists stay scannable. */
.entry-list {
  border-top: 1px solid var(--color-rule);
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
}
.entry {
  align-items: baseline;
  border-bottom: 1px solid var(--color-rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem var(--space-2);
  padding: 0.65rem 0;
}
.entry__name {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.entry__meta { color: var(--color-ink-muted); font-size: 0.85rem; }

.chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: var(--space-2); }
.chip {
  align-items: baseline;
  background: var(--color-paper-raised);
  border: 1px solid var(--color-rule);
  border-radius: 999px;
  display: inline-flex;
  gap: 0.35rem;
  /* 2.25rem clears the 24px minimum target size in WCAG 2.5.8. */
  min-height: 2.25rem;
  padding: 0.4rem 0.75rem;
  text-decoration: none;
}
.chip:hover { border-color: var(--color-accent); }
.chip__count { color: var(--color-gray-warm); font-size: 0.78rem; font-variant-numeric: tabular-nums; }

.crumbs { margin-bottom: var(--space-2); }
.crumbs ol { display: flex; flex-wrap: wrap; gap: 0.4rem; list-style: none; margin: 0; padding: 0; }
.crumbs li { color: var(--color-gray-warm); font-size: 0.8rem; }
.crumbs li + li::before { color: var(--color-rule); content: "/"; margin-right: 0.4rem; }

@media print {
  .chip-row, .collection-grid { display: none; }
  .entry { break-inside: avoid; }
}
