*,
*::before,
*::after {
  box-sizing: border-box;
}

@font-face {
  font-family: "Orbitron";
  src: url("/fonts/orbitron-variable.woff2") format("woff2");
  font-weight: 400 900;
  font-display: swap;
}

/* Satoshi from Fontshare, served as the official files (ITF Free Font License) */
@font-face {
  font-family: "Satoshi";
  src: url("/fonts/Satoshi-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Satoshi";
  src: url("/fonts/Satoshi-Medium.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "Satoshi";
  src: url("/fonts/Satoshi-Bold.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* The ASTR page's boxes on the halftone city: ink bars with paper letters,
   outlined paper bars for the quieter lines, orange for the title, the date
   and the one thing to press. Every bar has the same side padding, so their
   edges line up. */
:root {
  --paper: #efe7d6;
  --paper-hi: #f7f1e4;
  --ink: #141210;
  --accent: #ff8a2a;
  --title: "Orbitron", "Helvetica Neue", Arial, sans-serif;
  --body: "Satoshi", "Helvetica Neue", Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace;
  --gutter: max(1rem, 3vw);
  --bar-size: clamp(1.25rem, 2.5vw, 2.15rem);
  /* side padding inside every bar, the same whatever the bar's text size,
     so the date and the lines under it start on the same vertical */
  --pad: calc(var(--bar-size) * 0.32);
  --gap: 0.3rem;       /* between bars in a group */
  --group: 1.5rem;     /* between groups */
}

html,
body {
  margin: 0;
  min-height: 100%;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-weight: 500;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  overflow-x: hidden;
}

p,
h1,
h2 {
  margin: 0;
}

a {
  color: inherit;
}

#city-canvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
}

.no-city #city-canvas {
  display: none;
}

/* ------------------------------------------------------------ poster */

.poster {
  position: relative;
  z-index: 10;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 100vh;
  min-height: 100dvh;
  padding: max(var(--gutter), env(safe-area-inset-top, 0px)) max(var(--gutter), env(safe-area-inset-right, 0px))
    max(3.6rem, calc(env(safe-area-inset-bottom, 0px) + 3.2rem)) max(var(--gutter), env(safe-area-inset-left, 0px));
  pointer-events: none;
}

.poster-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
}

/* orange Orbitron with an ink outline, like the ASTR wordmark */
.wordmark {
  margin: 0 0 0 -0.03em;
  font-family: var(--title);
  font-weight: 900;
  font-size: clamp(2.4rem, 6vw, 6.6rem);
  line-height: 0.95;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--accent);
  -webkit-text-stroke: 2px var(--ink);
  paint-order: stroke fill;
}

.hint {
  margin-left: auto;
  padding: 0.2em 0.45em;
  background: var(--paper);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
}

.poster-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
}

.bill {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--group);
  min-width: 0;
}

.bill-group {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

.bar {
  display: inline-block;
  padding: 0.06em var(--pad) 0.12em;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--body);
  font-weight: 700;
  font-size: var(--bar-size);
  line-height: 1.1;
  letter-spacing: 0.01em;
}

/* everything on the poster is lowercase except the title; acronyms keep
   their capitals */
.poster :is(.bar, .strip, .pay-btn, .hint) {
  text-transform: lowercase;
}

.poster abbr {
  text-decoration: none;
  text-transform: none;
}

/* the round 0 sits a hair further left than the 1 below it, so the two
   read as one edge (round letters look indented when they align exactly) */
.bar-date {
  padding-left: calc(var(--pad) - 0.04em);
  color: var(--accent);
  font-size: clamp(1.8rem, 3.8vw, 3.3rem);
}

.bar-small {
  font-size: 0.95rem;
  letter-spacing: 0.04em;
}

.bar-quiet {
  background: var(--paper);
  color: var(--ink);
  box-shadow: inset 0 0 0 2px var(--ink);
  font-weight: 500;
}

/* the headliner, a size up from the rest of the line-up */
.bar.bar-head {
  font-weight: 700;
  font-size: clamp(1.6rem, 3.2vw, 2.8rem);
}

/* The supporting acts share one width, the longest name's, so their right
   edges line up. They sit in a column sized to them alone; the headliner
   spans past it and keeps its own width. */
.lineup {
  display: grid;
  grid-template-columns: max-content 1fr;
}

.lineup .bar {
  grid-column: 1;
  justify-self: stretch;
}

.lineup .bar.bar-head {
  grid-column: 1 / -1;
  justify-self: start;
}

/* ------------------------------------------------------------ tickets */

.ticket-panel {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--group);
  width: min(22rem, 100%);
  pointer-events: auto;
}

.ticket-group,
.checkout-panel,
.notes {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--gap);
}

.checkout-panel {
  width: 100%;
  gap: 0.55rem;
}

.bar-price {
  font-size: clamp(2.1rem, 3.4vw, 3rem);
  line-height: 0.95;
  font-variant-numeric: tabular-nums;
}

.qty {
  display: flex;
  align-items: stretch;
  gap: var(--gap);
}

.qty .bar {
  display: flex;
  align-items: center;
}

.qty-btn,
.qty-value {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--body);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.qty-value {
  background: var(--paper);
  color: var(--ink);
  box-shadow: inset 0 0 0 2px var(--ink);
}

.qty-btn {
  cursor: pointer;
}

.qty-btn:hover:not(:disabled),
.qty-btn:focus-visible {
  background: var(--accent);
  color: var(--ink);
}

.qty-btn:focus-visible,
.pay-btn:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}

.qty-btn:disabled {
  cursor: not-allowed;
  opacity: 0.35;
}

.email-field {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--gap);
  width: 100%;
}

.email-field input {
  width: 100%;
  min-height: 44px;
  padding: 0.3em 0.55em;
  border: 2px solid var(--ink);
  border-radius: 0;
  background: var(--paper-hi);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 1rem;
}

.email-field input:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 0;
}

/* buttons: outlined paper, orange when pressed (from the ASTR page) */
.pay-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.35em 0.9em 0.45em;
  border: 2px solid var(--ink);
  border-radius: 0;
  background: var(--paper-hi);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.02em;
  cursor: pointer;
}

.pay-btn:hover:not(:disabled),
.pay-btn:focus-visible {
  background: var(--accent);
}

.pay-btn:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}

.pay-btn:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.pay-submit {
  width: 100%;
  background: var(--ink);
  color: var(--paper);
  font-size: 1.35rem;
}

.pay-submit:hover:not(:disabled) {
  color: var(--ink);
}

/* the one orange bar to press */
.buy-btn {
  padding: 0.1em var(--pad) 0.18em;
  border: 0;
  background: var(--accent);
  color: var(--ink);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.8vw, 2.3rem);
  line-height: 1.05;
}

.buy-btn:hover,
.buy-btn:focus-visible {
  background: var(--ink);
  color: var(--accent);
}

/* a clear break between the buy button and the small print */
.notes {
  margin-top: 1.4rem;
}

.strip {
  max-width: 100%;
  padding: 0.18em 0.5em 0.24em;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.74rem;
  line-height: 1.45;
}

.strip:empty {
  display: none;
}

.legal-links {
  position: fixed;
  z-index: 25;
  left: max(var(--gutter), env(safe-area-inset-left, 0px));
  bottom: max(0.6rem, env(safe-area-inset-bottom, 0px));
  padding: 0.1em 0.4em;
  background: var(--paper);
  font-family: var(--mono);
  font-size: 0.72rem;
}

/* ------------------------------------------------------------ checkout sheet, ticket pages, door
   (the ASTR page's rules, with the new fonts) */

.pay-submit.is-busy::after {
  content: " ···";
  display: inline-block;
  animation: busy-pulse 0.9s ease-in-out infinite;
}

@keyframes busy-pulse {
  0%,
  100% {
    opacity: 0.2;
  }
  50% {
    opacity: 1;
  }
}

.ticket-err {
  min-height: 1.1em;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: #a12a12;
}

.save-warn {
  font-family: var(--mono);
  font-size: 0.74rem;
  line-height: 1.4;
}

/* checkout sheet */
.pay-sheet {
  position: fixed;
  z-index: 30;
  top: max(0.6rem, env(safe-area-inset-top, 0px));
  right: max(0.6rem, env(safe-area-inset-right, 0px));
  left: max(0.6rem, env(safe-area-inset-left, 0px));
  max-height: calc(100dvh - 1.2rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 1rem 1.1rem 1.2rem;
  background: var(--paper-hi);
  border: 2px solid var(--ink);
  box-shadow: 8px 8px 0 var(--ink);
}

.pay-sheet[hidden],
#pay-success[hidden],
#pay-form[hidden] {
  display: none;
}

.pay-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.8rem;
  font-weight: 700;
  font-size: 1.2rem;
}

.pay-close {
  font-size: 0.85rem;
}

#payment-element {
  margin: 0.35rem 0 0.8rem;
}

.wallet-hint {
  font-family: var(--mono);
  font-size: 0.78rem;
}

.pay-submit {
  margin-top: 0.4rem;
}

#sheet-thanks-note,
#thanks-note {
  font-family: var(--mono);
  font-size: 0.85rem;
}

/* thanks, contact and the door export page */
.sky-copy.thanks-copy {
  max-width: 38rem;
  padding: max(8vh, env(safe-area-inset-top, 0px)) var(--gutter) 8vh;
  font-size: 1.1rem;
  line-height: 1.45;
}

.thanks-copy > * + * {
  margin-top: 0.7rem;
}

.contact-page {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

.contact-kicker,
.type-credit {
  font-family: var(--mono);
  font-size: 0.78rem;
}

.contact-page .type-credit {
  margin-top: auto;
  padding-top: 1.6rem;
}


@media (min-width: 860px) {
  .pay-sheet {
    top: 6vh;
    right: var(--gutter);
    left: auto;
    width: min(27rem, 92vw);
    max-height: 88vh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pay-submit.is-busy::after {
    animation: none;
  }
}

/* tickets: the pay sheet success, thanks page and /t/<id> */
.ticket-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
  margin: 0.6rem 0;
  padding: 1.1rem 1rem 1.2rem;
  background: var(--paper-hi);
  border: 3px solid var(--ink);
  text-align: center;
}

.ticket-card[hidden] {
  display: none;
}

.ticket-qr {
  display: block;
  width: min(240px, 70vw);
  height: auto;
  aspect-ratio: 1;
  image-rendering: pixelated;
}

.ticket-admits {
  font-weight: 700;
  font-size: 1.6rem;
  line-height: 1.1;
}

.ticket-code {
  font-family: var(--mono);
  font-size: 0.95rem;
}

.ticket-used {
  padding: 0.15em 0.5em;
  background: var(--accent);
  font-family: var(--mono);
  font-size: 0.85rem;
}

.ticket-open {
  margin-top: 0.3rem;
  text-decoration: none;
}

.ticket-page {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
}

.ticket-page .ticket-card {
  align-self: stretch;
  max-width: 26rem;
}

.ticket-details {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.22rem;
}

.wordmark-small {
  font-size: clamp(2rem, 9vw, 3.4rem);
}

/* door scanner */
body.door {
  background: var(--paper);
}

.door-app {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 30rem;
  margin: 0 auto;
  padding: max(1rem, env(safe-area-inset-top, 0px)) 1rem 2rem;
}

.door-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
}

.door-status,
.door-sync,
.door-counts,
.door-hint {
  font-family: var(--mono);
  font-size: 0.85rem;
}

.door-actions {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.door-actions .buy-btn {
  width: 100%;
  margin: 0;
  padding: 0.4em;
}

.door-camera video {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border: 3px solid var(--ink);
  background: var(--ink);
}

.door-camera[hidden] {
  display: none;
}

.door-manual {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-family: var(--mono);
  font-size: 0.85rem;
}

.door-manual-row {
  display: flex;
  gap: 0.4rem;
}

.door-manual input {
  flex-grow: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0.2em 0.5em;
  border: 2px solid var(--ink);
  border-radius: 0;
  background: var(--paper-hi);
  font-family: var(--mono);
  font-size: 1.3rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.door-result {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  width: 100%;
  padding: 2rem;
  border: 0;
  color: var(--ink);
  font-family: var(--body);
  text-align: center;
  cursor: pointer;
}

.door-result[hidden] {
  display: none;
}

.door-result-ok {
  background: #3ddc84;
}

.door-result-warn {
  background: var(--accent);
}

.door-result-bad {
  background: #ff5a4f;
}

.door-result-big {
  font-weight: 700;
  font-size: clamp(3rem, 16vw, 6rem);
  line-height: 0.95;
}

.door-result-small {
  font-family: var(--mono);
  font-size: 1.1rem;
}

.door-result-tap {
  margin-top: 2rem;
  font-family: var(--mono);
  font-size: 0.85rem;
}

/* ------------------------------------------------------------ phones */

@media (pointer: coarse) {
  .hint {
    display: none;
  }
}

@media (max-width: 859px) {
  body.home {
    overflow-y: auto;
  }

  .poster {
    justify-content: flex-start;
    gap: var(--group);
    padding-bottom: 1.2rem;
  }

  .poster-top {
    margin-bottom: 38vh;
  }

  /* TUNNEL VISION is 9.4em wide in Orbitron: fill the line between gutters */
  .wordmark {
    font-size: calc((100vw - 2 * var(--gutter)) / 9.6);
    -webkit-text-stroke-width: 1.5px;
  }

  .hint {
    display: none;
  }

  .poster-bottom {
    flex-direction: column;
    align-items: stretch;
    gap: 2.4rem;
  }

  .ticket-panel,
  .ticket-group,
  .checkout-panel,
  .notes,
  .email-field {
    align-items: flex-start;
  }

  .bill,
  .ticket-panel {
    pointer-events: auto;
  }

  .legal-links {
    position: relative;
    left: auto;
    bottom: auto;
    display: inline-block;
    margin: 0 var(--gutter) max(1.2rem, env(safe-area-inset-bottom, 0px));
  }
}
