@font-face {
  font-family: 'Techarena Avant Garde';
  src: url('fonts/AvantGarde-Book.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Techarena Avant Garde';
  src: url('fonts/AvantGarde-Demi.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Techarena Avant Garde';
  src: url('fonts/AvantGarde-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg-page: #000000;
  --bg-card: #061124;
  --bg-panel: #00244a;
  --input-fill: #dbe4d4;
  --accent: #d000ff;
  --accent-hover: #c11674;
  --text-white: #f5f6fa;
  --text-dim: #aab0cc;
  /* Card, preview frames, and the controls panel all share one corner
     radius now (previously 28px/16px) so every box reads as equally
     rounded; that shared value is 25% smaller than the old outer-card
     radius. */
  --radius-lg: 21px;
  --radius-md: 21px;
  --radius-pill: 999px;
  font-family: 'Inter', sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  color: var(--text-white);
}

/* Background color lives on html only (not body). html's background is
   used to paint the page canvas, which sits at the very back -- behind
   even the negative z-index video below. If body also painted its own
   solid background box, it would draw on top of that negative z-index
   video and hide it completely (a well-known stacking-order quirk). */
html {
  background: var(--bg-page);
}

/* Full-page background video, fixed behind everything so it stays put
   while .page scrolls on top of it. A dark overlay sits above the video
   (but still behind .page's actual content) so text and the card keep
   good contrast against the moving footage. */
.site-bg-video {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
  pointer-events: none;
}

.site-bg-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.8);
  z-index: -1;
  pointer-events: none;
}

.page {
  /* 100vh on mobile is based on the browser's LARGEST possible size (as if
     its address bar/toolbar were hidden), not what's actually visible on
     screen -- so on a short step (little content), this used to leave a
     stretch of plain black page background below the card that you could
     scroll down into, well past anything actually on the page. 100dvh
     tracks the real, currently-visible height instead, so that empty
     stretch is capped at one real screen instead of being scrollable.
     Keep the vh line first as a fallback for browsers without dvh. */
  min-height: 100vh;
  min-height: 100dvh;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(20px, 4vw, 56px) clamp(16px, 4vw, 40px);
  overflow-x: hidden;
}

.page-title {
  font-family: 'Techarena Avant Garde', 'Inter', sans-serif;
  font-weight: 700;
  text-align: center;
  font-size: clamp(22px, 4vw, 40px);
  margin: 0 0 clamp(18px, 3vw, 36px) 0;
  max-width: 900px;
}

.card {
  width: 100%;
  max-width: 760px;
  background: var(--bg-card);
  border: 1px solid #192435;
  border-radius: var(--radius-lg);
  padding: clamp(14px, 2.5vw, 28px);
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 2.5vw, 24px);
}

.previews-row {
  display: flex;
  gap: clamp(10px, 2vw, 20px);
}
.previews-row[hidden] {
  display: none;
}

.preview-col {
  flex: 1 1 0;
  min-width: 0;
}

.badge-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1; /* matches the badge canvas resolution */
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #000;
}

#badge-canvas,
#badge-canvas-live {
  width: 100%;
  height: 100%;
  display: block;
}

/* Once the real downloadable file is ready, it's shown as an actual <img>
   layered exactly over the live canvas (same spot, same size) -- a canvas
   can't be long-pressed to save on a phone, but a real image can. The
   canvas keeps animating underneath; this only matters while the image is
   visible (result step). */
.badge-result-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Tapping it does the same thing as its Download button below. */
  cursor: pointer;
}
.badge-result-img[hidden] {
  display: none;
}

.bg-loading {
  position: absolute;
  inset: 0;
  background: rgba(6, 9, 26, 0.72);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 13px;
  color: var(--text-white);
  text-align: center;
  padding: 12px;
}
.bg-loading:not([hidden]) { display: flex; }
.bg-loading[hidden] { display: none; }

.spinner {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 3px solid rgba(255,255,255,0.25);
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.controls-pane {
  width: 100%;
  /* Capped and centered so the text fields/buttons don't stretch edge to
     edge of a wide card -- on narrow screens the card itself is already
     narrower than this cap, so it has no effect there; it only kicks in
     once there's room to spare, i.e. on desktop. */
  max-width: 460px;
  margin: 0 auto;
  min-width: 0;
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
}

.step { display: none; flex-direction: column; flex: 1; }
.step.is-active { display: flex; }

.field-label {
  display: block;
  font-family: 'Techarena Avant Garde', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin: 14px 0 8px 0;
}
.field-label:first-child { margin-top: 0; }

.step-title {
  font-family: 'Techarena Avant Garde', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 22px;
  margin: 0 0 24px 0;
}

.field-input {
  width: 100%;
  background: var(--input-fill);
  border: none;
  border-radius: 10px;
  padding: 12px 14px;
  font-family: 'Inter', sans-serif;
  font-size: 15px;
  color: #14181f;
  outline: none;
}

.field-textarea {
  resize: none; /* height is now driven by the auto-grow script instead */
  overflow: hidden;
  font-family: 'Inter', sans-serif;
}

.upload-row {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

/* Groups the "Add Logo" button with whichever note sits next to it -- the
   "Optional" hint before a logo's added, or the "Remove" link once one has
   (only one of the two is ever visible, so it just takes over the same
   spot). On desktop that note sits to the right, vertically centered; on
   narrow screens there's no room for that, so it drops below the button
   and centers under it instead. */
.upload-action {
  display: flex;
  align-items: center;
  gap: 8px;
}
.upload-action .hint-text {
  margin: 0;
  min-height: 0;
}
@media (max-width: 560px) {
  .upload-action {
    flex-direction: column;
    align-items: center;
    gap: 2px;
  }
}

/* Image and Logo uploads sit side by side on desktop. The "Image"/"Logo"
   labels are each the first child of their own .upload-field wrapper, so
   the .field-label:first-child rule zeroes their own margin-top -- give
   the row itself the same top margin a field-label would normally have,
   so the gap above this row matches the gap above Name/Title. */
.upload-fields-row {
  display: flex;
  gap: 28px;
  margin-top: 28px;
}
.upload-field {
  flex: 1 1 0;
  min-width: 0;
}
/* On narrow screens, don't stretch the two upload buttons into equal
   50%-width halves (which left-aligns each one inside its own half,
   reading as a lopsided pair) -- let them size to their own content and
   center that pair as a group instead. */
@media (max-width: 560px) {
  .upload-fields-row {
    justify-content: center;
  }
  .upload-field {
    flex: 0 0 auto;
  }
}

/* "Upload image"/"Change image" and "Add Logo"/"Change logo" are different
   lengths, so left to their natural content width they end up visibly
   different sizes -- pin both to the widest label's width so they always
   match, whichever text is currently showing. */
.btn-upload-slot {
  min-width: 165px;
}

.hint-text {
  font-size: 12.5px;
  color: var(--text-dim);
  margin: 8px 0 0 0;
  min-height: 16px;
}
/* An empty hint (e.g. the image upload's error line when there's no error)
   collapses instead of reserving blank space -- otherwise it silently
   makes that column taller than its neighbor, throwing off shared spacing
   like the gap below the logo column's "Optional"/"Remove" note. */
.hint-text:empty {
  display: none;
}

.btn {
  font-family: 'Techarena Avant Garde', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  border: none;
  cursor: pointer;
  transition: transform 0.08s ease, background 0.15s ease, opacity 0.15s ease;
}
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-pale {
  background: var(--input-fill);
  color: #14181f;
  padding: 12px 22px;
  border-radius: var(--radius-pill);
}

.btn-primary {
  background: var(--accent);
  color: #fff;
  padding: 14px 28px;
  border-radius: var(--radius-pill);
}
.btn-primary:not(:disabled):hover { background: var(--accent-hover); }

.btn-outline {
  background: transparent;
  color: var(--text-white);
  border: 2px solid var(--accent);
  padding: 12px 26px;
  border-radius: var(--radius-pill);
}

/* margin-top:14px matches the gap used everywhere else on this page (see
   .field-label and .upload-fields-row above) -- this used to be
   margin-top:auto to push the button to the bottom of the column, but
   that collapses to 0 whenever the column has no leftover height (which
   is the normal case), leaving the button jammed against the row above
   it instead of keeping the page's usual rhythm. */
.btn-block { width: 100%; margin-top: 14px; align-self: stretch; }

.link-btn {
  background: none;
  border: none;
  color: var(--text-white);
  font-family: 'Techarena Avant Garde', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 13px;
  text-decoration: underline;
  text-transform: uppercase;
  cursor: pointer;
  padding: 0;
}

.slider-block { margin-bottom: 22px; }

.slider {
  width: 100%;
  appearance: none;
  height: 6px;
  border-radius: 4px;
  background: rgba(255,255,255,0.25);
  outline: none;
}
.slider::-webkit-slider-thumb {
  appearance: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #ffffff;
  cursor: pointer;
  border: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.slider::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #ffffff;
  cursor: pointer;
  border: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.btn-row {
  display: flex;
  gap: 14px;
  margin-top: auto;
  padding-top: 10px;
}
.btn-row .btn { flex: 1 1 0; }

/* Result screen: the whole cluster (previews + buttons) sits centered in
   the panel, with the download buttons sitting close under the previews
   and Back on its own row underneath. */
#step-result.is-active { justify-content: center; }

.result-actions {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 18px;
}
.download-row { display: flex; gap: 14px; align-items: flex-end; }
.download-col {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.download-col .btn { width: 100%; }
/* Sits directly above the GIF button, e.g. "Rendering animated version…",
   centered on that button rather than the whole row. Empty and collapsed
   (via :empty) the rest of the time. */
.download-status { margin: 0; min-height: 0; text-align: center; }
.download-status:empty { display: none; }
.back-row { display: flex; }
.back-row .btn { flex: 0 0 auto; min-width: 140px; }

/* Deliberately quiet -- small, dim, and placed after the download buttons
   (not before/beside them) so it reads as a footnote on the way out,
   rather than competing with the actual download CTAs for attention. */
.download-disclaimer {
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
  margin: 0;
  opacity: 0.85;
}

/* Toggle switch (Photo adjustment step: "Remove background") */
.toggle-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 22px;
  cursor: pointer;
}
.toggle-row .field-label {
  margin: 0;
  cursor: pointer;
}
.toggle-switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 26px;
  flex: 0 0 auto;
}
.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.toggle-track {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.25);
  border-radius: var(--radius-pill);
  transition: background 0.15s ease;
}
.toggle-track::before {
  content: "";
  position: absolute;
  width: 20px;
  height: 20px;
  left: 3px;
  top: 3px;
  background: #fff;
  border-radius: 50%;
  transition: transform 0.15s ease;
}
.toggle-switch input:checked + .toggle-track {
  background: var(--accent);
}
.toggle-switch input:checked + .toggle-track::before {
  transform: translateX(18px);
}

/* "Save Your Badge" step -- shown on phones instead of the result step
   when the native Share Sheet isn't available (or fails), so the visitor
   can still get the file into their Photos app (a plain download normally
   lands in Files/Downloads instead). This is a plain step like the others
   (#step-form/#step-adjust/#step-result), not a floating overlay -- it
   just appears in the normal page flow, in the same spot, which sidesteps
   every mobile-browser-chrome/viewport quirk a fixed-position popup runs
   into (there's nothing here to fight with -- no address bar math, no
   scroll tricks, just ordinary content). */
.save-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.save-header .step-title { margin: 0; }
.save-icon {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
}

.save-instructions {
  margin: 0 0 16px 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-dim);
}
.save-instructions strong { color: var(--text-white); }

.save-image-wrap {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #000;
  margin-bottom: 18px;
}
#save-page-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Responsive: keep previews side by side, everything else stays full width */
@media (max-width: 560px) {
  .page-title { padding: 0 4px; }
  /* Image/Logo uploads stay side by side on narrow screens too, just with
     a tighter gap between them. */
  .upload-fields-row { gap: 14px; }
}
