/*
 * The room — /production/<slug>/tickets/.
 *
 * Loaded after theme.css so the tokens are already defined; this file sets no
 * new colours of its own beyond two seat-state fills derived from the sandstone
 * ramp. The one rule worth knowing before editing: seat STATE is never carried
 * by colour alone. Sold seats take a hatch pattern, held seats take dots,
 * wheelchair spaces are round instead of rectangular, and companion and
 * transfer seats carry a drawn mark. Colour is the fourth signal, not the
 * first, because this is the control that decides whether someone can buy a
 * ticket without telephoning.
 */

/* -------------------------------------------------------------- the hero -- */

.tickets-hero__inner {
  display: grid;
  gap: var(--gutter);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 60rem) {
  .tickets-hero__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    align-items: end;
  }
}

.tickets-hero__title {
  font-family: var(--display);
  font-size: var(--step-5);
  line-height: 1.12;
  margin: 0.2em 0 0.3em;
  color: var(--paper);
}

.tickets-hero__when {
  font-size: var(--step-2);
  margin: 0;
  color: var(--paper);
}

.tickets-hero__time {
  color: var(--accent);
  margin-left: 0.5ch;
}

.tickets-hero__where {
  margin: 0.35em 0 0;
  color: var(--stone-300);
}

/* The performance switcher. Chips, not a select: a select hides the run behind
   a click and this page exists to compare nights. */
.switcher__list {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.switcher__chip {
  display: flex;
  align-items: baseline;
  gap: 0.5ch;
  padding: 0.55rem 0.8rem;
  min-height: 44px;
  border: 1px solid var(--stone-700);
  border-radius: 3px;
  text-decoration: none;
  color: var(--paper);
  background: transparent;
}

.switcher__chip:hover { border-color: var(--accent); }

.switcher__chip[aria-current="page"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--night);
  font-weight: 600;
}

.switcher__dow {
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.switcher__date { font-weight: 600; }

.switcher__time {
  font-size: var(--step--1);
  opacity: 0.85;
}

/* ------------------------------------------------------- the honesty band -- */

/*
 * Deliberately not a warning box. It is the page's own voice, set in the
 * body face at reading size, sitting in the flow where a lede would — because
 * what it says is an argument for the architecture, not a caveat about it.
 */
.modelled {
  max-width: 46rem;
  margin: 0;
  padding: 1.6rem 0 0;
  color: var(--ink-soft);
  font-size: var(--step--1);
  line-height: 1.6;
}

.modelled__shell { padding-inline: var(--gutter); }

/* ------------------------------------------------------------ the layout -- */

/*
 * The key and the accessible filter sit in a band ABOVE the map rather than in
 * a rail beside it. The first build put them in a sidebar and it cost the map
 * three hundred pixels of width, which pushed the room into a horizontal
 * scroll on a 1440px desktop — the one surface in this build that must not
 * need scrolling to be understood. Above also puts the accessible-seat controls
 * in front of the map instead of alongside it, which is the ordering the RFP's
 * accessibility requirement deserves.
 */
.room__shell { display: block; }

.room__aside {
  display: grid;
  gap: var(--gutter) 2.5rem;
  grid-template-columns: minmax(0, 1fr);
  padding-bottom: 1.75rem;
  margin-bottom: 1.75rem;
  border-bottom: 1px solid var(--stone-300);
}

@media (min-width: 52rem) {
  .room__aside { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); }
  .seatfilter__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 76rem) {
  .seatfilter__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ------------------------------------------------------------ the legend -- */

.legend__list,
.seatfilter__list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.legend__list li {
  display: grid;
  grid-template-columns: 1.9rem 1fr auto;
  align-items: center;
  gap: 0.6rem;
  padding: 0.32rem 0;
  font-size: var(--step--1);
}

.legend__mark { width: 1.9rem; height: 1.6rem; }

.legend__n {
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

/*
 * The legend's swatches are their own tiny vector marks, so they cannot reference the
 * map's <defs> — an SVG pattern is scoped to its document fragment. Rather than
 * duplicate the pattern markup six times, the two patterned swatches redraw the
 * same geometry as a CSS gradient overlay. Same picture, a quarter of the
 * markup, and the shapes below still carry the difference on their own.
 */
.lg { stroke: var(--stone-600); stroke-width: 1; }
.lg--a { fill: var(--stone-200); }
.lg--s,
.lg--h { fill: var(--stone-100); }
.lgm { stroke: var(--ink); stroke-width: 2.4; fill: none; stroke-linecap: round; }

.legend__list li:nth-child(2) .legend__mark,
.legend__list li:nth-child(3) .legend__mark {
  position: relative;
}

.legend__list li:nth-child(2) .legend__mark::after,
.legend__list li:nth-child(3) .legend__mark::after {
  content: "";
  position: absolute;
  inset: 0.15rem 0.1rem;
  border-radius: 3px;
  pointer-events: none;
}

.legend__list li:nth-child(2) .legend__mark::after {
  background: repeating-linear-gradient(45deg, transparent 0 2px, var(--stone-600) 2px 3.4px);
}

.legend__list li:nth-child(3) .legend__mark::after {
  background: radial-gradient(var(--stone-600) 1.5px, transparent 1.6px) 0 0 / 5px 5px;
}

/* ------------------------------------------------------------ the filter -- */

.seatfilter__list {
  display: grid;
  gap: 0.9rem 1.75rem;
  align-items: start;
}

.seatfilter__row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  min-height: 44px;
  padding: 0.35rem 0;
  cursor: pointer;
}

.seatfilter__row input {
  width: 1.4rem;
  height: 1.4rem;
  margin: 0.1rem 0 0;
  accent-color: var(--ember);
  flex: none;
}

.seatfilter__label { font-weight: 600; }

.seatfilter__detail {
  margin: 0 0 0 2rem;
  font-size: var(--step--1);
  color: var(--ink-soft);
  line-height: 1.5;
}

.seatfilter__note {
  margin: 1.1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--stone-300);
  font-size: var(--step--1);
  color: var(--ink-soft);
}

/* --------------------------------------------------------------- the map -- */

.map__frame { min-width: 0; }

/*
 * The map scrolls sideways rather than shrinking. Seats must stay at least
 * 26 CSS pixels apart centre to centre for WCAG 2.2 target size (2.5.8) to
 * clear them by spacing, and 475 seats cannot do that inside 390 pixels. The
 * scroll is honest about it; the "best available" button beside it means nobody
 * has to use the scroll to buy.
 */
.map__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-bottom: 0.5rem;
}

/*
 * min-width is the accessibility floor, not a layout preference. The seats are
 * 20 units wide on a 26-unit pitch, and WCAG 2.2 target size (2.5.8) clears
 * undersized targets whose centres are at least 24 CSS pixels apart, so one
 * drawing unit must never fall below 1 CSS pixel. --map-w is the viewBox's own
 * measured width, written by the template, so this floor cannot drift out of
 * step with the geometry the way a hard-coded number would.
 *
 * max-width caps the other end: given the room's proportions, letting the map
 * fill a 1400px column would make it 1500px tall and put the balcony below the
 * fold on every desktop.
 */
.map {
  display: block;
  min-width: var(--map-w, 780px);
  max-width: 62rem;
  width: 100%;
  height: auto;
  margin-inline: auto;
}

.map__scrollnote {
  margin: 0.4rem 0 0;
  font-size: var(--step--1);
  color: var(--ink-soft);
}

@media (min-width: 78rem) {
  .map__scrollnote { display: none; }
}

/* The stage, under the proscenium. The one place the arch motif is literal. */
.stage__arch {
  fill: var(--stone-200);
  stroke: var(--stone-400);
  stroke-width: 1.5;
}

.stage__floor { fill: var(--stone-400); }

.stage__label {
  font-family: var(--body);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.22em;
  fill: var(--stone-700);
}

.boxfront {
  fill: none;
  stroke: var(--stone-400);
  stroke-width: 1.5;
}

.boxfront__label {
  font-family: var(--body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  fill: var(--ink-soft);
}

.rail line {
  stroke: var(--stone-400);
  stroke-width: 1.5;
  stroke-dasharray: 7 5;
}

.rail__label,
.rowlabels text {
  font-family: var(--body);
  fill: var(--ink-soft);
}

.rail__label {
  font-size: 13px;
  letter-spacing: 0.18em;
}

.rowlabels text {
  font-size: 15px;
  font-weight: 600;
}

/* --------------------------------------------------------------- a seat -- */

.seat {
  fill: var(--stone-200);
  stroke: var(--stone-500);
  stroke-width: 1;
  cursor: pointer;
  transition: fill 120ms ease, stroke 120ms ease;
}

.seat .mk {
  stroke: var(--ink);
  stroke-width: 2.4;
  fill: none;
  stroke-linecap: round;
}

.seat:hover { stroke: var(--ember); stroke-width: 2; }

/*
 * Focus has to survive on top of a hatch pattern and a tinted ground, so it is
 * a dark ring plus an outer light ring rather than a single hairline.
 */
.seat:focus-visible {
  outline: none;
  stroke: var(--ink);
  stroke-width: 3.5;
  paint-order: stroke;
}

/* State. Pattern first, colour second. */
.seat[data-s="s"] {
  fill: url(#hatch);
  stroke: var(--stone-400);
  cursor: not-allowed;
}

.seat[data-s="h"] {
  fill: url(#dots);
  stroke: var(--stone-500);
  cursor: not-allowed;
}

.pat-bg { fill: var(--stone-100); }
.pat-line { stroke: var(--stone-500); stroke-width: 2.2; }
.pat-dot { fill: var(--stone-500); }

/* Chosen. Solid ink, the only fully dark seat on the map, plus a heavier ring
   so the state reads without relying on the fill's darkness alone. */
.seat[data-chosen] {
  fill: var(--ember);
  stroke: var(--ink);
  stroke-width: 2.5;
}

.seat[data-chosen] .mk { stroke: var(--paper); }

/* Filter dimming. Never hides a seat — a map with holes in it stops being a
   map of this room — and never removes it from the keyboard order. */
.map[data-filtered] .seat:not([data-match]) {
  opacity: 0.28;
}

.map[data-filtered] .seat[data-match] {
  stroke: var(--ember);
  stroke-width: 2.5;
}

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

/* ------------------------------------------------------- the pick panel -- */

.pick {
  margin-top: 1.5rem;
  padding: 1.25rem;
  background: var(--paper-raised);
  border: 1px solid var(--stone-300);
  border-radius: 4px;
  display: grid;
  gap: 1.1rem;
}

@media (min-width: 48rem) {
  .pick {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
  }
}

.pick__empty {
  margin: 0.4rem 0 0;
  color: var(--ink-soft);
}

.pick__list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.pick__list li {
  display: flex;
  align-items: center;
  gap: 0.5ch;
  background: var(--paper);
  border: 1px solid var(--stone-400);
  border-radius: 3px;
  padding: 0.3rem 0.3rem 0.3rem 0.65rem;
  font-size: var(--step--1);
  font-weight: 600;
}

.pick__drop {
  min-width: 32px;
  min-height: 32px;
  border: 0;
  background: transparent;
  color: var(--ember);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 3px;
}

.pick__drop:hover { background: var(--band); }

.pick__price {
  margin: 0.9rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px solid var(--stone-300);
  display: flex;
  flex-wrap: wrap;
  gap: 0.6ch;
  align-items: baseline;
  font-size: var(--step--1);
}

.pick__price-label {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: var(--ink-soft);
}

.pick__price-value { color: var(--ink); }

.pick__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.pick__actions .btn { min-height: 48px; }

.btn[aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

/* ----------------------------------------------------------- the handoff -- */

.handoff__grid {
  display: grid;
  gap: var(--gutter);
  grid-template-columns: minmax(0, 1fr);
  margin-top: 1rem;
}

@media (min-width: 58rem) {
  .handoff__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.handoff__demo {
  background: var(--paper-raised);
  border: 1px solid var(--stone-300);
  border-radius: 4px;
  padding: 1.25rem;
}

.handoff__demo-label {
  margin: 0 0 0.9rem;
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: var(--ink-soft);
}

.handoff__layers {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: none;
}

/*
 * The seam, drawn. Our two layers sit flush against Tessitura's; the dashed
 * edges are where our control stops. That boundary is the honest part of this
 * panel and it should be the part you see first.
 */
.handoff__layer {
  display: grid;
  gap: 0.15rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--stone-400);
}

.handoff__layer + .handoff__layer { border-top: 0; }

.handoff__layer--ours {
  background: var(--band);
}

.handoff__layer--theirs {
  background: var(--paper);
  border-top: 2px dashed var(--stone-600);
  border-bottom: 2px dashed var(--stone-600);
}

/*
 * --ember is verified AA against --paper, not against --band, and this eyebrow
 * sits on --band: it measured 4.39:1, just under. That is the tinted-ground
 * trap theme.css warns about, caught by axe rather than by eye. A surface that
 * is not --paper needs its own verified ink, so this is one: 5.3:1 on --band.
 */
.handoff__who {
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: #7a4e0f;
}

.handoff__layer--theirs .handoff__who { color: var(--ember); }

.handoff__what {
  font-size: var(--step--1);
  color: var(--ink);
  line-height: 1.5;
}

.handoff__queue { margin: 1rem 0 0; font-size: var(--step--1); }

/* ------------------------------------------------------ the waiting room -- */

.queue {
  min-height: 60vh;
  display: grid;
  align-content: center;
}

.queue__inner {
  max-width: 34rem;
  margin: 0 auto;
  text-align: center;
}

.queue__title {
  font-family: var(--display);
  font-size: var(--step-4);
  line-height: 1;
  margin: 0.3em 0;
}

.queue__when {
  font-size: var(--step-2);
  margin: 0;
}

/* Text weight amber, because this bay is paper. See the note in the template. */
.queue__time {
  color: var(--ember);
  margin-left: 0.5ch;
}

/*
 * The queue's own graphic is the fanlight, filling. Not a spinner: a spinner
 * says "something is happening" and says nothing about how long, which is the
 * only question anybody in a queue has.
 */
.queue__glass {
  width: min(20rem, 70vw);
  margin: 1.5rem auto;
  aspect-ratio: 2 / 1;
  border-radius: var(--arch-top);
  border: 2px solid var(--stone-500);
  background:
    linear-gradient(to top, var(--accent) var(--queue-fill, 0%), transparent var(--queue-fill, 0%)),
    var(--paper-raised);
  position: relative;
  overflow: hidden;
  transition: background 600ms ease;
}

.queue__glass::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, var(--stone-500) 0 2px, transparent 2px) 50% 0 / 100% 100%,
    radial-gradient(circle at 50% 100%, transparent 40%, var(--stone-500) 40%, var(--stone-500) calc(40% + 2px), transparent calc(40% + 2px));
  opacity: 0.5;
}

.queue__pos {
  font-family: var(--display);
  font-size: var(--step-5);
  line-height: 1;
  display: block;
  font-variant-numeric: tabular-nums;
}

.queue__label {
  display: block;
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-soft);
  margin-top: 0.5rem;
}

.queue__wait { font-size: var(--step-1); margin: 1.2rem 0 0; }

.queue__note {
  margin: 1.6rem auto 0;
  max-width: 30rem;
  font-size: var(--step--1);
  color: var(--ink-soft);
  line-height: 1.6;
}

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