/* Components. They read semantic tokens only, so every one of them follows
   Live's look or the event style it sits inside. */

@layer components {
  /* ---- Type ------------------------------------------------------- */

  .ui-title {
    font-family: var(--font-display);
    font-weight: var(--title-weight);
    font-size: var(--title-size, var(--text-3xl));
    line-height: var(--title-leading);
    letter-spacing: var(--title-tracking);
    text-transform: var(--title-case);
    color: var(--color-heading);
    text-wrap: balance;
    overflow-wrap: anywhere;
  }

  /* DS8: a headline the display face cannot render is set entirely in the
     safe face, never letter by letter. Applied by the display_font filter. */
  .ui-title--safe,
  .ui-heading--safe {
    font-family: var(--font-display-safe);
    font-weight: var(--title-weight-safe);
    letter-spacing: var(--title-tracking-safe);
  }

  .ui-title em,
  .ui-heading em {
    font-style: var(--title-style-accent);
    color: var(--color-brand);
  }

  .ui-title--lg { --title-size: var(--text-4xl); }
  .ui-title--md { --title-size: var(--text-2xl); }

  .ui-heading {
    font-family: var(--heading-font);
    font-weight: var(--heading-weight);
    font-size: var(--heading-size, var(--text-2xl));
    letter-spacing: var(--heading-tracking);
    line-height: 1.1;
    color: var(--color-heading);
  }

  .ui-heading--sm { --heading-size: var(--text-xl); }

  /* Programme sets headings as small mono labels. */
  [data-style="programme"] .ui-heading {
    --heading-size: var(--text-xs);
    text-transform: uppercase;
    color: var(--color-faint);
  }

  .ui-label {
    font-family: var(--label-font);
    font-size: var(--label-size);
    font-weight: var(--label-weight);
    text-transform: var(--label-case);
    letter-spacing: var(--label-tracking);
    color: var(--label-color);
    line-height: 1.3;
  }

  .ui-lede {
    font-size: var(--text-lg);
    line-height: 1.55;
    color: var(--color-text);
    max-width: 38rem;
  }

  .ui-data {
    font-family: var(--font-data);
    font-weight: var(--data-weight);
    font-variant-numeric: var(--data-figures);
    color: var(--color-heading);
  }

  .ui-muted { color: var(--color-muted); }
  .ui-small { font-size: var(--text-sm); }

  /* ---- Buttons ---------------------------------------------------- */

  .ui-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--p-space-2);
    min-height: var(--control-height);
    padding: 0 var(--p-space-5);
    border: 1px solid transparent;
    border-radius: var(--radius-control);
    background: var(--color-surface);
    color: var(--color-heading);
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition:
      background-color var(--duration) var(--ease),
      border-color var(--duration) var(--ease),
      box-shadow var(--duration) var(--ease),
      transform var(--p-duration-fast) var(--ease);
  }

  .ui-btn:hover { text-decoration: none; }
  .ui-btn:active { transform: translateY(1px); }

  .ui-btn--primary {
    background: var(--color-brand);
    color: var(--color-on-brand);
    box-shadow: var(--shadow-action);
  }

  .ui-btn--primary:hover {
    background: var(--color-brand-hover);
    color: var(--color-on-brand);
  }

  .ui-btn--secondary {
    border-color: var(--color-line-strong);
  }

  .ui-btn--secondary:hover {
    border-color: var(--color-heading);
    color: var(--color-heading);
  }

  .ui-btn--quiet {
    background: transparent;
    color: var(--color-brand);
    padding-inline: var(--p-space-2);
  }

  .ui-btn--quiet:hover {
    color: var(--color-brand-hover);
    background: var(--color-brand-soft);
  }

  .ui-btn--lg {
    min-height: var(--control-height-lg);
    padding-inline: var(--p-space-7);
    font-size: var(--text-lg);
  }

  .ui-btn--sm {
    min-height: 2.25rem;
    padding-inline: var(--p-space-4);
    font-size: var(--text-sm);
    width: fit-content;
  }

  .ui-btn--danger {
    background: var(--color-bad);
    color: #ffffff;
  }

  .ui-btn--danger:hover { background: color-mix(in srgb, var(--color-bad) 88%, black); color: #ffffff; }

  .ui-btn--block { width: 100%; }

  .ui-btn:disabled,
  .ui-btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
  }

  /* ---- Fields ----------------------------------------------------- */

  .ui-field {
    display: flex;
    flex-direction: column;
    gap: var(--p-space-2);
  }

  .ui-field__label {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-heading);
  }

  .ui-field__help {
    font-size: var(--text-sm);
    color: var(--color-muted);
  }

  .ui-field__error {
    display: flex;
    align-items: center;
    gap: var(--p-space-2);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-bad);
  }

  .ui-field__required { color: var(--color-bad); margin-left: 2px; }

  .ui-field.has-error .ui-input { border-color: var(--color-bad); }

  select.ui-input {
    appearance: none;
    padding-right: 2.5rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236f6a88' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.875rem center;
  }

  input[type="file"].ui-input { padding: 0.45rem 0.8rem; }

  input[type="file"].ui-input::file-selector-button {
    margin-right: var(--p-space-3);
    padding: 0.35rem 0.8rem;
    border: 0;
    border-radius: var(--radius-inner);
    background: var(--color-brand-soft);
    color: var(--color-brand);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
  }

  /* Radio and checkbox options as clickable cards. */
  .ui-choices { display: grid; gap: var(--p-space-2); }

  .ui-choices[data-scrollable="true"] {
    max-height: 16rem;
    overflow-y: auto;
    padding: var(--p-space-2);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-field);
    background: var(--color-sunken);
  }

  .ui-choices__group {
    padding: var(--p-space-2) var(--p-space-1) 0;
    font-family: var(--label-font);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-faint);
  }

  .ui-choice {
    display: flex;
    align-items: center;
    gap: var(--p-space-3);
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-field);
    background: var(--color-surface);
    cursor: pointer;
    transition: border-color var(--duration) var(--ease), background-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
  }

  .ui-choice:hover { border-color: var(--color-brand-line); }

  .ui-choice:has(input:checked) {
    border-color: var(--color-brand);
    background: var(--color-brand-soft);
    box-shadow: 0 0 0 3px var(--color-brand-soft);
  }

  .ui-choice input,
  .ui-consent input {
    width: 1.125rem;
    height: 1.125rem;
    margin: 0;
    flex-shrink: 0;
    accent-color: var(--color-brand);
    cursor: pointer;
  }

  .ui-choice__label { color: var(--color-heading); font-weight: 500; }

  /* A single agreement, e.g. terms or consent to be contacted. */
  .ui-consent {
    display: flex;
    align-items: flex-start;
    gap: var(--p-space-3);
    padding: 0.85rem 1rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-field);
    background: var(--color-sunken);
  }

  .ui-consent input { margin-top: 0.2rem; }
  .ui-consent label { color: var(--color-heading); cursor: pointer; }

  /* An organiser's section heading or note inside a form. */
  .ui-form-section {
    display: flex;
    flex-direction: column;
    gap: var(--p-space-1);
    padding-top: var(--p-space-5);
    border-top: var(--divider);
  }

  form > .ui-form-section:first-child { padding-top: 0; border-top: 0; }

  .ui-form-note {
    display: flex;
    flex-direction: column;
    gap: var(--p-space-1);
    padding: 0.85rem 1rem;
    border: 1px solid var(--color-brand-line);
    border-radius: var(--radius-inner);
    background: var(--color-brand-soft);
    color: var(--color-text);
    font-size: var(--text-sm);
  }

  .ui-form-note strong { color: var(--color-heading); }

  .ui-input {
    width: 100%;
    min-height: var(--control-height);
    padding: 0.625rem 0.875rem;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-field);
    background: var(--color-surface);
    color: var(--color-heading);
    font-size: var(--text-base);
    transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
  }

  .ui-input::placeholder { color: var(--color-faint); }

  .ui-input:focus {
    outline: none;
    border-color: var(--color-brand);
    box-shadow: 0 0 0 3px var(--color-brand-soft);
  }

  .ui-input[aria-invalid="true"] {
    border-color: var(--color-bad);
  }

  textarea.ui-input {
    min-height: 7rem;
    resize: vertical;
    line-height: 1.5;
  }

  .ui-check {
    display: flex;
    align-items: flex-start;
    gap: var(--p-space-3);
    font-size: var(--text-base);
    color: var(--color-text);
    cursor: pointer;
  }

  .ui-check input {
    width: 1.25rem;
    height: 1.25rem;
    margin: 0.15rem 0 0;
    accent-color: var(--color-brand);
  }

  /* ---- Cards and rows -------------------------------------------- */

  .ui-card {
    background: var(--color-surface);
    border: var(--border-card);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
  }

  .ui-card--padded { padding: var(--p-space-5); }

  @media (min-width: 48rem) {
    .ui-card--padded { padding: var(--p-space-6); }
  }

  .ui-rows > * + * {
    border-top: var(--divider);
  }

  .ui-row {
    display: flex;
    align-items: center;
    gap: var(--p-space-3);
    padding: var(--p-space-4) 0;
  }

  .ui-card .ui-row { padding-inline: var(--p-space-5); }

  .ui-row__body {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    flex-grow: 1;
  }

  .ui-row__title {
    font-weight: 600;
    color: var(--color-heading);
  }

  .ui-row__meta {
    font-size: var(--text-sm);
    color: var(--color-muted);
  }

  .ui-row__icon {
    color: var(--color-brand);
    align-self: flex-start;
    flex-shrink: 0;
    padding-top: 0.125rem;
  }

  /* ---- Chips ------------------------------------------------------ */

  .ui-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--p-space-1);
    padding: 0.25rem 0.625rem;
    border-radius: var(--radius-chip);
    background: var(--color-sunken);
    color: var(--color-text);
    font-family: var(--label-font);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: var(--label-case);
    letter-spacing: var(--label-tracking);
    line-height: 1.4;
    white-space: nowrap;
    /* Keeps its own width inside a column instead of stretching. */
    width: fit-content;
  }

  .ui-chip--brand { background: var(--color-brand-soft); color: var(--color-brand); }
  .ui-chip--ok { background: var(--color-ok-soft); color: var(--color-ok); }
  .ui-chip--warn { background: var(--color-warn-soft); color: var(--color-warn); }
  .ui-chip--bad { background: var(--color-bad-soft); color: var(--color-bad); }

  /* ---- Stats ------------------------------------------------------ */

  .ui-stat {
    display: flex;
    flex-direction: column;
    gap: var(--p-space-1);
  }

  .ui-stat__value {
    font-family: var(--font-display);
    font-weight: var(--title-weight);
    font-size: var(--text-3xl);
    line-height: 1;
    letter-spacing: var(--title-tracking);
    font-variant-numeric: var(--data-figures);
    color: var(--color-heading);
  }

  [data-style="programme"] .ui-stat__value {
    font-family: var(--font-data);
    font-weight: 500;
  }

  /* ---- Tabs ------------------------------------------------------- */

  .ui-tabs {
    display: flex;
    gap: var(--p-space-6);
    border-bottom: 1px solid var(--color-line);
    overflow-x: auto;
    scrollbar-width: none;
  }

  .ui-tab {
    padding: 0 0 var(--p-space-3);
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--color-muted);
    font-weight: 500;
    white-space: nowrap;
  }

  .ui-tab:hover { color: var(--color-heading); text-decoration: none; }

  .ui-tab[aria-current="page"] {
    color: var(--color-heading);
    font-weight: 600;
    border-bottom-color: var(--color-brand);
  }

  /* ---- Event cover (generated from the title and style) ----------- */

  .ui-cover {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--p-space-4);
    min-height: var(--cover-height, 13rem);
    padding: var(--p-space-5) var(--p-space-6);
    border-radius: var(--cover-radius);
    background-color: var(--cover-bg);
    background-image: var(--cover-pattern);
    background-size: var(--cover-pattern-size);
    color: var(--cover-ink);
    overflow: hidden;
    isolation: isolate;
  }

  .ui-cover__eyebrow {
    font-family: var(--label-font);
    font-size: var(--text-sm);
    font-weight: 500;
    text-transform: var(--label-case);
    letter-spacing: var(--label-tracking);
    color: var(--cover-eyebrow);
  }

  .ui-cover__title {
    font-family: var(--cover-title-font);
    font-weight: var(--cover-title-weight);
    font-style: var(--cover-title-style);
    text-transform: var(--cover-title-case);
    letter-spacing: var(--cover-title-tracking);
    font-size: var(--cover-title-size, clamp(2.75rem, 2rem + 3vw, 4rem));
    line-height: 0.92;
    color: var(--cover-ink);
    text-wrap: balance;
    overflow-wrap: anywhere;
  }

  .ui-cover__title.ui-title--safe {
    font-family: var(--font-display-safe);
    font-weight: var(--cover-title-weight-safe);
  }

  /* Invitation's quiet ornament: two hairline rings. */
  .ui-cover::before,
  .ui-cover::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    border: 1px solid rgba(250, 250, 253, 0.24);
    z-index: -1;
  }

  .ui-cover::before { width: 14rem; height: 14rem; right: -4rem; top: -3.5rem; }
  .ui-cover::after { width: 9rem; height: 9rem; right: -1.5rem; top: -1rem; opacity: 0.7; }

  [data-style="poster"] .ui-cover::before,
  [data-style="poster"] .ui-cover::after,
  [data-style="programme"] .ui-cover::before,
  [data-style="programme"] .ui-cover::after {
    content: none;
  }

  /* Poster's date sticker. */
  .ui-cover__sticker { display: none; }

  [data-style="poster"] .ui-cover__sticker {
    position: absolute;
    top: var(--p-space-7);
    right: var(--p-space-5);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 5.5rem;
    height: 5.5rem;
    border-radius: 50%;
    background: var(--color-accent);
    color: #ffffff;
    font-family: var(--font-display);
    font-weight: 800;
    line-height: 0.95;
    transform: rotate(-8deg);
    animation: ui-stamp 450ms 350ms var(--p-ease-spring) both;
  }

  .ui-cover__sticker b { font-size: 1.75rem; letter-spacing: -0.03em; }
  .ui-cover__sticker span { font-size: 0.75rem; letter-spacing: 0.06em; }

  /* ---- Tickets ---------------------------------------------------- */

  .ui-ticket-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--p-space-4);
    padding: var(--p-space-4) var(--p-space-5);
  }

  .ui-ticket-row__price {
    font-family: var(--font-data);
    font-weight: var(--data-weight);
    font-size: var(--text-lg);
    font-variant-numeric: var(--data-figures);
    color: var(--color-heading);
    white-space: nowrap;
  }

  [data-style="poster"] .ui-ticket-row__price { font-family: var(--font-display); font-size: var(--text-xl); }

  .ui-ticket-row.is-unavailable { opacity: 0.55; }

  /* The tear line between an event's details and its tickets. The notches
     are cut in the page colour; the line itself is the style's. */
  .ui-perforation {
    position: relative;
    height: 1.75rem;
  }

  .ui-perforation::before {
    content: "";
    position: absolute;
    inset: 50% var(--p-space-5) auto;
    border-top: var(--perforation);
  }

  [data-style="programme"] .ui-perforation {
    background:
      radial-gradient(circle at 0 50%, var(--color-page) 0.875rem, transparent 0.9rem),
      radial-gradient(circle at 100% 50%, var(--color-page) 0.875rem, transparent 0.9rem);
  }

  /* ---- Avatar ----------------------------------------------------- */

  .ui-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--avatar-size, 2.25rem);
    height: var(--avatar-size, 2.25rem);
    border-radius: var(--radius-control);
    background: var(--color-inverse);
    color: var(--color-on-inverse);
    font-size: var(--text-xs);
    font-weight: 700;
    flex-shrink: 0;
  }

  /* ---- Empty state ------------------------------------------------ */

  .ui-empty {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--p-space-3);
    padding: var(--p-space-7);
    border: 1px dashed var(--color-line-strong);
    border-radius: var(--radius-card);
  }

  /* ---- Notices ---------------------------------------------------- */

  .ui-notice {
    display: flex;
    align-items: flex-start;
    gap: var(--p-space-3);
    padding: var(--p-space-3) var(--p-space-4);
    border-radius: var(--radius-inner);
    background: var(--color-brand-soft);
    color: var(--color-heading);
    font-size: var(--text-sm);
    line-height: 1.5;
  }

  .ui-notice--ok { background: var(--color-ok-soft); color: var(--color-ok); }
  .ui-notice--warn { background: var(--color-warn-soft); color: var(--color-warn); }
  .ui-notice--bad { background: var(--color-bad-soft); color: var(--color-bad); }
  .ui-notice svg { margin-top: 0.1rem; }

  /* ---- Rich text an organiser wrote ------------------------------- */

  .ui-prose {
    color: var(--color-text);
    font-size: var(--text-base);
    line-height: 1.7;
    overflow-wrap: anywhere;
  }

  /* :where keeps this reset weaker than the spacing rule below. */
  .ui-prose :where(p, ul, ol, blockquote) { margin: 0; }
  .ui-prose > * + * { margin-top: var(--p-space-4); }
  .ui-prose h2, .ui-prose h3 { font-family: var(--font-body); font-weight: 700; font-size: var(--text-lg); color: var(--color-heading); }
  .ui-prose ul, .ui-prose ol { padding-left: 1.25rem; }
  .ui-prose li + li { margin-top: var(--p-space-1); }
  .ui-prose a { text-decoration: underline; }
  .ui-prose img, .ui-prose video { border-radius: var(--radius-inner); height: auto; }
  .ui-prose :where(img, video) { display: block; max-width: 100%; }
  .ui-prose audio { display: block; max-width: 100%; }
  .ui-prose figcaption { margin-top: var(--p-space-2); font-size: var(--text-sm); color: var(--color-muted); }
  .ui-prose blockquote { padding-left: var(--p-space-4); border-left: 3px solid var(--color-brand-line); color: var(--color-muted); }

  /* ---- An uploaded event cover ------------------------------------ */

  .ui-cover-image {
    margin: 0;
    overflow: hidden;
    border-radius: var(--cover-radius);
    background: var(--color-sunken);
  }

  .ui-cover-image img {
    width: 100%;
    height: auto;
    max-height: 32rem;
    object-fit: contain;
  }

  /* ---- Map ---------------------------------------------------------- */

  .ui-map {
    overflow: hidden;
    border-radius: var(--radius-inner);
    aspect-ratio: 16 / 10;
    background: var(--color-sunken);
  }

  .ui-map iframe { width: 100%; height: 100%; border: 0; }

  .ui-map-link {
    display: flex;
    align-items: center;
    gap: var(--p-space-3);
    padding: var(--p-space-3) var(--p-space-4);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-inner);
    background: var(--color-surface);
    color: var(--color-heading);
  }

  .ui-map-link:hover { border-color: var(--color-brand-line); text-decoration: none; color: var(--color-heading); }
  .ui-map-link > svg:first-child, .ui-map-link > .ev-maps-icon { width: 2.5rem; height: 2.5rem; flex-shrink: 0; }
  .ui-map-link > .ui-icon:last-child { color: var(--color-brand); flex-shrink: 0; }

  /* ---- Event page ---------------------------------------------------
     One column on a phone. From 60rem, two: the flyer and ticket panel on
     the left, held in view, and everything there is to read on the right,
     scrolling on its own so the ticket button never leaves the screen. */

  .ui-event__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--p-space-2);
    width: fit-content;
    color: var(--color-brand);
  }

  .ui-facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--p-space-2) var(--p-space-5);
    margin: 0;
    padding: 0;
    list-style: none;
    color: var(--color-text);
  }

  .ui-facts li {
    display: inline-flex;
    align-items: center;
    gap: var(--p-space-2);
  }

  .ui-facts svg { color: var(--color-brand); flex-shrink: 0; }

  .ui-event__layout {
    display: grid;
    gap: var(--p-space-5);
    align-items: start;
  }

  .ui-event__details { min-width: 0; }

  @media (min-width: 60rem) {
    .ui-event__layout { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--p-space-6); }

    .ui-event__aside {
      position: sticky;
      top: var(--p-space-5);
    }

    .ui-event__details {
      max-height: calc(100dvh - 2 * var(--p-space-5));
      overflow-y: auto;
      /* No overscroll containment: reaching the end of the details carries on
         scrolling the page, and a column short enough to fit never traps. */
      scrollbar-width: none;
    }

    .ui-event__details::-webkit-scrollbar { width: 0; height: 0; }
  }

  @media (min-width: 75rem) {
    .ui-event__layout { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); }
  }

  .ui-card__section { padding: var(--p-space-5); }

  @media (min-width: 48rem) {
    .ui-card__section { padding: var(--p-space-6); }
  }

  .ui-card__section > .ui-label:first-child { display: block; margin-bottom: var(--p-space-3); }

  /* The ticket panel: tickets, the key facts, then the way in. */
  .ui-panel > * + * { border-top: var(--divider); }
  .ui-panel .ui-row { padding-block: var(--p-space-3); }
  .ui-panel .ui-rows .ui-row:first-child { padding-top: var(--p-space-4); }
  .ui-panel .ui-rows .ui-row:last-child { padding-bottom: var(--p-space-4); }
  .ui-panel .ui-row__body .ui-label { font-size: var(--text-xs); }

  .ui-row__value { color: var(--color-heading); }

  .ui-price-headline {
    display: flex;
    align-items: baseline;
    gap: var(--p-space-2);
    margin: 0;
  }

  .ui-price-headline .ui-data {
    font-family: var(--font-display);
    font-weight: var(--title-weight);
    font-size: var(--text-3xl);
    line-height: 1;
  }

  [data-style="programme"] .ui-price-headline .ui-data { font-family: var(--font-data); font-weight: 500; }

  /* Places taken against capacity. */
  .ui-meter { display: flex; flex-direction: column; gap: var(--p-space-2); }

  .ui-meter__track {
    height: 0.375rem;
    border-radius: 999px;
    background: var(--color-sunken);
    overflow: hidden;
  }

  .ui-meter__track > span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--color-brand);
  }

  /* ---- Registration -------------------------------------------------
     The form on the left, the event summary on the right from 60rem. */

  .ui-register {
    display: grid;
    gap: var(--p-space-5);
    align-items: start;
  }

  @media (min-width: 60rem) {
    .ui-register { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--p-space-6); }
    .ui-register__summary { position: sticky; top: var(--p-space-5); }
  }

  @media (min-width: 75rem) {
    .ui-register { grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); }
  }

  .ui-register > .ui-stack > .ui-btn { width: fit-content; }

  .ui-register__assurance {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--p-space-2);
  }

  /* One ticket type with its quantity box. */
  .ui-pick-row {
    display: flex;
    align-items: center;
    gap: var(--p-space-4);
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-field);
    background: var(--color-surface);
  }

  .ui-pick-row.is-unavailable { opacity: 0.55; }

  .ui-pick-row__price {
    margin-left: var(--p-space-2);
    font-family: var(--font-data);
    font-weight: var(--data-weight);
    font-variant-numeric: var(--data-figures);
    color: var(--color-brand);
    white-space: nowrap;
  }

  .ui-qty { width: 5.5rem; flex: 0 0 auto; text-align: center; }

  .ui-code {
    width: fit-content;
    padding: 0.1rem 0.4rem;
    border-radius: var(--radius-chip);
    background: var(--color-surface);
    border: 1px solid var(--color-brand-line);
    font-family: var(--p-face-plex-mono);
    font-size: 0.9em;
    color: var(--color-heading);
  }

  /* ---- Confirmation ---------------------------------------------------
     Centred like a receipt; the organiser's own rows keep their alignment. */

  .ui-confirm { text-align: center; }

  .ui-confirm__head,
  .ui-confirm__block {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--p-space-2);
  }

  .ui-confirm__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 4.25rem;
    height: 4.25rem;
    margin-bottom: var(--p-space-2);
    border-radius: 50%;
    background: var(--color-ok-soft);
    color: var(--color-ok);
    box-shadow: 0 0 0 10px color-mix(in srgb, var(--color-ok) 6%, transparent);
    animation: ui-stamp-in 450ms 150ms var(--p-ease-spring) both;
  }

  .ui-confirm__icon--brand { background: var(--color-brand-soft); color: var(--color-brand); box-shadow: 0 0 0 10px color-mix(in srgb, var(--color-brand) 6%, transparent); }
  .ui-confirm__icon--warn { background: var(--color-warn-soft); color: var(--color-warn); box-shadow: 0 0 0 10px color-mix(in srgb, var(--color-warn) 6%, transparent); }
  .ui-confirm__icon--bad { background: var(--color-bad-soft); color: var(--color-bad); box-shadow: 0 0 0 10px color-mix(in srgb, var(--color-bad) 6%, transparent); }
  .ui-confirm__icon--muted { background: var(--color-sunken); color: var(--color-muted); box-shadow: none; }

  .ui-confirm .ui-title { text-wrap: balance; }

  /* A ticket's QR code: dark on white whatever the style, so any scanner
     reads it. */
  .ui-qr {
    width: min(14rem, 70vw);
    aspect-ratio: 1;
    padding: var(--p-space-2);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-inner);
    background: #ffffff;
  }

  .ui-qr svg { display: block; width: 100%; height: 100%; }

  /* Label and value pairs, one per line: an order and its amounts. */
  .ui-dl {
    display: flex;
    flex-direction: column;
    margin: 0;
    text-align: left;
    border-top: var(--divider);
  }

  .ui-dl > div {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--p-space-4);
    padding: var(--p-space-3) 0;
    border-bottom: var(--divider);
  }

  .ui-dl dt { color: var(--color-muted); }
  .ui-dl dd { margin: 0; color: var(--color-heading); text-align: right; }
  .ui-dl__total dt, .ui-dl__total dd { font-weight: 700; color: var(--color-heading); }

  .ui-ref {
    padding: 0.65rem 1.3rem;
    border-radius: var(--radius-field);
    background: var(--color-brand-soft);
    color: var(--color-brand);
    font-family: var(--p-face-plex-mono);
    font-size: var(--text-xl);
    font-weight: 600;
    letter-spacing: 0.1em;
  }

  .ui-confirm__tickets { justify-content: center; }

  .ui-ticket-chip {
    display: flex;
    flex-direction: column;
    padding: 0.5rem 1rem;
    border: 1px solid var(--color-brand-line);
    border-radius: var(--radius-field);
    background: var(--color-surface);
    color: var(--color-heading);
  }

  .ui-ticket-chip code {
    font-family: var(--p-face-plex-mono);
    font-weight: 600;
    color: var(--color-brand);
  }

  .ui-confirm__facts { text-align: left; }
  .ui-confirm__facts .ui-row { padding: 0; align-items: flex-start; }

  .ui-confirm__actions { justify-content: center; }
  .ui-confirm__note { text-align: center; }

  /* Rows of blocks an organiser placed on the confirmation page. */
  .ui-blocks { display: grid; gap: var(--p-space-5); text-align: left; }

  .ui-blocks__row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--p-space-4) var(--p-space-5);
  }

  .ui-blocks__row--left { justify-content: flex-start; }
  .ui-blocks__row--center { justify-content: center; text-align: center; }
  .ui-blocks__row--right { justify-content: flex-end; text-align: right; }
  .ui-blocks__item { min-width: 0; }
  .ui-blocks__item :where(img, video) { max-width: 100%; height: auto; }
  .ui-blocks__item audio { display: block; max-width: 100%; }

  @keyframes ui-stamp-in {
    from { opacity: 0; transform: scale(0.6); }
    to { opacity: 1; transform: scale(1); }
  }

  /* ---- "or" between two ways of doing the same thing --------------- */

  .ui-divider {
    display: flex;
    align-items: center;
    gap: var(--p-space-3);
    color: var(--color-faint);
    font-size: var(--text-sm);
  }

  .ui-divider::before,
  .ui-divider::after {
    content: "";
    flex: 1;
    border-top: var(--divider);
  }

  /* ---- A quiet disclosure: "Use a password instead" ---------------- */

  .ui-details > summary {
    width: fit-content;
    color: var(--color-muted);
    font-size: var(--text-sm);
    cursor: pointer;
  }

  .ui-details > summary:hover { color: var(--color-heading); }
  .ui-details[open] > summary { margin-bottom: var(--p-space-4); }

  /* ---- Door check-in ----------------------------------------------- */

  .ui-checkin {
    width: 100%;
    max-width: 30rem;
    margin-inline: auto;
    text-align: center;
  }

  .ui-checkin__input {
    min-height: var(--control-height-lg);
    font-family: var(--p-face-plex-mono);
    font-size: var(--text-lg);
    letter-spacing: 0.05em;
    text-align: center;
  }

  .ui-checkin-result {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--p-space-1);
    padding: var(--p-space-6) var(--p-space-4);
    border-radius: var(--radius-card);
    background: var(--color-sunken);
    color: var(--color-muted);
    animation: ui-rise var(--p-duration-slow) var(--ease) both;
  }

  .ui-checkin-result__title { font-size: var(--text-lg); font-weight: 700; }
  .ui-checkin-result__name { font-size: var(--text-2xl); font-weight: 600; color: var(--color-heading); }
  .ui-checkin-result__meta { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 0.35rem; font-size: var(--text-sm); }

  .ui-checkin-result--admitted { background: var(--color-ok-soft); color: var(--color-ok); }
  .ui-checkin-result--already_checked_in { background: var(--color-warn-soft); color: var(--color-warn); }
  .ui-checkin-result--voided { background: var(--color-bad-soft); color: var(--color-bad); }

  /* ---- Organiser pages: headers, search, tables ------------------- */

  .ui-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--p-space-4);
  }

  .ui-back { width: fit-content; margin-left: calc(-1 * var(--p-space-2)); }
  .ui-narrow { max-width: 40rem; }

  .ui-search {
    display: flex;
    flex-wrap: wrap;
    gap: var(--p-space-2);
    max-width: 36rem;
  }

  .ui-search .ui-input { flex: 1 1 14rem; width: auto; }

  .ui-table-wrap { overflow-x: auto; }

  .ui-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
  }

  .ui-table th {
    padding: var(--p-space-3) var(--p-space-4);
    border-bottom: var(--divider);
    font-family: var(--label-font);
    font-size: var(--text-xs);
    font-weight: 600;
    text-align: left;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-faint);
    white-space: nowrap;
  }

  .ui-table td {
    padding: var(--p-space-3) var(--p-space-4);
    border-bottom: var(--divider);
    color: var(--color-text);
    vertical-align: middle;
  }

  .ui-table tbody tr:last-child td { border-bottom: 0; }
  .ui-table tbody tr:hover td { background: color-mix(in srgb, var(--color-sunken) 55%, transparent); }
  .ui-table--compact th, .ui-table--compact td { padding: var(--p-space-2) var(--p-space-3); white-space: nowrap; }
  .ui-table th.is-email { color: var(--color-brand); }
  .ui-table__primary { font-weight: 600; color: var(--color-heading); }
  a.ui-table__primary:hover { color: var(--color-brand); }
  .ui-table__actions { text-align: right; white-space: nowrap; }
  .ui-table__actions form { display: inline; }
  .ui-table__note td { background: var(--color-bad-soft); color: var(--color-bad); }

  /* On a phone a stacking table shows each row as a card of label and value. */
  @media (max-width: 47.99rem) {
    .ui-table--stack thead { display: none; }
    .ui-table--stack, .ui-table--stack tbody, .ui-table--stack tr, .ui-table--stack td { display: block; }
    .ui-table--stack tr { padding: var(--p-space-3) var(--p-space-4); border-bottom: var(--divider); }
    .ui-table--stack tbody tr:last-child { border-bottom: 0; }
    .ui-table--stack td {
      display: flex;
      justify-content: space-between;
      gap: var(--p-space-4);
      padding: var(--p-space-1) 0;
      border: 0;
      text-align: right;
      overflow-wrap: anywhere;
    }
    .ui-table--stack td[data-label]::before {
      content: attr(data-label);
      flex-shrink: 0;
      color: var(--color-faint);
      text-align: left;
    }
    .ui-table--stack td:first-child { font-size: var(--text-base); }
    .ui-table--stack .ui-table__actions { justify-content: flex-start; padding-top: var(--p-space-2); }
    .ui-table--stack tbody tr:hover td { background: none; }
    /* A note row belongs to the card above it: one block of left-aligned text. */
    .ui-table--stack tr.has-note { border-bottom: 0; }
    .ui-table--stack tr.ui-table__note { padding-top: 0; }
    .ui-table--stack .ui-table__note td {
      display: block;
      padding: var(--p-space-2) var(--p-space-3);
      border-radius: var(--radius-inner);
      text-align: left;
    }
    .ui-table--stack tbody tr.ui-table__note:hover td { background: var(--color-bad-soft); }
  }

  .ui-btn--danger-quiet { color: var(--color-bad); }
  .ui-btn--danger-quiet:hover { color: var(--color-bad); background: var(--color-bad-soft); }

  .ui-row--link { color: inherit; }
  .ui-row--link:hover { background: var(--color-sunken); text-decoration: none; color: inherit; }
  .ui-card .ui-row--link:first-child { border-top-left-radius: inherit; border-top-right-radius: inherit; }
  .ui-row--link > .ui-icon:last-child { color: var(--color-faint); }

  .ui-choice--button { width: 100%; text-align: left; font: inherit; }
  .ui-choice--button[aria-selected="true"] { border-color: var(--color-brand); background: var(--color-brand-soft); }
  .ui-choice--button > .ui-icon { color: var(--color-brand); flex-shrink: 0; }

  .ui-facts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
    gap: var(--p-space-4);
    margin: 0;
  }

  .ui-facts-grid dt { font-size: var(--text-sm); color: var(--color-muted); }
  .ui-facts-grid dd { margin: 0; font-weight: 600; color: var(--color-heading); overflow-wrap: anywhere; }

  .ui-codeblock {
    margin: 0;
    padding: var(--p-space-3) var(--p-space-4);
    overflow-x: auto;
    border-radius: var(--radius-inner);
    background: var(--color-sunken);
    font-family: var(--p-face-plex-mono);
    font-size: var(--text-sm);
    color: var(--color-heading);
  }

  .ui-list { margin: 0; padding-left: 1.1rem; display: grid; gap: var(--p-space-2); }

  .ui-column-row {
    display: grid;
    gap: var(--p-space-3);
    margin: 0;
    padding: var(--p-space-4) 0;
    border: 0;
  }

  .ui-column-row legend { float: left; width: 100%; padding: 0; margin-bottom: var(--p-space-1); }
  .ui-column-row__fields { display: grid; gap: var(--p-space-3); grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); clear: both; }

  .ui-report .ui-stat__value { font-size: var(--text-2xl); }

  /* ---- Guest page action bar -------------------------------------- */

  .ui-action-bar {
    position: sticky;
    bottom: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--p-space-4);
    padding: var(--p-space-3) var(--space-gutter) calc(var(--p-space-3) + env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--color-surface) 94%, transparent);
    border-top: 1px solid var(--color-line);
    backdrop-filter: blur(8px);
  }

  .ui-action-bar .ui-data { white-space: nowrap; }

  @media (min-width: 60rem) {
    .ui-action-bar { position: static; border: 0; background: none; padding-inline: 0; }
    /* On a desktop the ticket panel is always in view and carries the button. */
    .ui-action-bar--phone { display: none; }
  }

  /* ---- Email editor ----------------------------------------------- */

  /* The form first; on a wide screen the preview sits beside it and stays in view. */
  .ui-editor {
    display: grid;
    gap: var(--p-space-5);
    align-items: start;
  }

  .ui-editor__form,
  .ui-editor__aside,
  .ui-editor > * { min-width: 0; }

  @media (min-width: 72rem) {
    .ui-editor { grid-template-columns: minmax(0, 1fr) minmax(22rem, 34rem); }
    .ui-editor__aside { position: sticky; top: var(--p-space-5); }
    /* The review page lists its sections flat; the preview takes the second column. */
    .ui-editor--review { grid-template-rows: auto auto 1fr; }
    .ui-editor--review > * { grid-column: 1; }
    .ui-editor--review > .ui-editor__aside { grid-column: 2; grid-row: 1 / span 3; }
  }

  .ui-editor__preview { overflow: hidden; }
  .ui-editor__preview > * + * { border-top: var(--divider); }

  .ui-editor__preview iframe {
    display: block;
    width: 100%;
    height: min(70vh, 44rem);
    border: 0;
    background: #f5f4f8;
  }

  .ui-block { margin: 0; min-width: 0; }
  .ui-block legend { float: left; padding: 0; }
  .ui-block.is-focus { box-shadow: 0 0 0 3px var(--color-brand-soft); border-color: var(--color-brand-line); }
  .ui-block:target { box-shadow: 0 0 0 3px var(--color-brand-soft); }

  .ui-code-input {
    font-family: var(--p-face-plex-mono);
    font-size: var(--text-sm);
    line-height: 1.5;
  }

  .ui-chip--button {
    border: 1px solid var(--color-line);
    text-transform: none;
    letter-spacing: 0;
    font-family: inherit;
    cursor: pointer;
  }

  .ui-chip--button:hover { border-color: var(--color-brand-line); color: var(--color-heading); }

  .ui-variables > summary { cursor: pointer; }

  /* ---- Motion ----------------------------------------------------- */

  @keyframes ui-rise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
  }

  @keyframes ui-stamp {
    from { opacity: 0; transform: rotate(-8deg) scale(1.25); }
    to { opacity: 1; transform: rotate(-8deg) scale(1); }
  }

  /* One orchestrated entrance: children rise in sequence. */
  .ui-rise > * {
    animation: ui-rise var(--p-duration-slow) var(--ease) both;
  }

  .ui-rise > :nth-child(2) { animation-delay: 60ms; }
  .ui-rise > :nth-child(3) { animation-delay: 120ms; }
  .ui-rise > :nth-child(4) { animation-delay: 180ms; }
  .ui-rise > :nth-child(n + 5) { animation-delay: 240ms; }
}

@layer components {
  /* ---- Home: a person's own events (flow A4) ------------------------ */

  .ui-account__main { max-width: 46rem; }

  /* Someone's own words, quoted: a guest's refund request. */
  .ui-quote {
    margin: 0;
    padding: var(--p-space-3) var(--p-space-4);
    border-left: 3px solid var(--color-brand-line);
    border-radius: var(--radius-inner);
    background: var(--color-sunken);
    color: var(--color-heading);
  }

  .ui-attend { display: flex; flex-direction: column; }

  .ui-attend__head {
    display: flex;
    align-items: flex-start;
    gap: var(--p-space-4);
    padding: var(--p-space-5);
  }

  .ui-attend__date {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex-shrink: 0;
    width: 3.5rem;
    padding: var(--p-space-2) 0;
    border-radius: var(--radius-inner);
    background: var(--color-brand-soft);
    color: var(--color-brand);
    font-family: var(--label-font);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1.2;
  }

  .ui-attend__date strong {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    letter-spacing: 0;
    line-height: 1.1;
  }

  .ui-attend__title {
    margin: 0;
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: 1.3;
    color: var(--color-heading);
    overflow-wrap: anywhere;
  }

  .ui-attend__title a { color: inherit; }

  .ui-attend__section {
    display: flex;
    flex-direction: column;
    gap: var(--p-space-2);
    padding: var(--p-space-4) var(--p-space-5);
    border-top: var(--divider);
  }

  .ui-attend__section .ui-row { padding: 0; align-items: flex-start; }
  .ui-attend__section > .ui-btn { width: fit-content; }

  .ui-attend__ticket {
    border: 1px solid var(--color-line);
    border-radius: var(--radius-field);
  }

  .ui-attend__ticket > summary {
    display: flex;
    align-items: center;
    gap: var(--p-space-3);
    min-height: 3rem;
    padding: var(--p-space-2) var(--p-space-3);
    list-style: none;
    cursor: pointer;
  }

  .ui-attend__ticket > summary::-webkit-details-marker { display: none; }
  .ui-attend__ticket > summary > .ui-small,
  .ui-attend .ui-code,
  .ui-home .ui-dl .ui-code { white-space: nowrap; }
  .ui-attend__ticket[open] > summary .ui-small { visibility: hidden; }

  .ui-attend__qr {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--p-space-2);
    padding: 0 var(--p-space-3) var(--p-space-4);
  }

  .ui-attend__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--p-space-2);
    padding: var(--p-space-2) var(--p-space-3);
    border-top: var(--divider);
  }
}

@layer components {
  /* ---- Browse and organiser profiles (flows A1, A6) ------------------- */

  .ui-browse__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
    gap: var(--p-space-4);
  }

  .ui-browse-card {
    display: flex;
    flex-direction: column;
    gap: var(--p-space-3);
    padding: var(--p-space-3);
    color: inherit;
    transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
  }

  .ui-browse-card:hover { border-color: var(--color-brand-line); text-decoration: none; color: inherit; }
  .ui-browse-card .ui-cover { --cover-height: 9.5rem; padding: var(--p-space-4); }
  .ui-browse-card .ui-cover-image img { aspect-ratio: 16 / 9; max-height: none; object-fit: cover; }
  .ui-browse-card__body { padding: 0 var(--p-space-1) var(--p-space-1); flex-grow: 1; }
  .ui-browse-card__title { font-weight: 600; font-size: var(--text-lg); line-height: 1.3; color: var(--color-heading); overflow-wrap: anywhere; }
  .ui-browse-card__foot { margin-top: auto; padding-top: var(--p-space-2); gap: var(--p-space-2); }
  .ui-browse-card__foot strong { white-space: nowrap; }
  .ui-browse-card__org { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

  .ui-browse__city { width: auto; min-width: 12rem; flex: 1 1 12rem; }
  .ui-browse__date { width: auto; }
  .ui-chip--button.is-on { background: var(--color-brand); border-color: var(--color-brand); color: #ffffff; }
  .ui-chip--button:has(input:focus-visible) { outline: 2px solid var(--color-brand); outline-offset: 2px; }

  .ui-profile__head { display: flex; align-items: center; gap: var(--p-space-4); }
  .ui-profile__logo { width: 4.5rem; height: 4.5rem; border-radius: var(--radius-card); object-fit: cover; background: var(--color-sunken); flex-shrink: 0; }
}

@layer utilities {
  /* Read by screen readers, not shown. */
  .ui-visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
