/* ==========================================================================
   EvntNepal — design system
   Light-only, mobile-first. One stylesheet for every page.
   ========================================================================== */

:root {
  /* Two oranges, on purpose.
     --brand is the identity colour. At 3.5:1 against white it is right for
     large shapes and decoration, but too light to carry small text either as
     the ink or as the ground behind white ink.
     --brand-ink is the same hue taken far enough down to clear WCAG AA both
     ways: 5.0:1 as text on white, 5.0:1 under white text, 4.7:1 on --bg-soft.
     Anything bearing a word — a button fill, a link, a price — uses it. */
  --brand:        #f05537;
  --brand-ink:    #c2452d;
  --brand-dark:   #a83a26;   /* pressed / hover state of --brand-ink */
  --brand-soft:   #fff1ed;
  --ink:          #1e0a3c;   /* headings */
  --body:         #39364f;   /* body copy */
  --muted:        #696c80;   /* secondary copy — 5.2:1 white, 4.9:1 on soft */
  --line:         #dbdae3;
  --line-soft:    #eeedf2;
  --bg:           #ffffff;
  --bg-soft:      #f8f7fa;
  --green:        #0f7b57;
  --amber:        #a35b00;
  --red:          #c0392b;
  --blue:         #2160d3;

  --radius:       8px;
  --radius-lg:    12px;
  --shadow-sm:    0 1px 2px rgba(30,10,60,.08);
  --shadow:       0 2px 10px rgba(30,10,60,.10);
  --shadow-lg:    0 8px 28px rgba(30,10,60,.16);

  --header-h:     72px;
  --max:          1280px;

  /* Boxed layout. The site sits in a column this wide with the backdrop
     showing either side; --max keeps its own gutter inside that.
     For a full-width site again, set --site-max to 100%. */
  --site-max:     1400px;
  --backdrop:     #ebe9f1;
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, "Noto Sans", sans-serif;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--backdrop);
}

/*
 * body is the box.
 *
 * The header, main and footer are all children of it, so constraining body
 * boxes the entire site — no wrapper element, and nothing to add to any page.
 *
 * It deliberately runs the full height of the viewport rather than floating
 * with a margin at the top: the header is sticky, and a header that sticks to
 * the top of the window would otherwise escape above a floating box's edge.
 */
body {
  margin: 0 auto;
  max-width: var(--site-max);
  min-height: 100vh;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--body);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

/* The edges only exist once there is backdrop to show them against. */
@media (min-width: 1400px) {
  body { box-shadow: 0 0 0 1px rgba(30, 10, 60, .06), 0 0 40px rgba(30, 10, 60, .10); }
}

h1, h2, h3, h4 { color: var(--ink); line-height: 1.2; margin: 0 0 .5em; font-weight: 700; }
h1 { font-size: 2rem; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.175rem; }

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; display: block; }

.container { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 20px; }
.narrow    { max-width: 760px; }
.mid       { max-width: 1000px; }

.muted     { color: var(--muted); }
.small     { font-size: .875rem; }
.tiny      { font-size: .78rem; }
.center    { text-align: center; }
.nowrap    { white-space: nowrap; }
.hide      { display: none !important; }
.mt0 { margin-top: 0; } .mt1 { margin-top: 8px; } .mt2 { margin-top: 16px; }
.mt3 { margin-top: 24px; } .mt4 { margin-top: 32px; }
.mb0 { margin-bottom: 0; } .mb1 { margin-bottom: 8px; } .mb2 { margin-bottom: 16px; }
.mb3 { margin-bottom: 24px; }
.row  { display: flex; gap: 12px; align-items: center; }
.row-between { display: flex; gap: 12px; align-items: center; justify-content: space-between; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.stack { display: flex; flex-direction: column; gap: 12px; }

/* ------------------------------------------------------------------ buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: inherit; font-weight: 600; line-height: 1;
  padding: 12px 20px; border-radius: var(--radius);
  border: 1px solid transparent; background: var(--bg-soft); color: var(--ink);
  cursor: pointer; text-decoration: none; transition: background .15s, border-color .15s, color .15s;
  white-space: nowrap;
}
.btn:hover { text-decoration: none; }
.btn:disabled, .btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn-primary   { background: var(--brand-ink); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--brand-dark); }
.btn-dark      { background: var(--ink); color: #fff; }
.btn-dark:hover:not(:disabled) { background: #33125f; }
.btn-outline   { background: #fff; border-color: var(--ink); color: var(--ink); }
.btn-outline:hover:not(:disabled) { background: var(--bg-soft); }
.btn-ghost     { background: transparent; color: var(--body); }
.btn-ghost:hover:not(:disabled) { background: var(--bg-soft); }
.btn-danger    { background: #fff; border-color: var(--red); color: var(--red); }
.btn-danger:hover:not(:disabled) { background: #fdf0ee; }
.btn-sm        { padding: 8px 14px; font-size: .875rem; }

/* On a touch screen the compact buttons are below the 44px a finger needs, so
   they grow there only — a mouse keeps the tighter desktop density. */
@media (pointer: coarse) {
  .btn-sm { min-height: 44px; padding-top: 10px; padding-bottom: 10px; }
}
.btn-lg        { padding: 15px 26px; font-size: 1.0625rem; }
.btn-block     { width: 100%; }

/* ------------------------------------------------------------------- forms */
label, .label {
  display: block; font-size: .875rem; font-weight: 600;
  color: var(--ink); margin-bottom: 6px;
}
.hint { font-size: .8rem; color: var(--muted); margin-top: 4px; }

input[type=text], input[type=email], input[type=password], input[type=search],
input[type=tel], input[type=url], input[type=number], input[type=date],
input[type=time], input[type=datetime-local], select, textarea {
  width: 100%; font: inherit; color: var(--body);
  padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  background: #fff; transition: border-color .15s, box-shadow .15s;
}
/* ----------------------------------------------------------- skip link
   The header holds a search field and up to ten nav links, so reaching the
   listings by keyboard meant tabbing through all of them on every page. This
   is the first thing in the tab order and stays off-screen until focused. */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 60;
  background: var(--ink); color: #fff; text-decoration: none;
  padding: 10px 16px; border-radius: 0 0 var(--radius) var(--radius);
  font-weight: 600; font-size: .9375rem;
  transition: top .15s ease;
}
.skip-link:focus { top: 0; text-decoration: none; color: #fff; }

/* The header is sticky, so jumping to #main would otherwise park the first
   line underneath it. Same for any in-page anchor. */
#main, [id]:target { scroll-margin-top: calc(var(--header-h) + 12px); }

/* --------------------------------------------------------------- focus
   One ring for the whole site, on :focus-visible only — so it appears for
   keyboard and assistive-tech users and never flashes up on a mouse click.
   Browsers do draw a default ring, but it is a different shape and colour in
   each one and it disappears against the orange controls; this is consistent
   and has contrast against every surface the site uses, including the dark
   footer. Declared before the component rules so any of them can override it
   deliberately, and nothing overrides it by accident. */
:focus-visible {
  outline: 3px solid var(--brand-ink);
  outline-offset: 2px;
  border-radius: 3px;
}
.footer :focus-visible,
.cta-band :focus-visible,
.hero :focus-visible { outline-color: #fff; }

/* Mouse focus keeps the quiet tinted glow; keyboard focus gets the ring
   defined above, which is why these only suppress the non-visible case. */
input:focus:not(:focus-visible),
select:focus:not(:focus-visible),
textarea:focus:not(:focus-visible) {
  outline: none;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(240,85,55,.16);
}
textarea { min-height: 130px; resize: vertical; }
select { appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'><path d='M1 1l5 5 5-5' stroke='%2339364f' stroke-width='2' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat; background-position: right 12px center; padding-right: 34px;
}
.field { margin-bottom: 16px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* Grid items default to min-width:auto, so a control wider than its track
   pushes out of the row instead of shrinking — which is how the To date ended
   up overlapping the edge of the filters panel. */
.field-row > * { min-width: 0; }
.field-row input, .field-row select, .field-row textarea { width: 100%; min-width: 0; }

/* The filters column is about 260px wide. A native date input carries its own
   calendar button and will not go much below 150px, so two of them cannot sit
   side by side there however the track is sized — in this one place they
   stack. */
.filters .field-row { grid-template-columns: 1fr; gap: 12px; }
.check { display: flex; align-items: flex-start; gap: 10px; font-weight: 500; font-size: .95rem; }
.check input { width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--brand); flex: none; }

/* ------------------------------------------------------------------ header */
.site-header {
  position: sticky; top: 0; z-index: 60;
  background: #fff; border-bottom: 1px solid var(--line-soft);
}
.header-inner {
  display: flex; align-items: center; gap: 16px;
  height: var(--header-h); max-width: var(--max); margin: 0 auto; padding: 0 20px;
}
.logo { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 1.25rem; color: var(--brand); flex: none; }
.logo:hover { text-decoration: none; }
.logo svg { width: 26px; height: 26px; }

/* An uploaded logo. Height-constrained so any shape fits the bar, and capped in
   width so a very wide one cannot crowd out the search box. */
/* --logo-h is set from the Logo height setting; the fallback keeps the header
   sane if the script has not run yet or the setting is missing. max-width is
   generous because a wide wordmark at 40px tall can legitimately be long. */
.logo-img {
  height: var(--logo-h, 40px); width: auto; max-width: 260px;
  object-fit: contain; display: block;
}
/* Phones give the header less room, so the logo scales with it rather than
   being pinned to a second fixed number that would fight the setting. */
@media (max-width: 720px) {
  .logo-img { height: calc(var(--logo-h, 40px) * .8); max-width: 160px; }
}

.search-bar {
  display: flex; align-items: center; flex: 1 1 auto; max-width: 620px;
  border: 1px solid var(--line); border-radius: 999px; background: #fff;
  padding: 4px 4px 4px 16px; gap: 8px;
}
.search-bar:focus-within { border-color: var(--ink); box-shadow: var(--shadow-sm); }
.search-bar input {
  border: none; padding: 8px 0; background: transparent; min-width: 0;
}
.search-bar input:focus:not(:focus-visible) { outline: none; box-shadow: none; }
.search-bar .divider { width: 1px; height: 24px; background: var(--line); flex: none; }
/* The query field gives up its width first, and the location keeps enough to
   show the longest city name it holds. A text input shrinking merely truncated
   its placeholder; the dropdown that replaced it collapsed to "Toro…" and
   stopped being readable, so here the sizing runs the other way round. */
.search-bar input[name="q"] { flex: 1 1 auto; min-width: 70px; }
.search-bar .loc {
  display: flex; align-items: center; gap: 6px;
  flex: 0 1 196px; min-width: 172px;
}

/* An inline icon at text size. The markup has asked for `i16` since the search
   bar was built, but the class was never written, so the pin rendered at the
   SVG's own size — 66px, over a third of the location field, which is most of
   why the city never had room to show. */
.i16 { width: 16px; height: 16px; flex: none; }

/* The location picker is a <select>, but it sits inside the search bar and has
   to read as part of it rather than as a form control dropped in. The native
   arrow is replaced with a small chevron so the field still announces itself
   as something to open — without it people took the plain text for a label. */
.search-bar .loc select {
  appearance: none; -webkit-appearance: none;
  flex: 1 1 auto;
  border: none; background: transparent; padding: 8px 20px 8px 0;
  font: inherit; color: var(--ink); cursor: pointer;
  min-width: 0; width: 100%; text-overflow: ellipsis;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23696c80' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 2px center; background-size: 14px;
}
.search-bar .loc select:focus:not(:focus-visible) { outline: none; }
.search-bar .loc select:hover { color: var(--brand-ink); }
.search-go {
  flex: none; width: 38px; height: 38px; border-radius: 50%; border: none;
  background: var(--brand-ink); color: #fff; cursor: pointer;
  display: grid; place-items: center;
}
.search-go:hover { background: var(--brand-dark); }

.header-nav { display: flex; align-items: center; gap: 4px; margin-left: auto; flex: none; }
.header-nav a, .header-nav button {
  font-size: .9375rem; font-weight: 500; color: var(--body);
  padding: 9px 12px; border-radius: var(--radius); background: none; border: none;
  cursor: pointer; font-family: inherit; white-space: nowrap;
}
.header-nav a:hover, .header-nav button:hover { background: var(--bg-soft); text-decoration: none; }
.header-nav .cta { color: var(--brand-ink); font-weight: 600; }

.avatar {
  width: 34px; height: 34px; border-radius: 50%; background: var(--ink); color: #fff;
  display: grid; place-items: center; font-weight: 700; font-size: .875rem; flex: none;
}
.user-menu { position: relative; }
.user-menu .menu {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 220px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: 8px; z-index: 70;

  /*
   * The menu is twelve items long for an administrator, and it hangs off a
   * header that stays put. Without a ceiling it simply ran past the bottom of
   * the window on any laptop screen — Site admin, Help and Sign out were drawn
   * where nothing could reach them, and because the panel is positioned rather
   * than in the flow, the page would not scroll to them either. They looked
   * like they were missing.
   *
   * 80px leaves the header and a little air; the rest scrolls.
   */
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  overscroll-behavior: contain;   /* stop the page scrolling once the list ends */
}
.user-menu .menu a, .user-menu .menu button {
  display: block; width: 100%; text-align: left; padding: 10px 12px;
  border-radius: 6px; font-size: .9375rem; color: var(--body);
}
.user-menu .menu a:hover, .user-menu .menu button:hover { background: var(--bg-soft); }
.menu-head { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); margin-bottom: 6px; }
.menu-head strong { display: block; color: var(--ink); }

/* Second header row, shown only on narrow screens where the search pill and
   the nav links are hidden. */
.mobile-bar { display: none; padding: 0 16px 10px; border-top: 1px solid var(--line-soft); }
.mobile-search {
  display: flex; align-items: center; gap: 8px; margin: 10px 0 8px;
  border: 1px solid var(--line); border-radius: 999px; padding: 8px 14px; background: #fff;
}
.mobile-search:focus-within { border-color: var(--ink); }
.mobile-search input { border: none; padding: 2px 0; background: transparent; }
.mobile-search input:focus:not(:focus-visible) { outline: none; box-shadow: none; }
.mobile-search-ico { display: grid; place-items: center; flex: none; color: var(--muted); }
.mobile-search-ico svg { width: 18px; height: 18px; }
.mobile-links {
  display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none;
}
.mobile-links::-webkit-scrollbar { display: none; }
.mobile-links a {
  flex: none; font-size: .85rem; font-weight: 600; color: var(--body);
  padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px; background: #fff;
}
.mobile-links a:hover { text-decoration: none; border-color: var(--ink); }

/* The secondary of the two sign-in links, so they do not compete. */
.header-nav a.muted-link { color: var(--muted); font-size: .9375rem; }
.header-nav a.muted-link:hover { color: var(--ink); }

/* ------------------------------------------------------- social sign-in */
.social-row { display: flex; flex-direction: column; gap: 10px; }
.social-btn { display: flex; align-items: center; justify-content: center; gap: 10px; }
.social-or {
  display: flex; align-items: center; gap: 12px; margin: 18px 0;
  color: var(--muted); font-size: .8125rem;
}
.social-or::before, .social-or::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

/* --------------------------------------------------------- cookie notice */
.cookie-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 250;
  background: var(--ink); color: #fff; box-shadow: 0 -2px 20px rgba(30,10,60,.25);
}
.cookie-inner {
  max-width: var(--site-max); margin: 0 auto; padding: 14px 20px;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.cookie-inner p { margin: 0; font-size: .875rem; flex: 1 1 320px; color: rgba(255,255,255,.86); }
.cookie-inner a { color: #fff; text-decoration: underline; }

/* --------------------------------------------------------- social links */
.footer-social { display: inline-flex; gap: 10px; align-items: center; }
.footer-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 999px;
  background: rgba(255,255,255,.10); color: #e6e2ee; transition: background .15s, color .15s;
}
.footer-social a:hover { background: var(--brand-ink); color: #fff; text-decoration: none; }

/* ------------------------------------------------------- editable pages */
.page-body h2 { margin-top: 1.6em; }
.page-body h3 { margin-top: 1.3em; }
.page-body ul, .page-body ol { padding-left: 22px; }
.page-body li { margin-bottom: 6px; }
.page-body img { border-radius: var(--radius); margin: 14px 0; }
.page-body table { width: 100%; border-collapse: collapse; margin: 14px 0; }
.page-body th, .page-body td { border: 1px solid var(--line); padding: 8px 10px; text-align: left; }

/* ------------------------------------------- footer columns, in the admin */
.footer-board { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.fcol { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 14px; background: #fff; }
.fcol-head { padding-bottom: 10px; margin-bottom: 6px; border-bottom: 2px solid var(--brand); }
.fcol-head strong { display: block; color: var(--ink); font-size: 1.0625rem; }
.fcol-name {
  display: block; width: 100%; padding: 2px 6px; margin: 0 0 0 -6px;
  border: 1px solid transparent; border-radius: 6px; background: transparent;
  font: inherit; font-size: 1.0625rem; font-weight: 700; color: var(--ink);
  cursor: text;
}
.fcol-name:hover { border-color: var(--line); background: var(--bg-soft); }
.fcol-name:focus:not(:focus-visible) { outline: none; }
.fcol-name:focus {
  background: #fff;
  border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft);
}
.fcol-n {
  font-size: .66rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.fitem {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 6px; border-bottom: 1px solid var(--line-soft);
}
.fitem:last-of-type { border-bottom: 0; }
.fitem-label { color: var(--ink); font-size: .9375rem; }
.fitem.is-page .fitem-label { color: var(--body); }
.fitem.is-hidden { opacity: .55; }
.fitem-tools { display: flex; align-items: center; gap: 4px; flex: none; }
.fitem-tools .pos {
  font-size: .7rem; color: var(--muted); background: var(--bg-soft);
  border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------ site administration */
.admin-shell { display: grid; grid-template-columns: 232px 1fr; gap: 32px; align-items: start; }

.admin-side { position: sticky; top: calc(var(--header-h) + 20px); }
.admin-side-toggle { display: none; }

.admin-group + .admin-group { margin-top: 18px; }
.admin-group-label {
  font-size: .68rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); padding: 0 10px; margin-bottom: 6px;
}
.admin-link {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 8px 10px; border: 0; border-radius: 8px; margin-bottom: 2px;
  background: none; color: var(--body); font: inherit; font-size: .9375rem;
}
.admin-link:hover { background: var(--bg-soft); color: var(--ink); }
.admin-link.on { background: var(--brand-soft); color: var(--brand-dark); font-weight: 600; }

.admin-main { min-width: 0; }   /* lets wide tables scroll instead of stretching */

@media (max-width: 860px) {
  .admin-shell { grid-template-columns: 1fr; gap: 16px; }
  .admin-side { position: static; }

  /* On a phone the menu folds into a single control. */
  .admin-side-toggle {
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; padding: 12px 14px; cursor: pointer;
    border: 1px solid var(--line); border-radius: 8px;
    background: #fff; font: inherit; font-weight: 600; color: var(--ink);
  }
  .admin-side-toggle .chev { color: var(--muted); }
  #adminNav { display: none; padding-top: 10px; }
  #adminNav.open { display: block; }
}

/* ------------------------------------------------------- payment choice */
.pay-choice {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 8px; padding: 12px; margin-bottom: 8px;
}
.pay-choice:last-child { margin-bottom: 0; }
.pay-choice:hover { border-color: var(--brand); }
.pay-choice.only { cursor: default; }
.pay-choice.only:hover { border-color: var(--line); }
.pay-choice input { margin: 0; flex: none; }
.pill.blue { background: #e8f0fe; color: #1f4ea8; }

/* -------------------------------------------------------------- ad slots */
.ad-slot { margin: 28px 0 8px; }
.ad-slot-label {
  font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 8px;
}
.ad-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.ad-card {
  display: flex; gap: 14px; align-items: center; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius); background: #fff;
  color: inherit; transition: border-color .15s, box-shadow .15s;
}
.ad-card:hover { text-decoration: none; border-color: var(--brand); box-shadow: var(--shadow); }
.ad-card img { width: 132px; height: 96px; object-fit: cover; flex: none; background: var(--bg-soft); }
.ad-card.no-img img { display: none; }
.ad-body { padding: 12px 14px 12px 0; min-width: 0; }
.ad-card.no-img .ad-body { padding-left: 14px; }
.ad-body strong { display: block; color: var(--ink); }
.ad-body p {
  margin: 4px 0 6px; font-size: .85rem; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ------------------------------------------------------------ hero slider */
.hero.slider { position: relative; }
.hero .slides { position: relative; width: 100%; height: 100%; }
.hero .slide {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  transition: opacity .6s ease;
}
.hero .slide.on { opacity: 1; visibility: visible; position: relative; }
.slide-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255,255,255,.85); color: #1a0f2b; font-size: 1.4rem; line-height: 1;
  display: grid; place-items: center;
}
.slide-arrow:hover { background: #fff; }
.slide-arrow.prev { left: 14px; }
.slide-arrow.next { right: 14px; }
.slide-arrow[hidden] { display: none; }
.slide-dots {
  position: absolute; left: 0; right: 0; bottom: 14px; z-index: 3;
  display: flex; justify-content: center; gap: 8px;
}
.slide-dots button {
  width: 9px; height: 9px; padding: 0; border-radius: 50%; cursor: pointer;
  border: none; background: rgba(255,255,255,.5);
}
.slide-dots button.on { background: #fff; width: 22px; border-radius: 999px; }
@media (prefers-reduced-motion: reduce) { .hero .slide { transition: none; } }

/* ------------------------------------------------------- category strip
   One definition, used by both the home page band and the Find events strip,
   so the two cannot drift apart. It lives here rather than in home.css because
   style.css is the sheet every page loads. */

.cat-band  { padding: 26px 0 6px; }
/* Find events sits the strip in a bordered band of its own, so the spacing the
   home page gets from .cat-band has to come from here instead. */
.cat-strip { border-bottom: 1px solid var(--line-soft); background: #fff; padding: 14px 0 10px; }

.cat-rail { position: relative; display: flex; align-items: center; gap: 6px; }
/* No scroll-behavior here — the script asks for smooth scrolling and falls
   back to a jump, so the arrows work even where smooth is unsupported. */
.cat-rail .cat-scroll { flex: 1; }

.cat-scroll {
  display: flex; gap: 10px; overflow-x: auto; padding: 4px;
  max-width: var(--max); margin: 0 auto; scrollbar-width: none;
}
.cat-scroll::-webkit-scrollbar { display: none; }

.cat-item {
  flex: none; width: 100px; text-align: center; text-decoration: none;
  color: var(--body); padding: 6px 2px; border-radius: 12px;
}
.cat-item:hover { text-decoration: none; background: var(--bg-soft); }

.cat-icon {
  width: 62px; height: 62px; margin: 0 auto 9px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.cat-icon svg { width: 27px; height: 27px; stroke-width: 1.8; }

/* The icon is a <span> too, so this must not catch it — `.cat-item span` is
   more specific than `.cat-icon` and would override the flex centring, which
   pins every glyph to the top of its circle. */
.cat-item span:not(.cat-icon) {
  font-size: .8125rem; font-weight: 600; display: block; line-height: 1.3;
}

/* Each circle takes its colour from its position, cycling through eight, so a
   strip of any length stays varied without anyone choosing colours per
   category. */
.cat-item:nth-child(8n+1) .cat-icon { background: #e3f0ff; color: #1b62c9; }
.cat-item:nth-child(8n+2) .cat-icon { background: #efe6ff; color: #6d38cc; }
.cat-item:nth-child(8n+3) .cat-icon { background: #e2f6ec; color: #0f7b57; }
.cat-item:nth-child(8n+4) .cat-icon { background: #ffe6e6; color: #cf3b3b; }
.cat-item:nth-child(8n+5) .cat-icon { background: #e6f3fb; color: #1a7ba3; }
.cat-item:nth-child(8n+6) .cat-icon { background: #fdeede; color: #c0670f; }
.cat-item:nth-child(8n+7) .cat-icon { background: #ffe9f1; color: #c93a73; }
.cat-item:nth-child(8n+8) .cat-icon { background: #fff4d6; color: #9c7016; }

/* The filtered category on Find events. A ring rather than a different fill,
   so the wash above still reads and the circle does not change size. */
.cat-item.active .cat-icon { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--brand); }
.cat-item.active { color: var(--brand-ink); }
.cat-item.active span:not(.cat-icon) { font-weight: 700; }

.cat-arrow {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--line); background: #fff; cursor: pointer;
  color: var(--body); font-size: 17px; line-height: 1; z-index: 2;
  display: grid; place-items: center;
}
.cat-arrow:hover { border-color: var(--ink); }
.cat-arrow[hidden] { display: none; }

/* -------------------------------------------------------------------- hero */
.hero {
  position: relative; margin: 0 auto; max-width: var(--max);
  border-radius: var(--radius-lg); overflow: hidden;
  min-height: 340px; display: flex; align-items: center;
  background: #1e0a3c;
}
.hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .55; }
.hero-inner { position: relative; padding: 48px 44px; max-width: 620px; }
.hero .eyebrow {
  display: inline-block; background: var(--brand-ink); color: #fff;
  font-weight: 800; font-size: .8rem; letter-spacing: .1em; text-transform: uppercase;
  padding: 5px 10px; border-radius: 3px; margin-bottom: 14px;
}
.hero h1 {
  color: #fff; font-size: clamp(1.9rem, 4.2vw, 3rem); margin-bottom: 14px;
  text-shadow: 0 2px 18px rgba(0,0,0,.35);
}
.hero p { color: rgba(255,255,255,.92); font-size: 1.0625rem; margin: 0 0 22px; }

/* ------------------------------------------------------------------- tabs */
.tabs { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: none; padding: 9px 16px; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; color: var(--body); font-weight: 600; font-size: .9rem;
  cursor: pointer; font-family: inherit;
}
.tab:hover { border-color: var(--ink); text-decoration: none; }
.tab.active { background: var(--ink); border-color: var(--ink); color: #fff; }

/* ------------------------------------------------------------- event cards */
.section { padding: 40px 0; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.section-head h2 { margin: 0; }
.section-head a { color: var(--brand-ink); font-weight: 600; font-size: .9375rem; }

.card-grid {
  display: grid; gap: 24px;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
.card-grid.cols-3 { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }

.ecard { position: relative; display: flex; flex-direction: column; }
.ecard:hover { text-decoration: none; }
.ecard-media {
  position: relative; aspect-ratio: 2 / 1; border-radius: var(--radius);
  overflow: hidden; background: var(--bg-soft); margin-bottom: 12px;
}
.ecard-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.ecard:hover .ecard-media img { transform: scale(1.04); }
.ecard-badge {
  position: absolute; left: 10px; bottom: 10px; background: rgba(255,255,255,.95);
  color: var(--ink); font-size: .72rem; font-weight: 700; padding: 4px 8px;
  border-radius: 4px; box-shadow: var(--shadow-sm);
}
.ecard-badge.hot { background: var(--brand-ink); color: #fff; }
.ecard-save {
  position: absolute; right: 10px; top: 10px; width: 34px; height: 34px;
  border-radius: 50%; border: none; background: rgba(255,255,255,.94);
  display: grid; place-items: center; cursor: pointer; box-shadow: var(--shadow-sm);
}
/* 34px is a comfortable size for the corner of a card under a mouse, but it is
   below the 44px a fingertip needs. The button appears in two layouts — pinned
   to a card corner and in a row of actions — so rather than extending the hit
   area with a pseudo-element, which depends on the positioning context and
   only worked in one of them, it simply grows on touch devices. */
@media (pointer: coarse) {
  .ecard-save { width: 44px; height: 44px; }
}
.ecard-save svg { width: 18px; height: 18px; fill: none; stroke: var(--ink); stroke-width: 1.8; }
.ecard-save.saved svg { fill: var(--brand); stroke: var(--brand); }
.ecard-title {
  font-weight: 700; color: var(--ink); font-size: 1rem; margin: 0 0 4px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; line-height: 1.3;
}
.ecard-date { color: var(--brand-ink); font-weight: 600; font-size: .8125rem; margin-bottom: 3px; text-transform: uppercase; letter-spacing: .02em; }
.ecard-meta { color: var(--muted); font-size: .875rem; margin-bottom: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ecard-price { color: var(--ink); font-weight: 600; font-size: .875rem; }
.ecard-promoted { color: var(--muted); font-size: .75rem; margin-top: 4px; }

/* list variant used on the search page */
.elist { display: flex; flex-direction: column; gap: 4px; }
.erow {
  display: grid; grid-template-columns: 200px 1fr auto; gap: 20px;
  padding: 18px 0; border-bottom: 1px solid var(--line-soft); align-items: center;
}
.erow:hover { text-decoration: none; }
.erow .ecard-media { margin: 0; aspect-ratio: 16 / 9; }
.erow-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }

/* --------------------------------------------------------------- skeletons */
.skel { background: linear-gradient(90deg, #f1f0f4 25%, #e7e6ec 37%, #f1f0f4 63%);
  background-size: 400% 100%; animation: shimmer 1.3s infinite linear; border-radius: 6px; }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
.skel-card .skel-img { aspect-ratio: 2/1; border-radius: var(--radius); margin-bottom: 12px; }
.skel-line { height: 12px; margin-bottom: 8px; }

/* ------------------------------------------------------------------ badges */
.pill {
  display: inline-flex; align-items: center; gap: 6px; font-size: .75rem; font-weight: 700;
  padding: 4px 10px; border-radius: 999px; background: var(--bg-soft); color: var(--body);
}
.pill.green { background: #e6f4ef; color: var(--green); }
.pill.amber { background: #fdf1e0; color: var(--amber); }
.pill.red   { background: #fdecea; color: var(--red); }
.pill.blue  { background: #e9f0fd; color: var(--blue); }
.pill.brand { background: var(--brand-soft); color: var(--brand-dark); }

/* -------------------------------------------------------------- event page */
.event-hero { background: var(--bg-soft); border-bottom: 1px solid var(--line-soft); }
.event-hero-img {
  max-width: 1040px; margin: 0 auto; aspect-ratio: 2 / 1; max-height: 460px;
  overflow: hidden; background: #1e0a3c;
}
.event-hero-img img { width: 100%; height: 100%; object-fit: cover; }
.event-layout {
  display: grid; grid-template-columns: minmax(0,1fr) 360px; gap: 48px;
  padding: 36px 0 64px;
}
.event-body h2 { font-size: 1.5rem; margin: 32px 0 12px; }
.event-body h3 { font-size: 1.125rem; margin: 22px 0 8px; }
.event-body p, .event-body li { color: var(--body); }
.event-body ul, .event-body ol { padding-left: 20px; }
.event-title { font-size: clamp(1.7rem, 3.4vw, 2.6rem); margin-bottom: 10px; }

.info-line { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 18px; }
.info-line .ico {
  width: 40px; height: 40px; border-radius: 50%; background: var(--bg-soft);
  display: grid; place-items: center; flex: none;
}
.info-line .ico svg { width: 20px; height: 20px; stroke: var(--ink); fill: none; stroke-width: 1.7; }
.info-line strong { display: block; color: var(--ink); }

.ticket-panel {
  position: sticky; top: calc(var(--header-h) + 20px);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 20px; background: #fff;
}
.tier {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px; margin-bottom: 12px; transition: border-color .15s;
}
.tier.selected { border-color: var(--brand); background: var(--brand-soft); }
.tier.disabled { opacity: .6; }
.tier-head { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; }
.tier-name { font-weight: 700; color: var(--ink); }
.tier-price { font-weight: 700; color: var(--ink); white-space: nowrap; }
.qty { display: flex; align-items: center; gap: 4px; border: 1px solid var(--line);
  border-radius: 999px; padding: 2px; background: #fff; }
.qty button {
  width: 30px; height: 30px; border-radius: 50%; border: none; background: transparent;
  font-size: 1.125rem; line-height: 1; cursor: pointer; color: var(--ink); font-family: inherit;
}
.qty button:hover:not(:disabled) { background: var(--bg-soft); }
.qty button:disabled { opacity: .35; cursor: not-allowed; }
.qty span { min-width: 26px; text-align: center; font-weight: 700; }

.summary-line { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; font-size: .9375rem; }
.summary-total {
  display: flex; justify-content: space-between; gap: 12px;
  border-top: 1px solid var(--line); margin-top: 10px; padding-top: 12px;
  font-weight: 800; font-size: 1.125rem; color: var(--ink);
}

/* ----------------------------------------------------------------- panels */
.panel {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: #fff; padding: 24px; box-shadow: var(--shadow-sm);
}
.panel + .panel { margin-top: 20px; }
.panel-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 16px; }
.panel-head h2, .panel-head h3 { margin: 0; }

.stat-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.stat {
  border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 18px; background: #fff;
}
.stat .k { font-size: .8125rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.stat .v { font-size: 1.75rem; font-weight: 800; color: var(--ink); line-height: 1.15; margin-top: 6px; }
.stat .sub { font-size: .8125rem; color: var(--muted); margin-top: 2px; }

/* ------------------------------------------------------------------ table */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-lg); }
table.data { width: 100%; border-collapse: collapse; font-size: .9rem; background: #fff; }
table.data th, table.data td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--line-soft); }
table.data th {
  background: var(--bg-soft); font-weight: 700; color: var(--ink);
  font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; white-space: nowrap;
}
table.data tr:last-child td { border-bottom: none; }
table.data tbody tr:hover { background: #fcfbfd; }

/* ------------------------------------------------------------------ ticket */
.ticket-card {
  display: grid; grid-template-columns: 1fr 150px; border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden; background: #fff; box-shadow: var(--shadow-sm);
}
.ticket-stub {
  border-left: 2px dashed var(--line); padding: 16px; display: grid;
  place-items: center; gap: 8px; background: var(--bg-soft); text-align: center;
}
.ticket-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .8rem; letter-spacing: .06em; color: var(--ink); font-weight: 700; word-break: break-all;
}
.qr { width: 118px; height: 118px; background: #fff; padding: 6px; border-radius: 6px; }
.qr img, .qr canvas, .qr svg { width: 100%; height: 100%; display: block; }

/* ----------------------------------------------------------------- alerts */
.alert {
  padding: 12px 14px; border-radius: var(--radius); font-size: .9375rem;
  border: 1px solid; margin-bottom: 16px;
}
.alert-error   { background: #fdecea; border-color: #f5c6c0; color: #922; }
.alert-success { background: #e6f4ef; border-color: #b7e0d0; color: #0b5f43; }
.alert-info    { background: #e9f0fd; border-color: #c3d6f7; color: #1a4ba8; }
.alert-warn    { background: #fdf1e0; border-color: #f2d6a8; color: #7a4300; }

.empty { text-align: center; padding: 56px 20px; color: var(--muted); }
.empty svg { width: 56px; height: 56px; stroke: var(--line); fill: none; stroke-width: 1.4; margin-bottom: 14px; }
.empty h3 { color: var(--ink); }

/* ----------------------------------------------------------------- modals */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(30,10,60,.55); z-index: 200;
  display: grid; place-items: center; padding: 20px; overflow-y: auto;
}
.modal {
  background: #fff; border-radius: var(--radius-lg); width: 100%; max-width: 440px;
  box-shadow: var(--shadow-lg); padding: 28px; position: relative;
}
.modal-close {
  position: absolute; right: 14px; top: 12px; background: none; border: none;
  font-size: 1.5rem; line-height: 1; color: var(--muted); cursor: pointer; padding: 4px 8px;
}

/* ------------------------------------------------------------------ toast */
/*
 * Toasts hug the box, not the window. Centring the strip the same way body is
 * centred lands them exactly on the box edge — 100vw would be out by half the
 * scrollbar, which it counts and fixed positioning does not.
 */
#toasts {
  position: fixed; bottom: 20px; left: 0; right: 0;
  max-width: var(--site-max); margin: 0 auto; padding: 0 20px;
  align-items: flex-end; pointer-events: none; z-index: 300; display: flex; flex-direction: column; gap: 10px; }
#toasts > * { pointer-events: auto; }   /* the strip is transparent to clicks, the toasts are not */
.toast {
  background: var(--ink); color: #fff; padding: 12px 18px; border-radius: var(--radius);
  box-shadow: var(--shadow-lg); font-size: .9375rem; max-width: 340px;
  animation: toast-in .2s ease-out;
}
.toast.error { background: var(--red); }
.toast.success { background: var(--green); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---------------------------------------------------------------- filters */
.filters { position: sticky; top: calc(var(--header-h) + 16px); align-self: start; }
/* The panel sits on its own tinted surface rather than floating on the page.
   The results beside it are white cards, so a quiet ground is enough to say
   "this is the tool, that is the content" without a hard border. */
.filters {
  background: var(--bg-soft);
  border-radius: var(--radius-lg);
  padding: 18px 16px 8px;
}

.filters-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 4px;
}
.filters-head h3 {
  margin: 0; font-size: 1.0625rem;
  display: flex; align-items: center; gap: 8px;
}
/* How many filters are on. Without it, "Clear all" refers to nothing you can
   see, and on a long panel the applied ones scroll out of view. */
.filters-count {
  font-size: .75rem; font-weight: 700; line-height: 1;
  background: var(--brand-ink); color: #fff;
  padding: 4px 7px; border-radius: 999px;
}
.filters-head button {
  border: 0; background: none; padding: 0; cursor: pointer;
  font: inherit; font-size: .8125rem; font-weight: 600;
  color: var(--brand-ink); text-decoration: underline;
  text-underline-offset: 3px;
}
.filters-head button:hover { color: var(--brand-dark); }

/* Groups are separated by space, not by a rule under each one — six hairlines
   down a narrow column read as a form from 1998. */
.filter-group { padding: 14px 0 0; }
.filter-group h4 {
  font-size: .8125rem; font-weight: 700; letter-spacing: 0;
  margin: 0 0 9px; color: var(--ink);
}

/* ---- the choices themselves
   Still real radio buttons: the input is moved out of sight but keeps its
   place in the tab order, so keyboard and screen-reader behaviour is
   unchanged and the page's own JS still reads input[name=…]:checked. */
.filters .chips { display: flex; flex-wrap: wrap; gap: 6px; }
.filters .chips .check {
  display: inline-flex; align-items: center; margin: 0;
  padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: #fff;
  font-size: .8125rem; font-weight: 500; color: var(--body);
  cursor: pointer; user-select: none;
  transition: border-color .15s, background-color .15s, color .15s;
}
.filters .chips .check input {
  position: absolute; opacity: 0; width: 1px; height: 1px;
  margin: 0; pointer-events: none;
}
.filters .chips .check:hover { border-color: var(--ink); }
.filters .chips .check:has(input:checked) {
  background: var(--brand-soft); border-color: var(--brand-ink);
  color: var(--brand-ink); font-weight: 600;
}
.filters .chips .check:focus-within {
  outline: 3px solid var(--brand-ink); outline-offset: 2px;
}

/* Inputs in the panel share one width and one radius so the column has a
   single left and right edge all the way down. */
.filters select,
.filters input[type="date"] {
  width: 100%; background: #fff;
}
/* The date sub-labels must sit clearly under the group heading, not compete
   with it — at the same size and weight the panel reads as one flat list. */
.filters .tiny {
  display: block; margin-bottom: 5px;
  font-size: .6875rem; font-weight: 600; color: var(--muted);
}
.filters .field-row { margin-top: 10px; }

@media (prefers-reduced-motion: reduce) {
  .filters .chips .check { transition: none; }
}
.search-layout { display: grid; grid-template-columns: 250px minmax(0,1fr); gap: 40px; padding: 28px 0 64px; }

/* ----------------------------------------------------------------- footer */
/* Dark, with the brand block first and the link columns beside it. */
.site-footer { background: var(--ink); color: #cfc9dd; margin-top: 40px; }
.footer-cols {
  display: grid; gap: 30px 22px; padding: 52px 0 34px;
  /* auto-fit cannot share a track list with another flexible track, so the
     brand column earns its extra width by spanning two instead. The minimum is
     sized so brand(2) + four link columns + the app column still fit one row on
     a normal desktop. */
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
}
.footer-brand { grid-column: span 2; }
@media (max-width: 900px) { .footer-brand { grid-column: 1 / -1; } }
.footer-cols h4 {
  font-size: .8125rem; text-transform: uppercase; letter-spacing: .08em;
  margin-bottom: 14px; color: #fff;
}
.footer-cols ul { list-style: none; padding: 0; margin: 0; }
.footer-cols li { margin-bottom: 9px; }
.footer-cols a { color: #cfc9dd; font-size: .9375rem; }
.footer-cols a:hover { color: #fff; }

.footer-brand { max-width: 330px; }
.footer-logo { display: inline-flex; align-items: center; gap: 8px; margin-bottom: 12px;
               font-weight: 800; font-size: 1.25rem; color: #fff; }
.footer-logo:hover { text-decoration: none; }
.footer-logo svg { width: 26px; height: 26px; }
.footer-logo .logo-img { height: var(--logo-h, 40px); width: auto; max-width: 220px; object-fit: contain; }
.footer-brand p { margin: 0 0 16px; font-size: .9375rem; line-height: 1.6; color: #b7b0c9; }
/* "Get the app" — only rendered once a store link is set. */
.app-blurb { font-size: .875rem; color: #b7b0c9; margin: -4px 0 12px; line-height: 1.5; }
.app-badges { display: flex; flex-direction: column; gap: 9px; align-items: flex-start; }
/* On the dark footer these need an outline to read as buttons at all. */
.app-badge {
  display: inline-flex; align-items: center; gap: 10px;
  background: rgba(255,255,255,.08); color: #fff; border-radius: 9px;
  padding: 8px 14px 8px 12px; min-width: 156px; text-decoration: none;
  border: 1px solid rgba(255,255,255,.28);
}
.app-badge:hover { background: rgba(255,255,255,.16); color: #fff; text-decoration: none; }
.app-badge svg { width: 21px; height: 21px; flex: none; }
.app-badge span { display: flex; flex-direction: column; line-height: 1.15; }
.app-badge i { font-style: normal; font-size: .625rem; opacity: .8; letter-spacing: .02em; }
.app-badge b { font-size: .9375rem; font-weight: 700; }

.footer-bottom {
  border-top: 1px solid rgba(255,255,255,.14); padding: 20px 0; display: flex;
  justify-content: space-between; gap: 16px; flex-wrap: wrap;
  font-size: .875rem; color: #a49cba;
}
.footer-note { color: #a49cba; }

/* ------------------------------------------------------------ CTA banner */
.cta-band {
  background: var(--ink); color: #fff; border-radius: var(--radius-lg);
  padding: 44px; display: grid; grid-template-columns: 1fr auto;
  gap: 24px; align-items: center;
}
.cta-band h2 { color: #fff; margin-bottom: 6px; }
.cta-band p { color: rgba(255,255,255,.82); margin: 0; }

/* --------------------------------------------------------------- progress */
.bar { height: 6px; border-radius: 999px; background: var(--line-soft); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--brand); border-radius: 999px; }

/* ------------------------------------------------------------ responsive */
@media (max-width: 1080px) {
  .event-layout { grid-template-columns: minmax(0,1fr) 320px; gap: 32px; }
}
@media (max-width: 900px) {
  /* The second header row carries the search and the same links as pills, so
     the desktop nav goes at the same width. These used to switch at 900px and
     720px, which left every screen in between showing both sets at once. */
  .search-bar { display: none; }
  .mobile-bar { display: block; }
  .header-nav .desktop-only { display: none; }
  .site-header { position: static; }
  .ticket-panel, .filters { top: 20px; }
  .search-layout { grid-template-columns: 1fr; gap: 20px; }
  .filters { position: static; }
  .event-layout { grid-template-columns: 1fr; }
  .ticket-panel { position: static; }
  .erow { grid-template-columns: 140px 1fr; }
  .erow-actions { grid-column: 1 / -1; flex-direction: row; align-items: center; justify-content: space-between; }
  .cta-band { grid-template-columns: 1fr; padding: 32px; }
}
@media (max-width: 720px) {
  h1 { font-size: 1.625rem; }
  .hero { min-height: 260px; border-radius: 0; }
  .hero-inner { padding: 28px 22px; }
  .field-row { grid-template-columns: 1fr; gap: 0; }
  .container { padding: 0 16px; }
  .section { padding: 28px 0; }
  .card-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 18px; }
  .ecard-title { font-size: .9375rem; }
  .panel { padding: 18px; }
  .ticket-card { grid-template-columns: 1fr; }
  .ticket-stub { border-left: none; border-top: 2px dashed var(--line); }
  .erow { grid-template-columns: 1fr; }
  .erow .ecard-media { aspect-ratio: 2/1; }
}

/* --------------------------------------------------------------- printing */
@media print {
  .site-header, .site-footer, .no-print, #toasts { display: none !important; }
  body { background: #fff; }
  .ticket-card { break-inside: avoid; box-shadow: none; }
}

/* ------------------------------------------------------- wallet buttons
   Shown on a ticket only when the site has that wallet configured, so this
   row is usually empty and must take no space when it is. */
.wallet-row:empty { display: none; }
.wallet-row {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 10px; width: 100%;
}
.wallet-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 12px; border-radius: 8px; font-size: .8125rem; font-weight: 600;
  text-decoration: none; border: 1px solid transparent; min-height: 40px;
}
.wallet-btn:hover { text-decoration: none; }
.wallet-btn svg { width: 17px; height: 17px; flex: none; }

/* Apple's guidance is a black button; Google's is dark grey with their own
   wordmark, which we cannot reproduce without their asset — so both are kept
   plainly branded rather than badly imitated. */
.wallet-apple  { background: #000; color: #fff; }
.wallet-apple:hover  { background: #1c1c1e; color: #fff; }
.wallet-google { background: #fff; color: #1f1f1f; border-color: #dadce0; }
.wallet-google:hover { background: #f8f9fa; color: #1f1f1f; }

@media print { .wallet-row { display: none !important; } }

/* ----------------------------------------------------- sign-up / sign-in
   The photograph is the page, with the form on a card floating over it. The
   site chrome is hidden here: an auth screen has one job, and a header full of
   somewhere-else links works against it. The brand at the top of the card is
   the way back. */

body:has(.auth-page) #siteHeader,
body:has(.auth-page) #siteFooter { display: none; }

.auth-page {
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 32px 20px;
  /* The fallback when no photograph is set — a brand wash rather than a blank
     white page, so a fresh install still looks finished. */
  background:
    radial-gradient(120% 90% at 20% 15%, #3b1270 0%, transparent 60%),
    linear-gradient(160deg, var(--ink) 0%, #2b0f52 55%, var(--brand-ink) 140%);
  background-size: cover;
  background-position: center;
}

.auth-card {
  width: 100%; max-width: 440px;
  background: #fff;
  border-radius: var(--radius-lg);
  padding: 38px 36px 32px;
  box-shadow: 0 24px 70px rgba(12, 4, 28, .38);
}
.auth-card h1 { font-size: 1.75rem; line-height: 1.2; margin: 0 0 6px; }

/* The wordmark sits at the top of the card and doubles as the way home. */
.auth-brand {
  display: inline-flex; align-items: center; gap: 8px;
  margin-bottom: 26px; text-decoration: none;
  font-weight: 800; font-size: 1.25rem; color: var(--brand-ink);
}
.auth-brand:hover { text-decoration: none; }
.auth-brand .logo-img { height: var(--logo-h, 40px); width: auto; max-width: 200px; }

/* The helper notes under the form are asides, not panels — inside a card, a
   card within a card just adds edges. */
.auth-card .panel {
  background: none; border: 0; padding: 0;
  margin-top: 18px; border-top: 1px solid var(--line-soft); padding-top: 16px;
}
.auth-card .panel h3 { font-size: .9375rem; margin: 0 0 4px; }

@media (max-width: 560px) {
  .auth-page { padding: 0; place-items: stretch; }
  .auth-card {
    max-width: none; min-height: 100vh; border-radius: 0;
    padding: 28px 20px 40px; box-shadow: none;
  }
}

/* ------------------------------------------------------- auth tab switch
   Two links styled as one control. The track is the tinted ground and the
   active half is a raised white card, so which one you are on is obvious
   without relying on colour alone. */
.auth-tabs {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: var(--bg-soft); border: 1px solid var(--line-soft);
  border-radius: 999px; padding: 4px; margin-bottom: 22px;
}
.auth-tab {
  text-align: center; padding: 9px 10px; border-radius: 999px;
  font-size: .9375rem; font-weight: 600; color: var(--muted);
  text-decoration: none; transition: color .15s, background-color .15s;
}
.auth-tab:hover { color: var(--ink); text-decoration: none; }
.auth-tab.on {
  background: #fff; color: var(--ink);
  box-shadow: 0 1px 3px rgba(30,10,60,.12);
}
.auth-tab:focus-visible { outline: 3px solid var(--brand-ink); outline-offset: 2px; }

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

/* ------------------------------------------------- organizer: shared bits */
/*
 * Used by the block on an event page and by the organizer's own page at
 * /o/<slug>, so the same person looks the same in both places.
 */
.org-avatar {
  width: var(--av, 52px); height: var(--av, 52px);
  font-size: calc(var(--av, 52px) / 2.4);
  border-radius: 50%; flex: none; object-fit: cover;
  background: var(--bg-soft); color: var(--ink);
  display: grid; place-items: center; font-weight: 800;
  border: 1px solid var(--line-soft);
}
.org-stat-line { margin: 2px 0 0; color: var(--muted); font-size: .875rem; }

.org-stats { display: flex; flex-wrap: wrap; gap: 0; margin: 14px 0 0; }
.org-stats > div { padding: 0 20px; border-left: 1px solid var(--line); }
.org-stats > div:first-child { padding-left: 0; border-left: 0; }
.org-stat-label { display: block; color: var(--muted); font-size: .8125rem; }
.org-stat-value { color: var(--ink); font-size: 1rem; }

/* The block at the foot of an event page. */
.org-card { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.org-card .grow { min-width: 180px; }
.org-card-actions { display: flex; gap: 10px; margin-left: auto; }
@media (max-width: 560px) {
  .org-card-actions { margin-left: 0; width: 100%; }
  .org-card-actions .btn { flex: 1; }
}

/* The organizer's own page. */
.org-hero { display: flex; gap: 28px; align-items: flex-start; flex-wrap: wrap; }
.org-hero > .org-avatar { --av: 132px; }
.org-hero .org-identity { flex: 1 1 320px; min-width: 0; }
.org-hero h1 { margin: 0 0 2px; }
.org-hero-actions {
  display: flex; flex-direction: column; gap: 10px; width: 180px; flex: none;
}
.org-hero-actions .btn { width: 100%; }
@media (max-width: 720px) {
  .org-hero-actions { width: 100%; flex-direction: row; }
  .org-stats > div { padding: 0 14px; }
}
@media (max-width: 560px) {
  /* A 132px circle eats a third of a phone screen before the name is reached. */
  .org-hero > .org-avatar { --av: 84px; }
}
.org-links { display: flex; gap: 14px; margin-top: 14px; align-items: center; }
.org-links a { color: var(--muted); display: inline-flex; }
.org-links a:hover { color: var(--brand-ink); }
.org-links svg { width: 18px; height: 18px; }

/* The tick on the "message sent" panel. */
.org-sent {
  width: 54px; height: 54px; border-radius: 50%; display: inline-grid;
  place-items: center; background: #e8f6ee; color: #1b7f4d;
}
.org-sent svg { width: 26px; height: 26px; stroke: currentColor; fill: none; stroke-width: 2.2; }

/* The asterisk on a required label. */
.req { color: var(--brand-ink); }

.row-end { display: flex; justify-content: flex-end; align-items: center; }

/*
 * The honeypot. Taken out of the layout without display:none or
 * visibility:hidden, both of which the better form bots check for before
 * filling a field in.
 */
.hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; opacity: 0;
}

/* ------------------------------------------- organizer: the Contact inbox */
.msg-list { display: grid; gap: 14px; }
.msg.unread { border-left: 3px solid var(--brand-ink); }
.msg-body {
  white-space: pre-wrap;        /* the sender's own line breaks, kept */
  margin: 12px 0 14px; color: var(--ink);
}
.warn-text { color: #a3521a; }

/* The organizer's name where it links to their page. */
.org-name { color: var(--ink); }
.org-name:hover { color: var(--brand-ink); }

/* ------------------------------------------------- hero slide call to action */
/*
 * The button a slide can carry, under the search box.
 *
 * The [hidden] rule is not redundant: .btn sets display:inline-flex, which
 * outranks the hidden attribute's own display:none, so without this a slide
 * with no button would show an empty one.
 */
.h-cta { margin-top: 20px; }
.h-cta[hidden] { display: none; }

@media (max-width: 560px) {
  .h-cta { width: 100%; }
}

/* --------------------------------------------- share: QR code and post card */
.share-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 18px;
}
.share-col { text-align: center; }
.share-preview {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 12px; margin-bottom: 10px;
  display: grid; place-items: center; min-height: 170px;
}
/*
 * Both canvases are drawn far larger than they are shown — 640px for the code,
 * 1080 for the card — so the downloaded file is sharp while the preview stays
 * small. This is what scales them down.
 */
.share-preview canvas { width: 100%; height: auto; max-width: 240px; display: block; }
.share-col p { margin: 2px 0 10px; }

@media (max-width: 560px) {
  .share-grid { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------- contact page
 *
 * A contact page succeeds by being answered without anybody writing in, so
 * the layout puts the two things people actually came for above everything
 * else: the address, and the link that solves the common problem.
 *
 * .contact-routes is that first strip. .triage replaces a two-column table
 * that was unreadable on a phone -- a table forces the answer column into
 * about forty pixels, and the answers are where the links live.
 *
 * Rules are written under .page-body because that is where the CMS content
 * lands, and .page-body already styles bare h3 and p inside it.
 */

.page-body .contact-routes {
  display: grid;
  gap: 14px;
  margin: 22px 0 10px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.page-body .route {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  color: inherit;
  box-shadow: var(--shadow-sm);
  transition: border-color .15s, box-shadow .15s;
}
.page-body a.route:hover,
.page-body a.route:focus-visible {
  border-color: var(--brand);
  box-shadow: var(--shadow);
  text-decoration: none;
}

/* flex:none so a long email address shrinks the text, never the icon */
.page-body .route svg {
  width: 21px; height: 21px; flex: none; margin-top: 3px;
  stroke: var(--brand-ink); fill: none;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}

.page-body .route-label {
  display: block; font-size: .7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
}
/* An email address has no spaces to wrap at and will otherwise widen the
   whole grid track until the card overflows its column. */
.page-body .route-value {
  display: block; margin-top: 3px; font-weight: 700;
  font-size: 1.0625rem; color: var(--ink); line-height: 1.3;
  overflow-wrap: anywhere;
}
.page-body .route-note {
  display: block; margin-top: 4px; font-size: .8125rem; color: var(--muted);
}

.page-body .triage { display: grid; gap: 14px; margin: 18px 0 10px; }

.page-body .triage-item {
  padding: 16px 18px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
}
.page-body .triage-item h3 { margin: 0 0 6px; font-size: 1.0625rem; }
.page-body .triage-item p  { margin: 0; }
.page-body .triage-item .btn { margin-top: 12px; }

/* The checklist beside the message form. Not a .page-body ul: it carries its
   own marks and should not take that rule's 22px indent. */
.page-body .include-list { list-style: none; padding: 0; margin: 14px 0 0; }
.page-body .include-list li {
  position: relative; padding-left: 26px; margin-bottom: 9px;
}
.page-body .include-list li::before {
  content: ""; position: absolute; left: 4px; top: .45em;
  width: 11px; height: 6px;
  border-left: 2px solid var(--green); border-bottom: 2px solid var(--green);
  transform: rotate(-45deg);
}

@media (max-width: 560px) {
  .page-body .route,
  .page-body .triage-item { padding: 14px; }
}

/* An order code in running text. Monospace alone is too subtle to pick out of
   a sentence, and the point of printing EVN-XXXX-XXXX is that people recognise
   the shape of it on their own ticket. */
.page-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .9em; padding: 2px 6px; border-radius: 5px;
  background: var(--brand-soft); color: var(--brand-ink);
  white-space: nowrap;
}

/* ----------------------------------------------- policy and legal pages
 *
 * Privacy, Terms and the storage policy are long, are read under pressure --
 * somebody wants one clause, usually about refunds or their data -- and are
 * the pages a visitor checks to decide whether a site they have never heard
 * of can be trusted with a card. So they get a date they can see, a contents
 * list that jumps, and a storage table that survives a phone.
 */

.page-body .doc-meta {
  display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: baseline;
  margin: 0 0 24px; padding-bottom: 16px;
  border-bottom: 1px solid var(--line-soft);
  font-size: .8125rem; color: var(--muted);
}
.page-body .doc-meta strong { color: var(--ink); font-weight: 700; }

.page-body .toc {
  margin: 0 0 30px; padding: 18px 20px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.page-body .toc h2 {
  margin: 0 0 12px; font-size: .72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
}
/* Two columns so ten clauses do not push the page itself out of sight. */
.page-body .toc ol {
  margin: 0; padding: 0; list-style: none;
  columns: 2; column-gap: 30px;
}
.page-body .toc li { margin: 0 0 8px; break-inside: avoid; }
.page-body .toc a { color: var(--body); text-decoration: none; }
.page-body .toc a:hover,
.page-body .toc a:focus-visible { color: var(--brand-ink); text-decoration: underline; }

/* The headings are jump targets now, and the site header is sticky, so a jump
   would otherwise land the heading underneath it. */
.page-body h2[id] { scroll-margin-top: calc(var(--header-h) + 20px); }

/* .page-body already draws a box round every th and td, for tables typed into
   the editor by hand. A .data table brings its own lighter rules, so the
   generic ones are cleared here rather than fought with. */
.page-body table.data { margin: 18px 0; }
.page-body table.data th,
.page-body table.data td {
  border: none; border-bottom: 1px solid var(--line-soft); padding: 12px 14px;
}
.page-body table.data tr:last-child td { border-bottom: none; }

@media (max-width: 560px) {
  .page-body .toc ol { columns: 1; }

  /* A four-column reference table has nowhere to go on a phone. .table-wrap
     would scroll it sideways, which hides exactly the column somebody is
     looking for, so each row becomes a small card instead and every value
     carries its column name. */
  .page-body table.data thead {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .page-body table.data,
  .page-body table.data tbody,
  .page-body table.data tr,
  .page-body table.data td { display: block; width: 100%; }

  .page-body table.data tr {
    padding: 10px 0; border-bottom: 1px solid var(--line);
  }
  .page-body table.data tr:last-child { border-bottom: none; }
  .page-body table.data td { border-bottom: none; padding: 5px 14px; }
  .page-body table.data td::before {
    content: attr(data-label); display: block;
    font-size: .68rem; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--muted); margin-bottom: 2px;
  }
  /* The label is only useful when there is a value under it. */
  .page-body table.data td:empty { display: none; }
}

/* ------------------------------------------------- editorial page blocks
 *
 * For CMS pages that are selling something rather than stating a policy --
 * About, and anything like it. All of them are written to work inside the
 * 760px reading column the pages already use, so nothing here needs the
 * layout widened.
 *
 * White on --brand is 3.5:1, which the palette notes call out as too light
 * to carry a word. Anything here with text or a glyph on a filled ground
 * uses --brand-ink instead.
 */

.page-body .lede {
  font-size: 1.1875rem; line-height: 1.6; color: var(--body);
  margin: 0 0 18px;
}

/* Two features side by side, stacking below the layout's own 720px step. */
.page-body .cards-2 {
  display: grid; gap: 16px; margin: 18px 0 8px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.page-body .feature {
  padding: 22px; background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.page-body .feature-icon {
  width: 42px; height: 42px; border-radius: 12px; margin-bottom: 14px;
  background: var(--brand-soft); display: grid; place-items: center;
}
.page-body .feature-icon svg {
  width: 21px; height: 21px; fill: none; stroke: var(--brand-ink);
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.page-body .feature h3 { margin: 0 0 8px; font-size: 1.0625rem; }
.page-body .feature p:last-child { margin-bottom: 0; }

/* Numbered steps. The numeral is drawn by a counter rather than typed into
   the copy, so inserting a step cannot leave the list reading 1, 2, 2, 4. */
.page-body .steps {
  counter-reset: step; list-style: none;
  display: grid; gap: 12px; padding: 0; margin: 18px 0 8px;
}
.page-body .steps li {
  counter-increment: step; position: relative; margin: 0;
  padding: 16px 18px 16px 64px;
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.page-body .steps li::before {
  content: counter(step);
  position: absolute; left: 18px; top: 17px;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--brand-ink); color: #fff;
  display: grid; place-items: center;
  font-size: .9375rem; font-weight: 800; line-height: 1;
}
.page-body .steps h3 { margin: 0 0 4px; font-size: 1rem; }
.page-body .steps p  { margin: 0; }

/* A figure the reader should not be able to skim past. */
.page-body .callout {
  margin: 18px 0; padding: 18px 20px;
  background: var(--brand-soft);
  border: 1px solid #f7d9d1; border-left: 3px solid var(--brand);
  border-radius: var(--radius);
}
.page-body .callout p:first-child { margin-top: 0; }
.page-body .callout p:last-child  { margin-bottom: 0; }

/* A quieter band, to break up a run of white cards. */
.page-body .band {
  margin: 26px 0; padding: 24px 26px;
  background: var(--bg-soft);
  border: 1px solid var(--line-soft); border-radius: var(--radius-lg);
}
.page-body .band > :first-child { margin-top: 0; }
.page-body .band > :last-child  { margin-bottom: 0; }
.page-body .band h2 { margin-top: 0; }

@media (max-width: 560px) {
  .page-body .lede { font-size: 1.0625rem; }
  .page-body .feature { padding: 18px; }
  .page-body .band { padding: 18px; }
  .page-body .steps li { padding: 14px 16px 14px 58px; }
  .page-body .steps li::before { left: 15px; top: 15px; }
}
