/* What should we do today? — Toronto */

/* Inter, self-hosted, so the page reads the same on every platform. The
   design uses one weight, medium — headings included — so one weight is all
   that ships.
   SIL Open Font License — see fonts/LICENSE-Inter.txt.
   swap, not block: the text appears immediately in a fallback and reflows
   when Inter arrives, rather than leaving the page blank.
   Latin covers the page; latin-ext exists for one line — "Muharrem Şenyıl"
   in the credit — and unicode-range keeps it from being downloaded by
   anyone who never renders those glyphs. Both faces carry a range, because
   a face without one claims every codepoint and would win the match. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/inter-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/inter-ext-500.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

:root {
  color-scheme: light;

  --ink:        #191919;
  --ink-soft:   #6f6f6f;
  --paper:      #ffffff;
  --line:       #e7e6e3;

  --col-about:  640px;
  --col-window: 320px;
  --tabs-h:     48px;
  --topbar-h:   52px;
  --head-h:     56px;

  --c-museum:       #e7e2f6;  --s-museum:       #f5f1fd;
  --c-art:          #d9ece7;  --s-art:          #eef7f4;
  --c-market:       #e3eedc;  --s-market:       #eff7ec;
  --c-flea:         #fbeeda;  --s-flea:         #fdf6e8;
  --c-books:        #dfe8f5;  --s-books:        #edf4fc;
  --c-architecture: #f6e3ec;  --s-architecture: #fbeff5;
  --c-festival:     #fbe6de;  --s-festival:     #fdf1ec;
  --c-dropin:       #f4eec3;  --s-dropin:       #fbf8e6;
  --c-social:       #e8e4dc;  --s-social:       #f6f4f0;
  --c-comedy:       #f0dbf5;  --s-comedy:       #faf2fc;
  --c-stage:        #ecdcc9;  --s-stage:        #f7efe6;
  --c-music:        #f6dbe1;  --s-music:        #fcf1f4;
  --c-film:         #dcdef2;  --s-film:         #eff0fb;
  --c-outdoors:     #d2e8ea;  --s-outdoors:     #ecf6f7;
  --c-food:         #e6efd3;  --s-food:         #f4f8ea;

  --shadow: 0 8px 30px rgba(20, 20, 20, .10), 0 1px 3px rgba(20, 20, 20, .06);

  /* notch and home-indicator insets; 0 everywhere that has none */
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  /* Medium everywhere. Headings still need it spelled out: they are h1/h2/h3
     and the UA would otherwise make them bold, and there is no bold file. */
  font: 500 15px/22px Inter, -apple-system, BlinkMacSystemFont,
        "Segoe UI", Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;      /* iOS must not resize text on rotate */
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
}

a { color: inherit; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

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

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 60;
  padding: 10px 16px; border-radius: 999px;
  background: var(--paper); box-shadow: var(--shadow); text-decoration: none;
}
.skip-link:focus { top: 12px; }

/* ------------------------------------------------------------------ board */

.board {
  display: flex;
  height: calc(100dvh - var(--topbar-h));
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
}

.col {
  flex: 0 0 var(--col-window);
  min-width: 0;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior-y: contain;
  border-right: 1px solid var(--line);
  scroll-snap-align: start;
}
.col--about { flex-basis: var(--col-about); }
.col:last-child { border-right: 0; }

.col__head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-height: var(--head-h);
  padding: 16px calc(26px + var(--safe-r)) 16px calc(26px + var(--safe-l));
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.col__title {
  margin: 0;
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  letter-spacing: -0.01em;
}

.col__range {
  font-size: 15px;
  line-height: 22px;
  color: var(--ink-soft);
  letter-spacing: -0.01em;
}

.col__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 9px calc(8px + var(--safe-r)) calc(124px + var(--safe-b)) calc(9px + var(--safe-l));
}

.col__empty {
  padding: 22px 12px;
  color: var(--ink-soft);
  font-size: 14px;
}

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

.about {
  max-width: 560px;
  padding: 36px calc(26px + var(--safe-r)) calc(124px + var(--safe-b)) calc(26px + var(--safe-l));
}

.about__art {
  display: block;
  width: 420px;
  max-width: 100%;          /* a phone's column is narrower than the image */
  height: auto;
  margin: 0 0 34px;
}
svg.about__art { width: 340px; height: auto; }

/* Sits directly under the hero, so it reads as a caption rather than copy.
   Selector has to out-specify `.about p`, which is (0,1,1) and would otherwise
   put this back to 15px — it silently did exactly that until 2026-09-09. */
.about p.about__credit {
  margin: -26px 0 32px;
  font-size: 11px;
  line-height: 16px;
  color: var(--ink-soft);
  letter-spacing: 0;
}
.about p.about__credit a { color: inherit; }

.about__social { margin: 0 0 22px; }
.about__social a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  color: var(--ink);
  text-decoration: none;
}
.about__social a { text-decoration: none; }
.about__social-icon { width: 18px; height: 18px; display: block; }

.about__lede {
  margin: 0 0 24px;
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  letter-spacing: -0.01em;
}

/* Keeps a last line from ending on one word — "Email me." was breaking so
   that "me." sat alone on a 48px line under a 508px paragraph. */
.about p { text-wrap: pretty; }

.about p {
  margin: 0 0 22px;
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  color: #696969;
  letter-spacing: -0.005em;
}

.about__note { font-size: 14px !important; }
.about a { text-decoration: none; border-bottom: 1px solid #c3c3c3; padding-bottom: 1px; }
.about a:hover { border-bottom-color: var(--ink); }

/* The handle is a signature, not a link in a sentence, so it carries no rule.
   Needs to out-specify `.about a`, which is (0,1,1) — the same weight as
   `.about__social a`, so source order was deciding and the border stayed. */
.about p.about__social a { border-bottom: 0; padding-bottom: 0; }

/* ------------------------------------------------------------------- card */

.card {
  display: block;
  width: 100%;
  padding: 16px;
  border: 0;
  border-radius: 16px;
  background: var(--card, #f0f0ee);
  font: inherit;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}
@media (hover: hover) {
  .card:hover { transform: translateY(-1px); filter: brightness(.985); }
  .card:hover .card__title { text-decoration: underline; text-decoration-color: currentColor; }
}
.card:focus-visible .card__title { text-decoration: underline; text-decoration-color: currentColor; }
.card:active { transform: translateY(0); }
.card:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.card--museum       { --card: var(--c-museum); }
.card--art          { --card: var(--c-art); }
.card--market       { --card: var(--c-market); }
.card--flea         { --card: var(--c-flea); }
.card--books        { --card: var(--c-books); }
.card--architecture { --card: var(--c-architecture); }
.card--festival     { --card: var(--c-festival); }
.card--dropin       { --card: var(--c-dropin); }
.card--social       { --card: var(--c-social); }
.card--comedy       { --card: var(--c-comedy); }
.card--stage        { --card: var(--c-stage); }
.card--music        { --card: var(--c-music); }
.card--film         { --card: var(--c-film); }
.card--outdoors     { --card: var(--c-outdoors); }
.card--food         { --card: var(--c-food); }

.card__title {
  margin: 0;
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  color: #222;
  letter-spacing: -0.01em;
  text-decoration-color: transparent;
  text-underline-offset: 2px;
  transition: text-decoration-color .15s ease;
}

.card__when {
  margin: 4px 0 0;
  font-size: 15px;
  line-height: 22px;
  color: #696969;
  letter-spacing: -0.005em;
}

.card__art {
  display: block;
  width: 216px;
  height: 216px;          /* square, as in the reference; the drawing letterboxes */
  max-width: 100%;
  margin: 28px auto 18px;
}
img.card__art { border-radius: 8px; }

/* The footer belongs to the phone layout; on a wide screen the when-line
   already carries the time and the price is one tap away in the modal. */
.card__foot { display: none; }

/* ----------------------------------------------------------------- topbar */

/* On every screen: the site needs to say its name somewhere, and on a wide
   one the board filled the whole viewport with no masthead at all. */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--topbar-h);
  padding: 0 calc(26px + var(--safe-r)) 0 calc(26px + var(--safe-l));
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.topbar__brand {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}
.topbar__brand:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 6px; }

/* The About column is on screen at this width, so a button to it is noise. */
.topbar__about { display: none; }
.topbar__about {
  border: 0;
  background: none;
  padding: 6px 0;
  color: var(--ink-soft);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
}
.topbar__about[aria-pressed="true"] { color: var(--ink); }
.topbar__about:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: 6px; }

/* ------------------------------------------------------------------- tabs */

/* Hidden on wide screens, where the columns speak for themselves. */
.tabs {
  display: none;
  position: sticky;
  top: 0;
  z-index: 20;
  align-items: stretch;
  gap: 2px;
  height: var(--tabs-h);
  padding: 0 calc(10px + var(--safe-r)) 0 calc(10px + var(--safe-l));
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  flex: 0 0 auto;
  position: relative;
  border: 0;
  background: none;
  padding: 0 12px;
  color: var(--ink-soft);
  font: inherit;
  font-size: 15px;
  line-height: 22px;
  letter-spacing: -0.01em;
  white-space: nowrap;
  cursor: pointer;
}
/* The underline is drawn on a pseudo-element so switching tabs does not
   change any box's size and shuffle the strip. */
.tab::after {
  content: '';
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: transparent;
}
.tab[aria-selected="true"] { color: var(--ink); }
.tab[aria-selected="true"]::after { background: var(--ink); }
.tab:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; border-radius: 8px; }

/* ------------------------------------------------------------------- dock */

.dock {
  position: fixed;
  left: 50%;
  bottom: calc(24px + var(--safe-b));
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
}

.dock__filter,
.dock__nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  border: 0;
  border-radius: 999px;
  background: var(--paper);
  box-shadow: var(--shadow);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  cursor: pointer;
  transition: transform .15s ease;
}
.dock__filter { height: 48px; padding: 0 16px; font-size: 15px; }
.dock__nav { width: 48px; height: 48px; }
/* The forward button carries the name of where it goes. A bare chevron is
   read as decoration; "This week ›" is read as a direction. */
.dock__nav--wide { width: auto; padding: 0 8px 0 16px; font-size: 15px; }
.dock__nav__label { white-space: nowrap; }
@media (hover: hover) {
  .dock__filter:hover, .dock__nav:hover { transform: translateY(-1px); }
}
.dock__filter svg, .dock__nav svg { width: 20px; height: 20px; display: block; }
.dock__filter[aria-expanded="true"] { background: #f1f0ed; }

/* ------------------------------------------------------------ the sheet */

.sheet {
  position: fixed;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 50;
  display: flex;
  flex-direction: column;
  width: min(440px, calc(100vw - 32px));
  max-height: min(84dvh, 720px);
  padding: 26px 26px 22px;
  border-radius: 24px;
  background: var(--paper);
  box-shadow: 0 24px 70px rgba(20, 20, 20, .22);
}

.sheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 20px;
}

.sheet__title {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.sheet__rows {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;               /* lets the list, not the sheet, do the scrolling */
  overflow-y: auto;
  overscroll-behavior: contain;
  /* room for focus rings, and a hint that the list continues */
  margin: 0 -4px;
  padding: 2px 4px;
}

/* Group heading inside the filter list. Sticky, because the list scrolls and
   a heading that has slid away leaves its rows unlabelled — on a small screen
   only two or three are in view at once.
   The padding-bottom is doing real work: .sheet__rows is a flex column with a
   10px gap, and a gap is not painted by anything, so a row scrolling past
   would show through it and cross the heading. The padding paints that strip,
   and the negative margin takes back the space it added. */
.sheet__group {
  position: sticky;
  top: -2px;                   /* covers .sheet__rows' 2px top padding */
  z-index: 1;
  margin: 0 0 -10px;
  padding: 8px 4px 14px;
  background: var(--paper);
  font-size: 13px;
  letter-spacing: -0.005em;
  color: var(--ink-soft);
}
.sheet__group:not(:first-child) { margin-top: 14px; }

.filter-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 17px 22px;
  border: 1px solid transparent;
  border-radius: 999px;
  /* categories set --soft to their own tint; price has none, so it falls back
     to a neutral rather than to nothing, which would leave the row invisible */
  background: var(--soft, #f2f1ee);
  font-size: 15px;
  letter-spacing: -0.01em;
  cursor: pointer;
  user-select: none;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.filter-row input { position: absolute; opacity: 0; pointer-events: none; }
@media (hover: hover) { .filter-row:hover { filter: brightness(.98); } }

/* unselected reads as an empty outline */
.filter-row:not(:has(input:checked)) {
  background: var(--paper);
  border-color: var(--line);
  color: #9a9a9a;
}

.filter-row__tick { width: 18px; height: 18px; opacity: 0; flex: 0 0 auto; margin-left: auto; }
.filter-row:has(input:checked) .filter-row__tick { opacity: .55; }
.filter-row:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }

.sheet__foot { display: flex; flex: 0 0 auto; gap: 10px; margin-top: 18px; }
.sheet__head { flex: 0 0 auto; }

.btn {
  border: 0;
  border-radius: 999px;
  padding: 17px 26px;
  font: inherit;
  font-size: 15px;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: filter .15s ease;
}
@media (hover: hover) { .btn:hover { filter: brightness(.96); } }
.btn--quiet { background: #f1f0ed; color: var(--ink); }
.btn--solid { flex: 1; background: #1c1c1c; color: #fff; }

.round-close {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  border: 1px solid #d6d4cf;
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
}
.round-close:hover { background: #f6f5f2; }
.round-close svg { width: 20px; height: 20px; }

/* ------------------------------------------------------------------ modal */

.scrim {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(30, 30, 30, .18);
  backdrop-filter: blur(1px);
}

.modal {
  position: fixed;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 50;
  width: min(560px, calc(100vw - 32px));
  max-height: min(84dvh, 760px);
  overflow-y: auto;
  padding: 34px 38px 38px;
  border-radius: 20px;
  background: var(--paper);
  box-shadow: 0 24px 70px rgba(20, 20, 20, .22);
}

.modal__close { position: absolute; top: 22px; right: 24px; }

.modal__title {
  margin: 0 60px 26px 0;
  font-size: 17px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.modal__art { margin: 0 0 26px; }
.modal__art-item { display: block; width: min(300px, 72%); height: auto; margin: 0 auto; }

.modal__desc {
  margin: 0 0 22px;
  font-size: 15px;
  line-height: 1.6;
  color: #3d3d3d;
}

.link {
  display: inline-block;
  font-size: 15px;
  text-decoration: none;
  border-bottom: 1px solid #c3c3c3;
  padding-bottom: 1px;
}
.link:hover { border-bottom-color: var(--ink); }

.modal__caveat {
  margin: 24px 0 0;
  padding: 12px 14px;
  border-radius: 10px;
  background: #fbf2e4;
  font-size: 14px;
  line-height: 1.5;
  color: #6b5a3c;
}

.modal__meta { margin: 26px 0 22px; }
.modal__meta dt { font-size: 13px; color: var(--ink-soft); }
.modal__meta dd { margin: 4px 0 20px; font-size: 15px; }
.modal__meta dd:last-child { margin-bottom: 0; }
.modal__meta-link { margin-top: -12px !important; }

/* ----------------------------------------------------------------- mobile */

@media (max-width: 720px) {
  :root { --col-about: 100vw; --col-window: 100vw; --head-h: 52px; }

  /* One panel at a time, chosen from the tab strip, scrolling straight down.
     No sideways scrolling on a phone at all: the board stops being a run of
     columns and becomes a container for whichever one is showing. */
  .topbar { padding: 0 calc(20px + var(--safe-r)) 0 calc(20px + var(--safe-l)); border-bottom: 0; }
  .topbar__about { display: block; }
  .tabs { display: flex; }
  .board { height: calc(100dvh - var(--tabs-h) - var(--topbar-h)); }
  .col { display: none; flex: 1 1 auto; width: 100%; border-right: 0; }
  .col--active { display: block; }
  /* The tab already names the window, so the header keeps only the dates. */
  .col:not(.col--about) .col__title { display: none; }
  .col:not(.col--about) .col__range { color: var(--ink); }
  .col--about .col__head { display: none; }
  /* The tabs do this job now, and better. */
  .dock__nav { display: none; }

  .board { scroll-snap-type: x mandatory; }

  .col { border-right: 0; }
  .col__head {
    min-height: var(--head-h);
    padding: 14px calc(20px + var(--safe-r)) 14px calc(20px + var(--safe-l));
  }
  .col__body {
    gap: 12px;
    padding: 16px calc(20px + var(--safe-r)) calc(124px + var(--safe-b)) calc(20px + var(--safe-l));
  }
  .about {
    padding: 22px calc(20px + var(--safe-r)) calc(124px + var(--safe-b)) calc(20px + var(--safe-l));
  }

  /* Shorter cards. At the desktop size two filled the screen and you could
     not see what a window held without scrolling; the drawing is still the
     first thing you notice, just not the only thing. */
  .card { padding: 14px 16px; border-radius: 16px; }
  .card__art { width: 132px; height: 132px; margin: 10px auto 4px; }

  /* Price on the left, time on the right, along the bottom of every card. */
  .card__foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 8px;
    font-size: 14px;
    line-height: 20px;
    color: var(--ink-soft);
  }
  .card__price { font-weight: 500; color: var(--ink); }
  .card__time { text-align: right; }
  /* The time reads in the footer now, so it is dropped from the date line —
     and a line left holding only a time has nothing to show at all. */
  .card__when-time { display: none; }
  .card__when--time-only { display: none; }

  /* dialogs rise from the bottom edge, thumb-first */
  .modal, .sheet {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    max-width: none;
    transform: none;
    border-radius: 26px 26px 0 0;
    max-height: 88dvh;
  }

  .modal {
    padding: 30px calc(24px + var(--safe-r)) calc(32px + var(--safe-b)) calc(24px + var(--safe-l));
  }
  .modal__close { top: 22px; right: 20px; }
  .modal__title { margin-right: 56px; }

  .sheet {
    padding: 24px calc(20px + var(--safe-r)) calc(24px + var(--safe-b)) calc(20px + var(--safe-l));
  }
  .filter-row { padding: 15px 20px; }
}

/* Short viewports — phone landscape, split view. The illustration is the first
   thing to give up its space; the words matter more. */
@media (max-height: 560px) {
  .modal { padding-top: 24px; padding-bottom: 24px; }
  .modal, .sheet { max-height: 92dvh; }
  .modal__title { margin-bottom: 18px; }
  .modal__art { margin-bottom: 18px; }
  .modal__art-item { width: auto; height: 96px; }
  .modal__meta { margin: 18px 0 16px; }
  .modal__meta dd { margin-bottom: 14px; }

  .sheet { padding-top: 18px; }
  .sheet__head { margin-bottom: 12px; }
  .filter-row { padding-top: 13px; padding-bottom: 13px; }
  .sheet__foot { margin-top: 12px; }
  .btn { padding-top: 14px; padding-bottom: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .board { scroll-behavior: auto; }
  .card, .dock__filter, .dock__nav { transition: none; }
}
