:root {
  --bg: #090611;
  --bg-soft: #140a24;
  --text: #f7f7ff;
  --muted: #c7c7df;
  --cyan: #55efff;
  --pink: #ff4fb3;
  --gold: #ffd27a;
  --border: rgba(255, 255, 255, 0.16);
  --glass: rgba(17, 10, 31, 0.7);
  --shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

* {
  box-sizing: border-box;
}

.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

html,
body {
  margin: 0;
  min-height: 100%;
}

body {
  font-family: "Outfit", "Segoe UI", sans-serif;
  background:
    radial-gradient(circle at 8% 15%, rgba(85, 239, 255, 0.14), transparent 30%),
    radial-gradient(circle at 90% 80%, rgba(255, 79, 179, 0.12), transparent 35%),
    linear-gradient(130deg, #08050f 0%, #13091f 45%, #0b0722 100%);
  color: var(--text);
  overflow-x: hidden;
}

.bg-glow {
  position: fixed;
  inset: auto;
  width: 42vw;
  height: 42vw;
  border-radius: 50%;
  filter: blur(70px);
  z-index: -2;
  pointer-events: none;
}

.bg-glow-a {
  top: -10vw;
  left: -12vw;
  background: rgba(85, 239, 255, 0.28);
  animation: floatGlow 11s ease-in-out infinite;
}

.bg-glow-b {
  right: -8vw;
  bottom: -14vw;
  background: rgba(255, 79, 179, 0.24);
  animation: floatGlow 14s ease-in-out infinite reverse;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.menu-wrap {
  max-width: 1160px;
  margin: 0 auto;
  padding: 1rem 1.4rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.brand {
  text-decoration: none;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.brand-icon {
  font-size: 1.2rem;
  color: var(--pink);
  text-shadow: 0 0 18px rgba(255, 79, 179, 0.8);
}

.brand-text {
  font-family: "Orbitron", sans-serif;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-size: 1.1rem;
}

.menu-list {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin: 0;
  padding: 0;
}

.menu-list a {
  text-decoration: none;
  color: var(--text);
  font-weight: 500;
  position: relative;
}

.menu-list a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -0.4rem;
  width: 100%;
  height: 2px;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 180ms ease;
  background: linear-gradient(90deg, var(--pink), var(--cyan));
}

.menu-list a:hover::after,
.menu-list a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

.menu-cta {
  padding: 0.52rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: linear-gradient(110deg, rgba(255, 79, 179, 0.22), rgba(85, 239, 255, 0.2));
}

.menu-cta::after {
  display: none;
}

.menu-toggle {
  display: none;
  border: 1px solid var(--border);
  background: var(--glass);
  border-radius: 0.7rem;
  padding: 0.45rem;
  cursor: pointer;
}

.menu-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  margin: 4px;
  background: var(--text);
}

/* The admin area's own sub-navigation — kept separate from the public
   .menu-list so the two don't compete for space in one row (the old combined
   nav overflowed past the viewport once every admin link lived there too). */
.admin-subnav {
  background: rgba(6, 4, 14, 0.55);
  border-bottom: 1px solid var(--border);
}

.admin-subnav-tabs,
.admin-subnav {
  max-width: 1160px;
}

.admin-subnav {
  margin: 0 auto;
  padding: 0.55rem 1.4rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}

.admin-subnav-tabs {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
}

.admin-subnav-tabs a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  text-decoration: none;
  color: var(--muted);
  font-weight: 600;
  font-size: 0.86rem;
  padding: 0.45rem 0.75rem;
  border-radius: 0.6rem;
  border: 1px solid transparent;
  transition: background 150ms ease, color 150ms ease;
}

.admin-subnav-tabs a:hover,
.admin-subnav-tabs a:focus-visible {
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
}

.admin-subnav-tabs a.current {
  color: #0a1121;
  background: linear-gradient(105deg, var(--cyan), #9df3ff);
}

.admin-subnav-account {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.admin-subnav-account form {
  margin: 0;
}

.admin-subnav-account .btn {
  padding: 0.42rem 0.8rem;
  font-size: 0.86rem;
}

.hero {
  max-width: 1160px;
  margin: 2rem auto 0;
  padding: 1rem 1.4rem 0;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 2.4rem;
  align-items: center;
}

.eyebrow {
  color: var(--gold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.78rem;
  margin-bottom: 0.9rem;
}

.hero h1 {
  font-family: "Orbitron", sans-serif;
  margin: 0;
  line-height: 1.1;
  font-size: clamp(2rem, 5vw, 4rem);
  overflow-wrap: anywhere;
}

.lead {
  color: var(--muted);
  font-size: 1.05rem;
  max-width: 52ch;
  margin: 1.1rem 0 1.5rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}

.btn {
  text-decoration: none;
  font-weight: 700;
  padding: 0.8rem 1.2rem;
  border-radius: 0.7rem;
  transition: transform 180ms ease;
}

.btn:hover,
.btn:focus-visible {
  transform: translateY(-2px);
}

.btn-primary {
  color: #101218;
  background: linear-gradient(105deg, var(--gold), #fff0ad);
}

.btn-ghost {
  color: var(--text);
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.06);
}

.hero-art {
  position: relative;
}

.hero-art img {
  width: 100%;
  border-radius: 1.2rem;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  animation: reveal 850ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.hero-ring {
  position: absolute;
  inset: auto -10% -6% auto;
  width: 190px;
  height: 190px;
  border-radius: 50%;
  border: 2px solid rgba(85, 239, 255, 0.5);
  box-shadow: 0 0 35px rgba(85, 239, 255, 0.4);
  animation: pulse 3s ease-in-out infinite;
}

.cards {
  max-width: 1160px;
  margin: 3rem auto 0;
  padding: 0 1.4rem;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.cards-head {
  grid-column: 1 / -1;
  margin-bottom: 0.35rem;
}

.cards-kicker {
  margin: 0;
  color: var(--gold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.76rem;
}

.cards-head h2 {
  margin: 0.4rem 0 0;
  font-family: "Orbitron", sans-serif;
  font-size: clamp(1.2rem, 2.2vw, 1.8rem);
}

.cards-head p {
  margin: 0.55rem 0 0;
  color: var(--muted);
  max-width: 70ch;
}

.cards article {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.1rem;
  animation: reveal 700ms ease both;
}

.cards article:first-child {
  background-image:
    linear-gradient(rgba(9, 6, 17, 0.76), rgba(9, 6, 17, 0.82)),
    url("images/banner1.png");
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

.cards article:nth-child(2) {
  background-image:
    linear-gradient(rgba(9, 6, 17, 0.76), rgba(9, 6, 17, 0.82)),
    url("images/banner3.png");
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

.cards article:nth-child(3) {
  background-image:
    linear-gradient(rgba(9, 6, 17, 0.76), rgba(9, 6, 17, 0.82)),
    url("images/banner2.png");
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

.cards h2 {
  margin: 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1rem;
}

.cards p {
  color: var(--muted);
  margin: 0.7rem 0 0;
}

.lineup-card {
  display: grid;
  gap: 0.7rem;
  align-content: start;
  min-height: 260px;
}

.lineup-stage {
  margin: 0;
  color: var(--cyan);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 700;
}

.lineup-card h3 {
  margin: 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1.2rem;
  line-height: 1.25;
}

.lineup-time {
  margin: 0;
  color: #f3e3b3;
  font-weight: 700;
}

.lineup-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.lineup-tags span {
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(4, 9, 28, 0.55);
  border-radius: 999px;
  font-size: 0.76rem;
  padding: 0.28rem 0.6rem;
  color: #dbf8ff;
}

.lineup-copy {
  margin: 0;
  color: var(--muted);
  line-height: 1.55;
}

.banner-rotator {
  max-width: 1160px;
  margin: 2.4rem auto 0;
  padding: 0 1.4rem;
}

.banner-rotator-frame {
  position: relative;
  aspect-ratio: 21 / 8;
  border-radius: 1.2rem;
  overflow: hidden;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* Three images stacked in the same box, each fading in and out in its own
   third of an 18s loop. The delays are negative so every image starts
   already partway through its slice instead of all three flashing in
   together on load; which image the loop starts on is decided server-side
   (HomeController shuffles $bannerImages), so the rotation order itself is
   random per page load. */
.banner-rotator-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  animation: bannerRotate 18s ease-in-out infinite;
}

.banner-rotator-frame img:nth-child(1) {
  animation-delay: 0s;
}

.banner-rotator-frame img:nth-child(2) {
  animation-delay: -6s;
}

.banner-rotator-frame img:nth-child(3) {
  animation-delay: -12s;
}

.banner {
  max-width: 1160px;
  margin: 2rem auto 0;
  padding: 1.2rem 1.4rem;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.banner p {
  margin: 0;
  color: var(--muted);
}

.banner a {
  text-decoration: none;
  color: #0a1121;
  background: var(--cyan);
  font-weight: 700;
  padding: 0.65rem 1rem;
  border-radius: 999px;
}

.join-wrap {
  max-width: 1160px;
  margin: 2rem auto 0;
  padding: 0 1.4rem;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 1rem;
}

.form-card,
.list-card {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.15rem;
}

.form-card h2,
.list-card h2 {
  margin: 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1rem;
}

.form-card p,
.list-card p {
  margin: 0.8rem 0 1rem;
  color: var(--muted);
}

.join-form {
  display: grid;
  gap: 0.9rem;
}

.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

.join-form label {
  display: grid;
  gap: 0.35rem;
  font-size: 0.92rem;
}

.join-form input,
.join-form textarea {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.6rem;
  padding: 0.65rem 0.75rem;
  background: rgba(6, 4, 14, 0.65);
  color: var(--text);
}

.join-form textarea {
  resize: vertical;
}

.join-form .btn {
  border: 0;
  cursor: pointer;
}

.resend-form {
  margin-top: 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding-top: 1rem;
  display: grid;
  gap: 0.65rem;
}

.resend-form label {
  display: grid;
  gap: 0.35rem;
  font-size: 0.92rem;
}

.resend-form input {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.6rem;
  padding: 0.65rem 0.75rem;
  background: rgba(6, 4, 14, 0.65);
  color: var(--text);
}

.resend-form .btn {
  justify-self: start;
}

.flash-stack {
  display: grid;
  gap: 0.45rem;
  margin-bottom: 0.9rem;
}

.flash {
  margin: 0;
  border-radius: 0.6rem;
  padding: 0.55rem 0.7rem;
  font-size: 0.92rem;
}

.flash.success {
  background: rgba(76, 255, 175, 0.2);
  border: 1px solid rgba(76, 255, 175, 0.4);
}

.flash.error {
  background: rgba(255, 92, 139, 0.18);
  border: 1px solid rgba(255, 92, 139, 0.38);
}

.table-wrap {
  overflow: auto;
}

.quick-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

.menu-list form {
  margin: 0;
}

.menu-list .btn {
  padding: 0.45rem 0.85rem;
}

.registrations-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.registrations-table th,
.registrations-table td {
  padding: 0.6rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  text-align: left;
}

.registrations-table th {
  color: var(--gold);
  font-weight: 600;
}

.admin-shell {
  max-width: 1160px;
  margin: 2rem auto;
  padding: 0 1.4rem 2rem;
  display: grid;
  gap: 1rem;
}

.stats-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.stat-card {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1rem;
  transition: border-color 150ms ease, transform 150ms ease;
}

.stat-card-icon {
  width: 2.1rem;
  height: 2.1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.65rem;
  background: rgba(85, 239, 255, 0.12);
  border: 1px solid rgba(85, 239, 255, 0.3);
  margin-bottom: 0.7rem;
}

.stat-card-icon .nav-icon {
  margin-right: 0;
  width: 1.1rem;
  height: 1.1rem;
}

.stat-card h2 {
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
}

.stat-card p {
  margin: 0.6rem 0 0;
  font-family: "Orbitron", sans-serif;
  font-size: clamp(1.4rem, 2.2vw, 1.9rem);
}

/* When a stat card doubles as a shortcut into the section it summarises
   (e.g. content/index.orbit.php's per-section counts). */
a.stat-card {
  display: block;
  text-decoration: none;
  color: var(--text);
}

a.stat-card:hover,
a.stat-card:focus-visible {
  border-color: rgba(85, 239, 255, 0.5);
  transform: translateY(-2px);
}

.stat-card-arrow {
  float: right;
  color: var(--cyan);
}

.admin-list-card {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.1rem;
}

.admin-analytics-card {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.1rem;
}

.analytics-kpi-grid {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-top: 0.6rem;
}

.analytics-kpi {
  background: rgba(6, 4, 14, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.75rem;
  padding: 0.75rem;
}

.analytics-kpi h3 {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
}

.analytics-kpi p {
  margin: 0.35rem 0 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1.25rem;
}

.analytics-list-grid {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: 0.8rem;
}

.analytics-trend-card {
  margin-top: 0.8rem;
  background: rgba(6, 4, 14, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.75rem;
  padding: 0.75rem;
}

.analytics-trend-card h3 {
  margin: 0 0 0.55rem;
  font-size: 0.95rem;
}

.analytics-trend-chart {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(24px, 1fr));
  gap: 0.35rem;
  align-items: end;
  min-height: 150px;
}

.trend-col {
  display: grid;
  gap: 0.25rem;
  align-items: end;
}

.trend-bar {
  width: 100%;
  background: linear-gradient(180deg, var(--cyan), var(--pink));
  border-radius: 0.35rem 0.35rem 0.15rem 0.15rem;
  min-height: 2px;
}

.trend-col span {
  font-size: 0.68rem;
  color: var(--muted);
  text-align: center;
}

.analytics-list-card {
  background: rgba(6, 4, 14, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.75rem;
  padding: 0.75rem;
}

.analytics-list-card h3 {
  margin: 0 0 0.45rem;
  font-size: 0.95rem;
}

.analytics-list-card ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.42rem;
}

.analytics-list-card li {
  display: flex;
  justify-content: space-between;
  gap: 0.65rem;
  align-items: baseline;
  font-size: 0.86rem;
}

.analytics-list-card li span {
  color: var(--muted);
  overflow-wrap: anywhere;
}

.analytics-list-card li strong {
  font-family: "Orbitron", sans-serif;
  color: var(--gold);
}

.admin-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.admin-head h1 {
  margin: 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1.2rem;
}

.admin-head p {
  margin: 0.45rem 0 0;
  color: var(--muted);
  max-width: 62ch;
}

.admin-head .back-link {
  margin: 0 0 0.5rem;
}

.back-link a {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--cyan);
  text-decoration: none;
  font-size: 0.86rem;
  font-weight: 600;
}

.back-link a:hover,
.back-link a:focus-visible {
  text-decoration: underline;
}

.admin-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
}

.analytics-filters {
  display: inline-flex;
  gap: 0.4rem;
}

.analytics-filter-btn {
  text-decoration: none;
  color: var(--text);
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.04);
  border-radius: 999px;
  padding: 0.35rem 0.7rem;
  font-size: 0.8rem;
  font-weight: 600;
}

.analytics-filter-btn.active {
  color: #0e1222;
  background: linear-gradient(105deg, var(--gold), #fff0ad);
  border-color: transparent;
}

.admin-table td {
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.admin-row-shell {
  background: rgba(6, 4, 14, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 0.8rem;
  padding: 0.75rem;
}

.admin-row-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 0.65rem;
}

.admin-id {
  margin: 0;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.admin-status-group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.status-chip {
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
  font-size: 0.74rem;
  font-weight: 600;
  border: 1px solid transparent;
}

.status-chip.ok {
  background: rgba(76, 255, 175, 0.16);
  border-color: rgba(76, 255, 175, 0.45);
  color: #9dffc9;
}

.status-chip.wait {
  background: rgba(255, 210, 122, 0.12);
  border-color: rgba(255, 210, 122, 0.42);
  color: #ffe6ad;
}

.admin-row-form {
  display: grid;
  grid-template-columns: 1.2fr 1fr 0.9fr 0.6fr 1.4fr auto;
  gap: 0.5rem;
  align-items: center;
}

.admin-row-form input {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.55rem;
  padding: 0.5rem 0.6rem;
  background: rgba(6, 4, 14, 0.65);
  color: var(--text);
}

.admin-actions {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
}

.btn-danger {
  color: #fff;
  background: linear-gradient(110deg, #dc255e, #ff6a3c);
  border: 0;
  cursor: pointer;
}

.admin-meta {
  margin: 0.5rem 0 0;
  color: var(--muted);
  font-size: 0.82rem;
}

.login-shell {
  max-width: 760px;
  margin: 3rem auto;
  padding: 0 1.4rem 2rem;
}

.login-card {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.25rem;
}

.login-card h1 {
  margin: 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1.3rem;
}

.login-card p {
  margin: 0.8rem 0 1rem;
  color: var(--muted);
}

.login-form {
  display: grid;
  gap: 0.8rem;
}

.login-form label {
  display: grid;
  gap: 0.35rem;
}

.login-form input {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.6rem;
  padding: 0.65rem 0.75rem;
  background: rgba(6, 4, 14, 0.65);
  color: var(--text);
}

.error-shell {
  max-width: 880px;
  margin: 6rem auto 0;
  padding: 0 1.4rem 2rem;
}

.error-card {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.4rem;
  text-align: center;
}

.error-code {
  margin: 0;
  color: var(--gold);
  letter-spacing: 0.12em;
  font-size: 0.86rem;
  text-transform: uppercase;
}

.error-card h1 {
  margin: 0.55rem 0 0;
  font-family: "Orbitron", sans-serif;
  font-size: clamp(1.6rem, 4vw, 2.5rem);
}

.error-card p {
  margin: 0.9rem auto 0;
  color: var(--muted);
  max-width: 52ch;
}

.error-actions {
  margin-top: 1.2rem;
  display: flex;
  justify-content: center;
  gap: 0.7rem;
  flex-wrap: wrap;
}

/* The exception dump on the 500 page — APP_DEBUG only, see
   ErrorPagesMiddleware. Left-aligned and scrollable: a stack trace reads
   as a list, not a paragraph, and can run wider than the card. */
.error-detail {
  margin: 1.1rem 0 0;
  padding: 0.9rem 1rem;
  background: rgba(6, 4, 14, 0.6);
  border: 1px solid var(--border);
  border-radius: 0.7rem;
  text-align: left;
  overflow-x: auto;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--muted);
}

.site-footer {
  max-width: 1160px;
  margin: 1.5rem auto 0;
  padding: 0 1.4rem 2rem;
  color: #b3b3d3;
  font-size: 0.9rem;
}

@keyframes reveal {
  from {
    opacity: 0;
    transform: translateY(15px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes pulse {
  0%,
  100% {
    transform: scale(0.95);
    opacity: 0.75;
  }
  50% {
    transform: scale(1.07);
    opacity: 1;
  }
}

@keyframes floatGlow {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  50% {
    transform: translate3d(0, 16px, 0);
  }
}

@keyframes bannerRotate {
  0%,
  100% {
    opacity: 0;
  }
  3%,
  30% {
    opacity: 1;
  }
  33% {
    opacity: 0;
  }
}

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

  .hero-art {
    max-width: 500px;
    margin-inline: auto;
  }

  .cards {
    grid-template-columns: 1fr;
  }

  .join-wrap {
    grid-template-columns: 1fr;
  }

  .stats-grid {
    grid-template-columns: 1fr;
  }

  .admin-row-form {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 760px) {
  .menu-toggle {
    display: inline-block;
  }

  .menu-list {
    position: absolute;
    top: 74px;
    right: 1rem;
    width: min(84vw, 310px);
    flex-direction: column;
    align-items: stretch;
    gap: 0.3rem;
    background: rgba(12, 8, 22, 0.96);
    border: 1px solid var(--border);
    border-radius: 0.8rem;
    padding: 0.7rem;
    transform: translateY(-8px) scale(0.98);
    opacity: 0;
    pointer-events: none;
    transition: 190ms ease;
  }

  .menu-list li a {
    display: block;
    padding: 0.55rem 0.7rem;
    border-radius: 0.5rem;
  }

  .menu-list li a:hover,
  .menu-list li a:focus-visible {
    background: rgba(255, 255, 255, 0.08);
  }

  .menu-list.open {
    transform: translateY(0) scale(1);
    opacity: 1;
    pointer-events: auto;
  }

  .hero {
    margin-top: 1.2rem;
  }

  .banner-rotator-frame {
    aspect-ratio: 4 / 3;
  }

  .banner {
    flex-direction: column;
    align-items: flex-start;
  }

  .admin-head {
    flex-direction: column;
    align-items: flex-start;
  }

  .admin-subnav {
    flex-direction: column;
    align-items: stretch;
  }

  .admin-subnav-tabs {
    overflow-x: auto;
    flex-wrap: nowrap;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    padding-bottom: 0.2rem;
  }

  .admin-subnav-account {
    width: 100%;
    min-width: 0;
    justify-content: space-between;
  }

  .analytics-filters {
    width: 100%;
    overflow-x: auto;
    padding-bottom: 0.2rem;
  }

  .admin-row-top {
    flex-direction: column;
    align-items: flex-start;
  }

  .analytics-list-grid {
    grid-template-columns: 1fr;
  }

  .form-grid {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   Lovefest app additions.

   Everything above this line is the LoveFest festival-template stylesheet,
   unmodified. phporbit's Form component (app/src/**/*Form.php) renders its
   own markup — <p class="field">, <label>, <input>/<select>/<textarea>,
   <span class="hint">/<span class="error">, a bare <button type="submit"> —
   with no hook to add the template's own .join-form/.btn classes to it. These
   rules give that generic markup the same look using the same tokens instead,
   so a Form-rendered page reads as part of one system rather than two.
   -------------------------------------------------------------------------- */

.current::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -0.4rem;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, var(--pink), var(--cyan));
}

.who {
  color: var(--muted);
  font-size: 0.92rem;
}

/* Icons in the nav — see the <symbol> sprite at the top of layout.orbit.php.
   A fixed cyan glow rather than currentColor: it marks these as icons the
   same way .brand-icon's pink glow marks the wordmark, and keeps them
   readable against both the plain link colour and .menu-cta's gradient. */
.menu-list a,
.menu-list .btn {
  display: inline-flex;
  align-items: center;
}

.nav-icon {
  width: 1.05em;
  height: 1.05em;
  margin-right: 0.42rem;
  vertical-align: -0.2em;
  flex-shrink: 0;
  fill: none;
  stroke: var(--cyan);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 4px rgba(85, 239, 255, 0.45));
}

.field {
  display: grid;
  gap: 0.35rem;
  margin: 0 0 0.9rem;
}

/* .field's own `display: grid` would otherwise outrank the UA stylesheet's
   `[hidden] { display: none }` on a specificity tie — register.js toggles
   this attribute to hide the karaoke-songs field when the answer is "no". */
.field[hidden] {
  display: none;
}

.field label {
  display: block;
  font-size: 0.92rem;
}

.field .hint {
  color: var(--muted);
  font-size: 0.82rem;
}

.field .error {
  color: #ff9fc4;
  font-size: 0.85rem;
  font-weight: 600;
}

.field [aria-invalid="true"] {
  border-color: #ff5c8b;
}

.field input,
.field select,
.field textarea,
.login-shell input,
form input[type="text"],
form input[type="email"],
form input[type="password"],
form input[type="tel"],
form input[type="url"],
form input[type="number"],
form input[type="date"],
form select,
form textarea {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.6rem;
  padding: 0.65rem 0.75rem;
  background: rgba(6, 4, 14, 0.65);
  color: var(--text);
  font: inherit;
}

form textarea {
  resize: vertical;
  min-height: 6rem;
}

/* The button phporbit's Form renders carries no class at all — style it like
   .btn.btn-primary by tag selector instead. Scoped with :not([class]) so it
   never outranks an explicitly classed button (.btn-ghost, .btn-danger, …)
   sharing the same <form>: form button[type="submit"] alone is more specific
   than a single class and was silently painting every admin action button —
   including the danger-red delete button — gold. */
form button[type="submit"]:not([class]) {
  text-decoration: none;
  font-weight: 700;
  padding: 0.8rem 1.2rem;
  border: 0;
  border-radius: 0.7rem;
  color: #101218;
  background: linear-gradient(105deg, var(--gold), #fff0ad);
  cursor: pointer;
  transition: transform 180ms ease;
}

form button[type="submit"]:not([class]):hover,
form button[type="submit"]:not([class]):focus-visible {
  transform: translateY(-2px);
}

/* A destructive or de-emphasised action inside a form — sign-out, delete —
   rendered as a plain <button class="link"> by the app's own templates
   (never by the Form component, which always submits the primary action). */
button.link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--text);
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}

button.link:hover {
  color: var(--pink);
}

/* Long-form content (schedule, venue, FAQ) rather than the structured
   sections the template was built for. */
.content-card {
  max-width: 70ch;
  margin: 2rem auto 0;
  padding: 0 1.4rem;
  display: grid;
  gap: 1.4rem;
}

.content-card h1 {
  font-family: "Orbitron", sans-serif;
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  margin: 0;
}

.content-card h2,
.content-card h3 {
  font-family: "Orbitron", sans-serif;
  margin: 1.2rem 0 0;
}

.content-card p {
  color: var(--muted);
  line-height: 1.65;
}

.content-facts {
  width: 100%;
  border-collapse: collapse;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 1rem;
  overflow: hidden;
}

.content-facts th,
.content-facts td {
  text-align: left;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.content-facts tr:last-child th,
.content-facts tr:last-child td {
  border-bottom: 0;
}

.content-facts th {
  font-weight: 600;
  color: var(--gold);
  width: 40%;
}

.muted {
  color: var(--muted);
  font-size: 0.9rem;
}

/* A generic glass panel for the odd place — a single signup, a login note —
   that isn't quite a .form-card/.list-card/.stat-card. */
.card {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.1rem;
}

.card + .card {
  margin-top: 0.85rem;
}

.card h3 {
  margin: 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1rem;
}

.card footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--muted);
  font-size: 0.82rem;
}

.card-list {
  display: grid;
  gap: 0.85rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
}

/* Compact, grid-based layout for the admin content-management forms — the
   "new item" form and every existing item's inline edit form on
   /admin/content/{schedule,venue,faq}. Stacking every field full-width,
   one per row, turned a handful of items into a very long page to scroll
   through; laying same-size fields side by side and letting only the
   textarea span the full row reads as a proper data-entry form instead.
   Scoped to .admin-shell so it doesn't reach the public registration form,
   which also happens to use .form-card.

   `dense`: schedule's form has 3 short fields before the textarea, so they
   already fill one row on their own. Venue and FAQ only have 2 (label,
   volgorde) split apart by the textarea between them — without `dense` the
   textarea's full-row span forces a new row immediately after the first
   short field, stranding the second short field alone on a row of its own
   below the textarea. `dense` lets the grid backfill that first row instead. */
.admin-shell .form-card form,
.admin-shell .card form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  grid-auto-flow: dense;
  gap: 0 1rem;
  align-items: start;
  margin-top: 0.8rem;
}

.admin-shell .form-card form .field:has(textarea),
.admin-shell .card form .field:has(textarea) {
  grid-column: 1 / -1;
}

.admin-shell .form-card form button[type="submit"],
.admin-shell .card form button[type="submit"] {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: 0.2rem;
}

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 100;
  background: var(--bg-soft);
  color: var(--text);
  padding: 0.6rem 1rem;
  border-radius: 0.5rem;
}

/* The door scanner (/admin/scan) — a live camera preview plus a big,
   colour-coded result banner, sized to be read at arm's length in a dim
   venue rather than studied up close. */
.scan-shell {
  max-width: 480px;
  margin: 1.2rem auto 0;
  display: grid;
  gap: 0.9rem;
  justify-items: center;
}

.scan-video {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: #000;
  border: 1px solid var(--border);
  border-radius: 1rem;
}

.scan-result {
  width: 100%;
  border-radius: 1rem;
  padding: 1.1rem 1.3rem;
  text-align: center;
  border: 1px solid transparent;
}

.scan-result-ok {
  background: rgba(76, 255, 175, 0.18);
  border-color: rgba(76, 255, 175, 0.5);
}

.scan-result-already {
  background: rgba(255, 210, 122, 0.16);
  border-color: rgba(255, 210, 122, 0.5);
}

.scan-result-invalid {
  background: rgba(255, 92, 139, 0.2);
  border-color: rgba(255, 92, 139, 0.55);
}

.scan-message {
  margin: 0;
  font-family: "Orbitron", sans-serif;
  font-size: 1.3rem;
  font-weight: 700;
}

.scan-details {
  margin: 0.5rem 0 0;
  color: var(--text);
  font-size: 0.95rem;
}
