/*
 * app-components.css — the "pa-" design system used by the <x-app.*> Blade
 * components (tabs, page-header, notice, button, field, card, status,
 * empty-state). These components were scaffolded without any CSS, so they
 * rendered unstyled on every page that uses them (the Saved workspace nav,
 * onboarding, directory, help). This file styles them with the shared design
 * tokens (tokens.css) and is loaded globally by layouts/app.blade.php, so any
 * <x-app.*> is styled consistently wherever it appears.
 *
 * Scoped entirely to .pa-* classes (only emitted by the components), so it
 * can't affect anything else on a page.
 */

/* ── Tabs (x-app.tabs → <nav class="pa-tabs"> > a) ──
   This app has NO global box-sizing reset — it is applied per page root
   (`.saved-page *`, `.judge-dir-v2 *`, `.club-dir-v2 *`, `.account-page *`).
   The directory tabs partial is included as a sibling BEFORE those roots on
   judges/organizers profile + search, so it inherits content-box and the
   min-height below would stack on top of the padding and borders (44 -> 66px).
   Pin it here so the component is self-contained wherever it is dropped. */
.pa-tabs, .pa-tabs a { box-sizing: border-box; }
.pa-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid var(--line);
  margin: 0 0 22px;
}
.pa-tabs a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 10px 16px;
  margin-bottom: -1px;
  color: var(--ink-muted);
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.pa-tabs a:hover { color: var(--brand); }
.pa-tabs a[aria-current="page"] {
  color: var(--brand);
  border-bottom-color: var(--brand);
}
.pa-tabs a:focus-visible {
  outline: 3px solid var(--brand-vivid);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ── Page header (x-app.page-header) ── */
.pa-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 22px;
}
.pa-eyebrow {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--brand);
}
.pa-page-header h1 {
  margin: 0;
  font-size: var(--h1-size);
  font-weight: var(--h1-weight);
  color: var(--ink);
  line-height: 1.2;
}
.pa-page-description {
  margin: 8px 0 0;
  color: var(--ink-muted);
  font-size: 15px;
  max-width: 60ch;
}
.pa-page-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ── Notice / alert (x-app.notice) ── */
.pa-notice {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  margin: 0 0 16px;
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: var(--radius-md);
  background: #fff;
  color: var(--ink);
}
.pa-notice > i { font-size: 18px; margin-top: 1px; }
.pa-notice > div { flex: 1; }
.pa-notice strong { display: block; margin-bottom: 2px; }
.pa-notice__close {
  border: 0;
  background: transparent;
  color: var(--ink-subtle);
  cursor: pointer;
  font-size: 15px;
  padding: 4px;
  min-height: 32px;
}
.pa-notice--info    { border-left-color: #2563eb; }
.pa-notice--info > i    { color: #2563eb; }
.pa-notice--success { border-left-color: var(--success); }
.pa-notice--success > i { color: var(--success); }
.pa-notice--warning { border-left-color: var(--warn); background: #fffbeb; }
.pa-notice--warning > i { color: var(--warn); }
.pa-notice--error   { border-left-color: var(--danger); background: #fef2f2; }
.pa-notice--error > i   { color: var(--danger); }

/* ── Button (x-app.button) ── */
.pa-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 11px 22px;
  border: 1.5px solid transparent;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-weight: 700;
  font-size: 15px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, transform .1s ease;
}
.pa-button:focus-visible { outline: 3px solid var(--brand-vivid); outline-offset: 2px; }
.pa-button:active { transform: translateY(1px); }
.pa-button--primary { background: var(--brand); color: #fff; }
.pa-button--primary:hover { background: var(--brand-dark); color: #fff; }
.pa-button--secondary,
.pa-button--ghost {
  background: #fff;
  color: var(--brand);
  border-color: var(--line);
}
.pa-button--secondary:hover,
.pa-button--ghost:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
}

/* ── Field (x-app.field) ── base; page-specific overrides may add more ── */
.pa-field { text-align: left; margin-bottom: 4px; }
.pa-field > label {
  display: block;
  margin-bottom: 6px;
  color: var(--ink);
  font-weight: 700;
  font-size: 14px;
}
.pa-field__hint { margin: 6px 0 0; color: var(--ink-subtle); font-size: 13px; }
.pa-field__error { margin: 6px 0 0; color: var(--danger); font-size: 13px; font-weight: 600; }

/* ── Card (x-app.card) ── */
.pa-card {
  margin-bottom: 18px;
  padding: 22px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}
.pa-card--flush { padding: 0; }
.pa-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 16px;
}
.pa-card-header h2 { margin: 0; font-size: var(--h2-size); font-weight: var(--h2-weight); color: var(--ink); }
.pa-card-header p { margin: 4px 0 0; color: var(--ink-muted); font-size: 14px; }
.pa-card-actions { display: flex; gap: 10px; flex-shrink: 0; }

/* ── Status pill (x-app.status) ── */
.pa-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 11px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 700;
  background: var(--brand-soft);
  color: var(--brand);
}
.pa-status--neutral { background: #f1f5f9; color: var(--ink-muted); }
.pa-status--success { background: #d1fae5; color: #065f46; }
.pa-status--warning { background: #fef3c7; color: #92400e; }
.pa-status--danger  { background: #fee2e2; color: #991b1b; }
.pa-status--info    { background: #dbeafe; color: #1e40af; }

/* ── Empty state (x-app.empty-state) ── */
.pa-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 48px 24px;
  text-align: center;
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
}
.pa-empty-state__icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand);
  font-size: 26px;
}
.pa-empty-state h2 { margin: 6px 0 0; font-size: var(--h3-size); color: var(--ink); }
.pa-empty-state p { margin: 0; color: var(--ink-muted); max-width: 48ch; }
.pa-empty-state__action { margin-top: 8px; }

/* ── Directory tabs: segmented track (Saved workspace-tabs language) ──
   Overrides the flat underline .pa-tabs style on the Overview / Judges /
   Clubs directory pages so the Directory and Saved areas read as one app.
   Mirrors .saved-workspace-tabs in saved.css — keep the two in step.

   NOTE: account/partials/tabs.blade.php also carries .directory-tabs, so the
   Account pill row (/profile, /notifications, /invoices, /referrals,
   /feedback) inherits this too. That is intentional; .account-tabs is on the
   element if it ever needs to opt back out. */
.pa-tabs.directory-tabs {
  display: inline-flex;
  flex-wrap: nowrap;
  max-width: 100%;
  border-bottom: none;
  gap: 2px;
  padding: 4px;
  border: 1px solid #e5dcec;
  border-radius: 999px;
  /* White, not brand-soft: the profile/directory canvases are lavender, and a
     brand-soft track is near-identical in tone — the control read as a muddy
     gray blob. White matches the floating-card language and the tab pills. */
  background: #fff;
  box-shadow: 0 1px 4px rgba(81, 28, 102, 0.06);
  /* Breathing room below the app nav — matches the Saved workspace's 28px
     top padding so the tab track doesn't sit flush against the header. */
  margin: 26px 0 22px;
}
.pa-tabs.directory-tabs a {
  min-height: 44px;
  padding: 10px 18px;
  margin-bottom: 0;
  border: 1px solid transparent;
  border-radius: 999px;
  font-weight: 600;
  font-size: 15px;
  white-space: nowrap;
  color: var(--ink);
  background: transparent;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.pa-tabs.directory-tabs a:hover {
  /* Track is white now, so the hover tint flips to brand-soft. */
  background: var(--brand-soft);
  border-color: transparent;
  color: var(--brand);
}
.pa-tabs.directory-tabs a[aria-current="page"] {
  color: #fff;
  background: var(--brand);
  border-color: var(--brand);
  box-shadow: 0 1px 2px rgba(81, 28, 102, 0.24), 0 4px 10px rgba(81, 28, 102, 0.18);
}
.pa-tabs.directory-tabs a[aria-current="page"] .sv-tab-label > span {
  font-weight: 700;
}
/* Bold-width reservation — see the matching block in saved.css. */
.pa-tabs.directory-tabs .sv-tab-label { display: grid; grid-template-columns: 1fr; }
.pa-tabs.directory-tabs .sv-tab-label > span { grid-area: 1 / 1; }
.pa-tabs.directory-tabs .sv-tab-label::after {
  content: attr(data-label);
  grid-area: 1 / 1;
  font-weight: 700;
  visibility: hidden;
  pointer-events: none;
}
/* Icons inherit currentColor, so they go white on the active pill. .pa-tabs a
   already supplies the 6px flex gap between icon and label. */
.pa-tabs.directory-tabs a > .bi { font-size: 16px; line-height: 1; }

/* ── Mobile ── */
@media (max-width: 600px) {
  .pa-tabs { gap: 0; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .pa-tabs a { padding: 10px 12px; font-size: 14px; white-space: nowrap; }
  /* The track itself becomes the scroll viewport so the control keeps its
     shape instead of wrapping. The ::after spacer preserves trailing padding
     at the scroll end, which flex scroll containers otherwise drop. */
  .pa-tabs.directory-tabs {
    /* inline-flex, not flex: a short track (2 pills) should hug its pills
       rather than stretch to a full-width band of empty lavender. It still
       shrink-to-fits and scrolls once the pills exceed max-width. */
    display: inline-flex;
    gap: 2px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .pa-tabs.directory-tabs::-webkit-scrollbar { display: none; }
  .pa-tabs.directory-tabs::after { content: ""; flex: 0 0 4px; }
  .pa-tabs.directory-tabs a { padding: 10px 14px; font-size: 15px; }
  .pa-page-header { flex-direction: column; }
}

/* ── Account "Viewing" disclosure (mobile replacement for .account-tabs) ──
   Desktop never shows it; the ≤600px block above swaps it in. Kept outside
   the media query so the closed/open styling is defined once. */
.account-tabs-dd {
  display: none;
  position: relative;
  margin: 26px 0 22px;
}
.account-tabs-dd summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 50px;
  padding: 0 16px;
  border: 1.5px solid #e5dcec;
  border-radius: 12px;
  background: #fff;
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
}
.account-tabs-dd summary::-webkit-details-marker { display: none; }
.account-tabs-dd summary:focus-visible {
  outline: 3px solid var(--brand-vivid);
  outline-offset: 2px;
}
.account-dd-lbl b { color: var(--brand); font-weight: 800; }
.account-dd-caret { color: var(--ink); transition: transform 0.15s ease; }
.account-tabs-dd[open] .account-dd-caret { transform: rotate(180deg); }
.account-dd-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 60;
  background: #fff;
  border: 1px solid #e5dcec;
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(26, 26, 46, 0.16);
  overflow: hidden;
}
.account-dd-menu a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 48px;
  padding: 12px 16px;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid #f4f1fb;
}
.account-dd-menu a:last-child { border-bottom: 0; }
.account-dd-menu a[aria-current="page"] {
  color: var(--brand);
  font-weight: 800;
  background: #faf8fe;
}
.account-dd-menu .account-dd-tick { color: var(--brand); visibility: hidden; }
.account-dd-menu a[aria-current="page"] .account-dd-tick { visibility: visible; }

/* Mobile audit fix 3 (July 2026): the Account strip (5 destinations) hid its
   tail off-screen — on /referrals the active pill itself loaded half-clipped.
   On phones the strip is swapped for the "Viewing" disclosure above. This
   block must come AFTER the component's base display:none so it wins the
   equal-specificity cascade. */
@media (max-width: 600px) {
  .pa-tabs.account-tabs { display: none; }
  .account-tabs-dd { display: block; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Round 105 — classes extracted from inline style="" attributes so a strict
   CSP (style-src-attr 'none') can be enforced. Declarations are copied
   VERBATIM from the attributes they replace: same properties, same values,
   same order. No !important anywhere in this section — where an inline
   declaration used to beat a framework rule by virtue of being inline, the
   selector is compounded with the framework class instead (e.g.
   `.modal-content.es-x-filter-modal`) so it wins on specificity/source order.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Round 105: classes extracted from event/partials/filter-modals.blade.php ──
   These live here rather than in events-redesign.css because the partial is
   included from BOTH event/partials/filters-listing.blade.php (rendered by
   event/index.blade.php, which loads events-redesign.css) and
   event/partials/user-saved-searches.blade.php (rendered by
   event/saved-search.blade.php, which does NOT). app-components.css is loaded
   globally by layouts/app.blade.php, so the modal looks identical on both. */
.modal-content.es-x-filter-modal { border-radius: 16px; border: none; }
.es-x-delete-filter-prompt { font-size: 1.05rem; }
.es-x-delete-filter-name { font-weight: 700; color: #511c66; }
.form-control.es-x-clone-name-input { border-radius: 10px; padding: 0.6rem 0.85rem; }
.es-x-clone-name-hint { font-size: 0.85rem; color: #111; margin-top: 0.3rem; }
.btn.es-x-clone-submit { background-color: #511c66; }

/* ── Round 105: classes extracted from event/partials/search-table.blade.php ──
   Here, not events-redesign.css: this partial is rendered by
   event/search.blade.php, which does not load events-redesign.css. The
   compound selector is required to beat style.css's `.accordion-item { border:
   var(--bs-accordion-border-width) solid ... }`. */
.accordion-item.es-x-event-type-accordion-item { border:none; }

/* ── Round 105: classes extracted from event/partials/quick-confirmation-search.blade.php ──
   Same load-path reason as search-table above (event/search.blade.php). */
.es-x-qs-save-icon { color: #511c66; }
.form-control.es-x-qs-save-name-input { max-width: 420px; }

/* ── Round 105: classes extracted from tutorial/partials/instructions.blade.php ── */
.tut-quickstart-heading { font-size:22px; font-weight: bold; }
.tut-param-table { width: 100%; border-collapse: collapse; }
.tut-sort-note { color:red; font-weight: 600; margin-top:2rem; }

/* ── Round 105: classes extracted from subscription/partials/error-modal.blade.php ── */
.modal-body.sub-error-modal-body { padding: 20px; border-radius: 10px; text-align: center; }
.sub-error-icon { color: #d9534f; font-size: 48px; }
.sub-error-title { color: #333; }
.sub-error-text { color: #777; }
.sub-error-ok-btn {
  background-color: #d9534f;
  color: white;
  border: none;
  padding: 10px 20px;
  font-size: 16px;
  border-radius: 5px;
  cursor: pointer;
}

/* ── Round 105: classes extracted from subscription/partials/success-payment.blade.php ── */
.sub-success-img { width:350px; }
.sub-receipt-summary {
  background:#f3edf7;
  border:1px solid #e2d8f0;
  border-radius:12px;
  padding:16px 24px;
  width:100%;
}
/* Compound with .btn so it keeps beating Bootstrap's `.btn` / `.btn:hover`
   background-color the way the inline attribute did. */
.btn.sub-success-cta { background-color:#511c66; color:white; }

/* ── Round 105: classes extracted from subscription/partials/subscription-nav.blade.php ──
   `font-size: inherit` was already being overridden by landing.css's
   `.nav-cta { font-size: 14px !important; }` while it was inline, and still is
   here — the rendered size is unchanged at 14px. */
.nav-cta.sub-nav-signout-btn {
  border:none;
  cursor:pointer;
  font-family:inherit;
  font-size:inherit;
}

/* ── Round 105: classes extracted from subscription/partials/subscription-breadcrumb.blade.php ──
   Needs the full descendant chain: style.css sets `.breadcrumb .breadcrumb-item
   .breadcrumb-item-link { font-size: 13.5px; }` (0,3,0) inside two media
   queries, which a plain class would lose to. */
.breadcrumb .breadcrumb-item .breadcrumb-item-link.sub-breadcrumb-back {
  color:rgb(81, 28, 102);
  font-size:30px;
}

/* ── Round 105: classes extracted from contact.blade.php ──
   contact.blade.php is a standalone view (not layouts.app), so it now links
   this stylesheet explicitly — see the comment on that <link>. */
.ct-intro {
  margin-bottom:24px;
  font-size:14px;
  color:#1a1a2e;
  line-height:1.6;
  text-align:left;
}
.ct-faq-link { color:#511c66;font-weight:600; }

/* ── Round 105: classes extracted from feedback/partials/feedback-main.blade.php ──
   .fb-upload-bar is the INITIAL width only: feedback.blade.php drives the bar
   with jQuery `$bar.css('width', pct)`, which writes an inline style and so
   still overrides this class (which is why it must not be !important). */
.progress.fb-upload-progress { height:8px; }
.progress-bar.fb-upload-bar { width:0%; }

/* ── Round 105: per-page results form (was inline display:inline-block). ── */
.es-x-perpage-form { display:inline-block; margin-left:8px; }
