/* Kid Events in Ann Arbor
   Green and blue, borrowed from the city's own palette. Mobile first, because
   that is where I actually use this: standing in the kitchen on a Saturday
   morning trying to figure out where to take the kid.

   Every foreground and background pair in here is checked against WCAG 2.2 AA
   by tests/test_accessibility.py, so do not change a token without running it.
*/

:root {
  color-scheme: light;

  --brand-green: #1f7a4c;
  --brand-green-dark: #14563a;

  /* The brand bar is dark in both themes. Deliberately not a semantic token:
     --brand-green-dark flips light in dark mode so it works as text, which
     turned the header pale green. */
  --masthead-bg: #14563a;
  --masthead-rule: #62b9d8;
  --brand-green-soft: #e6f3ec;
  --warn-bg: #fdf4e3;
  --warn-line: #a8710f;
  --warn-text: #5c3d02;
  --brand-blue: #1b6c8c;
  --brand-blue-dark: #12506a;
  --brand-blue-soft: #e2f0f5;

  --bg: #f6f9f5;
  --surface: #ffffff;
  --surface-2: #f0f5f0;
  --text: #16261f;
  --text-soft: #4d6259;
  --line: #c8d7cd;
  --line-strong: #799486;
  --focus: #b4531f;

  --warn-bg: #fdf0e2;
  --warn-text: #8a4a12;

  --radius: 14px;
  --radius-sm: 9px;
  --shadow: 0 1px 2px rgba(20, 45, 35, .06), 0 6px 20px rgba(20, 45, 35, .06);
  --shadow-pop: 0 10px 30px rgba(16, 40, 30, .18);
  --wrap: 1120px;
  /* The reading column on the about, contact and thanks pages. The footer on
     those pages lines up with it, so both read off this one value. In rem,
     not ch, because ch is relative to font size and the footer text is
     smaller, which is exactly how the two ended up different widths. */
  --prose-measure: 38rem;
  /* Baloo 2 for the friendly bits, Karla for everything you actually read.
     Both fall back to the system stack if Google Fonts is blocked. */
  --font-display: "Baloo 2", "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  --font: Karla, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

[data-theme="dark"] {
  color-scheme: dark;
  --brand-green: #57c48c;
  --brand-green-dark: #7fd8a8;
  --masthead-bg: #0e3527;
  --masthead-rule: #2f7f66;
  --brand-green-soft: #15332a;
  --brand-blue: #62b9d8;
  --brand-blue-dark: #8fd0e6;
  --brand-blue-soft: #12303c;

  --bg: #0d1512;
  --surface: #16211d;
  --surface-2: #1c2926;
  --warn-bg: #2e2415;
  --warn-line: #d9a441;
  --warn-text: #f2ddb4;
  --text: #e8f1ec;
  --text-soft: #a3b7ae;
  --line: #33443d;
  --line-strong: #61796f;
  --focus: #ffb066;

  --warn-bg: #3a2a15;
  --warn-text: #f3c187;

  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 20px rgba(0, 0, 0, .3);
  --shadow-pop: 0 10px 30px rgba(0, 0, 0, .5);
}

/* Same tokens again for anyone who never touches the toggle and just has
   their OS set to dark. An explicit light choice still wins. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --brand-green: #57c48c;
    --brand-green-dark: #7fd8a8;
    --masthead-bg: #0e3527;
    --masthead-rule: #2f7f66;
    --brand-green-soft: #15332a;
    --brand-blue: #62b9d8;
    --brand-blue-dark: #8fd0e6;
    --brand-blue-soft: #12303c;

    --bg: #0d1512;
    --surface: #16211d;
    --surface-2: #1c2926;
    --text: #e8f1ec;
    --text-soft: #a3b7ae;
    --line: #33443d;
    --line-strong: #61796f;
    --focus: #ffb066;

    --warn-bg: #3a2a15;
    --warn-text: #f3c187;

    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 20px rgba(0, 0, 0, .3);
    --shadow-pop: 0 10px 30px rgba(0, 0, 0, .5);
  }
}

* { box-sizing: border-box; }

/* The browser's own [hidden] rule lives in the user agent stylesheet, which
   loses to any author declaration. So the moment something toggled with
   .hidden also has a display: rule in here, it stops hiding. That shipped:
   every filter dropdown rendered open on page load, because .multi-panel sets
   display: flex. One rule fixes the whole class of bug.
   tests/test_accessibility.py fails the build if this goes missing. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  /* iOS paints a grey box over anything tappable. The focus styles below do
     that job properly, so turn the default off. */
  -webkit-tap-highlight-color: rgba(31, 122, 76, .15);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 16px;
}

a { color: var(--brand-blue-dark); }

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

.skip {
  /* Clipped rather than pushed to left: -9999px. The old way leaves a real
     box sitting off the left edge, which some Android browsers count toward
     the scrollable width and turn into a phantom sideways scroll. */
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  background: var(--masthead-bg);
  color: #fff;
  padding: 10px 16px;
  z-index: 60;
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip:focus {
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
}

.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;
}

/* --- Masthead ---------------------------------------------------------- */

.masthead {
  /* A flat brand bar rather than a gradient. Solid colour reads as
     deliberate; a gradient reads as decoration. */
  background: var(--masthead-bg);
  border-bottom: 3px solid var(--masthead-rule);
  color: #fff;
  padding: 14px 0;
}

.masthead-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 20px;
  align-items: center;
  justify-content: space-between;

  /* Wider than the content column below it. A brand bar that stops where the
     article stops looks like a widget dropped onto the page; one that runs
     most of the window looks like the top of a site. Not edge to edge, so the
     logo still has a margin to breathe in. */
  max-width: 1560px;
  padding-inline: clamp(16px, 3.2vw, 48px);
}

/* --- Brand lockup ------------------------------------------------------- */

.brand {
  display: flex;
  gap: 13px;
  align-items: center;
  border-radius: var(--radius-sm);
  padding: 4px;
  margin: -4px;
}

/* White, and never underlined. The generic `a` rule paints links brand blue,
   which on a dark green bar is unreadable, so this has to win on every
   descendant rather than just the anchor itself. */
.brand,
.brand:link,
.brand:visited,
.brand:hover,
.brand:focus,
.brand .brand-name,
.brand .tagline {
  color: #fff;
  text-decoration: none;
}

/* Hover is a lift in the bar, not an underline. */
.brand:hover { background: rgba(255, 255, 255, .1); }
.brand:focus-visible,
.masthead .btn:focus-visible,
.masthead a:focus-visible {
  /* The global ring is a rust orange chosen for light backgrounds. Against
     dark green it all but disappears, so the brand bar gets a white one. */
  outline: 3px solid #fff;
  outline-offset: 2px;
}

.brand-mark {
  width: 54px;
  height: 54px;
  flex: none;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .3));
}

.brand-words { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

.masthead .brand-name {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: .002em;
}

.tagline {
  margin: 0;
  font-size: .82rem;
  line-height: 1.3;
  color: rgba(255, 255, 255, .82);
}

/* --- Header nav --------------------------------------------------------- */

/* Calendar and About are buttons to look at and links to use. They go to
   another page, so they stay anchors: a real <button> would break middle
   click, open in a new tab, and copy link address, and a screen reader would
   announce "button" for something that navigates. Same pill as every other
   button on the page. */

.masthead-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.masthead-nav .btn { text-decoration: none; }

.masthead .btn-nav,
.masthead .btn-nav:link,
.masthead .btn-nav:visited {
  color: #fff;
  border-color: rgba(255, 255, 255, .55);
  background: rgba(255, 255, 255, .1);
  text-decoration: none;
}
.masthead .btn-nav:hover { background: rgba(255, 255, 255, .24); color: #fff; }

/* The page you are on: filled, the way the active view button is filled. */
.masthead .btn-nav.is-current,
.masthead .btn-nav.is-current:link,
.masthead .btn-nav.is-current:visited {
  background: #fff;
  border-color: #fff;
  color: var(--masthead-bg);
}
.masthead .btn-nav.is-current:hover { background: #dff0e6; }

.masthead .btn-primary { background: #fff; color: #0f4530; }
.masthead .btn-primary:hover { background: #dff0e6; }

.masthead .btn-ghost {
  color: #fff;
  border-color: rgba(255, 255, 255, .55);
  background: rgba(255, 255, 255, .1);
}
.masthead .btn-ghost:hover { background: rgba(255, 255, 255, .22); }

/* One toggle, two icons: whichever theme you would switch TO. */
.theme-moon { display: none; }
[data-theme="dark"] .theme-sun { display: none; }
[data-theme="dark"] .theme-moon { display: inline-block; }

@media (max-width: 620px) {
  /* The label goes, the icon stays, and the accessible name comes from the
     aria-label the script keeps current. */
  .theme-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .brand-mark { width: 44px; height: 44px; }
  .masthead .brand-name { font-size: 1.2rem; }
  .tagline { display: none; }
}

/* --- Buttons ----------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 9px 16px;
  font: inherit;
  font-size: .9rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  min-height: 44px;
  transition: background-color .12s ease, border-color .12s ease;
}

.btn-primary { background: var(--brand-green); color: #fff; }
.btn-primary:hover { background: var(--brand-green-dark); }
[data-theme="dark"] .btn-primary { color: #0b1a13; }
[data-theme="dark"] .btn-primary:hover { background: var(--brand-green-dark); }

.btn-secondary {
  background: var(--brand-blue-soft);
  color: var(--brand-blue-dark);
  border-color: var(--brand-blue-soft);
}
.btn-secondary:hover { border-color: var(--brand-blue); }

.btn-ghost { background: var(--surface); color: var(--text); border-color: var(--line-strong); }
.btn-ghost:hover { background: var(--surface-2); }

.btn-small { padding: 6px 13px; min-height: 40px; font-size: .82rem; }

.btn.is-active {
  background: var(--brand-green);
  color: #fff;
  border-color: var(--brand-green);
}
[data-theme="dark"] .btn.is-active { color: #0b1a13; }

.icon { width: 17px; height: 17px; flex: none; }

.icon-btn {
  background: none;
  border: 1px solid transparent;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text);
  min-width: 44px;
  min-height: 44px;
  border-radius: var(--radius-sm);
}
.icon-btn:hover { background: var(--surface-2); }

/* --- Filters ----------------------------------------------------------- */

.filters {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px;
  margin: 18px 0;
  display: grid;
  gap: 12px;
  /* minmax(0, 1fr) rather than 1fr. A plain 1fr refuses to shrink below the
     widest item's min-content, and the row of view buttons does not wrap, so
     on a phone the whole grid pushed past the screen edge and the page
     scrolled sideways. */
  grid-template-columns: minmax(0, 1fr);
  /* Bottom aligned so a label that wraps onto two lines, like
     "Indoor or outdoor", does not shove its control out of the row. */
  align-items: end;
}

.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }

.field-label {
  display: block;
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-soft);
  padding: 0;
  line-height: 1.3;
}

.field input[type="search"],
.field select,
.multi-btn {
  font: inherit;
  /* 16px is the floor. Anything smaller and iOS Safari zooms the whole page
     the moment you tap the control, then leaves you scrolled sideways. */
  font-size: 1rem;
  padding: 10px 12px;
  height: 46px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  width: 100%;
}

/* Safari draws its own inset shadow and pill shape on these unless told not to,
   and the prefixed property is the one older iOS actually listens to. */
.field input[type="search"],
.ask-row input[type="search"] {
  -webkit-appearance: none;
  appearance: none;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration { -webkit-appearance: none; }
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.field select {
  -webkit-appearance: none;
  appearance: none;
}

/* --- Multi select ------------------------------------------------------- */

.multi { position: relative; }

.multi-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  text-align: left;
  cursor: pointer;
}
.multi-btn:hover { border-color: var(--brand-green); }
.multi-btn[aria-expanded="true"] {
  border-color: var(--brand-green);
  box-shadow: inset 0 0 0 1px var(--brand-green);
}

.multi-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.multi-btn.is-set .multi-value { font-weight: 700; color: var(--brand-green-dark); }

.caret { width: 12px; height: 8px; flex: none; color: var(--text-soft); }
.multi-btn[aria-expanded="true"] .caret { transform: rotate(180deg); }

.multi-panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 5px);
  left: 0;
  min-width: 100%;
  width: max-content;
  max-width: min(300px, 84vw);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.opt {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 10px;
  border-radius: 7px;
  cursor: pointer;
  font-size: .92rem;
  min-height: 44px;
}
.opt:hover { background: var(--surface-2); }
.opt input {
  width: 18px;
  height: 18px;
  accent-color: var(--brand-green);
  flex: none;
  margin: 0;
}
.opt input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

.multi-clear {
  margin-top: 4px;
  border: 0;
  border-top: 1px solid var(--line);
  background: none;
  color: var(--brand-blue-dark);
  font: inherit;
  font-size: .85rem;
  font-weight: 600;
  padding: 11px 10px 7px;
  text-align: left;
  cursor: pointer;
  border-radius: 0 0 7px 7px;
  min-height: 44px;
}
.multi-clear:hover { background: var(--surface-2); }

/* --- When chips --------------------------------------------------------- */

.field-when { border: 0; padding: 0; margin: 0; min-inline-size: 0; grid-column: 1 / -1; }

.chips { display: flex; flex-wrap: wrap; gap: 7px; }

/* Undo and Reset, pushed to the right of the When chips so they sit with the
   filters they act on rather than with the view buttons. */
.filter-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}
@media (min-width: 700px) {
  .field-when { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
  .field-when legend { float: left; width: 100%; }
  .field-when .chips { flex: 1 1 auto; }
  .filter-actions { margin-top: 0; margin-left: auto; }
}

.chip { position: relative; }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip span {
  display: inline-flex;
  align-items: center;
  padding: 8px 15px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: .88rem;
  cursor: pointer;
  background: var(--surface);
  min-height: 44px;
}
.chip input:checked + span {
  background: var(--brand-green-soft);
  border-color: var(--brand-green);
  color: var(--brand-green-dark);
  font-weight: 700;
}
.chip input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 2px; }

.filters-footer {
  min-width: 0;
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}

.count { margin: 0; font-size: .9rem; font-weight: 600; color: var(--text-soft); }
.view-switch { display: flex; gap: 8px; flex-wrap: wrap; }
.seg { display: flex; gap: 6px; flex-wrap: wrap; }

/* --- Day groups and cards ---------------------------------------------- */

.day-group { margin-bottom: 26px; }

.day-heading {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 10px;
  padding: 9px 13px;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--brand-green-dark);
  background: var(--brand-green-soft);
  border-radius: var(--radius-sm);
  border-left: 4px solid var(--brand-green);
}

.day-count { font-family: var(--font); font-size: .84rem; font-weight: 500; color: var(--text-soft); }

.card {
  display: grid;
  grid-template-columns: 86px 1fr;
  gap: 13px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 13px;
  margin-bottom: 10px;
  box-shadow: var(--shadow);
}

.card-time {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-right: 11px;
  border-right: 1px solid var(--line);
}

.card-day { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-soft); }
.card-hour {
  font-weight: 700;
  font-size: .96rem;
  font-variant-numeric: tabular-nums;
  color: var(--brand-blue-dark);
}

.card-body { min-width: 0; display: flex; flex-direction: column; gap: 5px; }

.card-title { margin: 0; font-family: var(--font-display); font-size: 1.1rem; font-weight: 600; line-height: 1.25; }

.card-open {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.card-open:hover { color: var(--brand-blue-dark); }
.card-open:hover .card-name { text-decoration: underline; }
.card-name { text-wrap: balance; }

.card-chevron {
  width: 12px;
  height: 8px;
  flex: none;
  color: var(--text-soft);
  transition: transform .15s ease;
}
.card.is-open .card-chevron { transform: rotate(180deg); }
.card.is-open { border-color: var(--brand-green); box-shadow: inset 0 0 0 1px var(--brand-green); }
.card.is-shared { border-color: var(--brand-blue); box-shadow: inset 0 0 0 2px var(--brand-blue); }

/* Expanded, the description is no longer clamped and the full detail list
   sits underneath it. */
.card.is-open .card-desc {
  display: block;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
}

.card-more { margin-top: 4px; }

.detail-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 14px;
  margin: 0;
  padding: 11px 13px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  font-size: .87rem;
}
.detail-list dt {
  font-weight: 700;
  color: var(--text-soft);
  font-size: .74rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  align-self: center;
}
.detail-list dd { margin: 0; color: var(--text); }

@media (max-width: 470px) {
  .detail-list { grid-template-columns: 1fr; gap: 1px 0; }
  .detail-list dd { margin-bottom: 8px; }
}

/* The subtitle. Deliberately not the same weight or color as the
   description underneath it, so the two never blur together. */
.card-where {
  margin: 0;
  font-size: .84rem;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--brand-blue-dark);
}
.card-where .dot { color: var(--line-strong); padding: 0 5px; font-weight: 400; }

.card-desc {
  margin: 0;
  font-size: .89rem;
  color: var(--text-soft);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.badges { display: flex; flex-wrap: wrap; gap: 5px; margin: 2px 0 0; padding: 0; list-style: none; }

.badge {
  font-size: .73rem;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-soft);
  border: 1px solid var(--line);
  white-space: nowrap;
}
.badge-age { background: var(--brand-blue-soft); color: var(--brand-blue-dark); border-color: transparent; }
.badge-free { background: var(--brand-green-soft); color: var(--brand-green-dark); border-color: transparent; }
.badge-register { background: var(--warn-bg); color: var(--warn-text); border-color: transparent; }

.card-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 5px; }

/* --- Month grid --------------------------------------------------------- */

.month { margin-bottom: 28px; }
.month-head { margin-bottom: 8px; }
.month-head h2 { margin: 0; font-family: var(--font-display); font-weight: 600; font-size: 1.2rem; }

.month-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }

.month-dow {
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-soft);
  text-align: center;
  padding: 4px 0;
}

.month-cell {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  min-height: 92px;
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.month-cell.is-empty { background: transparent; border-color: transparent; min-height: 0; }
.month-cell.is-today { border-color: var(--brand-green); box-shadow: inset 0 0 0 1px var(--brand-green); }

.month-date { font-size: .76rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text-soft); }

.month-item {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: var(--brand-blue-soft);
  color: var(--brand-blue-dark);
  border-radius: 5px;
  padding: 4px 5px;
  font: inherit;
  font-size: .7rem;
  line-height: 1.25;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.month-item:hover { background: var(--brand-green-soft); color: var(--brand-green-dark); }

.month-item { min-height: 26px; display: flex; align-items: center; }

.month-more {
  display: block;
  width: 100%;
  padding: 3px 4px;
  border: 0;
  border-radius: 4px;
  background: none;
  font: inherit;
  font-size: .68rem;
  color: var(--text-soft);
  text-align: left;
  cursor: pointer;
}
.month-more:hover { background: var(--surface-2); color: var(--text); }
.month-more:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* --- Dialogs ------------------------------------------------------------ */

dialog {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 18px;
  max-width: 520px;
  width: calc(100% - 32px);
  max-height: 86vh;
  max-height: 86dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-pop);
}
dialog::backdrop { background: rgba(10, 26, 20, .6); }

.dialog-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.dialog-head h2 { margin: 0 0 4px; font-family: var(--font-display); font-weight: 600; font-size: 1.25rem; }
.dialog-note { margin: 0 0 14px; font-size: .9rem; color: var(--text-soft); }
.dialog-hint { font-size: .82rem; color: var(--text-soft); margin: 12px 0 0; }
.dialog-url { font-size: .76rem; color: var(--text-soft); word-break: break-all; margin: 8px 0 0; }
.dialog-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }

.detail-when {
  margin: 0 0 3px;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--brand-green-dark);
}
.detail-body { margin-top: 12px; font-size: .94rem; }
.detail-body p { margin: 0 0 9px; }

.site-footer {
  /* Full content width, so the footer lines up with the event rows above it
     rather than stopping short in the middle of the page. */
  --footer-measure: none;
  margin-top: 34px;
  padding: 22px 0 40px;
  border-top: 1px solid var(--line);
  font-size: .86rem;
  color: var(--text-soft);
  background: var(--surface);
}
.site-footer p { margin: 0 0 7px; }
.sources { line-height: 1.9; }
.source-pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  border: 1px solid var(--line);
  margin-right: 4px;
  font-size: .78rem;
}
.source-pill.is-down { border-color: var(--warn-text); color: var(--warn-text); }

.empty {
  text-align: center;
  padding: 44px 16px;
  color: var(--text-soft);
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}

.loading { text-align: center; padding: 44px 16px; color: var(--text-soft); }

/* --- Wider screens ------------------------------------------------------ */

@media (min-width: 640px) {
  .filters { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .masthead .brand-name { font-size: 1.6rem; }
  .card { grid-template-columns: 96px 1fr; }
}

@media (min-width: 1000px) {
  .filters { grid-template-columns: 1.5fr 1fr 1.25fr 1.15fr .85fr 1.1fr; }
  .month-cell { min-height: 112px; }
}

@media (max-width: 470px) {
  .card { grid-template-columns: 1fr; }
  .card-time {
    flex-direction: row;
    gap: 8px;
    align-items: baseline;
    border-right: 0;
    border-bottom: 1px solid var(--line);
    padding: 0 0 7px;
  }
  .card-actions .btn { flex: 1 1 auto; }
  .month-cell { min-height: 64px; }
  .month-item { font-size: .62rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

@media (forced-colors: active) {
  .btn, .multi-btn, .card, .month-cell, dialog { border: 1px solid ButtonBorder; }
  .badge { border: 1px solid CanvasText; }
}

@media print {
  .filters, .masthead-actions, .card-actions, .site-footer { display: none; }
  .card { break-inside: avoid; box-shadow: none; }
  .card-desc { -webkit-line-clamp: unset; line-clamp: unset; display: block; }
}

/* --- The plain language search ------------------------------------------ */

.ask {
  background: linear-gradient(135deg, var(--brand-green-soft), var(--brand-blue-soft));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin: 18px 0 12px;
}

.ask-label {
  display: block;
  font-family: var(--font-display);
  font-size: 1.08rem;
  font-weight: 600;
  color: var(--brand-green-dark);
  margin-bottom: 8px;
}

.ask-row { display: flex; gap: 8px; align-items: center; position: relative; }

.ask-icon {
  position: absolute;
  left: 13px;
  width: 19px;
  height: 19px;
  color: var(--text-soft);
  pointer-events: none;
}

.ask-row input[type="search"] {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: 1rem;
  height: 52px;
  padding: 10px 14px 10px 42px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
}
.ask-row .btn { flex: none; min-height: 52px; }

.ask-help {
  margin: 10px 0 0;
  font-size: .84rem;
  color: var(--text-soft);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

.ask-example {
  font: inherit;
  font-size: .8rem;
  border: 1px dashed var(--line-strong);
  background: var(--surface);
  color: var(--brand-blue-dark);
  border-radius: 999px;
  padding: 6px 12px;
  min-height: 34px;
  cursor: pointer;
}
.ask-example:hover { border-style: solid; background: var(--surface-2); }

.ask-read {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-top: 12px;
}
.ask-read:empty { margin-top: 0; }

.ask-lead {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-soft);
}

.read-chip {
  font-size: .8rem;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--brand-green);
  color: var(--brand-green-dark);
}

.read-clear {
  font: inherit;
  font-size: .8rem;
  font-weight: 600;
  border: 0;
  background: none;
  color: var(--brand-blue-dark);
  text-decoration: underline;
  cursor: pointer;
  padding: 6px 8px;
  min-height: 34px;
}

.ask-note { margin: 0; font-size: .84rem; color: var(--text-soft); }

@media (max-width: 560px) {
  .ask-row { flex-wrap: wrap; }
  .ask-row .btn { width: 100%; }
}

/* --- Active filters ------------------------------------------------------ */

.active-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  align-items: center;
  margin: 0 0 14px;
}
.active-bar:empty { margin: 0; }

.active-lead {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-soft);
}

.active-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: inherit;
  font-size: .82rem;
  font-weight: 600;
  padding: 6px 10px 6px 13px;
  min-height: 36px;
  border-radius: 999px;
  background: var(--brand-green-soft);
  border: 1px solid var(--brand-green);
  color: var(--brand-green-dark);
  cursor: pointer;
}
.active-chip:hover { background: var(--surface-2); border-color: var(--line-strong); }
.active-x { font-size: 1.1rem; line-height: 1; opacity: .75; }

.active-clear {
  font: inherit;
  font-size: .82rem;
  font-weight: 600;
  border: 0;
  background: none;
  color: var(--brand-blue-dark);
  text-decoration: underline;
  cursor: pointer;
  padding: 6px 8px;
  min-height: 36px;
}

.card-until { font-size: .78rem; color: var(--text-soft); font-variant-numeric: tabular-nums; }

.empty-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 14px;
}

@media (max-width: 470px) {
  .card-time { flex-wrap: wrap; }
}

/* --- Sync to my calendar ------------------------------------------------- */

.feed-group {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 10px 10px;
  margin: 0 0 12px;
  min-inline-size: 0;
}
.feed-group legend {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-soft);
  padding: 0 5px;
}
.feed-options { display: grid; grid-template-columns: 1fr 1fr; gap: 1px 8px; }

.feed-count {
  margin: 4px 0 8px;
  font-size: .78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-soft);
}

.feed-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}
.feed-name { flex: 1 1 100%; font-weight: 700; font-size: .88rem; }

@media (max-width: 470px) {
  .feed-options { grid-template-columns: 1fr; }
}

/* The attribution and opt-out notice in the footer. Quiet, but not hidden:
   the whole point is that an organizer can find it without hunting. */
/* One measure for the whole footer. These used to be set in ch, which is
   relative to font size, so two paragraphs at different sizes wrapped at
   visibly different widths. */
.site-footer p { max-width: var(--footer-measure); }

/* Tags, with the control that turns them off sitting on the same line. */
.tag-row {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 8px 0 0;
}
.tag-row .badges { margin: 0; flex: 1 1 auto; }
.tags-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  margin-left: auto;
  padding: 4px 9px;
  min-height: 32px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--text-soft);
  font: inherit;
  font-size: .78rem;
  cursor: pointer;
}
.tags-toggle:hover { background: var(--surface-2); color: var(--text); }
.tags-toggle:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.tags-toggle .icon { width: 14px; height: 14px; flex: 0 0 auto; }
.card.tags-off .tag-row { margin-top: 6px; }

.site-footer .credit {
  font-size: .82rem;
  color: var(--text-soft);
  margin: 10px 0 0;
}

/* A caveat on a single filter option, read before you tick it rather than in
   a footnote nobody scrolls to. */
.opt-note {
  display: block;
  margin-top: 2px;
  font-size: .76rem;
  line-height: 1.35;
  color: var(--text-soft);
}

/* --- Card actions ------------------------------------------------------- */

/* Icons sit inside the buttons, so the label and the mark share a baseline
   and stay together when the row wraps on a narrow phone. */
.btn .icon {
  width: 16px;
  height: 16px;
  flex: none;
}

.cal-menu { position: relative; display: inline-flex; }

.card-cal .caret { width: 10px; height: 7px; flex: none; opacity: .8; }

.cal-panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 5px);
  left: 0;
  min-width: 100%;
  width: max-content;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop);
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cal-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text);
  font: inherit;
  font-size: .9rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  /* 2.5.8 target size, and a comfortable tap for somebody holding a baby. */
  min-height: 44px;
  white-space: nowrap;
}
.cal-item svg { width: 18px; height: 18px; flex: none; }
.cal-item:hover { background: var(--brand-green-soft); color: var(--brand-green-dark); }
.cal-item:focus-visible { outline: 3px solid var(--focus); outline-offset: -2px; }

@media (max-width: 480px) {
  /* On a phone the row is already tight, so the menu opens from the right
     edge instead of running off the screen. */
  .cal-panel { left: auto; right: 0; }
}

/* --- Calendar views ----------------------------------------------------- */

.cal-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--line);
}

.cal-heading {
  flex: 1 1 auto;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.05rem, 3.4vw, 1.3rem);
  text-align: center;
  color: var(--text);
}

.cal-nav .icon-btn svg { width: 20px; height: 20px; }
.cal-nav .btn { flex: none; }
#cal-today:disabled { opacity: .45; cursor: default; }

/* A row in a day or week view. Deliberately compact: the full card with its
   buttons lives in list view, and clicking a row takes you there. */
.cal-row {
  display: flex;
  align-items: baseline;
  gap: 9px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-left: 3px solid var(--brand-green);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--brand-green-soft);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  min-height: 44px;
}
.cal-row + .cal-row { margin-top: 6px; }

/* Day view expands a row into the full card where the row was standing. */
.cal-inline + .cal-inline { margin-top: 6px; }
.cal-inline-panel { margin: 0; }
.card.is-inline { margin: 0; }
.card.is-inline .card-open { cursor: pointer; }
.cal-row:hover { background: var(--surface-2); }
.cal-row:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.cal-row.is-allday { border-left-color: var(--brand-blue); background: var(--brand-blue-soft); }

.cal-row-time {
  flex: none;
  font-weight: 700;
  font-size: .8rem;
  color: var(--brand-green-dark);
  min-width: 3.4rem;
}
.cal-row.is-allday .cal-row-time { color: var(--brand-blue-dark); }

.cal-row-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cal-row-title { font-weight: 600; font-size: .9rem; line-height: 1.3; }
.cal-row-venue {
  font-size: .78rem;
  color: var(--text-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cal-empty {
  margin: 2rem 0;
  text-align: center;
  color: var(--text-soft);
}

/* --- Day ---------------------------------------------------------------- */

.day-allday { margin-bottom: 18px; }
.day-allday h3 {
  margin: 0 0 8px;
  font-size: .74rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-soft);
}

.day-slot {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.day-hour {
  font-weight: 700;
  font-size: .82rem;
  color: var(--text-soft);
  padding-top: 10px;
}
.day-items { min-width: 0; }

/* --- Week --------------------------------------------------------------- */

.week-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px;
}

.week-day {
  min-width: 0;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.week-day.is-today {
  border-color: var(--brand-green);
  box-shadow: inset 0 0 0 1px var(--brand-green);
}

.week-day-head {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin: 0 0 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: .9rem;
}
.week-dow {
  font-size: .72rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.week-date { font-weight: 700; font-size: 1.05rem; }
.week-today {
  margin-left: auto;
  font-size: .65rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--brand-green-dark);
}
.week-quiet { margin: 6px 0; font-size: .8rem; color: var(--text-soft); }

/* A week column is about 150px wide, which is not enough for a time and a
   title side by side without the title breaking one word per line. */
.week-day .cal-row { flex-direction: column; align-items: stretch; gap: 2px; }
.week-day .cal-row-time { min-width: 0; }
.week-day .cal-row-title { font-size: .84rem; }

/* Seven columns on a phone is seven unreadable slivers, so below this the
   week becomes seven stacked days. */
@media (max-width: 800px) {
  .week-grid { grid-template-columns: 1fr; }
  .week-day-head { font-size: 1rem; }
  .week-dow { font-size: .8rem; }
}

@media (max-width: 480px) {
  .day-slot { grid-template-columns: 3.2rem 1fr; gap: 8px; }
  .cal-row-time { min-width: 3rem; }
}


/* --- Staleness notice --------------------------------------------------- */

.notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 14px;
  padding: 12px 14px;
  border: 1px solid var(--warn-line);
  border-left: 4px solid var(--warn-line);
  border-radius: var(--radius-sm);
  background: var(--warn-bg);
  color: var(--warn-text);
}
.notice svg { width: 19px; height: 19px; flex: none; margin-top: 1px; }
.notice p { margin: 0; font-size: .88rem; line-height: 1.45; }

/* --- Prose pages (About) ------------------------------------------------ */

.prose {
  max-width: var(--prose-measure);
  margin: 0 auto;
  padding: 2.5rem 0 3.5rem;
}

/* On a text page the article is a centred column, so a full width footer
   underneath it starts and ends in the wrong places. Same box, same edges. */
.page-prose .site-footer .wrap > * {
  max-width: var(--prose-measure);
  margin-inline: auto;
}
.prose h1 {
  margin: 0 0 .6rem;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 6vw, 2.6rem);
  line-height: 1.1;
  color: var(--brand-green-dark);
}
.prose h2 {
  margin: 2.2rem 0 .5rem;
  font-family: var(--font-display);
  font-size: 1.25rem;
  color: var(--brand-green-dark);
}
.prose p { margin: 0 0 1rem; font-size: 1rem; line-height: 1.65; }
.prose .lede {
  font-size: 1.15rem;
  line-height: 1.55;
  color: var(--brand-blue-dark);
  font-weight: 500;
  margin-bottom: 1.4rem;
}
.prose ul { margin: 0 0 1rem; padding-left: 1.15rem; }
.prose li { margin: .4rem 0; line-height: 1.6; }
/* Body links only. Without the :not, this beats .btn-primary on specificity
   and paints the button's label blue on a green background. */
.prose a:not(.btn) { color: var(--brand-blue-dark); }
.prose-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 2rem; }

[data-theme="dark"] .prose h1,
[data-theme="dark"] .prose h2 { color: var(--text); }
[data-theme="dark"] .prose .lede { color: var(--text-soft); }


/* --- Touch targets ------------------------------------------------------ */

/* WCAG 2.5.8 asks for 44px, and so does anybody tapping one-handed with a
   toddler on the other arm. These were the three that missed. */

.card-open { min-height: 44px; }

.active-chip,
.active-clear { min-height: 44px; }

/* The month date is a button now: tap a day, get that day. */
.month-date {
  display: flex;
  align-items: center;
  gap: 5px;
  width: 100%;
  min-height: 30px;
  padding: 2px 4px;
  border: 0;
  border-radius: 5px;
  background: none;
  font: inherit;
  font-weight: 700;
  font-size: .78rem;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.month-date:hover { background: var(--brand-green-soft); color: var(--brand-green-dark); }
.month-date:focus-visible { outline: 3px solid var(--focus); outline-offset: -1px; }

.month-count {
  margin-left: auto;
  min-width: 18px;
  padding: 1px 5px;
  border-radius: 999px;
  background: var(--brand-green);
  color: #fff;
  font-size: .66rem;
  font-weight: 700;
  text-align: center;
}

@media (max-width: 700px) {
  /* Seven columns in a phone width is about fifty pixels each, which turns
     every title into "10...". Show the count instead and let the date button
     open the day. */
  .month-item,
  .month-more { display: none; }

  .month-cell { min-height: 52px; padding: 3px; }
  .month-date { min-height: 44px; justify-content: space-between; font-size: .85rem; }
  .month-count { font-size: .7rem; }
}


/* ---------- the contact form ------------------------------------------- */

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 34rem;
  margin: 1.6rem 0 0;
}
.form-row { display: flex; flex-direction: column; gap: 5px; }
.form-row label {
  font-size: .78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-soft);
}
.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form select,
.contact-form textarea {
  font: inherit;
  /* 16px, because anything smaller makes iOS Safari zoom the page on focus. */
  font-size: 1rem;
  padding: 11px 12px;
  min-height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
}
.contact-form textarea { min-height: 140px; resize: vertical; line-height: 1.5; }
.contact-form select {
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 34px;
}
.contact-form :is(input, select, textarea):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--brand-green);
}
.form-hint { font-size: .8rem; color: var(--text-soft); }

/* The honeypot. Only something automated ever finds it. */
.botcheck { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.h-captcha { min-height: 78px; }
