/* ═══════════════════════════════════════════════════════
   ORTBITE — attendee dashboard
   ─────────────────────────────────────────────────────────
   Sits on top of ortbite.css, which carries the tokens and
   every primitive (cards, rows, buttons, forms, chips,
   sheets, banners, bottom nav). Only what is specific to
   the attendee surface lives here: the itinerary timeline,
   the day-quiz wizard, the vote widget, the invite/RSVP
   views, and the payment flow.

   Mobile-first throughout: base is 375px, every query is
   min-width. Nothing in attendee.js carries a style="…"
   attribute any more — inline styles outrank stylesheet
   rules and were why the old page could not be fixed by
   CSS at all (68 of them, MOBILE-SPEC §2).
═══════════════════════════════════════════════════════ */

/* ── Login ───────────────────────────────────────────── */
.login {
  max-width: 400px;
  margin: 24px auto 0;
  padding: 28px 22px;
  text-align: center;
}
.login-icon { font-size: 2rem; font-style: normal; display: block; margin-bottom: 10px; }
.login h1 { font-size: 1.3rem; color: var(--ink); margin-bottom: 8px; letter-spacing: -.01em; }
.login p { font-size: .9rem; color: var(--muted); margin-bottom: 20px; overflow-wrap: break-word; }

.login-code {
  width: 100%;
  min-height: 52px;
  padding: 13px 15px;
  /* Deliberately well above the 16px floor: this is the one field on the site
     everybody types into, from an email, usually one-handed. */
  font-size: 1.25rem;
  text-align: center;
  letter-spacing: .35em;
  text-indent: .35em;            /* re-centres text that letter-spacing pushed left */
  text-transform: uppercase;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  outline: none;
}
.login-code:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }

/* ── Greeting ────────────────────────────────────────── */
.greet { margin-bottom: 16px; }
.greet-eyebrow {
  font-size: .72rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--brand);
}
.greet-name {
  margin-top: 5px;
  font-size: clamp(1.6rem, 7vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.1;
  color: var(--ink);
  overflow-wrap: break-word;
}
.greet-sub { margin-top: 5px; font-size: .87rem; color: var(--muted); overflow-wrap: break-word; }

/* ── Payment flow ────────────────────────────────────── */
.pay-intro { font-size: .86rem; color: var(--muted); line-height: 1.55; margin-bottom: 14px; overflow-wrap: break-word; }
.pay-brand-icon { height: 1.05em; width: 1.05em; flex: none; }
.pay-step { margin-top: 12px; }
.pay-confirm { background: var(--brand-soft); border-color: transparent; }
.pay-confirm-title { font-weight: 800; color: var(--ink); margin-bottom: 12px; }
.pay-opened { background: var(--good-soft); border-color: var(--good-line); }
.pay-opened-title { font-weight: 800; color: var(--good); margin-bottom: 4px; }
.pay-divider { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-soft); }

/* Pending submissions */
.pending { display: flex; flex-direction: column; gap: 9px; }
.pending-card {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 13px 14px;
}
.pending-card.rejected { border-color: var(--bad-line); }
.pending-icon { flex: none; font-size: 1.25rem; font-style: normal; line-height: 1.2; }
.pending-body { flex: 1; min-width: 0; }
.pending-title { font-weight: 700; font-size: .92rem; color: var(--ink); overflow-wrap: break-word; }
.pending-meta { margin-top: 3px; font-size: .8rem; color: var(--muted); overflow-wrap: break-word; }
.pending-meta.warn { color: var(--warn); }
.pending-reason { margin-top: 6px; font-size: .82rem; color: var(--bad); font-style: italic; overflow-wrap: break-word; }
.pending-dismiss { margin-top: 9px; }

/* ── Info cards (trip essentials, packing list, future releases) ──
   Deliberately generic and data-driven: a new attendee-facing release
   drops in as another card with no redesign. */
.info-cards { display: flex; flex-direction: column; gap: 10px; }
.info-card { padding: 15px 16px; }
.info-card-head { display: flex; align-items: center; gap: 9px; }
.info-card-icon { flex: none; font-size: 1.15rem; font-style: normal; }
.info-card-title {
  flex: 1; min-width: 0;
  font-size: .8rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
  overflow-wrap: break-word;
}
.info-card-value {
  margin-top: 7px;
  font-size: .98rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.45;
  overflow-wrap: break-word;
  white-space: pre-wrap;
}
.info-list { margin-top: 9px; display: flex; flex-direction: column; gap: 6px; }
.info-list li {
  position: relative;
  padding-left: 20px;
  font-size: .92rem;
  color: var(--text);
  overflow-wrap: break-word;
}
.info-list li::before {
  content: '';
  position: absolute;
  left: 5px; top: .62em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--brand);
}

/* ── Spending ────────────────────────────────────────── */
/* Card list, not a <table>. The old spend modal used a four-column table with
   inline padding on every cell; at 320px that is an unreadable horizontal
   scroll. Dense but word-safe — the card-density lesson. */
.spend-list { display: flex; flex-direction: column; gap: 8px; }
.spend-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
}
.spend-body { flex: 1; min-width: 0; }
.spend-title { font-size: .94rem; font-weight: 600; color: var(--ink); overflow-wrap: break-word; }
.spend-meta { margin-top: 3px; font-size: .78rem; color: var(--muted); overflow-wrap: break-word; }
.spend-amount {
  flex: none;
  font-size: .96rem;
  font-weight: 800;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ── Itinerary ───────────────────────────────────────── */
.itin { display: flex; flex-direction: column; gap: 14px; }

.itin-day { }
.itin-day-head {
  /* Sticky, so you always know which day you are scrolling through. Sits below
     the topbar; on desktop the nav is sticky too and takes another band. */
  position: sticky;
  top: calc(var(--topbar-h) + var(--safe-t));
  z-index: 20;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
  padding: 8px 2px;
  /* Frosted, never opaque — a solid bar over a scrolling timeline reads as a
     seam. No clip-path anywhere near this: it suppresses backdrop-filter. */
  background: rgba(245,246,249,.85);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.itin-day-label {
  flex: 1; min-width: 0;
  font-size: .95rem; font-weight: 800; color: var(--ink);
  letter-spacing: -.01em;
  overflow-wrap: break-word;
}
.itin-day-count { flex: none; font-size: .76rem; color: var(--faint); font-weight: 600; }

.itin-items { display: flex; flex-direction: column; gap: 8px; }

/* The card, not a three-column flex row. Time is a badge above the title at
   base width; the row only becomes horizontal when there is room for it. */
.itin-item {
  width: 100%;
  padding: 12px 14px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  overflow-wrap: break-word;
}
button.itin-item { cursor: pointer; -webkit-tap-highlight-color: transparent; display: block; }
button.itin-item:active { background: var(--surface-2); }

.itin-item-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.itin-time {
  flex: none;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--brand-soft);
  color: var(--brand);
  font-size: .76rem;
  font-weight: 800;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
}
.itin-icon { flex: none; font-size: 1rem; font-style: normal; }

.itin-title {
  margin-top: 7px;
  font-size: .99rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.35;
  overflow-wrap: break-word;
}
.itin-item-top + .itin-title { margin-top: 8px; }
.itin-notes { margin-top: 5px; font-size: .87rem; color: var(--muted); line-height: 1.5; overflow-wrap: break-word; }
.itin-expand { margin-top: 8px; font-size: .8rem; font-weight: 700; color: var(--brand); }

.itin-item-redacted { border-style: dashed; background: var(--surface-2); }
.itin-item-redacted .itin-title { color: var(--muted); font-weight: 600; font-style: italic; }

.itin-details { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-soft); }
.itin-detail-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
  font-size: .86rem;
}
.itin-detail-label { flex: 1; min-width: 0; color: var(--muted); overflow-wrap: break-word; }
.itin-detail-value { flex: none; max-width: 60%; text-align: right; font-weight: 600; color: var(--ink); overflow-wrap: break-word; }
.itin-detail-plain { display: block; color: var(--text); text-align: left; }

/* Locked day */
.itin-locked {
  padding: 16px;
  text-align: center;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r);
  background: var(--surface-2);
  color: var(--muted);
  font-size: .9rem;
  overflow-wrap: break-word;
}

/* Collaboration (Epernay only) */
.itin-item-added   { border-color: var(--good); }
.itin-item-edited  { border-color: var(--warn); }
.itin-item-removed { opacity: .6; }
.itin-item-removed .itin-title { text-decoration: line-through; }
.sugg-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  vertical-align: 2px;
}
.sugg-add  { background: var(--good-soft); color: var(--good); }
.sugg-edit { background: var(--warn-soft); color: var(--warn); }
.sugg-del  { background: var(--bad-soft);  color: var(--bad); }
.sugg-dot  { color: var(--warn); font-size: .7rem; vertical-align: 2px; }
.diff-old  { text-decoration: line-through; color: var(--faint); }
.diff-new  { color: var(--good); font-weight: 700; }
.itin-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.itin-collab-note { font-size: .84rem; color: var(--muted); line-height: 1.5; margin: 10px 0; overflow-wrap: break-word; }

/* ── Vote / quiz shared ──────────────────────────────── */
/* The rule has to be unmissable: this only opens when everyone has voted. */
.vote-rule {
  padding: 11px 13px;
  border-radius: var(--r-sm);
  background: var(--brand-soft);
  color: #23386f;
  font-size: .84rem;
  line-height: 1.5;
  overflow-wrap: break-word;
}
.vote-rule strong { font-weight: 800; }
.vote-rule-line + .vote-rule-line { margin-top: 4px; }

.vote-widget { margin-top: 11px; display: flex; flex-direction: column; gap: 10px; }

.vote-status {
  padding: 10px 12px;
  border-radius: var(--r-sm);
  font-size: .85rem;
  line-height: 1.5;
  overflow-wrap: break-word;
}
.vote-status-valid    { background: var(--good-soft); color: #0c6b4b; }
.vote-status-pending  { background: var(--warn-soft); color: #7a5212; }
.vote-status-incorrect{ background: var(--bad-soft);  color: #93261a; }
.vote-status-closed   { background: var(--surface-2); color: var(--muted); border: 1px solid var(--border); }

/* Options are full-width stacked buttons, not a wrapping row of pills. An
   option is director-authored free text and can be long; a wrapping row put
   two words on one line and shattered the rest. */
.vote-options { display: flex; flex-direction: column; gap: 8px; }
.vote-option {
  display: block;
  width: 100%;
  min-height: 46px;
  padding: 11px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font-size: .93rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  overflow-wrap: break-word;
}
.vote-option:active { background: var(--surface-2); }
.vote-option[aria-pressed="true"] {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.vote-option:disabled { opacity: .5; cursor: default; }

/* Free-text answer: a one-row auto-growing textarea, never <input type=text>.
   An input scrolls sideways and hides the start of what you typed. */
.vote-text { display: flex; flex-direction: column; gap: 8px; }

.vote-progress { padding-top: 10px; border-top: 1px solid var(--border-soft); }
.vote-summary { font-size: .8rem; font-weight: 700; color: var(--muted); margin-bottom: 7px; }
.vote-voters { display: flex; flex-wrap: wrap; gap: 6px; }
.vote-voter {
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: .78rem;
  font-weight: 600;
  overflow-wrap: break-word;
}
.vote-voter-done { background: var(--good-soft); border-color: transparent; color: var(--good); }

.vote-choices { margin-top: 8px; }
.vote-choice-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--border-soft);
  font-size: .85rem;
}
.vote-choice-row:last-child { border-bottom: 0; }
.vote-choice-name { flex: 1; min-width: 0; color: var(--muted); overflow-wrap: break-word; }
.vote-choice-value { flex: none; max-width: 60%; text-align: right; font-weight: 600; color: var(--ink); overflow-wrap: break-word; }
.vote-choice-none { color: var(--faint); font-style: italic; font-weight: 400; }

/* ── Day quiz: teaser + wizard ───────────────────────── */
.quiz-teaser { display: flex; flex-direction: column; gap: 10px; padding: 15px 16px; }
.quiz-teaser-note { font-size: .92rem; font-weight: 600; color: var(--ink); overflow-wrap: break-word; }

.quiz-wizard { display: flex; flex-direction: column; gap: 14px; }
.quiz-exit { align-self: flex-start; }

.quiz-progress { display: flex; flex-wrap: wrap; gap: 7px; }
.quiz-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  color: var(--faint);
  font-size: .74rem;
  font-weight: 800;
}
.quiz-dot-active { background: var(--brand); border-color: var(--brand); color: #fff; }
.quiz-dot-done   { background: var(--good-soft); border-color: transparent; color: var(--good); }

.quiz-screen { display: flex; flex-direction: column; gap: 12px; }
.quiz-mixed-label { font-size: .84rem; font-weight: 700; color: var(--muted); overflow-wrap: break-word; }

.quiz-card { padding: 16px; display: flex; flex-direction: column; gap: 11px; }
.quiz-prompt {
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.4;
  overflow-wrap: break-word;
}
.quiz-tag {
  display: inline-block;
  margin-right: 8px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase;
  vertical-align: 2px;
  white-space: nowrap;
}
.quiz-tag-guess  { background: var(--brand-soft); color: var(--brand); }
.quiz-tag-decide { background: var(--good-soft);  color: var(--good); }
.quiz-tag-test   { background: var(--warn-soft);  color: var(--warn); }

.quiz-hint {
  font-size: .84rem;
  font-style: italic;
  color: var(--muted);
  overflow-wrap: break-word;
}

/* The answer row stacks. A number field beside a button at 320px leaves the
   field ~120px wide and the button label clipped. */
.quiz-answer-row { display: flex; flex-direction: column; gap: 9px; }

.quiz-result { font-size: .9rem; overflow-wrap: break-word; }
.quiz-result-mine { color: var(--muted); }
.quiz-result-mine strong { color: var(--ink); font-weight: 700; }
.quiz-reveal {
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: var(--good-soft);
  color: #0c6b4b;
  font-size: .88rem;
  font-weight: 600;
  overflow-wrap: break-word;
}
.quiz-pending {
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: .86rem;
  overflow-wrap: break-word;
}
.quiz-wrong {
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: var(--bad-soft);
  color: #93261a;
  font-size: .86rem;
  font-weight: 600;
  overflow-wrap: break-word;
}
.quiz-deadline { font-size: .84rem; color: var(--warn); font-weight: 600; overflow-wrap: break-word; }

.quiz-nav { display: flex; gap: 10px; align-items: center; }
.quiz-nav > .btn { flex: 1; min-width: 0; }
.quiz-nav-spacer { flex: 1; min-width: 0; }

.quiz-done { text-align: center; }
.quiz-done-icon { font-size: 2.2rem; font-style: normal; display: block; margin-bottom: 8px; }

/* ── Invite / RSVP views ─────────────────────────────── */
/* ── Unlock-quiz guest ─────────────────────────────────
   Someone invited into the unlock quiz who is not an attendee. A single
   welcome block above the shared packing/weather card — no nav, nothing
   else on the surface, because the payload contains nothing else. */
.guest { padding: 20px 0 8px; }
.guest-head { margin-bottom: 26px; }
.guest-title {
  font-size: clamp(1.6rem, 7vw, 2.3rem);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.12;
  color: var(--ink);
  overflow-wrap: break-word;
}
.guest-sub {
  margin-top: 10px;
  font-size: .95rem;
  line-height: 1.6;
  color: var(--muted);
  overflow-wrap: break-word;
}

.inv { padding: 20px 0 8px; }
.inv-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 13px;
  border-radius: 999px;
  background: var(--brand-soft);
  color: var(--brand);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.inv-badge-success { background: var(--good-soft); color: var(--good); }
.inv-badge-muted   { background: var(--surface-2); color: var(--muted); border: 1px solid var(--border); }
.inv-badge-warning { background: var(--warn-soft); color: var(--warn); }

.inv-title {
  margin-top: 16px;
  font-size: clamp(1.75rem, 8vw, 2.6rem);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.12;
  color: var(--ink);
  overflow-wrap: break-word;
}
.inv-meta { margin-top: 10px; font-size: .93rem; color: var(--muted); overflow-wrap: break-word; }
.inv-meta strong { color: var(--ink); font-weight: 700; }

.inv-cost { margin-top: 20px; padding: 22px 20px; }
.inv-cost-muted { opacity: .6; }
.inv-cost-label {
  font-size: .72rem; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
  overflow-wrap: break-word;
}
.inv-cost-value {
  margin-top: 7px;
  font-size: clamp(2.1rem, 11vw, 2.7rem);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1;
  color: var(--ink);
}
.inv-cost-note { margin-top: 14px; font-size: .86rem; color: var(--muted); line-height: 1.6; overflow-wrap: break-word; }
.inv-cost-note strong { color: var(--ink); font-weight: 700; }

.inv-actions { margin-top: 22px; }
.inv-revise { margin-top: 20px; text-align: center; }
/* A real tap target, not a 17px line of text. inline-flex so it still centres
   in the block but can carry the 44px floor. */
.inv-revise a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 10px;
  font-size: .88rem;
  font-weight: 600;
  text-decoration: none;
  overflow-wrap: break-word;
}
.inv-revise a:hover { text-decoration: underline; }

.inv-note { margin-top: 8px; font-size: .87rem; font-style: italic; overflow-wrap: break-word; }

/* ── Mockery (>£100 outstanding) ─────────────────────── */
.mock-marquee {
  overflow: hidden;
  white-space: nowrap;
  margin-bottom: 14px;
  padding: 16px 0;
  border-radius: var(--r);
  box-shadow: var(--shadow-md);
  color: #fff;
  font-weight: 800;
  font-size: 1.15rem;
  animation: mock-flash .8s steps(1) infinite;
}
.mock-track { display: inline-block; padding-left: 100%; animation: mock-scroll 24s linear infinite; }
@keyframes mock-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes mock-flash { 0% { background: #DC4040; } 50% { background: #B7791F; } 100% { background: #DC4040; } }

.mock-avril {
  margin-bottom: 14px;
  padding: 14px 16px;
  border: 2px dashed var(--warn);
  border-radius: var(--r);
  background: var(--warn-soft);
  color: #7a5212;
  font-weight: 700;
  text-align: center;
  overflow-wrap: break-word;
}

.mock-popup {
  position: fixed;
  z-index: 55;
  max-width: 230px;
  padding: 11px 16px;
  border-radius: var(--r);
  background: var(--ink);
  color: #fff;
  font-size: .86rem;
  font-weight: 700;
  box-shadow: var(--shadow-md);
  pointer-events: none;
  overflow-wrap: break-word;
  transform: rotate(var(--rot, 0deg));
  animation: mock-pop .3s cubic-bezier(.2,.9,.3,1.2);
}
.mock-popup.out { opacity: 0; transition: opacity .4s; }
@keyframes mock-pop {
  from { opacity: 0; transform: translateY(16px) scale(.9) rotate(var(--rot, 0deg)); }
  to   { opacity: 1; transform: rotate(var(--rot, 0deg)); }
}

@media (prefers-reduced-motion: reduce) {
  .mock-marquee { animation: none; background: #DC4040; }
  .mock-track { animation: none; padding-left: 0; }
  .mock-popup { animation: none; }
}

/* iOS-only "add to home screen" tip — the dismiss button still needs its
   full 44px tap target (see .icon-btn), so pull the target's own padding in
   with negative margins rather than shrinking the target itself. */
.a2hs-banner { align-items: center; }
.a2hs-banner .icon-btn { margin: -10px -8px -10px 4px; color: inherit; }

/* ── Desktop ─────────────────────────────────────────── */
@media (min-width: 700px) {
  /* The nav is sticky below the topbar on desktop, so a sticky day header has
     to clear both bands or it slides underneath the nav. */
  .itin-day-head { top: calc(var(--topbar-h) + var(--safe-t) + 61px); }

  /* Room for a horizontal answer row once the field can hold a real number
     and still leave the button its full label. */
  .quiz-answer-row { flex-direction: row; align-items: flex-start; }
  .quiz-answer-row > .input,
  .quiz-answer-row > .textarea { flex: 1; min-width: 0; }
  .quiz-answer-row > .btn { flex: none; }

  .inv { padding-top: 32px; }
}
