/**
 * Shared primitives for every Neo Event Manager screen.
 *
 * Class names are lifted from the wireframe (`btn`, `chip`, `sk`, `tag`, `card`) and
 * namespaced `nem-` so they cannot collide with a theme. Every screen is a single mount
 * element hydrated from REST, so loading, empty and error are first-class states here, not
 * afterthoughts bolted on per-screen.
 */

.neo-evt-mount {
  font-family: var(--nem-body);
  color: var(--nem-ink);
  -webkit-font-smoothing: antialiased;
}

.neo-evt-mount *,
.neo-evt-mount *::before,
.neo-evt-mount *::after {
  box-sizing: border-box;
}

/*
 * 70px of air on every side of every screen.
 *
 * The mount used to sit flush against whatever container the theme dropped it into: on the
 * events page the first card's left edge touched the viewport on a 1180px window, and on the
 * event-admin dashboard the tiles ran into the footer. Padding here, on the one element every
 * screen wraps itself in, rather than five per-screen rules that each have to be remembered.
 *
 * `.nem-detail` and `.nem-admin` used to add their own vertical padding on top of this. They
 * no longer do; the rhythm is stated once.
 */
.nem-wrap {
  max-width: var(--nem-wrap-max);
  margin: 0 auto;
  padding: calc(var(--nem-wrap-pad-y) + var(--nem-header-offset)) var(--nem-wrap-pad-x) var(--nem-wrap-pad-y);
}

/*
 * A screen that opens on a coloured band keeps the wrap's ordinary top padding, and the band
 * takes the header offset into its own. Otherwise the offset lands *above* the band and puts
 * a 70px strip of white between the header and the purple - the gap has to carry the colour.
 */
.nem-wrap.nem-listing,
.nem-wrap.nem-detail {
  padding-top: var(--nem-wrap-pad-y);
}

/*
 * `overflow-x: clip`, not `hidden`.
 *
 * The hero bands escape the wrap with `margin-inline: calc(50% - 50vw)`, which is one
 * scrollbar-width wider than the page on Windows and adds a horizontal scrollbar to every
 * event page. Clipping removes it. `hidden` would too, and would also make this element a
 * scroll container, which silently kills `position: sticky` on the ticket card. `clip`
 * does not create a scroll container, so the card still sticks.
 */
.neo-evt-mount,
.neo-evt-wrapper {
  overflow-x: clip;
}

/* The gutter is already small. On a phone it is the only thing between text and glass. */
@media (max-width: 640px) {
  .nem-wrap {
    --nem-wrap-pad-y: 32px;
    --nem-wrap-pad-x: 20px;
  }
}

/* ---------------------------------------------------------------- link decoration

 * No underline on any call to action, in any state.
 *
 * Every `.nem-btn`, `.nem-chip`, card and `.nem-directions` already declares
 * `text-decoration: none`, and every one of them loses on hover. The theme's rule is
 * `.entry-content a:hover`, which scores 0,2,1 because `:hover` counts as a class. Ours
 * scored 0,1,0. Matching the score is not enough either: whichever stylesheet WordPress
 * prints last wins a tie, and Elementor's are printed after the plugin's on this site.
 *
 * `!important` is the right tool exactly once, on a rule that can only ever remove a
 * decoration from inside the plugin's own mount. It cannot leak, and there is nothing a
 * theme could legitimately want to say here that would be worth honouring.
 */
.neo-evt-mount a,
.neo-evt-mount a:link,
.neo-evt-mount a:visited,
.neo-evt-mount a:hover,
.neo-evt-mount a:focus,
.neo-evt-mount a:active,
.neo-evt-mount button,
.neo-evt-mount button:hover,
.neo-evt-mount button:focus,
.neo-evt-mount .nem-btn:hover,
.neo-evt-mount .nem-chip:hover {
  text-decoration: none !important;
}

/* The focus ring stays. Removing an underline is a style choice; removing the ring is not. */
.neo-evt-mount a:focus-visible {
  outline: 3px solid var(--nem-orange);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- icons

 * Line icons that inherit their colour and their size from the text beside them. The meta
 * row and the venue block used to print emoji, which do neither.
 */
.nem-icon {
  width: 1.05em;
  height: 1.05em;
  flex: 0 0 auto;
  display: block;
  color: var(--nem-purple);
}

/* ---------------------------------------------------------------- theme reset

 * Everything below is scoped to `.neo-evt-mount` for one reason: specificity.
 *
 * A single class selector is 0,1,0. A theme's `.entry-content h2` is 0,1,1 and beats it.
 * Elementor's `.elementor-widget-container h2` beats it. Hello Elementor's `h2 { margin:
 * 0 0 var(--paragraph-spacing) }` does not, but its `.site-main section { margin-block:
 * 4rem }` does. So the plugin's own `margin: 0 0 8px` on `.nem-h2` lost on a live page,
 * and 4rem of theme margin opened above every section heading while the 8px under it
 * stayed. That is exactly the two complaints: too much air between sections, too little
 * between a heading and its content.
 *
 * `.neo-evt-mount .nem-h2` is 0,2,0 and wins without a single `!important`.
 */

/*
 * `:where()` contributes nothing to specificity, so this whole rule scores 0,0,0. It is a
 * floor, not a wall: any `.nem-` class beats it, and it never has to be undone. Written as
 * `.neo-evt-mount section` it would have scored 0,1,1 and silently eaten the padding off
 * `.nem-related` and the margin off `.nem-detail-head`, which is the same specificity
 * mistake the theme is making, just pointing the other way.
 */
:where(.neo-evt-mount) :where(h1, h2, h3, h4, p, section, header, aside, ul, ol, dl, figure, address) {
  margin: 0;
  padding: 0;
}

:where(.neo-evt-mount) :where(button, input, select, textarea) {
  font-family: inherit;
  letter-spacing: normal;
  text-transform: none;
}

/* ---------------------------------------------------------------- type */

.neo-evt-mount .nem-h1 {
  font: 700 clamp(32px, 4vw, 44px)/1.1 var(--nem-display);
  color: var(--nem-dpurple);
  letter-spacing: -0.2px;
  margin: 0 0 12px;
}

/*
 * A section heading and the words under it are one thing. 8px did not say so, and the
 * wireframe's `margin-bottom:8px` was measured on a 720px-wide mock where the body copy
 * was 11px. At full size the pair needs air under the rule, not inside it.
 */
.neo-evt-mount .nem-h2 {
  font: 700 26px/1.2 var(--nem-display);
  color: var(--nem-dpurple);
  margin: 0 0 16px;
}

.neo-evt-mount .nem-h3 {
  font: 600 18px/1.3 var(--nem-display);
  color: var(--nem-dpurple);
  margin: 0 0 6px;
}

.nem-dim { color: var(--nem-muted); }
.nem-small { font-size: 12px; }
.nem-strong { font-weight: 600; }

/* ---------------------------------------------------------------- buttons */

.nem-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font: 600 13px var(--nem-body);
  padding: 10px 18px;
  border-radius: var(--nem-radius-pill);
  border: 1.5px solid var(--nem-purple);
  background: var(--nem-purple);
  color: #fff;
  cursor: pointer;
  transition: transform 0.12s ease, background 0.12s ease;
}

.nem-btn:hover:not(:disabled) { transform: translateY(-1px); }
.nem-btn:focus-visible { outline: 3px solid var(--nem-purple); outline-offset: 2px; }
.nem-btn.ghost { background: #fff; color: var(--nem-purple); }
.nem-btn.org { background: var(--nem-purple); border-color: var(--nem-purple); }
.nem-btn.sm { padding: 6px 13px; font-size: 11px; }
.nem-btn.block { width: 100%; }

.nem-btn:disabled,
.nem-btn[aria-disabled="true"] {
  background: #fff;
  color: var(--nem-muted);
  border-color: var(--nem-line);
  cursor: not-allowed;
  transform: none;
}

/* ---------------------------------------------------------------- chips, tags */

/*
 * `.nem-chip` was 0,1,0 and lost the catalog's filter row to the theme.
 *
 * Hello Elementor and every child of it style `button` and `.entry-content button` with
 * `text-transform: uppercase`, `letter-spacing: .05em`, `font-size: 15px` and `padding:
 * 14px 28px`. That is a 0,1,1 selector against a 0,1,0 one, so the pills on /events shipped
 * as uppercase 44px-tall slabs that wrapped onto three rows. Scoping to the mount makes this
 * 0,2,0 and it wins - but only for the properties it actually names, so it names all of
 * them, including the ones a chip would never think to set (`height`, `min-height`,
 * `letter-spacing`, `text-transform`, `box-shadow`).
 *
 * The three numbers come from tokens. See neo-evt-tokens.css.
 */
.neo-evt-mount .nem-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-family: var(--nem-body);
  font-size: var(--nem-chip-size);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: normal;
  text-transform: none;
  padding: var(--nem-chip-pad-y) var(--nem-chip-pad-x);
  width: auto;
  height: auto;
  min-height: 0;
  border: 1px solid var(--nem-line);
  border-radius: 999px;
  background: #fff;
  color: var(--nem-ink);
  box-shadow: none;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.neo-evt-mount .nem-chip.on { background: var(--nem-purple); border-color: var(--nem-purple); color: #fff; }

.nem-tag { font: 600 10px var(--nem-body); padding: 3px 8px; border-radius: 5px; display: inline-block; }
.nem-tag.rec { background: rgba(63, 143, 95, 0.14); color: #2f7a4c; }
.nem-tag.hot { background: rgba(255, 85, 29, 0.14); color: var(--nem-orange); }
.nem-tag.out { background: #efeae1; color: var(--nem-muted); }
.nem-tag.free { background: rgba(141, 34, 195, 0.12); color: var(--nem-purple); }

/* ---------------------------------------------------------------- card */

.nem-card {
  border: 1px solid var(--nem-line-2);
  border-radius: var(--nem-radius);
  background: var(--nem-panel);
  overflow: hidden;
}

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

/*
 * Skeletons match the final layout so the grid does not jump when data lands. That is the
 * whole reason to have them; a spinner would be less code and worse.
 */
.nem-sk {
  background: var(--nem-skeleton);
  border-radius: 5px;
  height: 11px;
  display: block;
  animation: nem-pulse 1.3s ease-in-out infinite;
  animation-name: var(--nem-anim, nem-pulse);
}

@keyframes nem-pulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 0.9; }
}

.nem-state {
  text-align: center;
  padding: 56px 24px;
  border: 1px dashed var(--nem-line);
  border-radius: var(--nem-radius);
  background: #fff;
}

.nem-state h3 { font: 600 18px var(--nem-display); color: var(--nem-dpurple); margin: 0 0 6px; }
.nem-state p { margin: 0 0 16px; color: var(--nem-muted); font-size: 13px; max-width: 420px; margin-inline: auto; }
.nem-state.error { border-color: var(--nem-refuse); }
.nem-state.error h3 { color: var(--nem-refuse); }

/* An error is a thing you can retry. Say what failed, offer the retry, do not apologise. */
.nem-retry { margin-top: 4px; }

.nem-inline-error {
  color: var(--nem-refuse);
  font: 500 12px var(--nem-body);
  margin-top: 5px;
}

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

.nem-field { margin-bottom: 16px; }
.nem-field label { display: block; font: 600 12px var(--nem-body); margin-bottom: 5px; color: var(--nem-dpurple); }

.nem-field input[type="text"],
.nem-field input[type="email"],
.nem-field input[type="password"],
.nem-field input[type="number"],
.nem-field input[type="datetime-local"],
.nem-field select,
.nem-field textarea {
  width: 100%;
  font: 400 14px var(--nem-body);
  padding: 10px 12px;
  border: 1px solid var(--nem-line);
  border-radius: 8px;
  background: #fff;
  color: var(--nem-ink);
}

.nem-field input:focus,
.nem-field select:focus,
.nem-field textarea:focus {
  outline: none;
  border-color: var(--nem-purple);
  box-shadow: 0 0 0 3px rgba(141, 34, 195, 0.12);
}

.nem-field.invalid input,
.nem-field.invalid select { border-color: var(--nem-refuse); }
.nem-field .nem-help { font: 400 11.5px var(--nem-body); color: var(--nem-muted); margin-top: 4px; }

/* ---------------------------------------------------------------- stepper */

/*
 * The buttons were `width:34px; height:34px` and nothing else. A theme that sets
 * `button { padding: 12px 24px; line-height: 1.6 }` - which is most of them - pushed the
 * glyph off the box's centre and off the number's baseline, and the minus sign (U+2212,
 * which sits at maths-axis height, not at cap height) drifted further than the plus.
 *
 * Centring a glyph means a flex box with no padding and no line-height, not a width and a
 * hope. The row is `align-items: stretch` so all three cells share one height.
 */
.nem-stepper {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--nem-line);
  border-radius: 20px;
  overflow: hidden;
  background: #fff;
  line-height: 1;
}

.neo-evt-mount .nem-stepper button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 0;
  background: #fff;
  cursor: pointer;
  font: 600 18px/1 var(--nem-body);
  color: var(--nem-purple);
  transition: background 0.12s ease;
}

.neo-evt-mount .nem-stepper button:hover:not(:disabled) { background: rgba(141, 34, 195, 0.07); }
.neo-evt-mount .nem-stepper button:disabled { color: var(--nem-line); cursor: not-allowed; background: #fff; }
.neo-evt-mount .nem-stepper button:focus-visible { outline: 2px solid var(--nem-purple); outline-offset: -2px; }

.neo-evt-mount .nem-stepper output {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  padding: 0 4px;
  font: 600 15px/1 var(--nem-body);
  color: var(--nem-ink);
  border-left: 1px solid var(--nem-line-2);
  border-right: 1px solid var(--nem-line-2);
}

/* ---------------------------------------------------------------- qr */

.nem-qr { width: 100%; max-width: 220px; height: auto; border: 1px solid var(--nem-line); border-radius: 8px; background: #fff; display: block; }
.nem-qr.spent { filter: grayscale(1); opacity: 0.35; }

/* ---------------------------------------------------------------- misc */

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

.nem-row { display: flex; gap: var(--nem-gap); flex-wrap: wrap; align-items: center; }
.nem-spread { display: flex; justify-content: space-between; align-items: center; gap: 12px; }

.nem-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.nem-dot.on { background: var(--nem-admit); }
.nem-dot.off { background: var(--nem-refuse); }


/* ---------------------------------------------------------------- theme page title

 * The theme prints the WordPress page's title. On a plugin page that title is the template's
 * name, so every event on the site opened to a heading reading "Event Details", and once
 * `Services\PageTitle` started rewriting it, to the event's name in the wrong place: centred,
 * above the hero, in the theme's header band, while the app rendered its own title in the
 * content where the wireframe puts it.
 *
 * `the_title` covers a theme that asks WordPress for the title. It does not cover an Elementor
 * Heading widget with the words typed into it, or a template that echoes `$post->post_title`.
 * This does.
 *
 * Scoped to `.neo-evt-page`, which `PageTitle::filter_body_class()` adds, and excluded from
 * anything inside the plugin's own mount.
 */

body.neo-evt-page .elementor-widget-theme-page-title,
body.neo-evt-page .elementor-page-title,
body.neo-evt-page .page-header .entry-title,
body.neo-evt-page > .site .page-title,
body.neo-evt-page .entry-header > .entry-title,
body.neo-evt-page header.page-header,
/*
 * Added in 1.6.7. The above list assumed the heading is a *page title* widget. On this
 * site the header template uses a plain Heading widget bound to the post-title dynamic
 * tag, which renders as `.elementor-widget-heading` and matches none of them. With
 * `the_title` blanked the widget renders an empty box, which is harmless; these rules
 * remove the box so it does not reserve 100px of header.
 */
body.neo-evt-page .elementor-widget-heading .elementor-heading-title:empty,
body.neo-evt-page .entry-title:empty,
body.neo-evt-page .page-title:empty,
body.neo-evt-page h1.wp-block-post-title:empty,
body.neo-evt-page .elementor-widget-theme-post-title {
  display: none !important;
}

/* An empty heading that still has an ancestor with padding. */
body.neo-evt-page .elementor-widget-heading:has(.elementor-heading-title:empty) {
  display: none !important;
}

/* The app's own headings are never hidden. */
body.neo-evt-page .neo-evt-mount .nem-h1 {
  display: block !important;
}
