/*
 * My Boston View.
 *
 * One column of dated rows is the whole site. Everything below earns its place
 * against that: there is no card, no shadow, no illustration, no hero and no
 * second colour. The accent is a Bruins gold, and it appears in exactly three
 * places (an urgency pill, the open row's left edge, and focus rings) so that
 * seeing it means something.
 *
 * NO INLINE STYLE ANYWHERE. The content security policy refuses it, and that
 * includes style attributes set from script through element.style. The page
 * code changes classes and the hidden attribute instead.
 */

:root {
  --ink: #111114;
  --ink-2: #55555f;
  --ink-3: #85858f;
  --paper: #ffffff;
  --paper-2: #f6f6f4;
  --line: #e4e4e0;
  --line-2: #d2d2cc;
  --accent: #b8860b;
  --accent-fill: #ffb81c;
  --accent-ink: #1a1a1a;
  --bad: #b3261e;
  --good: #1a6b3c;
  --good-bg: #eaf5ee;
  --warn-bg: #fdf6e3;
  --radius: 10px;
  --gutter: 16px;
  --column: 680px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/*
 * Dark mode follows the device and has no toggle, because a toggle is a
 * control the owner asked not to have. The accent is lightened rather than
 * reused: gold on near black at the light value fails contrast.
 */
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f2f2ef;
    --ink-2: #a8a8a2;
    --ink-3: #7a7a76;
    --paper: #131315;
    --paper-2: #1c1c1f;
    --line: #2b2b2f;
    --line-2: #3a3a3f;
    --accent: #ffc94d;
    --accent-fill: #ffb81c;
    --accent-ink: #1a1a1a;
    --bad: #ff8a80;
    --good: #7ddba4;
    --good-bg: #16281e;
    --warn-bg: #2a2416;
  }
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.45;
  /* No horizontal scroll at any width, ever. A single long word in a venue
   * name is the usual cause, and it is handled at the element rather than by
   * hiding overflow here, which would also hide a real layout bug. */
  overflow-x: hidden;
}

[hidden] { display: none !important; }

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

/* Focus is visible on everything, and it is the accent, so the one ring on the
 * page always means the same thing. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

button, input, textarea, select {
  font: inherit;
  color: inherit;
}

/* ------------------------------------------------------------- the gate -- */

.gate {
  max-width: 320px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  /* The block sits above centre. Vertically centred, it fights the on-screen
   * keyboard on a phone, which pushes the whole viewport up. */
  padding-top: max(18vh, 72px);
  padding-bottom: 120px;
  text-align: center;
}

.gate-mark {
  margin: 0;
  font-size: 20px;
  font-weight: 650;
  letter-spacing: -0.015em;
}

.gate-help {
  margin: 8px 0 28px;
  font-size: 13px;
  color: var(--ink-2);
}

.gate-form { text-align: left; }

.gate-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 6px;
}

.gate-input {
  width: 100%;
  height: 52px;
  padding: 0 14px;
  font-size: 18px;
  /* Tabular figures so the code does not reflow character by character as it
   * is typed, and uppercase because that is how it is written on the card it
   * was read off. */
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--paper);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
}

.gate-input::placeholder {
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-3);
}

.gate-error {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--bad);
}

.gate-button {
  width: 100%;
  height: 48px;
  margin-top: 14px;
  background: var(--ink);
  color: var(--paper);
  border: 0;
  border-radius: var(--radius);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

.gate-button:disabled { opacity: 0.55; cursor: default; }

.gate-foot {
  margin-top: 56px;
  font-size: 11px;
  color: var(--ink-3);
}

/* ----------------------------------------------------------- the frame -- */

.bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 48px;
  padding: 0 var(--gutter);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.bar-mark {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.015em;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}

.bar-nav { display: flex; align-items: center; gap: 14px; }

.bar-link {
  background: none;
  border: 0;
  padding: 6px 0;
  font-size: 13px;
  color: var(--ink-2);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}

.bar-link:hover { color: var(--ink); }

.board {
  max-width: var(--column);
  margin: 0 auto;
  padding: 0 0 96px;
}

/* -------------------------------------------------------- month divider -- */

.month {
  position: sticky;
  /* Under the bar, not under the top of the viewport, so the two never
   * overlap and the month a row belongs to is always on screen. */
  top: 48px;
  z-index: 10;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  height: 28px;
  padding: 0 var(--gutter);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.month-count { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- the row -- */

.row { border-bottom: 1px solid var(--line); }

.row-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 68px;
  padding: 10px var(--gutter);
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  /* The whole row is the tap target, date block included. */
  color: inherit;
}

.row-head:hover { background: var(--paper-2); }

.row.open { border-left: 3px solid var(--accent-fill); }
.row.open .row-head { padding-left: calc(var(--gutter) - 3px); }

.row.gone { opacity: 0.45; }
.row.gone .row-head { cursor: default; }
.row.gone .row-head:hover { background: none; }

.date {
  flex: 0 0 48px;
  text-align: center;
  line-height: 1.1;
}

.date-day {
  font-size: 20px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.date-month, .date-weekday {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* The second and later rows of one date run read quieter, so a day with three
 * things on it reads as one cluster instead of three separate days. */
.date.repeat .date-day { color: var(--ink-3); font-weight: 500; }
.date.repeat .date-month, .date.repeat .date-weekday { opacity: 0.55; }

.row-body { flex: 1 1 auto; min-width: 0; }

.row-title {
  font-size: 16px;
  font-weight: 620;
  letter-spacing: -0.01em;
  /* One line, ellipsis, never wrapping. The title is capped at 42 characters
   * on the way in, so this only ever catches a very narrow screen. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row-summary {
  margin-top: 2px;
  font-size: 13px;
  color: var(--ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row-by {
  margin-top: 2px;
  font-size: 12px;
  color: var(--ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row-aside {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  text-align: right;
}

.row-price {
  font-size: 15px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/*
 * THE UNIT LABEL. It is the only thing stopping $4,800 being read as a seat
 * price, so it is never abbreviated, never truncated and never dropped: no
 * ellipsis, no max-width, and nowrap so it cannot break in half.
 */
.row-unit {
  font-size: 11px;
  color: var(--ink-3);
  white-space: nowrap;
}

.row-avail {
  font-size: 11px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Drawn with two borders rather than an icon file or an inline SVG: it is two
 * lines, and this way there is nothing to load and nothing to sanitize. */
.chev {
  flex: 0 0 8px;
  width: 8px;
  height: 8px;
  margin: 0 2px 4px 2px;
  border-right: 2px solid var(--ink-3);
  border-bottom: 2px solid var(--ink-3);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}

.row.open .chev { transform: rotate(225deg); margin-bottom: 0; margin-top: 4px; }

@media (prefers-reduced-motion: reduce) {
  .chev { transition: none; }
}

/* --------------------------------------------------------------- pills -- */

.pill {
  display: inline-block;
  margin-bottom: 2px;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pill.soon { background: var(--accent-fill); color: var(--accent-ink); }
.pill.near { border: 1px solid var(--accent); color: var(--accent); }
.pill.flat { border: 1px solid var(--line-2); color: var(--ink-3); }

/* ---------------------------------------------------------- expansion -- */

/*
 * A CSS grid row from 0fr to 1fr, not a measured pixel height. A measured
 * height would mean writing element.style.height from script, which the
 * content security policy refuses.
 */
.row-more {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.2s ease;
}

.row.open .row-more { grid-template-rows: 1fr; }

.row-more > div { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .row-more { transition: none; }
}

.more-inner { padding: 2px var(--gutter) 22px; }

.details {
  margin: 0 0 16px;
  font-size: 14px;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 20px;
  margin-bottom: 20px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}

.fact-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.fact-value {
  margin-top: 2px;
  font-size: 14px;
  overflow-wrap: anywhere;
}

.hold-note {
  margin: 0 0 14px;
  padding: 10px 12px;
  background: var(--warn-bg);
  border-radius: 8px;
  font-size: 13px;
  color: var(--ink-2);
}

/* ---------------------------------------------------------- the forms -- */

.form { display: grid; gap: 14px; }

.field { display: block; }

.field-label {
  display: block;
  margin-bottom: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
}

.field-count {
  float: right;
  font-weight: 500;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.input, .textarea, .select {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  font-size: 16px; /* 16px or iOS zooms the page when the field is focused. */
}

.textarea { min-height: 76px; resize: vertical; line-height: 1.45; }

.input:disabled { background: var(--paper-2); color: var(--ink-3); }

.field-error {
  margin: 5px 0 0;
  font-size: 12px;
  color: var(--bad);
}

.input.bad, .textarea.bad { border-color: var(--bad); }

.two-up {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

/* The honeypot. Off screen by class, never by an inline style, and never
   display:none, which some bots check for. */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.stepper {
  display: flex;
  align-items: center;
  gap: 4px;
}

.stepper button {
  width: 44px;
  height: 44px;
  background: var(--paper);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.stepper button:disabled { color: var(--ink-3); cursor: default; }

.stepper-value {
  min-width: 52px;
  text-align: center;
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.static-line {
  padding: 11px 0;
  font-size: 14px;
  color: var(--ink-2);
}

.total-line {
  font-size: 13px;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

.identity {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  padding: 11px 12px;
  background: var(--paper-2);
  border-radius: 8px;
  font-size: 13px;
  color: var(--ink-2);
}

.identity-who { overflow-wrap: anywhere; }

.linkish {
  background: none;
  border: 0;
  padding: 0;
  font-size: 13px;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

.primary {
  width: 100%;
  min-height: 46px;
  background: var(--ink);
  color: var(--paper);
  border: 0;
  border-radius: var(--radius);
  font-size: 15px;
  font-weight: 620;
  cursor: pointer;
}

.primary:disabled { opacity: 0.55; cursor: default; }

.under-button {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--ink-3);
  text-align: center;
}

.form-error {
  margin: 0;
  padding: 10px 12px;
  background: var(--warn-bg);
  border-radius: 8px;
  font-size: 13px;
  color: var(--bad);
}

.done {
  padding: 16px;
  background: var(--good-bg);
  border-radius: var(--radius);
}

.done-line {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--good);
  overflow-wrap: anywhere;
}

.done-note {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--ink-2);
}

/* --------------------------------------------------------- the panels -- */

.panel {
  padding: 20px var(--gutter) 28px;
  border-bottom: 1px solid var(--line);
  background: var(--paper-2);
}

.panel-title { margin: 0; font-size: 15px; font-weight: 650; }

.panel-sub { margin: 4px 0 18px; font-size: 12px; color: var(--ink-3); }

.preview-label {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.preview {
  margin-bottom: 20px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.preview .row { border-bottom: 0; }
.preview .row-head { cursor: default; }
.preview .row-head:hover { background: none; }

.toggles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }

/* The scope picker has four, which wrap to two rows on a phone rather than
 * squeezing four labels into 343 pixels. */
.toggles.four { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* The line that tells a visitor their link covers only part of the board. */
.scope-note {
  margin: 0;
  padding: 10px var(--gutter);
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  color: var(--ink-2);
}

.toggle {
  height: 48px;
  background: var(--paper);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.toggle[aria-pressed="true"] {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.money { display: flex; align-items: center; gap: 8px; }
.money .input { flex: 1 1 auto; }
.money-unit { font-size: 13px; color: var(--ink-2); white-space: nowrap; }

/* ------------------------------------------------------- empty states -- */

.empty {
  padding: 64px var(--gutter);
  text-align: center;
  color: var(--ink-3);
  font-size: 14px;
}

.sold-toggle {
  display: block;
  width: 100%;
  padding: 16px var(--gutter);
  background: none;
  border: 0;
  font-size: 12px;
  color: var(--ink-3);
  cursor: pointer;
  text-align: center;
}

/* ---------------------------------------------------------- the admin -- */

.tabs {
  display: flex;
  gap: 2px;
  padding: 10px var(--gutter) 0;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}

.tab {
  flex: 0 0 auto;
  padding: 9px 12px;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-3);
  cursor: pointer;
  white-space: nowrap;
}

.tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--accent-fill); }

.tab-badge {
  display: inline-block;
  margin-left: 5px;
  padding: 1px 6px;
  background: var(--accent-fill);
  color: var(--accent-ink);
  border-radius: 999px;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}

.section-head {
  padding: 18px var(--gutter) 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.card {
  padding: 14px var(--gutter);
  border-bottom: 1px solid var(--line);
}

.card.untrusted {
  background: var(--warn-bg);
  border-left: 3px solid var(--accent-fill);
}

.card-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.card-title { font-size: 15px; font-weight: 620; overflow-wrap: anywhere; }

.card-meta { margin-top: 3px; font-size: 12px; color: var(--ink-2); overflow-wrap: anywhere; }

.card-note {
  margin-top: 8px;
  padding: 9px 11px;
  background: var(--paper-2);
  border-left: 2px solid var(--line-2);
  border-radius: 0 6px 6px 0;
  font-size: 13px;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

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

.action {
  padding: 7px 11px;
  background: var(--paper);
  border: 1px solid var(--line-2);
  border-radius: 7px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}

.action:hover { color: var(--ink); border-color: var(--ink-3); }
.action.strong { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.action.danger { color: var(--bad); border-color: var(--line-2); }
.action:disabled { opacity: 0.4; cursor: default; }

.status-tag {
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}

.status-tag.live { border-color: var(--good); color: var(--good); }
.status-tag.new { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--accent-ink); }

.code-value {
  font-size: 17px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  overflow-wrap: anywhere;
}

.admin-note {
  padding: 14px var(--gutter);
  font-size: 12px;
  color: var(--ink-3);
}

.bignum {
  font-size: 22px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 16px var(--gutter);
  border-bottom: 1px solid var(--line);
}

.log { padding: 4px var(--gutter) 24px; }

.log-row {
  display: flex;
  gap: 10px;
  padding: 5px 0;
  font-size: 12px;
  color: var(--ink-3);
  border-bottom: 1px solid var(--line);
  overflow-wrap: anywhere;
}

.log-when { flex: 0 0 116px; font-variant-numeric: tabular-nums; }

/* ----------------------------------------------- server rendered pages -- */

body.plain {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  min-height: 100vh;
  padding: max(16vh, 64px) var(--gutter) 64px;
}

.plain-card { max-width: 380px; text-align: center; }
.plain-title { margin: 0 0 14px; font-size: 20px; font-weight: 650; letter-spacing: -0.015em; }
.plain-line { margin: 0; font-size: 15px; }
.plain-note { margin: 10px 0 0; font-size: 13px; color: var(--ink-2); }
.plain-actions { margin-top: 26px; }
.plain-link { color: var(--accent); font-size: 14px; }

.plain-button {
  margin-top: 18px;
  min-height: 46px;
  padding: 0 22px;
  background: var(--ink);
  color: var(--paper);
  border: 0;
  border-radius: var(--radius);
  font-size: 15px;
  font-weight: 620;
  cursor: pointer;
}

/* ------------------------------------------------------------- phones -- */

@media (max-width: 560px) {
  .facts { grid-template-columns: minmax(0, 1fr); gap: 11px; }
  .two-up { grid-template-columns: minmax(0, 1fr); }
  .stats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .bignum { font-size: 18px; }
  .log-when { flex-basis: 78px; }
  .bar-nav { gap: 12px; }
  .row-head { min-height: 72px; }
}

@media (max-width: 380px) {
  :root { --gutter: 13px; }
  .date { flex-basis: 42px; }
  .row-title { font-size: 15px; }
}
