/* GigRally — reset, typography and page frame.
 *
 * Loaded after tokens.css. Nothing here names a colour or a size directly; everything
 * comes from a token, so the two themes and a band's own accent all work without this
 * file knowing they exist.
 */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* Stops iOS inflating text in landscape, which silently breaks the calendar grid. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-lg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* --- headings ------------------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  letter-spacing: var(--tracking-display);
  line-height: 1.05;
  margin: 0;
}
h1 { font-size: var(--text-h1); font-weight: 800; }
h2 { font-size: var(--text-h2); font-weight: 700; }
h3 { font-size: var(--text-h3); font-weight: 700; }

p { margin: 0; }

a {
  color: inherit;
  /* ⚠️ NOT var(--accent): stage gold on paper is 1.86:1. See tokens.css. */
  text-underline-offset: 2px;
}

/* A DM Mono uppercase label — the small heading used above every group on the screens. */
.label {
  font-family: var(--font-mono);
  font-size: var(--text-label-lg);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--muted);
}
.label--sm { font-size: var(--text-label); }

/* Dates and counts are tabular: a proportional font makes the digits jitter as numbers
 * change, which on a calendar is every tap. */
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

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

/* --- page frame ------------------------------------------------------------------ */
/* Drawn at 390px and capped at 760px on desktop; the gutter never collapses. */
.page {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.stack > * + * { margin-top: var(--s, 1rem); }
.stack--sm { --s: 0.5rem; }
.stack--lg { --s: 1.5rem; }

.row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}
.row--between { justify-content: space-between; }

/* ⚠️ The UA stylesheet's `[hidden] { display: none }` loses to ANY display rule set by a
   class, so `<div class="row" hidden>` is a visible flex row. The save-error notice is
   exactly that shape, and hiding it is how it stays out of the way until it is needed. */
[hidden] { display: none !important; }
.grow { flex-grow: 1; }

/* --- focus ----------------------------------------------------------------------- */
/* Visible, and the same shape everywhere. :focus-visible so a mouse click on a calendar
 * cell does not leave a ring behind, while a keyboard user always sees where they are. */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-sm, 4px);
}
:focus:not(:focus-visible) { outline: none; }

/* Keyboard users reach the content without tabbing the whole header first. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1rem;
  border-radius: 0 0 var(--radius-md) 0;
}
.skip-link:focus { left: 0; }

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

/* --- motion ---------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- hover ----------------------------------------------------------------------- */
/* ⚠️ Every :hover rule in this codebase is wrapped in this query. A phone keeps :hover
 * on the last thing tapped, which in the app this replaces made a just-tapped date look
 * unselected until you scrolled. The wrapper is not optional. */
@media (hover: hover) and (pointer: fine) {
  a:hover { text-decoration: underline; }
}

/* --- forced colors ---------------------------------------------------------------- */
/* Windows high-contrast throws away backgrounds, which is exactly what distinguishes a
 * free day from a busy one. The calendar's borders carry the state there instead. */
@media (forced-colors: active) {
  .day--free,
  .day--busy,
  .day--unanswered,
  .day--booked {
    forced-color-adjust: none;
    border-width: 2px;
  }
}

/* --- print ------------------------------------------------------------------------ */
@media print {
  .tab-bar,
  .skip-link { display: none; }
  body { background: #fff; color: #000; }
}
