/*
 * The public site. Everything is a token from packages/tokens, so it follows the same two
 * themes as the app and changes with it.
 *
 * The page is a timetable first: the schedule sits beside the headline rather than below a
 * picture of one, because the schedule is the thing a visitor came for and the only thing on
 * the page nobody else has.
 */

html {
  background: var(--hq-bg);
}

/* Going from one page of the site to another is a cross-fade where the browser can do it,
   rather than a blank frame and a redraw. The header is its own layer, so it stays put. */
@view-transition {
  navigation: auto;
}
.bar {
  view-transition-name: bar;
}
@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main {
  flex: 1;
}

h1,
h2,
h3 {
  text-wrap: balance;
  margin: 0;
}

p {
  margin: 0;
}

.muted {
  color: var(--hq-muted);
}

.mono {
  font-family: var(--hq-font-mono);
  font-size: var(--hq-text-sm);
}

.skip {
  position: absolute;
  left: var(--hq-space-lg);
  top: -48px;
  padding: var(--hq-space-sm) var(--hq-space-md);
  background: var(--hq-surface);
  border: var(--hq-border-hairline) solid var(--hq-line);
  border-radius: var(--hq-radius-sm);
  z-index: var(--hq-layer-toast);
}
.skip:focus {
  top: var(--hq-space-sm);
}

/* ---- header ---- */

.bar {
  background: var(--hq-surface);
  border-bottom: var(--hq-border-hairline) solid var(--hq-line-soft);
}
.bar__inner,
.foot__inner,
.hero,
.band {
  max-width: 1120px;
  margin: 0 auto;
  padding-left: var(--hq-space-lg);
  padding-right: var(--hq-space-lg);
}
.bar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hq-space-sm);
  flex-wrap: wrap;
  padding-top: var(--hq-space-md);
  padding-bottom: var(--hq-space-md);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--hq-space-sm);
  font-weight: var(--hq-weight-semibold);
  font-size: var(--hq-text-md);
  text-decoration: none;
  letter-spacing: -0.01em;
}

.mark path {
  fill: var(--hq-accent);
}
.mark circle {
  fill: var(--hq-surface);
}

.bar__nav {
  display: flex;
  align-items: center;
  gap: var(--hq-space-md);
  flex-wrap: wrap;
  font-size: var(--hq-text-sm);
}
.bar__nav > a:not(.button) {
  text-decoration: none;
  color: var(--hq-muted);
}
.bar__nav > a:not(.button):hover,
.bar__nav > a[aria-current="page"] {
  color: var(--hq-ink);
}
.bar__nav > a[aria-current="page"] {
  font-weight: var(--hq-weight-semibold);
}
/* A phone gets one row: the brand is the way home, and the page's own button opens the app just
   below, so the header's two copies of them wait for a wider screen; the places and the
   questions wait too, and are in the footer of every page. */
.bar__nav > .bar__home,
.bar__nav > .bar__app,
.bar__nav > .bar__more {
  display: none;
}
@media (min-width: 640px) {
  .bar__inner {
    gap: var(--hq-space-md);
  }
  .bar__nav {
    gap: var(--hq-space-lg);
  }
  .bar__nav > .bar__home,
  .bar__nav > .bar__app,
  .bar__nav > .bar__more {
    display: inline-flex;
  }
}

.lang {
  display: inline-flex;
  border: var(--hq-border-hairline) solid var(--hq-line);
  border-radius: var(--hq-radius-full);
  overflow: hidden;
}
.lang__item {
  padding: var(--hq-space-2xs) var(--hq-space-md);
  text-decoration: none;
  color: var(--hq-muted);
}
.lang__item + .lang__item {
  border-left: var(--hq-border-hairline) solid var(--hq-line);
}
.lang__item[aria-current] {
  background: var(--hq-surface-2);
  color: var(--hq-ink);
  font-weight: var(--hq-weight-medium);
}

/* The island mounts the app's own two controls here; the links under it are what a reader
   without scripts gets. */
.controls {
  display: flex;
  align-items: center;
  gap: var(--hq-space-sm);
}
.controls--live {
  gap: var(--hq-space-md);
}
/* With scripts on, the island's own size is kept from the first paint and the plain links are
   never drawn, so nothing in the header moves when the controls arrive. */
.js .controls {
  min-width: 96px;
  min-height: 36px;
  justify-content: flex-end;
}
.js .controls .lang {
  display: none;
}

/* ---- buttons and links ---- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  white-space: nowrap;
  padding: 0 var(--hq-space-xl);
  border-radius: var(--hq-radius-sm);
  background: var(--hq-accent);
  color: var(--hq-accent-ink);
  font-weight: var(--hq-weight-semibold);
  text-decoration: none;
  transition: background var(--hq-duration-fast) var(--hq-ease-standard);
}
.button:hover {
  background: var(--hq-accent-strong);
}
/* The second action beside the main one: the same shape, drawn in outline. */
.button--quiet {
  background: transparent;
  color: var(--hq-ink);
  box-shadow: inset 0 0 0 var(--hq-border-hairline) var(--hq-line);
}
.button--quiet:hover {
  background: var(--hq-surface);
}
.button--small {
  min-height: 34px;
  padding: 0 var(--hq-space-lg);
  font-size: var(--hq-text-sm);
}

.link {
  color: var(--hq-accent);
  font-weight: var(--hq-weight-medium);
  text-underline-offset: 3px;
}

/* ---- hero: the headline beside the timetable ---- */

/* The headline and the panel beside it are one row of equal height: the text is centred on the
   panel's height rather than hanging from the top of a taller column. */
.hero {
  display: grid;
  gap: var(--hq-space-2xl);
  padding-top: var(--hq-space-3xl);
  padding-bottom: var(--hq-space-3xl);
  align-items: stretch;
}

.hero__text {
  display: grid;
  gap: var(--hq-space-lg);
  align-content: center;
}
.hero h1 {
  font-size: clamp(34px, 6vw, var(--hq-text-4xl));
  line-height: var(--hq-leading-tight);
  letter-spacing: -0.025em;
  font-weight: var(--hq-weight-semibold);
}
.lead {
  font-size: var(--hq-text-lg);
  line-height: var(--hq-leading-snug);
  color: var(--hq-muted);
  max-width: 52ch;
}
/* The hero's two buttons are one width, the wider label's, so neither reads as the lesser one. */
/* Side by side at an even width where both labels fit on one line; on a phone, where a longer
   label (Cyrillic, for one) would break inside its button, one under the other at full width. */
.actions {
  display: grid;
  gap: var(--hq-space-md);
  padding-top: var(--hq-space-sm);
}
@media (min-width: 560px) {
  .actions {
    display: inline-grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    align-items: center;
    justify-self: start;
  }
}

@media (min-width: 900px) {
  .hero {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    gap: var(--hq-space-3xl);
    padding-top: var(--hq-space-4xl);
  }
}

/* ---- the schedule ---- */

/* A column, so the link to the app is the panel's last line whatever the day holds: the panel
   is as tall as the headline beside it, and a quiet day's few rows leave the space above the
   link rather than under it. */
.schedule {
  display: flex;
  flex-direction: column;
  background: var(--hq-surface);
  border: var(--hq-border-hairline) solid var(--hq-line-soft);
  border-radius: var(--hq-radius-lg);
  box-shadow: var(--hq-shadow-sm);
  overflow: hidden;
}
/* "Today" and the date under it read as one heading: the date is the panel's first line and
   sits right under the title, and the rule comes after both. */
.schedule__head {
  padding: var(--hq-space-lg) var(--hq-space-lg) 0;
}
.schedule__head h2 {
  font-size: var(--hq-text-lg);
}

.day__drives {
  list-style: none;
  margin: 0;
  padding: 0;
}
.day__heading {
  margin: 0;
  padding: var(--hq-space-3xs) var(--hq-space-lg) var(--hq-space-md);
  font-size: var(--hq-text-sm);
  color: var(--hq-muted);
  border-bottom: var(--hq-border-hairline) solid var(--hq-line-soft);
}

.drive a {
  display: grid;
  grid-template-columns: 8.5em minmax(0, 1fr);
  align-items: baseline;
  gap: var(--hq-space-md);
  padding: var(--hq-space-sm) var(--hq-space-lg);
  text-decoration: none;
}
.drive a:hover {
  background: var(--hq-bg);
}
.drive + .drive a {
  border-top: var(--hq-border-hairline) solid var(--hq-line-soft);
}
.drive__time {
  white-space: nowrap;
  font-weight: var(--hq-weight-medium);
  font-variant-numeric: tabular-nums;
}
/* One line per drive: a long venue is cut short with an ellipsis rather than wrapping, and the
   whole of it is one tap away on the drive's own page. */
.drive__place {
  min-width: 0;
  color: var(--hq-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.drive__place strong {
  color: var(--hq-ink);
  font-weight: var(--hq-weight-semibold);
}
.drive--cancelled .drive__place,
.drive--cancelled .drive__time {
  text-decoration: line-through;
}

.tag {
  display: inline-block;
  vertical-align: 1px;
  margin-left: var(--hq-space-2xs);
  font-size: var(--hq-text-xs);
  padding: 0 var(--hq-space-xs);
  border-radius: var(--hq-radius-sm);
  background: var(--hq-info-soft);
  color: var(--hq-info);
}
.tag--cancelled {
  background: var(--hq-accent-soft);
  color: var(--hq-accent);
  font-weight: var(--hq-weight-semibold);
}

.day__more {
  display: block;
  padding: var(--hq-space-xs) var(--hq-space-lg) var(--hq-space-sm);
  font-size: var(--hq-text-sm);
  color: var(--hq-accent);
}

.schedule__empty,
.schedule__foot {
  padding: var(--hq-space-md) var(--hq-space-lg);
  font-size: var(--hq-text-sm);
  color: var(--hq-muted);
}
.schedule__foot {
  margin-top: auto;
  border-top: var(--hq-border-hairline) solid var(--hq-line-soft);
  background: var(--hq-bg);
}
.schedule__empty a,
.schedule__foot a {
  color: var(--hq-muted);
  font-weight: var(--hq-weight-medium);
  text-underline-offset: 3px;
}
.schedule__empty a:hover,
.schedule__foot a:hover {
  color: var(--hq-ink);
}

/* ---- bands below ---- */

.band {
  padding-top: var(--hq-space-3xl);
  padding-bottom: var(--hq-space-3xl);
  border-top: var(--hq-border-hairline) solid var(--hq-line);
  display: grid;
  gap: var(--hq-space-xl);
}
.band h2 {
  font-size: var(--hq-text-xl);
  letter-spacing: -0.01em;
}

.features {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr));
  gap: var(--hq-space-xl) var(--hq-space-2xl);
}
.feature {
  display: grid;
  gap: var(--hq-space-xs);
  align-content: start;
}
.feature h3 {
  font-size: var(--hq-text-md);
  font-weight: var(--hq-weight-semibold);
}
.feature p {
  color: var(--hq-muted);
  line-height: var(--hq-leading-normal);
}

@media (min-width: 900px) {
  .band--split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    gap: var(--hq-space-4xl);
  }
}
.band--split > div:first-child {
  display: grid;
  gap: var(--hq-space-sm);
  align-content: start;
}

.kept {
  margin: 0;
  display: grid;
  gap: var(--hq-space-lg);
}
.kept div {
  display: grid;
  gap: var(--hq-space-2xs);
  padding-bottom: var(--hq-space-lg);
  border-bottom: var(--hq-border-hairline) solid var(--hq-line-soft);
}
.kept dt {
  font-weight: var(--hq-weight-semibold);
}
.kept dd {
  margin: 0;
  color: var(--hq-muted);
  line-height: var(--hq-leading-relaxed);
}

/* ---- what the app does, as tiles ---- */

/* Two columns from a tablet up, one on a phone. Two and not four, because a picture is only sharp
   at the size it was taken: every crop is the phone's own width (412px), and a tile narrower than
   that shrinks the screen's text until it smudges. Six tiles in two columns are three even rows. */
.bento {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--hq-space-lg);
}
@media (min-width: 760px) {
  .bento {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.tile {
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--hq-surface);
  border: var(--hq-border-hairline) solid var(--hq-line-soft);
  border-radius: var(--hq-radius-xl);
  overflow: hidden;
}
.tile__words {
  display: grid;
  gap: var(--hq-space-xs);
  align-content: start;
  padding: var(--hq-space-lg) var(--hq-space-lg) var(--hq-space-md);
}
.tile h3 {
  font-size: var(--hq-text-md);
  font-weight: var(--hq-weight-semibold);
}
.tile p {
  color: var(--hq-muted);
  line-height: var(--hq-leading-normal);
}
/* Every picture strip is this tall and at most the phone's width, so a crop is drawn at the size
   it was taken, pixel for pixel on a wide screen, and shows the top of its screen, which is where
   each crop starts. */
.tile__shot {
  align-self: end;
  height: 300px;
  padding: 0 var(--hq-space-lg);
  overflow: hidden;
}
.tile__shot img {
  display: block;
  width: 100%;
  max-width: 412px;
  height: 100%;
  margin: 0 auto;
  object-fit: cover;
  object-position: top center;
  border-radius: var(--hq-radius-md) var(--hq-radius-md) 0 0;
  box-shadow: var(--hq-shadow-lg);
}
@media (min-width: 760px) {
  .tile--wide {
    grid-column: 1 / -1;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: none;
  }
  .tile--wide .tile__words {
    align-content: center;
    padding: var(--hq-space-lg);
  }
  .tile--wide .tile__shot {
    padding-top: var(--hq-space-lg);
  }
}
.tile--accent {
  background: var(--hq-accent);
  border-color: var(--hq-accent);
}
.tile--accent h3 {
  color: var(--hq-accent-ink);
}
.tile--accent p {
  color: var(--hq-accent-ink);
  opacity: 0.88;
}
.bento + .features {
  padding-top: var(--hq-space-xl);
  border-top: var(--hq-border-hairline) solid var(--hq-line-soft);
}

/* ---- about ---- */

.prose {
  max-width: calc(var(--hq-measure-prose) + 2 * var(--hq-space-lg));
  width: 100%;
  margin: 0 auto;
  padding: var(--hq-space-3xl) var(--hq-space-lg);
  display: grid;
  gap: var(--hq-space-lg);
  line-height: var(--hq-leading-relaxed);
}
.prose h1 {
  font-size: clamp(32px, 5vw, var(--hq-text-3xl));
  line-height: var(--hq-leading-tight);
  letter-spacing: -0.02em;
  font-weight: var(--hq-weight-semibold);
}
.prose .lead {
  max-width: none;
}
.prose section {
  display: grid;
  gap: var(--hq-space-sm);
  padding-top: var(--hq-space-lg);
}
.prose h2 {
  font-size: var(--hq-text-lg);
}
.eyebrow {
  font-size: var(--hq-text-xs);
  font-weight: var(--hq-weight-semibold);
  letter-spacing: var(--hq-tracking-wide);
  text-transform: uppercase;
  color: var(--hq-accent);
}
.sources {
  margin: 0;
  padding-left: var(--hq-space-lg);
}

/* ---- questions ---- */

/* One question per row, each opening on a tap: the question is the row, the answer under it. */
.faqs {
  display: grid;
  border-top: 1px solid var(--hq-line);
}
.faq {
  border-bottom: 1px solid var(--hq-line);
}
.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--hq-space-md);
  padding: var(--hq-space-md) 0;
  font-weight: var(--hq-weight-semibold);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker {
  display: none;
}
.faq summary::after {
  content: "+";
  flex: none;
  font-size: var(--hq-text-lg);
  line-height: 1;
  color: var(--hq-accent);
}
.faq[open] summary::after {
  content: "\2212";
}
.faq summary:focus-visible {
  outline: 2px solid var(--hq-accent);
  outline-offset: 2px;
}
.faq p {
  margin: 0 0 var(--hq-space-md);
}

/* ---- places ---- */

/* The towns as a row of pills on the landing, each with its count of drives this week, and as
   columns on the index, where every place is listed and the quiet ones say so. */
.places {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--hq-space-sm);
}
.places li {
  padding: var(--hq-space-xs) var(--hq-space-md);
  border: var(--hq-border-hairline) solid var(--hq-line-soft);
  border-radius: var(--hq-radius-full);
  background: var(--hq-surface);
  font-variant-numeric: tabular-nums;
}
.places a {
  color: var(--hq-ink);
  font-weight: var(--hq-weight-medium);
  text-decoration: none;
}
.places a:hover {
  text-decoration: underline;
}
.places--index {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15em, 1fr));
}
.places--index li {
  border-radius: var(--hq-radius-sm);
}
/* A place with drives this week stands out from the quiet ones in the brand's soft red, its
   count in the red that reads as words. */
.places--index li.is-busy {
  background: var(--hq-accent-soft);
  border-color: var(--hq-accent);
}
.places--index li.is-busy .muted {
  color: var(--hq-accent);
  font-weight: var(--hq-weight-semibold);
}
.eyebrow a {
  color: inherit;
  text-decoration: none;
}
/* A place's days are the landing's panel, one per day, its date as the panel's first line. */
.prose .schedule > * {
  margin: 0;
}
.prose .schedule .day__heading {
  padding-top: var(--hq-space-md);
}
.drive--place a {
  grid-template-columns: minmax(0, 1fr);
}
.drive--place .drive__place {
  white-space: normal;
}
.drive__address {
  display: block;
}
.drive__away {
  color: var(--hq-ink);
  font-variant-numeric: tabular-nums;
}

/* ---- what's new ---- */

.news {
  margin: 0;
  padding-left: var(--hq-space-lg);
  display: grid;
  gap: var(--hq-space-sm);
}
/* The services' part of a release, under the donors' part: a small heading, as a sub-list. */
.news__part {
  margin: var(--hq-space-md) 0 var(--hq-space-2xs);
  font-size: var(--hq-text-md);
}
/* A release with nothing for donors steps back, so the ones that changed something stand out: its
   number in the quiet colour and its sentence in italics behind a dashed rule. */
.news__none {
  padding-left: var(--hq-space-md);
  border-left: 2px dashed var(--hq-line);
  font-style: italic;
}
.news__quiet h2 {
  color: var(--hq-muted);
}
.news__when {
  margin-left: var(--hq-space-xs);
  font-size: var(--hq-text-sm);
  font-weight: var(--hq-weight-regular);
  font-variant-numeric: tabular-nums;
}

/* ---- footer ---- */

.foot {
  background: var(--hq-surface);
  border-top: var(--hq-border-hairline) solid var(--hq-line-soft);
}
.foot__inner {
  padding-top: var(--hq-space-xl);
  padding-bottom: var(--hq-space-xl);
  display: grid;
  gap: var(--hq-space-md);
  font-size: var(--hq-text-sm);
  color: var(--hq-muted);
}
.foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hq-space-sm) var(--hq-space-xl);
}
.foot__links a {
  color: var(--hq-ink);
}
