/* Henry's Car Comps — British racing green, bright yellow, cream white.
   Vintage 80s motorsport garage sign energy: bold italic block lettering,
   high-contrast decal colors, racing-stripe dividers. Matches the brand
   logo. System fonts only (no webfont load, stays fast on mobile). */

:root {
  --bg: #f6f2e4;
  --bg-raised: #ffffff;
  --bg-inset: #efe9d4;
  --ink: #12251a;
  --ink-dim: #3c5445;
  --ink-faint: #6c8272;
  --line: #cfc6a0;
  --green: #0d3d28;
  --green-dark: #082a1c;
  --yellow: #f6c500;
  --yellow-bright: #ffdd33;
  --ok: #3c7a4c;
  --warn: #b5490f;
  --danger: #a8332a;
  --focus: #082a1c;
  --radius: 8px;
  --radius-lg: 18px;
  --shadow-card: 0 1px 2px rgba(8, 42, 28, 0.04), 0 8px 24px rgba(8, 42, 28, 0.07);
  --shadow-card-hover: 0 1px 2px rgba(8, 42, 28, 0.05), 0 14px 32px rgba(8, 42, 28, 0.1);
  --display: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html {
  background: var(--bg);
  color-scheme: light;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

img { max-width: 100%; display: block; }

a { color: var(--green); font-weight: 600; }
a:hover { color: var(--warn); }

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--green-dark);
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(1.9rem, 6vw, 3rem); font-style: italic; }
h2 { font-size: clamp(1.3rem, 4vw, 1.8rem); }
h3 { font-size: 1.05rem; }

p { margin: 0 0 1em; color: var(--ink-dim); }

.container {
  max-width: 780px;
  margin: 0 auto;
  padding: 0 20px;
}

/* Racing-stripe divider — thin livery pinstripe used under the header and
   between the hero and content, instead of a plain border. */
.racing-stripe {
  height: 6px;
  background: repeating-linear-gradient(
    -45deg,
    var(--green) 0, var(--green) 14px,
    var(--yellow) 14px, var(--yellow) 20px
  );
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  background: var(--bg-raised);
  border-bottom: 3px solid var(--green-dark);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
}
.wordmark img {
  height: 76px;
  width: auto;
  display: block;
}
@media (max-width: 480px) {
  .wordmark img { height: 48px; }
}

.site-nav a {
  color: var(--green-dark);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 700;
  margin-left: 18px;
}
.site-nav a:hover { color: var(--warn); }

/* Ticker strip — full-width scrolling banner above the header, repeating
   the current competition's price + name. Hidden entirely until a
   competition is loaded (and stays hidden if the car identity itself
   hasn't been revealed yet, same mystery-teaser rule as the hero). */
.ticker-strip {
  width: 100%;
  overflow: hidden;
  background: var(--green-dark);
  border-bottom: 2px solid var(--yellow);
  white-space: nowrap;
}
.ticker-strip-track {
  display: inline-block;
  padding-left: 100%;
  color: var(--yellow);
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.64rem;
  letter-spacing: 0.03em;
  padding-top: 12px;
  padding-bottom: 12px;
  animation: ticker-scroll 22s linear infinite;
}
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-100%); }
}
@media (prefers-reduced-motion: reduce) {
  .ticker-strip-track { animation: none; padding-left: 20px; }
}

.site-nav {
  display: flex;
  align-items: center;
  background: var(--bg-inset);
  border-radius: 999px;
  padding: 6px 8px;
}
.site-nav a { margin-left: 0; padding: 6px 14px; }

.site-header-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}
.cart-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: var(--green-dark);
}
.cart-icon:hover { color: var(--warn); }
.cart-badge {
  position: absolute;
  top: -8px;
  right: -10px;
  background: var(--warn);
  color: #fff;
  font-size: 0.65rem;
  font-weight: 800;
  border-radius: 999px;
  padding: 1px 5px;
  min-width: 16px;
  text-align: center;
}

.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: var(--green-dark);
  font-weight: 700;
  font-size: 0.88rem;
}
.user-chip-initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--green);
  color: var(--yellow);
  font-weight: 800;
  font-size: 0.8rem;
}
.nav-login {
  color: var(--green-dark);
  text-decoration: none;
  font-weight: 700;
  font-size: 0.88rem;
  margin-right: 10px;
}
.btn-nav-signup {
  display: inline-block;
  background: var(--yellow);
  color: var(--green-dark);
  text-decoration: none;
  font-weight: 800;
  font-size: 0.85rem;
  padding: 8px 16px;
  border-radius: 999px;
  border: 2px solid var(--green-dark);
}
.btn-nav-signup:hover { background: var(--yellow-bright); }

/* Entry-list header block: prize thumbnail, title, three stats, sold
   counter + progress bar. Price/Max Tickets/Ends are not sensitive and
   always shown; the sold counter/progress bar reuses the same gated
   stats fetch as before (loadStats()) — see public/js/main.js. */
.entry-list-header {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  margin-bottom: 20px;
}
.entry-list-thumb {
  width: 96px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--radius);
  border: 2px solid var(--line);
  flex: none;
}
.entry-list-header-info { flex: 1; }
.entry-stats-row {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  margin: 8px 0 12px;
}
.entry-stat { display: flex; flex-direction: column; }
.entry-stat-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  font-weight: 700;
}
.entry-stat-value {
  font-family: var(--display);
  font-weight: 800;
  color: var(--green-dark);
  font-size: 1.05rem;
}
.entry-sold-row {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  color: var(--ink-dim);
  margin-bottom: 4px;
}
.progress-bar {
  width: 100%;
  height: 8px;
  background: var(--bg-inset);
  border-radius: 999px;
  overflow: hidden;
}
.progress-bar-fill {
  height: 100%;
  background: var(--green);
  border-radius: 999px;
}

/* Footer — logo, social icons, two link columns, copyright + legal line. */
.footer-top {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 32px;
  margin-bottom: 24px;
}
.footer-social { display: flex; gap: 10px; margin-top: 12px; }
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: var(--green);
  color: var(--yellow);
  font-size: 0.75rem;
  font-weight: 800;
  text-decoration: none;
}
.footer-social a:hover { background: var(--green-dark); }
.footer-columns { display: flex; gap: 48px; flex-wrap: wrap; }
.footer-column h3 {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  margin: 0 0 10px;
}
.footer-column a {
  display: block;
  color: var(--ink);
  text-decoration: none;
  font-size: 0.9rem;
  margin-bottom: 8px;
}
.footer-column a:hover { color: var(--warn); }
.footer-bottom-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
  color: var(--ink-faint);
}
.footer-payment-icons { display: flex; gap: 8px; align-items: center; }
.footer-payment-icons svg { display: block; }

/* Hero — stays the plain green brand background. The rotating photo
   slideshow sits beside the headline (stacked above it on narrow
   screens), not behind the text. When there are no photos yet,
   .hero-slides is empty and collapses, leaving just the text. */
.hero {
  position: relative;
  display: flex;
  background: linear-gradient(180deg, rgba(13,61,40,0.05) 0%, rgba(13,61,40,0.15) 55%, rgba(8,42,28,0.9) 100%), var(--green) center/cover no-repeat;
}
.hero-inner {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 32px 20px 40px;
  width: 100%;
}
.hero-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  margin-bottom: 28px;
}
@media (min-width: 700px) {
  .hero-row { flex-direction: row; align-items: center; gap: 32px; }
}
.hero-slides {
  position: relative;
  flex: none;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}
@media (min-width: 700px) {
  .hero-slides { width: 460px; }
}
.hero-slides:empty { display: none; }
.hero-side-text {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--display);
  font-weight: 800;
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1.15;
  font-size: 1.7rem;
  color: #fff;
  text-shadow: 2px 2px 0 var(--green-dark);
}
@media (min-width: 700px) {
  .hero-side-text { font-size: 2.1rem; }
}
.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1400ms ease;
}
.hero-slide.active { opacity: 1; }
.hero-eyebrow {
  display: inline-block;
  font-family: var(--display);
  font-weight: 800;
  font-style: italic;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--green-dark);
  background: var(--yellow);
  padding: 4px 10px;
  border-radius: 3px;
  margin-bottom: 12px;
}
.hero h1 { color: #fff; text-shadow: 2px 2px 0 var(--green-dark); }
.hero p.lede {
  color: #fff;
  font-size: 1.05rem;
  max-width: 46ch;
}

/* Sell-through bar on the green hero — yellow fill on a dark inset track,
   so the "x% sold" reading carries at a glance against the green. */
.sold-progress {
  max-width: 460px;
  margin: 20px 0 22px;
}
.sold-progress-labels {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 7px;
}
.sold-progress-pct {
  font-family: var(--display);
  font-weight: 800;
  font-style: italic;
  font-size: 1.35rem;
  letter-spacing: 0.01em;
  color: var(--yellow);
  text-shadow: 2px 2px 0 var(--green-dark);
}
.sold-progress-count {
  font-size: 0.85rem;
  font-weight: 600;
  color: #fff;
  opacity: 0.9;
}
.sold-progress-track {
  height: 16px;
  background: var(--green-dark);
  border: 2px solid rgba(255, 255, 255, 0.28);
  border-radius: 999px;
  overflow: hidden;
}
.sold-progress-fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--yellow) 0%, var(--yellow-bright) 100%);
  transition: width 600ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* A just-opened competition still needs a visible sliver at 0%, otherwise
   the bar reads as broken rather than as "none sold yet". */
.sold-progress-fill.is-empty { width: 4px; opacity: 0.5; }

@media (max-width: 480px) {
  .sold-progress-pct { font-size: 1.15rem; }
  .sold-progress { margin: 16px 0 18px; }
}

/* Tabs (Online / Free Entry) — deliberately identical size/position */
.entry-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 16px;
  background: var(--bg-inset);
  padding: 5px;
  border-radius: 999px;
}
.entry-tab {
  flex: 1 1 0;
  padding: 11px 16px;
  text-align: center;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-dim);
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 0.85rem;
  cursor: pointer;
}
.entry-tab[aria-selected="true"] {
  color: var(--bg-raised);
  background: var(--green);
  box-shadow: var(--shadow-card);
}
.entry-panel[hidden] { display: none; }

/* Cards / sections */
.section { padding: 56px 0; border-top: 3px solid var(--line); }
.card {
  background: var(--bg-raised);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
}

.listing-spec-card {
  border: none;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 22px 24px;
  margin-bottom: 20px;
}

.spec-list { list-style: none; margin: 0; padding: 0; }
.spec-list li {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.95rem;
}
.spec-list li:last-child { border-bottom: none; }
.spec-label { color: var(--ink-faint); font-weight: 600; }
.spec-value { color: var(--ink); text-align: right; }
.ticket-stats-line { margin: 10px 0 0; font-size: 0.8rem; color: var(--ink-faint); }
.placeholder-flag {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--warn);
  border: 1px dashed var(--warn);
  padding: 1px 5px;
  border-radius: 4px;
  margin-left: 8px;
  white-space: nowrap;
}

/* Ticket slider — one discrete stop per bundle tier (see
   assertSlidingScale in functions/lib/revenue.js), not a free quantity
   input, so it snaps rather than scrolling continuously. */
.ticket-slider-card {
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  background: var(--bg-raised);
  padding: 22px 24px 18px;
  margin-bottom: 16px;
}
.ticket-slider-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.ticket-slider-count {
  font-family: var(--display);
  font-weight: 800;
  font-style: italic;
  font-size: 1.6rem;
  color: var(--green-dark);
}
.ticket-slider-price {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.6rem;
  color: var(--ink);
}
.ticket-slider-bonus {
  display: inline-block;
  margin-top: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(181, 73, 15, 0.12);
  color: var(--warn);
  font-weight: 700;
  font-size: 0.78rem;
}

.ticket-slider {
  --slider-fill: 0%;
  width: 100%;
  margin-top: 18px;
  height: 6px;
  border-radius: 999px;
  appearance: none;
  -webkit-appearance: none;
  background: linear-gradient(to right, var(--green) var(--slider-fill), var(--line) var(--slider-fill));
  cursor: pointer;
}
.ticket-slider::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--yellow);
  border: 3px solid var(--green-dark);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
.ticket-slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--yellow);
  border: 3px solid var(--green-dark);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
.ticket-slider::-moz-range-track {
  height: 6px;
  border-radius: 999px;
  background: var(--line);
}
.ticket-slider::-moz-range-progress {
  height: 6px;
  border-radius: 999px;
  background: var(--green);
}

/* Positioned via inline left (set in main.js, layoutTickLabels) to match
   each bundle amount's real point on the 1..maxTicketsPerPerson track,
   nudged apart in JS where two labels would otherwise overlap. Every tick
   centers on its left value the same way (translateX(-50%)) — JS clamps
   the center position at both ends so none of them run past the track's
   edges, rather than special-casing the first/last item in CSS. */
.ticket-slider-ticks {
  position: relative;
  /* Tall enough for a two-line tick (quantity + "N% off"); the labels are
     absolutely positioned, so too short a container spills them over the
     button below rather than clipping them. */
  height: 36px;
  margin-top: 10px;
}
.ticket-slider-tick {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  border: none;
  background: none;
  padding: 4px 2px;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--ink-faint);
  cursor: pointer;
  white-space: nowrap;
}
.ticket-slider-tick.active { color: var(--green-dark); }

/* Forms */
label { display: block; font-size: 0.9rem; color: var(--ink-dim); font-weight: 600; margin: 14px 0 6px; }
input[type="text"], input[type="email"], input[type="tel"], input[type="password"], textarea {
  width: 100%;
  padding: 11px 12px;
  background: var(--bg-raised);
  border: 2px solid var(--line);
  border-radius: 6px;
  color: var(--ink);
  font-size: 1rem;
  font-family: inherit;
}
input:focus-visible, textarea:focus-visible, button:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 14px 0;
}
.checkbox-row input { margin-top: 4px; width: 18px; height: 18px; flex: none; }
.checkbox-row label { margin: 0; font-size: 0.9rem; font-weight: 400; }

.btn {
  display: inline-block;
  width: 100%;
  padding: 14px 20px;
  border-radius: 6px;
  border: 2px solid var(--green-dark);
  background: var(--yellow);
  color: var(--green-dark);
  font-family: var(--display);
  font-weight: 800;
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  font-size: 1.05rem;
  cursor: pointer;
  margin-top: 18px;
}
.btn:hover { background: var(--yellow-bright); }
.btn:disabled { background: var(--line); border-color: var(--line); color: var(--ink-faint); cursor: not-allowed; }
.btn-secondary {
  background: transparent;
  border: 2px solid var(--green-dark);
  color: var(--green-dark);
}
.btn-secondary:hover { background: var(--green-dark); color: var(--yellow); }

.form-error {
  color: var(--danger);
  font-weight: 600;
  font-size: 0.88rem;
  margin-top: 8px;
}
.form-success {
  border: 2px solid var(--ok);
  background: rgba(60,122,76,0.08);
  border-radius: var(--radius);
  padding: 18px;
  color: var(--ink);
}

.hash-box {
  font-family: var(--mono);
  font-size: 0.85rem;
  word-break: break-all;
  background: var(--green-dark);
  border: 2px solid var(--green-dark);
  border-radius: 6px;
  padding: 12px;
  color: var(--yellow);
}

.entry-list { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.entry-list th, .entry-list td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.entry-list th { color: var(--ink-faint); font-weight: 700; text-transform: uppercase; font-size: 0.78rem; }
.entry-list td.num { font-family: var(--display); font-weight: 800; color: var(--green); }
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--ok);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 999px;
}

footer {
  border-top: 3px solid var(--green-dark);
  padding: 36px 0 60px;
  color: var(--ink-faint);
  font-size: 0.85rem;
  background: var(--bg-raised);
}
footer a { color: var(--ink-dim); }
footer .legal-lines { margin-top: 10px; }
footer .legal-lines div { margin: 2px 0; }

.badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.72rem;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-dim);
}

.responsible-strip {
  background: var(--green-dark);
  padding: 14px 0;
  font-size: 0.85rem;
  color: var(--bg);
  text-align: center;
}
.responsible-strip a { color: var(--yellow); font-weight: 700; }

@media (prefers-reduced-motion: no-preference) {
  .btn, .bundle, .entry-tab { transition: background-color 120ms ease, border-color 120ms ease; }
}

@media (max-width: 480px) {
  .site-nav { display: none; }
}

/* Competition photo gallery — one large "current" image, arrows on
   desktop, a thumbnail strip underneath (desktop only), swipe on mobile.
   Uploaded via Cloudflare Images (admin dashboard), gated server-side
   behind the car's identity reveal — see functions/api/competitions/
   current.js. No borders, matches the rest of the site's clean-edge look. */
/* Listing layout — photos left, spec/CTA right on wide screens (like a
   real car-dealer listing page), single column stacked on mobile. The
   info column stays put while the photo column scrolls past it, so the
   buy box is still on screen further down the page. */
.listing-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
  margin-bottom: 28px;
}
@media (min-width: 900px) {
  .listing-layout { grid-template-columns: 1.25fr 1fr; align-items: start; }
  .listing-info { position: sticky; top: 20px; }
}

.photo-gallery-section { margin-bottom: 0; }
.gallery-hero-btn {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  background: var(--bg-inset);
  border-radius: var(--radius-lg);
  overflow: hidden;
  padding: 0;
  border: none;
  cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: box-shadow 160ms ease;
}
.gallery-hero-btn:hover { box-shadow: var(--shadow-card-hover); }
.gallery-hero-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
  transition: transform 300ms ease;
}
.gallery-hero-btn:hover .gallery-hero-image { transform: scale(1.02); }

/* Smaller photos underneath the hero, fitted together like a real listing's
   photo set — not a single scrolling filmstrip. */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-top: 8px;
}
.gallery-grid-btn {
  aspect-ratio: 4 / 3;
  padding: 0;
  border: none;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  background: var(--bg-inset);
  transition: opacity 120ms ease;
}
.gallery-grid-btn:hover { opacity: 0.85; }
.gallery-grid-btn img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 480px) {
  .gallery-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Full-screen click-to-enlarge lightbox — swipe on mobile, arrows on
   desktop, same ~40px swipe threshold used elsewhere on this page. */
.gallery-lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(8, 20, 14, 0.96);
  display: flex;
  align-items: center;
  justify-content: center;
}
.gallery-lightbox[hidden] { display: none; }
.lightbox-image {
  max-width: min(92vw, 1100px);
  max-height: 88vh;
  object-fit: contain;
  user-select: none;
}
.lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: none;
  border: none;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
  padding: 6px 10px;
}
.lightbox-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: none;
  border-radius: 999px;
  width: 44px;
  height: 44px;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}
.lightbox-arrow:hover { background: rgba(255, 255, 255, 0.25); }
.lightbox-arrow-prev { left: 16px; }
.lightbox-arrow-next { right: 16px; }
@media (max-width: 480px) {
  .lightbox-arrow { display: none; }
}
.lightbox-count {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: 0.85rem;
  opacity: 0.8;
}

/* Photo essay — a repeating pattern of [2 stacked squares + 1 large photo]
   then [1 full-width photo], straight square corners, no shadow, flush
   against the page like a real dealer listing's photo set — with the
   description running down the right side, sticky, on wide screens. Same
   click-to-enlarge lightbox as the hero gallery (renderPhotoEssay shares
   galleryPhotos/openLightbox in main.js). */
.listing-essay-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
  margin-top: 28px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
@media (min-width: 900px) {
  .listing-essay-layout { grid-template-columns: 1.4fr 1fr; align-items: start; }
  .listing-essay-text { position: sticky; top: 20px; }
}
.listing-essay-text p {
  margin: 0 0 16px;
  color: var(--ink-dim);
  font-size: 1.02rem;
  line-height: 1.7;
}
.listing-essay-text p:last-of-type { margin-bottom: 0; }
.essay-spec-bullets {
  margin: 20px 0 0;
  padding-left: 20px;
  color: var(--ink-dim);
}
.essay-spec-bullets li { margin-bottom: 8px; line-height: 1.5; }
.essay-spec-bullets li::marker { color: var(--green); }

.essay-photo {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  min-width: 0;
  padding: 0;
  border: none;
  cursor: pointer;
  background: var(--bg-inset);
}
.essay-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.essay-photo:hover img { opacity: 0.9; }

.essay-pair-row {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  grid-template-rows: 1fr;
  gap: 8px;
  height: clamp(220px, 32vw, 420px);
  margin-bottom: 8px;
}
.essay-pair-stack {
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 8px;
  height: 100%;
  min-height: 0;
}
.essay-photo-full { width: 100%; height: clamp(220px, 32vw, 420px); margin-bottom: 8px; }

.essay-half-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  height: clamp(160px, 20vw, 260px);
  margin-bottom: 8px;
}


/* Tables in the policy pages (cookies, privacy) — same card-ish treatment as
   the rest of the long-form legal content, and horizontally scrollable rather
   than overflowing on a phone. */
.policy-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin: 14px 0 22px;
  display: block;
  overflow-x: auto;
  white-space: normal;
}
.policy-table th,
.policy-table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.policy-table th {
  font-family: var(--display);
  font-weight: 800;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-dim);
  background: var(--bg-inset);
}
.policy-table code {
  font-family: var(--mono);
  font-size: 0.85em;
  background: var(--bg-inset);
  padding: 1px 5px;
  border-radius: 3px;
}

/* ---------------------------------------------------------------------------
   The draw ceremony (/draw.html). Steps fade in one at a time as the reveal
   progresses; the reels land on the real winner, recomputed in the browser.
   Everything degrades to plain readable content if JS never runs.
   --------------------------------------------------------------------------- */
.draw-stage { max-width: 760px; margin: 0 auto; padding: 40px 0 80px; }

.draw-head { text-align: center; margin-bottom: 40px; }
.draw-eyebrow {
  display: inline-block;
  font-family: var(--display);
  font-weight: 800; font-style: italic;
  font-size: 0.8rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--green-dark); background: var(--yellow);
  padding: 4px 12px; border-radius: 3px; margin-bottom: 12px;
}
.draw-sub { color: var(--ink-dim); font-size: 1.05rem; }

.draw-step {
  border-left: 3px solid var(--line);
  padding: 4px 0 4px 22px;
  margin-bottom: 34px;
  opacity: 0.25;
  transform: translateY(6px);
  transition: opacity 500ms ease, transform 500ms ease, border-color 500ms ease;
}
.draw-step.is-live {
  opacity: 1;
  transform: none;
  border-left-color: var(--yellow);
}
.draw-step-label {
  font-family: var(--display);
  font-weight: 800; font-style: italic;
  text-transform: uppercase; letter-spacing: 0.06em;
  font-size: 0.85rem; color: var(--ink-dim);
  display: flex; align-items: center; gap: 9px; margin-bottom: 8px;
}
.draw-step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--green); color: #fff; font-size: 0.75rem; font-style: normal;
}
.draw-step-copy { color: var(--ink-dim); margin: 0 0 12px; }

.draw-mono {
  font-family: var(--mono);
  font-size: 0.8rem;
  word-break: break-all;
  background: var(--bg-inset);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 12px 14px;
  min-height: 44px;
}
.draw-mono-dim { color: var(--ink-faint); }
.draw-mono-reveal { color: var(--ink); border-color: var(--yellow); }

.draw-note { font-size: 0.8rem; color: var(--ink-faint); margin-top: 7px; }

.draw-check {
  font-size: 0.9rem; font-weight: 700;
  margin-top: 10px; padding: 9px 12px; border-radius: 6px;
}
.draw-check.ok  { background: #dff2e3; color: var(--ok); }
.draw-check.bad { background: #fbe4e1; color: var(--danger); }

.draw-formula {
  font-family: var(--display); font-weight: 800; font-style: italic;
  font-size: 1rem; color: var(--ink-dim);
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.draw-formula span {
  background: var(--bg-inset); border: 1px solid var(--line);
  border-radius: 5px; padding: 4px 10px; color: var(--ink);
}

/* The reels */
.draw-reels { display: flex; gap: 8px; flex-wrap: wrap; margin: 16px 0 6px; }
.draw-reel {
  font-family: var(--display);
  font-weight: 800;
  font-size: 2.6rem;
  line-height: 1;
  width: 54px; height: 74px;
  display: flex; align-items: center; justify-content: center;
  background: var(--green-dark); color: var(--yellow);
  border-radius: 8px;
  box-shadow: inset 0 3px 10px rgba(0,0,0,0.45);
}
.draw-reel.locked { animation: reel-lock 420ms cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes reel-lock {
  0%   { transform: translateY(-9px) scale(1.06); }
  60%  { transform: translateY(3px)  scale(0.98); }
  100% { transform: none; }
}

.draw-winner-line {
  font-size: 1.15rem; margin-top: 14px; color: var(--ink);
}
.draw-winner-line strong {
  font-family: var(--display); font-style: italic;
  font-size: 1.6rem; color: var(--green);
}

.draw-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 30px 0 0; }
.draw-actions .btn { width: auto; margin-top: 0; }

.draw-verify {
  margin-top: 34px; padding: 22px;
  background: var(--bg-raised);
  border: 2px solid var(--line); border-radius: var(--radius);
}
.draw-verify h2 { margin-top: 0; }
.draw-verify h3 { margin-bottom: 6px; font-size: 1rem; }
.draw-pre {
  font-family: var(--mono); font-size: 0.75rem;
  background: var(--bg-inset); border: 1px solid var(--line);
  border-radius: 6px; padding: 12px; overflow-x: auto; white-space: pre;
}
.draw-video { margin-top: 26px; }
.draw-empty { color: var(--ink-dim); }

/* Anyone who prefers less motion gets the outcome without the spectacle. */
@media (prefers-reduced-motion: reduce) {
  .draw-step { opacity: 1; transform: none; transition: none; }
  .draw-reel.locked { animation: none; }
}

@media (max-width: 480px) {
  .draw-reel { width: 42px; height: 58px; font-size: 2rem; }
  .draw-step { padding-left: 15px; margin-bottom: 26px; }
}

/* The refund-threshold explanation under the competition spec card. Stated in
   plain English because clause 2.3 of the terms depends on the entrant having
   actually seen this figure. */
.spec-threshold-note {
  font-size: 0.82rem;
  color: var(--ink-dim);
  background: var(--bg-inset);
  border-left: 3px solid var(--yellow);
  padding: 9px 12px;
  border-radius: 0 6px 6px 0;
  margin: 12px 0 0;
}

/* "Coming next" teaser — draft competitions the operator has flagged. Shown
   even when nothing is open, so the site is never a dead end between draws. */
.upcoming-lede { color: var(--ink-dim); margin-top: -6px; }
.upcoming-list { display: grid; gap: 18px; grid-template-columns: 1fr; }
@media (min-width: 700px) {
  .upcoming-list { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
}
.upcoming-card {
  background: var(--bg-raised);
  border: 2px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}
.upcoming-image {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  transition: opacity 200ms ease;
}
.upcoming-body { padding: 18px 20px 22px; }
.upcoming-body h3 { margin: 8px 0 6px; }
.upcoming-body p { margin: 0; color: var(--ink-dim); }
.upcoming-badge {
  display: inline-block;
  font-family: var(--display);
  font-weight: 800;
  font-style: italic;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green-dark);
  background: var(--yellow);
  padding: 3px 9px;
  border-radius: 3px;
}

/* Volume-discount feedback on the ticket slider. The saving line replaces the
   old "X paid + Y free" note, which never appeared for a ladder built from
   straight price discounts — so the discount was invisible. */
.ticket-slider-bonus.is-saving {
  color: var(--ok);
  font-weight: 600;
}
.ticket-slider-bonus.is-saving strong {
  color: var(--ok);
  font-weight: 800;
}
.ticket-slider-tick .tick-off {
  display: block;
  font-size: 0.62rem;
  font-weight: 800;
  line-height: 1.1;
  color: var(--warn);
  letter-spacing: 0.01em;
}
.ticket-slider-tick.active .tick-off { color: inherit; }
