/* ==========================================================================
   TIKI DESIGN SYSTEM — COMPONENTS
   Every reusable UI primitive. Each component defines its full state set
   (rest / hover / focus / active / disabled) — a control that only styles
   its rest state is an unfinished control.
   ========================================================================== */

/* ==========================================================================
   BUTTONS
   One primary action per view. .tiki-btn--primary is the only coral fill in
   the system, which is what makes it read as "the" action.
   ========================================================================== */
.tiki-btn {
  --btn-bg: transparent;
  --btn-fg: var(--tiki-text);
  --btn-border: transparent;
  --btn-shadow: none;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--tiki-space-2);

  padding: 0.6875rem var(--tiki-space-5);
  border: 1px solid var(--btn-border);
  border-radius: var(--tiki-radius-md);
  background: var(--btn-bg);
  color: var(--btn-fg);
  box-shadow: var(--btn-shadow);

  font-family: inherit;
  font-size: var(--tiki-text-sm);
  font-weight: var(--tiki-weight-semibold);
  line-height: 1.2;
  letter-spacing: 0;
  text-align: center;
  white-space: nowrap;

  cursor: pointer;
  user-select: none;
  transition: background-color var(--tiki-duration-fast) var(--tiki-ease),
              border-color var(--tiki-duration-fast) var(--tiki-ease),
              color var(--tiki-duration-fast) var(--tiki-ease),
              box-shadow var(--tiki-duration-fast) var(--tiki-ease),
              transform var(--tiki-duration-fast) var(--tiki-ease);
}

.tiki-btn:hover  { color: var(--btn-fg); }
.tiki-btn:active { transform: translateY(1px); }

.tiki-btn:disabled,
.tiki-btn.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  pointer-events: none;
}

/* Primary — the single most important action on the screen */
.tiki-btn--primary {
  --btn-bg: var(--tiki-accent);
  --btn-fg: var(--tiki-white);
  --btn-shadow: var(--tiki-shadow-accent);
}
.tiki-btn--primary:hover  { --btn-bg: var(--tiki-accent-hover); box-shadow: 0 8px 22px rgba(255,90,95,.34); }
.tiki-btn--primary:active { --btn-bg: var(--tiki-accent-active); }

/* Secondary — navy fill, for confirmations that are not the main CTA */
.tiki-btn--secondary {
  --btn-bg: var(--tiki-navy-700);
  --btn-fg: var(--tiki-white);
}
.tiki-btn--secondary:hover  { --btn-bg: var(--tiki-navy-800); }
.tiki-btn--secondary:active { --btn-bg: var(--tiki-navy-900); }

/* Tertiary — outlined, the default for most actions */
.tiki-btn--tertiary {
  --btn-bg: var(--tiki-surface);
  --btn-fg: var(--tiki-text);
  --btn-border: var(--tiki-border-strong);
  --btn-shadow: var(--tiki-shadow-xs);
}
.tiki-btn--tertiary:hover {
  --btn-bg: var(--tiki-surface-hover);
  --btn-border: var(--tiki-navy-300);
}

/* Ghost — for toolbars and low-emphasis repeated actions */
.tiki-btn--ghost { --btn-fg: var(--tiki-text-muted); }
.tiki-btn--ghost:hover { --btn-bg: var(--tiki-slate-100); --btn-fg: var(--tiki-text); }

.tiki-btn--danger  { --btn-bg: var(--tiki-danger);  --btn-fg: var(--tiki-white); }
.tiki-btn--danger:hover { --btn-bg: #CE3B40; }
.tiki-btn--success { --btn-bg: var(--tiki-success); --btn-fg: var(--tiki-white); }

/* Sizes */
.tiki-btn--sm { padding: 0.4375rem var(--tiki-space-3); font-size: var(--tiki-text-xs); border-radius: var(--tiki-radius-sm); }
.tiki-btn--lg { padding: 0.875rem var(--tiki-space-6);  font-size: var(--tiki-text-md); border-radius: var(--tiki-radius-lg); }
.tiki-btn--xl { padding: 1.0625rem var(--tiki-space-8); font-size: var(--tiki-text-lg); border-radius: var(--tiki-radius-lg); }
.tiki-btn--block { display: flex; width: 100%; }
.tiki-btn--pill  { border-radius: var(--tiki-radius-pill); }

/* Loading: the label is hidden and a spinner is centred, so the button
   keeps its width and the layout does not jump mid-submit. */
.tiki-btn.is-loading { color: transparent !important; pointer-events: none; position: relative; }
.tiki-btn.is-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1.05rem;
  height: 1.05rem;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--btn-fg);
  animation: tiki-spin 620ms linear infinite;
}
@keyframes tiki-spin { to { transform: rotate(360deg); } }

/* Square icon-only button */
.tiki-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid transparent;
  border-radius: var(--tiki-radius-md);
  background: transparent;
  color: var(--tiki-text-muted);
  cursor: pointer;
  transition: var(--tiki-transition);
}
.tiki-icon-btn:hover { background: var(--tiki-slate-100); color: var(--tiki-text); }
.tiki-icon-btn--bordered { border-color: var(--tiki-border); background: var(--tiki-surface); }

/* ==========================================================================
   FORMS
   ========================================================================== */
.tiki-field { margin-bottom: var(--tiki-space-5); }

.tiki-label {
  display: block;
  margin-bottom: var(--tiki-space-2);
  font-size: var(--tiki-text-sm);
  font-weight: var(--tiki-weight-semibold);
  color: var(--tiki-text-strong);
}
.tiki-label__required { color: var(--tiki-accent); margin-inline-start: 2px; }

.tiki-input,
.tiki-select,
.tiki-textarea {
  display: block;
  width: 100%;
  padding: 0.6875rem var(--tiki-space-4);
  border: 1px solid var(--tiki-border-strong);
  border-radius: var(--tiki-radius-md);
  background: var(--tiki-surface);
  color: var(--tiki-text);
  font-family: inherit;
  font-size: var(--tiki-text-md);
  line-height: 1.4;
  transition: border-color var(--tiki-duration-fast) var(--tiki-ease),
              box-shadow var(--tiki-duration-fast) var(--tiki-ease);
  /* 16px on mobile prevents iOS Safari from zooming the viewport on focus. */
}
@media (max-width: 767.98px) {
  .tiki-input, .tiki-select, .tiki-textarea { font-size: 16px; }
}

.tiki-input::placeholder,
.tiki-textarea::placeholder { color: var(--tiki-text-subtle); }

.tiki-input:hover,
.tiki-select:hover,
.tiki-textarea:hover { border-color: var(--tiki-navy-300); }

.tiki-input:focus,
.tiki-select:focus,
.tiki-textarea:focus {
  outline: none;
  border-color: var(--tiki-accent);
  box-shadow: 0 0 0 3px var(--tiki-focus-ring);
}

.tiki-input:disabled,
.tiki-select:disabled,
.tiki-textarea:disabled {
  background: var(--tiki-slate-100);
  color: var(--tiki-text-subtle);
  cursor: not-allowed;
}

.tiki-textarea { min-height: 7.5rem; resize: vertical; }

.tiki-select {
  appearance: none;
  padding-inline-end: var(--tiki-space-10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235B6B85' 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 var(--tiki-space-4) center;
  background-size: 16px;
}
[dir="rtl"] .tiki-select { background-position: left var(--tiki-space-4) center; }

/* Input with a leading icon (search fields) */
.tiki-input-group { position: relative; display: flex; align-items: center; }
.tiki-input-group__icon {
  position: absolute;
  inset-inline-start: var(--tiki-space-4);
  color: var(--tiki-text-subtle);
  pointer-events: none;
}
.tiki-input-group .tiki-input { padding-inline-start: var(--tiki-space-10); }

.tiki-help {
  display: block;
  margin-top: var(--tiki-space-2);
  font-size: var(--tiki-text-xs);
  color: var(--tiki-text-muted);
}

.tiki-error {
  display: flex;
  align-items: center;
  gap: var(--tiki-space-1);
  margin-top: var(--tiki-space-2);
  font-size: var(--tiki-text-xs);
  font-weight: var(--tiki-weight-medium);
  color: var(--tiki-danger);
}

.tiki-field.has-error .tiki-input,
.tiki-field.has-error .tiki-select,
.tiki-field.has-error .tiki-textarea { border-color: var(--tiki-danger); }
.tiki-field.has-error .tiki-input:focus { box-shadow: 0 0 0 3px rgba(232,71,76,.18); }

.tiki-field.is-valid .tiki-input { border-color: var(--tiki-success); }

/* Checkbox / radio */
.tiki-check {
  display: flex;
  align-items: flex-start;
  gap: var(--tiki-space-3);
  cursor: pointer;
  font-size: var(--tiki-text-sm);
  color: var(--tiki-text);
}
.tiki-check input {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.1rem;
  accent-color: var(--tiki-accent);
  cursor: pointer;
}

/* ==========================================================================
   CARDS
   ========================================================================== */
.tiki-card {
  background: var(--tiki-surface);
  border: 1px solid var(--tiki-border);
  border-radius: var(--tiki-radius-lg);
  box-shadow: var(--tiki-shadow-sm);
  overflow: hidden;
}
.tiki-card--flat        { box-shadow: none; }
.tiki-card--interactive { transition: border-color var(--tiki-duration-base) var(--tiki-ease),
                                      box-shadow var(--tiki-duration-base) var(--tiki-ease),
                                      transform var(--tiki-duration-base) var(--tiki-ease); }
.tiki-card--interactive:hover {
  border-color: var(--tiki-navy-200);
  box-shadow: var(--tiki-shadow-lg);
  transform: translateY(-2px);
}

.tiki-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tiki-space-4);
  padding: var(--tiki-space-5) var(--tiki-space-6);
  border-bottom: 1px solid var(--tiki-border);
}
.tiki-card__title { margin: 0; font-size: var(--tiki-text-md); font-weight: var(--tiki-weight-bold); }
.tiki-card__body  { padding: var(--tiki-space-6); }
.tiki-card__foot  {
  padding: var(--tiki-space-4) var(--tiki-space-6);
  border-top: 1px solid var(--tiki-border);
  background: var(--tiki-bg-subtle);
}

/* ==========================================================================
   STAT CARD (KPI)
   Deliberately restrained: one number, one label, one trend. A KPI card
   that carries five values stops being a KPI card.
   ========================================================================== */
.tiki-stat {
  position: relative;
  padding: var(--tiki-space-5) var(--tiki-space-6);
  background: var(--tiki-surface);
  border: 1px solid var(--tiki-border);
  border-radius: var(--tiki-radius-lg);
  box-shadow: var(--tiki-shadow-xs);
}
.tiki-stat__label {
  display: block;
  font-size: var(--tiki-text-xs);
  font-weight: var(--tiki-weight-semibold);
  letter-spacing: var(--tiki-tracking-wide);
  text-transform: uppercase;
  color: var(--tiki-text-subtle);
  margin-bottom: var(--tiki-space-2);
}
.tiki-stat__value {
  display: block;
  font-size: var(--tiki-text-3xl);
  font-weight: var(--tiki-weight-extra);
  line-height: 1.1;
  letter-spacing: var(--tiki-tracking-tight);
  color: var(--tiki-text-strong);
  font-variant-numeric: tabular-nums;
}
.tiki-stat__meta {
  display: inline-flex;
  align-items: center;
  gap: var(--tiki-space-1);
  margin-top: var(--tiki-space-2);
  font-size: var(--tiki-text-xs);
  font-weight: var(--tiki-weight-semibold);
}
.tiki-stat__meta--up   { color: var(--tiki-success); }
.tiki-stat__meta--down { color: var(--tiki-danger); }
.tiki-stat__meta--flat { color: var(--tiki-text-subtle); }

/* ==========================================================================
   BADGES & STATUS
   ========================================================================== */
.tiki-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--tiki-space-1);
  padding: 0.25rem var(--tiki-space-2);
  border-radius: var(--tiki-radius-xs);
  font-size: var(--tiki-text-2xs);
  font-weight: var(--tiki-weight-bold);
  letter-spacing: var(--tiki-tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
  background: var(--tiki-slate-100);
  color: var(--tiki-text-muted);
}
.tiki-badge--accent  { background: var(--tiki-coral-100);  color: var(--tiki-coral-700); }
.tiki-badge--purple  { background: var(--tiki-purple-100); color: var(--tiki-purple-700); }
.tiki-badge--success { background: var(--tiki-success-soft); color: #0A7A5F; }
.tiki-badge--warning { background: var(--tiki-warning-soft); color: #A66400; }
.tiki-badge--danger  { background: var(--tiki-danger-soft);  color: var(--tiki-coral-700); }
.tiki-badge--info    { background: var(--tiki-info-soft);    color: #2A57A8; }
.tiki-badge--navy    { background: var(--tiki-navy-700);     color: var(--tiki-white); }

/* Status pill with a leading dot — used for order/event/settlement states */
.tiki-status {
  display: inline-flex;
  align-items: center;
  gap: var(--tiki-space-2);
  font-size: var(--tiki-text-xs);
  font-weight: var(--tiki-weight-semibold);
  color: var(--tiki-text-muted);
}
.tiki-status::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.tiki-status--success { color: var(--tiki-success); }
.tiki-status--warning { color: var(--tiki-warning); }
.tiki-status--danger  { color: var(--tiki-danger); }
.tiki-status--muted   { color: var(--tiki-text-subtle); }

/* Live indicator for the organizer dashboard */
.tiki-live {
  display: inline-flex;
  align-items: center;
  gap: var(--tiki-space-2);
  font-size: var(--tiki-text-2xs);
  font-weight: var(--tiki-weight-bold);
  letter-spacing: var(--tiki-tracking-caps);
  text-transform: uppercase;
  color: var(--tiki-success);
}
.tiki-live__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  animation: tiki-pulse 2s var(--tiki-ease) infinite;
}
@keyframes tiki-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.85); }
}

/* ==========================================================================
   AVATAR
   ========================================================================== */
.tiki-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--tiki-navy-100);
  color: var(--tiki-navy-700);
  font-size: var(--tiki-text-xs);
  font-weight: var(--tiki-weight-bold);
  overflow: hidden;
  flex: none;
}
.tiki-avatar img { width: 100%; height: 100%; object-fit: cover; }
.tiki-avatar--sm { width: 1.75rem; height: 1.75rem; font-size: var(--tiki-text-2xs); }
.tiki-avatar--lg { width: 3rem;    height: 3rem;    font-size: var(--tiki-text-md); }
.tiki-avatar--xl { width: 4.5rem;  height: 4.5rem;  font-size: var(--tiki-text-xl); }

/* ==========================================================================
   ALERTS
   ========================================================================== */
.tiki-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--tiki-space-3);
  padding: var(--tiki-space-4) var(--tiki-space-5);
  border: 1px solid transparent;
  border-radius: var(--tiki-radius-md);
  font-size: var(--tiki-text-sm);
  line-height: var(--tiki-leading-normal);
}
.tiki-alert__icon  { flex: none; margin-top: 0.1rem; }
.tiki-alert__title { display: block; font-weight: var(--tiki-weight-bold); margin-bottom: 2px; }
.tiki-alert--success { background: var(--tiki-success-soft); border-color: #BFE7DC; color: #0A6B54; }
.tiki-alert--warning { background: var(--tiki-warning-soft); border-color: #F4DDB0; color: #8A5400; }
.tiki-alert--danger  { background: var(--tiki-danger-soft);  border-color: #F7C9CB; color: #A32B30; }
.tiki-alert--info    { background: var(--tiki-info-soft);    border-color: #C6D9F7; color: #24508F; }

/* ==========================================================================
   TABLES
   ========================================================================== */
.tiki-table-wrap {
  border: 1px solid var(--tiki-border);
  border-radius: var(--tiki-radius-lg);
  background: var(--tiki-surface);
  overflow: hidden;
}
/* ==========================================================================
   Scrollable table
   --------------------------------------------------------------------------
   A dense operations table scrolls sideways on a phone rather than stacking
   into cards: an admin scanning fifty refunds compares values down a column,
   and cards break exactly that reading.

   What scrolling lacks is a way to know it is there. Without an edge, a
   table cut off at the viewport looks like a table with fewer columns, and
   the ones past the fold are simply never found.

   The fade is painted by a background attached to the scroller itself, so it
   appears only while there is more to the right and disappears as the end is
   reached — no JavaScript, no scroll listener.
   ========================================================================== */
.tiki-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;

  background:
    /* Shadow at the far edge of the content, in reading order. */
    linear-gradient(to left, rgba(15, 27, 51, 0.10), rgba(15, 27, 51, 0)) right center / 24px 100% no-repeat,
    /* Cover that hides it once the scroller reaches its end. */
    linear-gradient(to left, var(--tiki-surface), var(--tiki-surface)) right center / 24px 100% no-repeat;
  background-attachment: local, scroll;
}

/* `background-position` has no logical keywords, so the direction is
   mirrored explicitly — the same approach .tiki-select already uses above.
   Without this the fade sits at the start of an Arabic table, marking
   content the reader has already passed. */
[dir="rtl"] .tiki-table-scroll {
  background:
    linear-gradient(to right, rgba(15, 27, 51, 0.10), rgba(15, 27, 51, 0)) left center / 24px 100% no-repeat,
    linear-gradient(to right, var(--tiki-surface), var(--tiki-surface)) left center / 24px 100% no-repeat;
  background-attachment: local, scroll;
}

/* Pointer users get a scrollbar; touch users get the fade. Neither needs a
   permanent element in the markup. */
@media (min-width: 992px) {
  .tiki-table-scroll,
  [dir="rtl"] .tiki-table-scroll { background: none; }
}

.tiki-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--tiki-text-sm); }

/* The header stays put while the body scrolls. On a page of fifty
   settlements the column you are reading is the one that scrolls out of
   sight first, and an operator who has to scroll back up to remember which
   column holds the net amount is one keystroke from paying the wrong figure.
   border-collapse must be `separate` for this: a collapsed border is owned
   by the table, not the cell, and does not travel with a sticky header. */
.tiki-table th {
  position: sticky;
  top: 0;
  z-index: var(--tiki-z-base);
  padding: var(--tiki-space-3) var(--tiki-space-5);
  background: var(--tiki-bg-subtle);
  border-bottom: 1px solid var(--tiki-border);
  text-align: start;
  font-size: var(--tiki-text-xs);
  font-weight: var(--tiki-weight-bold);
  letter-spacing: var(--tiki-tracking-wide);
  text-transform: uppercase;
  color: var(--tiki-text-subtle);
  white-space: nowrap;
}
[lang="ar"] .tiki-table th { text-transform: none; letter-spacing: 0; }

.tiki-table td {
  padding: var(--tiki-space-4) var(--tiki-space-5);
  border-bottom: 1px solid var(--tiki-border);
  vertical-align: middle;
  color: var(--tiki-text);
}
.tiki-table tbody tr:last-child td { border-bottom: 0; }
.tiki-table tbody tr { transition: background-color var(--tiki-duration-fast) var(--tiki-ease); }
.tiki-table tbody tr:hover { background: var(--tiki-bg-subtle); }

/* Figures are compared vertically, so they are aligned to the end of the
   column and set in tabular figures: proportional digits make a column of
   numbers ragged even when the values line up. */
.tiki-table__num { text-align: end; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   EMPTY STATE
   Never show a bare empty table: say what is missing, why, and what to do.
   ========================================================================== */
.tiki-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--tiki-space-16) var(--tiki-space-6);
}
.tiki-empty__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4rem; height: 4rem;
  margin-bottom: var(--tiki-space-5);
  border-radius: var(--tiki-radius-xl);
  background: var(--tiki-slate-100);
  color: var(--tiki-slate-500);
}
.tiki-empty__title {
  margin: 0 0 var(--tiki-space-2);
  font-size: var(--tiki-text-lg);
  font-weight: var(--tiki-weight-bold);
  color: var(--tiki-text-strong);
}
.tiki-empty__text {
  max-width: 42ch;
  margin: 0 0 var(--tiki-space-6);
  color: var(--tiki-text-muted);
  font-size: var(--tiki-text-sm);
}

/* ==========================================================================
   SKELETON LOADING
   Preferred over spinners for content that has a known shape — it
   communicates the layout before the data arrives.
   ========================================================================== */
.tiki-skeleton {
  position: relative;
  overflow: hidden;
  background: var(--tiki-slate-100);
  border-radius: var(--tiki-radius-sm);
}
.tiki-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg,
              transparent,
              rgba(255,255,255,.72),
              transparent);
  animation: tiki-shimmer 1.4s infinite;
}
@keyframes tiki-shimmer { 100% { transform: translateX(100%); } }

.tiki-skeleton--text  { height: 0.75rem; margin-bottom: var(--tiki-space-2); border-radius: var(--tiki-radius-pill); }
.tiki-skeleton--title { height: 1.25rem; width: 60%; margin-bottom: var(--tiki-space-3); }
.tiki-skeleton--image { aspect-ratio: 3 / 2; width: 100%; border-radius: var(--tiki-radius-md); }

/* ==========================================================================
   TABS
   ========================================================================== */
.tiki-tabs {
  display: flex;
  gap: var(--tiki-space-1);
  border-bottom: 1px solid var(--tiki-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.tiki-tabs::-webkit-scrollbar { display: none; }
.tiki-tab {
  position: relative;
  padding: var(--tiki-space-3) var(--tiki-space-4);
  border: 0;
  background: none;
  color: var(--tiki-text-muted);
  font-size: var(--tiki-text-sm);
  font-weight: var(--tiki-weight-semibold);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--tiki-duration-fast) var(--tiki-ease);
}
.tiki-tab:hover { color: var(--tiki-text); }
.tiki-tab.is-active { color: var(--tiki-text-strong); }
.tiki-tab.is-active::after {
  content: "";
  position: absolute;
  inset-inline: var(--tiki-space-3);
  bottom: -1px;
  height: 2px;
  border-radius: var(--tiki-radius-pill);
  background: var(--tiki-accent);
}

/* ==========================================================================
   PAGINATION
   ========================================================================== */
.tiki-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--tiki-space-1);
  margin-top: var(--tiki-space-10);
  flex-wrap: wrap;
}
.tiki-pagination__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.375rem;
  height: 2.375rem;
  padding-inline: var(--tiki-space-2);
  border: 1px solid var(--tiki-border);
  border-radius: var(--tiki-radius-sm);
  background: var(--tiki-surface);
  color: var(--tiki-text-muted);
  font-size: var(--tiki-text-sm);
  font-weight: var(--tiki-weight-semibold);
  transition: var(--tiki-transition);
}
.tiki-pagination__item:hover {
  border-color: var(--tiki-navy-300);
  color: var(--tiki-text);
}
.tiki-pagination__item.is-active {
  background: var(--tiki-navy-700);
  border-color: var(--tiki-navy-700);
  color: var(--tiki-white);
}
.tiki-pagination__item.is-disabled { opacity: .45; pointer-events: none; }
.tiki-pagination__gap { padding-inline: var(--tiki-space-2); color: var(--tiki-text-subtle); }

/* ==========================================================================
   BREADCRUMBS
   ========================================================================== */
.tiki-breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--tiki-space-2);
  margin: 0 0 var(--tiki-space-4);
  padding: 0;
  list-style: none;
  font-size: var(--tiki-text-xs);
  color: var(--tiki-text-subtle);
}
.tiki-breadcrumb a { color: var(--tiki-text-muted); }
.tiki-breadcrumb a:hover { color: var(--tiki-accent); }
.tiki-breadcrumb li { display: flex; align-items: center; gap: var(--tiki-space-2); }
.tiki-breadcrumb li + li::before { content: "/"; color: var(--tiki-slate-300); }

/* ==========================================================================
   MODAL / DRAWER (Bootstrap-compatible skins)
   ========================================================================== */
.modal-content.tiki-modal {
  border: 0;
  border-radius: var(--tiki-radius-xl);
  box-shadow: var(--tiki-shadow-xl);
  overflow: hidden;
}
.tiki-modal .modal-header {
  padding: var(--tiki-space-5) var(--tiki-space-6);
  border-bottom: 1px solid var(--tiki-border);
}
.tiki-modal .modal-title { font-size: var(--tiki-text-lg); font-weight: var(--tiki-weight-bold); }
.tiki-modal .modal-body  { padding: var(--tiki-space-6); }
.tiki-modal .modal-footer {
  padding: var(--tiki-space-4) var(--tiki-space-6);
  border-top: 1px solid var(--tiki-border);
  background: var(--tiki-bg-subtle);
  gap: var(--tiki-space-2);
}

/* On phones a centred dialog becomes a bottom sheet — reachable with a
   thumb instead of stranded in the middle of the screen. */
@media (max-width: 575.98px) {
  .modal-dialog.tiki-sheet {
    margin: 0;
    position: fixed;
    inset: auto 0 0 0;
    max-width: 100%;
  }
  .tiki-sheet .tiki-modal {
    border-radius: var(--tiki-radius-xl) var(--tiki-radius-xl) 0 0;
    max-height: 92vh;
  }
  .tiki-sheet .modal-body { overflow-y: auto; }
}

.offcanvas.tiki-drawer { border: 0; box-shadow: var(--tiki-shadow-xl); }
.tiki-drawer .offcanvas-header {
  padding: var(--tiki-space-5) var(--tiki-space-5);
  border-bottom: 1px solid var(--tiki-border);
}
.tiki-drawer .offcanvas-title { font-size: var(--tiki-text-md); font-weight: var(--tiki-weight-bold); }
.tiki-drawer .offcanvas-body { padding: var(--tiki-space-5); }

/* ==========================================================================
   DROPDOWN (Bootstrap skin)
   ========================================================================== */
.dropdown-menu.tiki-dropdown {
  padding: var(--tiki-space-2);
  border: 1px solid var(--tiki-border);
  border-radius: var(--tiki-radius-lg);
  box-shadow: var(--tiki-shadow-lg);
  font-size: var(--tiki-text-sm);
  min-width: 12rem;
}
.tiki-dropdown .dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--tiki-space-3);
  padding: var(--tiki-space-2) var(--tiki-space-3);
  border-radius: var(--tiki-radius-sm);
  color: var(--tiki-text);
  font-weight: var(--tiki-weight-medium);
}
.tiki-dropdown .dropdown-item:hover  { background: var(--tiki-slate-100); }
.tiki-dropdown .dropdown-item:active { background: var(--tiki-slate-200); color: var(--tiki-text); }
.tiki-dropdown .dropdown-item--danger { color: var(--tiki-danger); }
.tiki-dropdown .dropdown-divider { margin: var(--tiki-space-2) 0; border-color: var(--tiki-border); }
.tiki-dropdown__label {
  padding: var(--tiki-space-2) var(--tiki-space-3);
  font-size: var(--tiki-text-2xs);
  font-weight: var(--tiki-weight-bold);
  letter-spacing: var(--tiki-tracking-caps);
  text-transform: uppercase;
  color: var(--tiki-text-subtle);
}

/* ==========================================================================
   TOASTS
   ========================================================================== */
.tiki-toast-region {
  position: fixed;
  inset-block-end: var(--tiki-space-5);
  inset-inline-end: var(--tiki-space-5);
  z-index: var(--tiki-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--tiki-space-2);
  pointer-events: none;
}
.tiki-toast {
  display: flex;
  align-items: center;
  gap: var(--tiki-space-3);
  min-width: 17rem;
  max-width: min(24rem, calc(100vw - 2rem));
  padding: var(--tiki-space-4) var(--tiki-space-5);
  border-radius: var(--tiki-radius-md);
  background: var(--tiki-navy-800);
  color: var(--tiki-white);
  box-shadow: var(--tiki-shadow-xl);
  font-size: var(--tiki-text-sm);
  font-weight: var(--tiki-weight-medium);
  pointer-events: auto;
  animation: tiki-toast-in var(--tiki-duration-slow) var(--tiki-ease-out);
}
.tiki-toast--success { background: #0B6B55; }
.tiki-toast--danger  { background: #A32B30; }
@keyframes tiki-toast-in {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@media (max-width: 575.98px) {
  .tiki-toast-region {
    inset-inline: var(--tiki-space-4);
    inset-block-end: var(--tiki-space-4);
  }
  .tiki-toast { max-width: 100%; }
}


/* ==========================================================================
   2026 — THE STUB
   --------------------------------------------------------------------------
   Tiki's signature shape: the silhouette of a torn ticket. Two notches bitten
   out of the inline edges, a perforated tear line between them.

   Built with a mask rather than two background-coloured circles, because a
   circle painted in "the parent's colour" is a lie the moment the parent is
   an image, a stage section, or a hover state. A mask removes the pixels, so
   the shape is correct on any background.

   `--stub-y` places the tear. Components set it to match their own layout;
   the notch must line up with the perforation or the eye reads it as damage
   rather than as a ticket.
   ========================================================================== */

.tiki-stub {
  --stub-notch: var(--tiki-notch-md);
  --stub-y: 50%;

  position: relative;
  background: var(--tiki-surface);
  border-radius: var(--tiki-radius-lg);
}

/* Feature-queried: without mask support the block simply stays a rounded
   rectangle. That degrades to "a clean card", never to a broken one. */
@supports (mask-composite: intersect) or (-webkit-mask-composite: source-in) {
  .tiki-stub {
    -webkit-mask-image:
      radial-gradient(circle var(--stub-notch) at 0 var(--stub-y),    transparent 99%, #000 100%),
      radial-gradient(circle var(--stub-notch) at 100% var(--stub-y), transparent 99%, #000 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      radial-gradient(circle var(--stub-notch) at 0 var(--stub-y),    transparent 99%, #000 100%),
      radial-gradient(circle var(--stub-notch) at 100% var(--stub-y), transparent 99%, #000 100%);
    mask-composite: intersect;
  }
}

.tiki-stub--sm { --stub-notch: var(--tiki-notch-sm); }
.tiki-stub--lg { --stub-notch: var(--tiki-notch-lg); }

/* The tear. repeating-linear-gradient rather than `border: dashed`, because
   a dashed border gives no control over dash length and renders differently
   in every engine. The pattern is symmetric, so it needs no RTL mirror. */
.tiki-stub__tear {
  height: var(--tiki-perf-size);
  margin-inline: var(--tiki-space-4);
  background-image: repeating-linear-gradient(
    to right,
    var(--tiki-border-strong) 0 var(--tiki-perf-gap),
    transparent var(--tiki-perf-gap) calc(var(--tiki-perf-gap) * 2)
  );
}

/* ==========================================================================
   2026 — DATE BLOCK
   --------------------------------------------------------------------------
   The date is the second thing a buyer looks for and the first thing they
   compare between two events, so it is set as an object rather than as a
   line of text: day large, month and weekday small around it.

   Deliberately not a stub. The notch belongs to things that are tickets;
   a date is a label on one.
   ========================================================================== */

.tiki-datechip {
  display: inline-grid;
  justify-items: center;
  gap: 1px;
  min-width: 3.25rem;
  padding: var(--tiki-space-2) var(--tiki-space-2) var(--tiki-space-1);
  border-radius: var(--tiki-radius-md);
  background: var(--tiki-surface);
  box-shadow: var(--tiki-ring), var(--tiki-shadow-sm);
  text-align: center;
  line-height: 1;
}

.tiki-datechip__month,
.tiki-datechip__dow {
  font-size: var(--tiki-text-2xs);
  font-weight: var(--tiki-weight-bold);
  letter-spacing: var(--tiki-tracking-caps);
  text-transform: uppercase;
}

.tiki-datechip__month { color: var(--tiki-accent); }
.tiki-datechip__dow   { color: var(--tiki-text-subtle); }

.tiki-datechip__day {
  font-size: var(--tiki-text-2xl);
  font-weight: var(--tiki-weight-extra);
  letter-spacing: var(--tiki-tracking-tight);
  color: var(--tiki-text-strong);
  font-variant-numeric: tabular-nums;
}

/* Arabic day and month names are words, not three-letter codes: uppercase
   does nothing and the extra tracking pulls the letters apart mid-word. */
[lang="ar"] .tiki-datechip__month,
[lang="ar"] .tiki-datechip__dow {
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--tiki-text-xs);
}

.tiki-datechip--lg { min-width: 4.25rem; padding: var(--tiki-space-3); }
.tiki-datechip--lg .tiki-datechip__day { font-size: var(--tiki-text-4xl); }

/* On a photograph. Solid, not translucent: a cover with a bright patch
   behind a frosted chip makes the day unreadable exactly when the rail is
   most attractive. */
.tiki-datechip--float {
  background: var(--tiki-white);
  box-shadow: var(--tiki-shadow-lg);
}

.tiki-datechip--invert {
  background: transparent;
  box-shadow: var(--tiki-ring-stage);
}
.tiki-datechip--invert .tiki-datechip__day   { color: var(--tiki-stage-text); }
.tiki-datechip--invert .tiki-datechip__dow   { color: var(--tiki-stage-muted); }

/* ==========================================================================
   2026 — STAGE SECTION
   --------------------------------------------------------------------------
   A darkened band. Its job is to make the covers inside it brighten, the way
   a house light going down makes a stage lift. One flat colour — no gradient,
   no blur — so it stays a background rather than becoming an effect.

   The applied text roles are rebound rather than overridden per component,
   so a card dropped into a stage inherits legible colours with no extra CSS.
   ========================================================================== */

/* ==========================================================================
   2026 — MY TICKETS
   --------------------------------------------------------------------------
   The holder's own list. These rows are the only ones on the site that are
   literally tickets, so they carry the notch: the shape says what the object
   is before any label does.
   ========================================================================== */

.tiki-mytickets__item {
  --stub-notch: var(--tiki-notch-sm);
  --stub-y: 50%;

  display: flex;
  align-items: center;
  gap: var(--tiki-space-4);
  padding: var(--tiki-space-4) var(--tiki-space-5);
  background: var(--tiki-surface);
  border-radius: var(--tiki-radius-lg);
  box-shadow: var(--tiki-ring);
  color: var(--tiki-text);
  text-decoration: none;
  transition: box-shadow var(--tiki-duration-base) var(--tiki-ease),
              transform var(--tiki-duration-base) var(--tiki-ease);
}
.tiki-mytickets__item:hover {
  transform: translateY(-2px);
  box-shadow: var(--tiki-ring-strong), var(--tiki-shadow-md);
  color: var(--tiki-text);
}
.tiki-mytickets__item:focus-visible { box-shadow: var(--tiki-ring-accent), var(--tiki-shadow-md); }

@supports (mask-composite: intersect) or (-webkit-mask-composite: source-in) {
  .tiki-mytickets__item {
    -webkit-mask-image:
      radial-gradient(circle var(--stub-notch) at 0 var(--stub-y),    transparent 99%, #000 100%),
      radial-gradient(circle var(--stub-notch) at 100% var(--stub-y), transparent 99%, #000 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      radial-gradient(circle var(--stub-notch) at 0 var(--stub-y),    transparent 99%, #000 100%),
      radial-gradient(circle var(--stub-notch) at 100% var(--stub-y), transparent 99%, #000 100%);
    mask-composite: intersect;
  }
}

.tiki-mytickets__date { flex: none; }
.tiki-mytickets__body { flex: 1 1 auto; min-width: 0; display: block; }

.tiki-mytickets__title {
  display: block;
  font-size: var(--tiki-text-md);
  font-weight: var(--tiki-weight-bold);
  line-height: var(--tiki-leading-snug);
  color: var(--tiki-text-strong);
}
.tiki-mytickets__meta {
  display: flex;
  align-items: center;
  gap: var(--tiki-space-2);
  margin-top: var(--tiki-space-1);
  font-size: var(--tiki-text-xs);
  color: var(--tiki-text-muted);
  min-width: 0;
}
.tiki-mytickets__meta .tiki-icon { flex: none; color: var(--tiki-text-subtle); }

.tiki-mytickets__tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--tiki-space-2);
  margin-top: var(--tiki-space-3);
}

.tiki-mytickets__go { flex: none; color: var(--tiki-text-subtle); }

/* A used ticket keeps its shape and loses its colour: the holder still needs
   to find it, and greying it answers "have I already been in?" at a glance. */
.tiki-mytickets__item.is-used { opacity: .68; }

/* Past events are dimmed once, at the section. The row's own used-state is
   suppressed inside it so the two cannot multiply. */
.tiki-mytickets--past { opacity: .72; }
.tiki-mytickets--past .tiki-mytickets__item.is-used { opacity: 1; }

@media (max-width: 575.98px) {
  .tiki-mytickets__item { padding: var(--tiki-space-4); gap: var(--tiki-space-3); }
  .tiki-mytickets__go { display: none; }
}

/*
 | This deepens `.tiki-section--dark`, already defined in the base layer,
 | rather than introducing a second dark modifier beside it. Two classes that
 | both mean "dark band" would drift apart the first time one of them is
 | tuned.
 |
 | What it deliberately does NOT rebind is `--tiki-surface`. Cards keep their
 | light face: the band is the ground, and the covers are the lit objects
 | standing on it. Inverting the cards too would flatten exactly the contrast
 | the band exists to create.
 */
.tiki-section--dark {
  --tiki-bg: var(--tiki-stage-bg);
  --tiki-text: var(--tiki-stage-text);
  --tiki-text-muted: var(--tiki-stage-muted);
  --tiki-text-subtle: var(--tiki-stage-muted);
  --tiki-border: var(--tiki-stage-border);
  --tiki-border-strong: rgba(255, 255, 255, 0.18);

  background: var(--tiki-stage-bg);
  color: var(--tiki-stage-text);
}

/* Cards inside the band restore the light roles they draw themselves with,
   so nothing inside them has to know it is on a dark ground. */
.tiki-section--dark .tiki-event,
.tiki-section--dark .tiki-card,
.tiki-section--dark .tiki-stub {
  --tiki-text: var(--tiki-navy-800);
  --tiki-text-strong: var(--tiki-navy-900);
  --tiki-text-muted: var(--tiki-slate-600);
  --tiki-text-subtle: var(--tiki-slate-500);
  --tiki-border: var(--tiki-slate-200);
  --tiki-border-strong: var(--tiki-slate-300);
  color: var(--tiki-navy-800);
}
