/* PineLoop — palette lifted from the logo's own PNG palette. */
:root {
  --blue:       #0042CD;
  --blue-lift:  #0053E6;
  --blue-deep:  #0030A4;
  --red:        #EC000B;
  --red-deep:   #C6000E;

  --ground:     #EEF2FA;  /* cool porcelain, tinted toward the blue */
  --card:       #FFFFFF;
  --ink:        #0A1633;  /* navy-black, not a neutral grey */
  --ink-soft:   #5A6683;
  --line:       #D5DEEE;

  /* Everything below flips with the theme. Keeping them as tokens is what lets
     dark mode be a palette swap instead of a second stylesheet. */
  --accent:      #0042CD;              /* blue for text, icons and focus */
  --heading:     #0030A4;
  --tint:        rgba(10, 22, 51, 0.07);   /* pressed-state wash */
  --hairline:    rgba(10, 22, 51, 0.14);
  --placeholder: #9AA5BD;
  --glass:       rgba(250, 250, 252, 0.86);
  --sheen:       rgba(255, 255, 255, 0.5);
  --current:     rgba(0, 66, 205, 0.09);
  --focus-ring:  rgba(0, 66, 205, 0.14);
  --focus-glow:  rgba(0, 66, 205, 0.30);   /* the bloom outside the ring */
  --scrim:       rgba(10, 22, 51, 0.45);
  --veil:        rgba(10, 22, 51, 0.18);

  --step:       clamp(1.25rem, 6vw, 2rem);
  --ease:       cubic-bezier(0.22, 0.61, 0.36, 1);
  --dock-space: 7rem;
  --shell:      27.5rem;  /* a phone-width column, so desktop reads as an app */
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--ground);
  color: var(--ink);
  font-family: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-weight: 500;
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
}

/* Lock the loading screen; the welcome actions must remain reachable. */
body[data-phase] {
  overflow: hidden;
  -webkit-user-select: none;
  user-select: none;
}
body[data-phase="welcome"] { overflow-y: auto; }

/* A single soft blue bloom — the only decoration on the page. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: radial-gradient(58% 42% at 50% 38%, rgba(0, 83, 230, 0.13), transparent 70%);
  pointer-events: none;
}

/* Everything lives inside one phone-width column, centred. On a desktop this
   is what stops the layout stretching to 1900px and reading as a website. */
.shell {
  position: relative;
  width: 100%;
  max-width: var(--shell);
  min-height: 100dvh;
  margin-inline: auto;
}

@media (min-width: 30rem) {
  .shell {
    box-shadow: 0 0 4rem rgba(10, 22, 51, 0.07);
    background: linear-gradient(180deg, var(--sheen), transparent);
  }
}

/* ---- Splash + welcome ------------------------------------------------ */
.stage {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--step);
  padding: calc(env(safe-area-inset-top) + var(--step)) var(--step)
           calc(env(safe-area-inset-bottom) + var(--step));
  text-align: center;
  transition: padding-bottom 0.7s var(--ease);
}

/* The install offer participates in this layout. An absolute footer below a
   full-height stage could otherwise be pushed beyond the locked viewport. */
body[data-phase="welcome"] > .shell {
  display: flex;
  flex-direction: column;
}
[data-phase="welcome"] .stage {
  flex: 1 0 auto;
  min-height: 20rem;
  padding-bottom: var(--step);
}

/* One logo element serves both phases. It rises on its own as the greeting
   opens beneath it, so the movement is real layout, not a second copy.

   While loading, the logo sits in the water loader. The player's frames are
   4:3 with the vessel in the middle, so the mark's padding grows the box to
   that shape around the logo and the player fills the box exactly: the logo
   lands in the vessel by geometry, not by nudging. content-box so the padding
   adds to the logo's width rather than eating into it. */
.mark {
  --mark-w: clamp(112px, 32vw, 156px);
  position: relative;
  display: grid;
  place-items: center;
  box-sizing: content-box;
  width: var(--mark-w);
  padding: calc(var(--mark-w) * 0.62) calc(var(--mark-w) * 0.95);
  transition: padding 0.7s var(--ease);
}

.mark__water {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.4s var(--ease);
}

.mark__img {
  position: relative;
  display: block;
  width: var(--mark-w);
  height: auto;
  transition: width 0.7s var(--ease);
}

[data-phase="welcome"] .mark { --mark-w: clamp(84px, 24vw, 116px); padding: 0; }
[data-phase="welcome"] .mark__water { opacity: 0; }

.loader {
  display: flex;
  gap: 0.65rem;
  height: 0.75rem;
  transition: opacity 0.3s var(--ease), height 0.7s var(--ease), margin-top 0.7s var(--ease);
}

.loader__dot {
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 1.35s var(--ease) infinite;
}

.loader__dot:nth-child(2) { background: var(--red); animation-delay: 0.18s; }
.loader__dot:nth-child(3) { background: var(--blue-lift); animation-delay: 0.36s; }

@keyframes pulse {
  0%, 70%, 100% { transform: scale(0.62); opacity: 0.35; }
  35%           { transform: scale(1);    opacity: 1; }
}

[data-phase="welcome"] .loader {
  opacity: 0;
  height: 0;
  margin-top: calc(var(--step) * -1);
}

/* Collapsed to zero height during the splash so it reserves no space; the
   0fr -> 1fr grid row is what makes the height animatable. */
.greeting {
  display: grid;
  grid-template-rows: 0fr;
  width: 100%;
  opacity: 0;
  transition: grid-template-rows 0.7s var(--ease),
              opacity 0.5s var(--ease) 0.15s;
}

.greeting__inner { overflow: hidden; }

.greeting__title {
  margin: 0;
  font-size: clamp(2.25rem, 12vw, 3.25rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.1;
  color: var(--heading);
}

.greeting__line {
  margin: 0.65rem auto 0;
  max-width: 24ch;
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

[data-phase="welcome"] .greeting {
  grid-template-rows: 1fr;
  opacity: 1;
}

/* ---- Action dock ----------------------------------------------------- */
/* Absolute inside the shell, not fixed to the viewport, so it stays inside
   the phone-width column on desktop. */
.dock {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0 var(--step) calc(env(safe-area-inset-bottom) + var(--step));
  opacity: 0;
  transform: translateY(120%);
  transition: opacity 0.5s var(--ease) 0.3s, transform 0.55s var(--ease) 0.3s;
  pointer-events: none;
}

[data-phase="welcome"] .dock {
  position: relative;
  flex: none;
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.dock--static {
  position: static;
  opacity: 1;
  transform: none;
  pointer-events: auto;
  transition: none;
  padding-top: var(--step);
}

.button {
  display: grid;          /* label and dots share one cell, so no size jump */
  place-items: center;
  width: 100%;
  min-height: 3.5rem;   /* comfortable thumb target */
  border: 0;
  border-radius: 1.75rem;
  background: var(--red);
  color: #fff;
  font-family: inherit;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 0.5rem 1.25rem rgba(236, 0, 11, 0.28);
  transition: transform 0.15s var(--ease), background-color 0.15s var(--ease);
}

.button:active {
  transform: scale(0.975);
  background: var(--red-deep);
}

.button:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.button--submit { margin-top: 0.5rem; }

/* A secondary action: same shape, none of the red's pull. */
.button--quiet {
  background: var(--tint);
  color: var(--ink);
  box-shadow: none;
}

.button--quiet:active { background: var(--hairline); }

.button--danger {
  background: none;
  color: var(--red-deep);
  box-shadow: none;
  border: 1.5px solid var(--red-deep);
}

.button--danger:active { background: var(--tint); }

:root:not([data-theme="light"]) .button--danger { color: #FF8A8A; border-color: #FF8A8A; }

/* Sits in a row or a card rather than spanning a form. */
.button--compact {
  min-height: 3rem;
  padding-inline: 1.25rem;
  font-size: 1rem;
}

.button--wide { margin-top: 1rem; }

.button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}

.button:disabled:active { transform: none; }

/* ---- Content panels -------------------------------------------------- */
.panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: calc(env(safe-area-inset-top) + var(--step)) var(--step) var(--step);
  text-align: center;
}

/* A back arrow pinned to the top-left corner of the panel, clear of the
   logo. Big enough to hit with a thumb, drawn bold so it reads as a control
   rather than a decoration. */
.panel__back {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 0.9rem);
  left: 0.9rem;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--card);
  border: 1.5px solid var(--line);
  color: var(--ink);
  transition: transform 0.2s var(--ease), border-color 0.2s var(--ease);
}
.panel__back svg {
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.panel__back:hover { border-color: var(--accent); color: var(--accent); }
.panel__back:active { transform: scale(0.92); }
.panel__back:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

.panel__mark {
  display: block;
  width: 116px;
  height: auto;
  margin-bottom: 1.5rem;
}

.panel__mark--small { width: 86px; margin-bottom: 1.25rem; }

.panel__title {
  margin: 0;
  max-width: 16ch;
  font-size: clamp(1.75rem, 8vw, 2.25rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.15;
  color: var(--heading);
}

.panel__title--compact { font-size: clamp(1.5rem, 7vw, 1.875rem); }

.panel__body {
  margin: 0.9rem 0 0;
  max-width: 32ch;
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

.panel__body--compact { font-size: 1rem; }

.panel__note {
  margin: 1.75rem 0 0;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}

/* ---- Selling points -------------------------------------------------- */
.points {
  width: 100%;
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.75rem;
  text-align: left;
}

.points__item {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.9rem 1rem;
  border-radius: 1rem;
  background: var(--card);
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--ink);
}

.points__icon {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.points__tick { stroke: var(--red); }

/* ---- Form ------------------------------------------------------------ */
.form {
  width: 100%;
  margin-top: 1.75rem;
  display: grid;
  gap: 1rem;
  text-align: left;
}

.field__label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--ink);
}

.field__box {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: 0.875rem;
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

.field__box:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.field--bad .field__box { border-color: var(--red); }

.field__icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-left: 0.9rem;
  fill: none;
  stroke: var(--ink-soft);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.field__box:focus-within .field__icon { stroke: var(--accent); }

.field__input {
  flex: 1;
  width: 100%;
  min-width: 0;
  min-height: 3.25rem;
  padding: 0 0.9rem;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: inherit;
  font-size: 1rem;   /* 16px minimum, or iOS zooms the page on focus */
  font-weight: 500;
}

.field__input:focus { outline: none; }

.field__input::placeholder { color: var(--placeholder); }

.field__input--select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.5rem;
  cursor: pointer;
  /* Chrome paints the native option list from the select's own colours. Left
     transparent, the dark-theme ink lands on a white popup and the country
     names all but vanish, so the box colour has to be stated outright. */
  background-color: var(--card);
  color: var(--ink);
  border-radius: 0.875rem;
}

/* The popup is drawn by the OS: only these two properties reliably reach it. */
.field__input--select option,
.field__input--select optgroup {
  background-color: var(--card);
  color: var(--ink);
}

/* The prompt row reads as a placeholder, in the list and in the closed box. */
.field__input--select option[value=""] { color: var(--placeholder); }
.field__input--select:has(option[value=""]:checked) { color: var(--placeholder); }

.field__caret {
  position: absolute;
  right: 0.9rem;
  width: 1.25rem;
  height: 1.25rem;
  pointer-events: none;
  fill: none;
  stroke: var(--ink-soft);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- Country combobox -------------------------------------------------- */
/* Only present once country.js has upgraded the <select>: the list is our own
   markup, so it can be themed, which the OS-drawn popup can't be. */
.combo { position: relative; }

.combo__input { cursor: text; }

.combo.is-open .field__caret { transform: rotate(180deg); }

.combo__list {
  position: absolute;
  z-index: 30;
  top: calc(100% + 0.4rem);
  left: -1.5px;             /* line the panel up with the box's border, not its inside */
  right: -1.5px;
  max-height: 15rem;
  margin: 0;
  padding: 0.35rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: 0.875rem;
  box-shadow: 0 1rem 2rem var(--scrim);
  -webkit-overflow-scrolling: touch;
}

.combo__row {
  display: flex;
  gap: 0.7rem;
  align-items: center;
  padding: 0.6rem 0.7rem;
  border-radius: 0.625rem;
  cursor: pointer;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
}

.combo__row.is-active { background: var(--current); }
.combo__row[aria-selected="true"] .combo__name { font-weight: 700; }

/* The two-letter code, which is also searchable -- "TZ" finds Tanzania. On
   Windows this is what the flag emoji would have shown anyway. */
.combo__code {
  flex: none;
  min-width: 1.9rem;
  padding: 0.15rem 0.35rem;
  border-radius: 0.375rem;
  background: var(--tint);
  color: var(--ink-soft);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-align: center;
}

.combo__row.is-active .combo__code { color: var(--accent); }

.combo__empty {
  padding: 0.85rem 0.7rem;
  color: var(--ink-soft);
  font-size: 0.9375rem;
}

/* The line under a field. The hint and the error share the slot -- only one of
   the two is ever rendered -- so they share a size and position and differ
   only in colour and weight. */
.field__hint,
.field__error {
  margin: 0.4rem 0 0;
  padding-left: 0.15rem;
  font-size: 0.8125rem;
  line-height: 1.45;
}

.field__hint {
  color: var(--ink-soft);
  font-weight: 500;
}

.field__error {
  color: var(--red-deep);
  font-weight: 700;
}

/* --red-deep is legible on porcelain but muddy on navy, so dark mode lifts it
   rather than reusing the light palette's red. */
:root:not([data-theme="light"]) .field__error { color: #FF8A8A; }

/* ---- Settings cards ---------------------------------------------------- */
/* A hairline that brightens toward the middle and throws a soft bloom, so the
   sections read as separate without a hard rule across the column. */
.divider {
  position: relative;
  width: 100%;
  height: 2px;
  margin: 2rem 0 0.5rem;
  border: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--accent) 50%, transparent);
}

/* Two blooms rather than one: a tight bright core, and a wide soft halo. A
   single blur reads as a fuzzy line; the pair reads as light. */
.divider::before,
.divider::after {
  content: "";
  position: absolute;
  left: 8%;
  right: 8%;
  background: linear-gradient(90deg, transparent, var(--accent) 50%, transparent);
  pointer-events: none;
}

.divider::before {
  top: -1px;
  bottom: -1px;
  filter: blur(3px);
  opacity: 0.9;
}

.divider::after {
  top: -7px;
  bottom: -7px;
  filter: blur(9px);
  opacity: 0.45;
}

/* The bloom is what sells it on a dark ground. On porcelain the same glow
   reads as a smudge, so light mode keeps the line and drops the halo. */
:root[data-theme="light"] .divider { opacity: 0.7; }
:root[data-theme="light"] .divider::before { opacity: 0.5; }
:root[data-theme="light"] .divider::after { opacity: 0.18; }

.card {
  width: 100%;
  margin-top: 1.25rem;
  padding: 1.25rem;
  border-radius: 1.25rem;
  background: var(--card);
  border: 1.5px solid var(--line);
  text-align: left;
}

.card__head {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}

.card__title {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.card__pill {
  flex: none;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--tint);
  color: var(--ink-soft);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.card__pill--on {
  background: var(--current);
  color: var(--accent);
}

.email-verification__head { flex-wrap: wrap; }
.email-verification__address { overflow-wrap: anywhere; }
.card__fine.email-verification__help { margin-top: 1rem; }
#email-verification { scroll-margin-top: 1.5rem; }

.card__text {
  margin: 0 0 1rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.card__meta {
  margin: -0.5rem 0 1rem;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--ink-soft);
}

.card__meta--low { color: var(--red-deep); }
:root:not([data-theme="light"]) .card__meta--low { color: #FF8A8A; }

/* The case for turning something on, as three things you can skim rather than
   another paragraph to read. */
.why {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.7rem;
}

.why__item {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--ink);
}

.why__icon {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.1rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.card__fine {
  margin: 0 0 1rem;
  padding: 0.7rem 0.8rem;
  border-radius: 0.75rem;
  background: var(--tint);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

.card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
}

.card__actions .button { width: auto; flex: 1 1 10rem; }

/* ---- Modal ------------------------------------------------------------- */
.modal {
  width: min(100%, 26rem);
  max-height: 92dvh;
  padding: 0;
  border: 0;
  border-radius: 1.25rem;
  background: none;
  overflow: visible;
}

/* ---- Splash progress --------------------------------------------------- */
/* Scaled rather than resized: width animation relayouts on every frame, a
   transform does not, which matters while 4 MB is decoding alongside it. */
.splash-gauge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.65rem;
  width: min(15rem, 62vw);
  margin: 1.35rem auto 0;
}

.splash-gauge__track {
  width: 100%;
  height: 0.75rem;
  border-radius: 999px;
  background: var(--hairline);
  overflow: hidden;
}

.splash-gauge__fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  transform: scaleX(0);
  transform-origin: left center;
  background: linear-gradient(90deg, var(--blue), var(--red));
}

.splash-gauge__value {
  font-size: 0.75rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

[data-phase="welcome"] .splash-gauge { display: none; }

/* The page behind softens rather than just darkens, so the panel reads as the
   only thing in focus. The alert's backdrop does the same. */
.modal::backdrop {
  background: var(--scrim);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* Modals rise into place rather than snapping open. Declared here, before the
   wallet sheet's own entrance: that rule carries the same specificity, so
   order is what lets it keep its richer backdrop. */
.modal[open] .modal__panel {
  transform-origin: center center;
  animation: modal-enter 300ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.modal[open]::backdrop { animation: modal-backdrop-enter 300ms ease-out both; }

@keyframes modal-enter {
  from { opacity: 0; transform: translateY(16px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes modal-backdrop-enter {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .modal[open] .modal__panel,
  .modal[open]::backdrop { animation: none; }
}

.modal__panel {
  display: flex;
  flex-direction: column;
  max-height: 92dvh;
  border-radius: 1.25rem;
  background: var(--card);
  border: 1.5px solid var(--line);
  box-shadow: 0 1.5rem 3rem var(--scrim);
  overflow: hidden;
}

.modal__head {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 1.25rem 1.25rem 0.5rem;
}

.modal__title {
  flex: 1;
  margin: 0;
  font-size: 1.125rem;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.modal__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  margin: -0.25rem -0.25rem 0 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--tint);
  color: var(--ink-soft);
  cursor: pointer;
}

#modal-withdraw .modal__head {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr) 2rem;
}

#withdraw-title {
  grid-column: 2;
  text-align: center;
}

#modal-withdraw .modal__close { grid-column: 3; }

.modal__close svg {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* The body scrolls, so the title and the buttons stay put on a short screen. */
.modal__body {
  padding: 0.5rem 1.25rem 1rem;
  overflow-y: auto;
}

/* For a modal that asks rather than offers: a short statement reads better
   centred than ragged, and it sits under the title as one block. */
.modal__body--centred { text-align: center; }
.modal__body--centred .modal__text { text-wrap: balance; }

/* ---- Glowing scrollbar ------------------------------------------------- */
/* Every scroller in the app shares one bar, so the drawer and the modals do
   not each invent their own. Firefox gets the thin coloured fallback; where
   ::-webkit-scrollbar exists the gradient thumb below replaces it. Add a new
   scroller to both lists to opt it in. */
.modal__body,
.menu__nav {
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}

@supports selector(::-webkit-scrollbar) {
  .modal__body,
  .menu__nav {
    scrollbar-width: auto;
    scrollbar-color: auto;
  }

  .modal__body::-webkit-scrollbar,
  .menu__nav::-webkit-scrollbar { width: 10px; }

  .modal__body::-webkit-scrollbar-track,
  .menu__nav::-webkit-scrollbar-track {
    margin-block: 6px;
    border-radius: 999px;
    background: var(--tint);
  }

  .modal__body::-webkit-scrollbar-thumb,
  .menu__nav::-webkit-scrollbar-thumb {
    border: 2px solid transparent;
    border-radius: 999px;
    background: linear-gradient(180deg, #4C94FF, #8A81F8 55%, #F45C75) padding-box;
    box-shadow: inset 0 0 5px rgba(200, 222, 255, 0.65), 0 0 6px rgba(76, 148, 255, 0.45);
  }

  .modal__body::-webkit-scrollbar-thumb:hover,
  .menu__nav::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, #80B5FF, #A89FFF 55%, #FF8A99) padding-box;
    box-shadow: inset 0 0 6px rgba(230, 240, 255, 0.8), 0 0 8px rgba(76, 148, 255, 0.65);
  }

  .modal__body::-webkit-scrollbar-button,
  .menu__nav::-webkit-scrollbar-button { display: none; width: 0; height: 0; }

  .modal__body::-webkit-scrollbar-corner,
  .menu__nav::-webkit-scrollbar-corner { background: transparent; }
}

.modal__text {
  margin: 0 0 1rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.modal__actions {
  display: flex;
  gap: 0.65rem;
  padding: 1rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--hairline);
}

.modal__actions .button { width: auto; flex: 1; margin-top: 0; }

/* ---- Two-step verification --------------------------------------------- */
/* Always white: a QR rendered light-on-dark fails to scan in a good number of
   apps, and this one only has to work once. */
.qr {
  width: min(100%, 15rem);
  margin: 1.5rem auto 0.5rem;
  padding: 0.85rem;
  border-radius: 1rem;
  background: #fff;
}

.qr svg { display: block; width: 100%; height: auto; }
.qr svg path { fill: #000; }

.field__input--code {
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: 0.32em;
}

.reveal {
  width: 100%;
  margin-top: 0.5rem;
  text-align: left;
}

/* Without script the panel is simply open, so a button that could not do
   anything is not shown at all. */
.reveal__summary { display: none; }

.js .reveal__summary {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0;
  border: 0;
  background: none;
  color: var(--accent);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  cursor: pointer;
}

.reveal__caret {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.28s var(--ease);
}

.reveal.is-open .reveal__caret { transform: rotate(90deg); }

/* 0fr -> 1fr is what makes an unknown height animatable, the same trick the
   splash greeting uses. The inner element is what clips during the slide. */
.reveal__panel {
  display: grid;
  grid-template-rows: 1fr;
  opacity: 1;
  transition: grid-template-rows 0.3s var(--ease), opacity 0.24s var(--ease);
}

.js .reveal__panel {
  grid-template-rows: 0fr;
  opacity: 0;
}

.js .reveal.is-open .reveal__panel {
  grid-template-rows: 1fr;
  opacity: 1;
}

.reveal__inner { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .reveal__panel,
  .reveal__caret { transition: none; }
}

.reveal__text {
  margin: 0.25rem 0 0.5rem;
  font-size: 0.875rem;
  color: var(--ink-soft);
}

.reveal__key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.5rem;
}

.reveal__key span {
  padding: 0.3rem 0.5rem;
  border-radius: 0.5rem;
  background: var(--tint);
  color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}

.codes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
  width: 100%;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
  counter-reset: code;
}

.codes__item {
  padding: 0.6rem 0.5rem;
  border-radius: 0.625rem;
  background: var(--tint);
  color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-align: center;
}

.check {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  width: 100%;
  margin: 1.5rem 0 0.25rem;
  text-align: left;
  cursor: pointer;
}

.check__box {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.1rem 0 0;
  accent-color: var(--accent);
}

.check__text {
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--ink);
}

/* The consent box at the foot of a form: a field like the others, so it
   turns red the same way when it is the thing holding the form up. */
.consent { width: 100%; margin-top: 0.5rem; }
.check--consent { margin: 0.75rem 0 0.35rem; }
.check--consent .check__text { font-size: 0.875rem; }
.check--consent .check__text strong { font-weight: 800; color: var(--accent); }
.consent--bad .check__text { color: var(--red); }
:root:not([data-theme="light"]) .consent--bad .check__text { color: #FF8A8A; }
.consent--bad .check__box { outline: 2px solid var(--red); outline-offset: 1px; border-radius: 3px; }

/* ---- Notice banner --------------------------------------------------- */
.banner {
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  width: 100%;
  margin-top: 1.75rem;
  padding: 1rem;
  border-radius: 1rem;
  background: var(--card);
  text-align: left;
}

.banner__icon {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.1rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.banner__title {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
}

.banner__text {
  margin: 0.25rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* ---- Motion preferences ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .loader__dot { animation-duration: 2.4s; }
  .stage,
  .mark__img,
  .loader,
  .greeting,
  .dock,
  .button { transition-duration: 0.01ms; }
}

/* ---- Button loading state -------------------------------------------- */
/* The label and the dots occupy the same grid cell, so the button never
   changes size when it swaps between them. */
.button__label,
.button__dots {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.18s var(--ease);
}

.button__label { opacity: 1; }

.button__dots {
  gap: 0.4rem;
  opacity: 0;
  pointer-events: none;
}

.button__dots i {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
}

.button.is-busy { cursor: progress; }

.button.is-busy .button__label { opacity: 0; }

.button.is-busy .button__dots {
  opacity: 1;
  animation: none;
}

.button.is-busy .button__dots i {
  animation: pulse 1.35s var(--ease) infinite;
}

.button.is-busy .button__dots i:nth-child(2) { animation-delay: 0.18s; }
.button.is-busy .button__dots i:nth-child(3) { animation-delay: 0.36s; }

/* Holds its pressed-down look rather than springing back mid-navigation. */
.button.is-busy:active { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .button.is-busy .button__dots i { animation-duration: 2.4s; }
}

/* ---- Password reveal ------------------------------------------------- */
.field__input--reveal { padding-right: 3rem; }

.field__toggle {
  position: absolute;
  right: 0.35rem;
  display: grid;
  place-items: center;
  width: 2.75rem;      /* full-height tap target, not just the glyph */
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 0.7rem;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.field__toggle:hover { color: var(--ink); }

.field__toggle:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -1px;
}

.field__toggle[aria-pressed="true"] { color: var(--accent); }

.field__eye {
  width: 1.3rem;
  height: 1.3rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The slash means "hidden again if you press me", so it shows only once the
   password is already visible. */
.field__slash {
  opacity: 0;
  transition: opacity 0.15s var(--ease);
}

.field__toggle[aria-pressed="true"] .field__slash { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .field__slash { transition-duration: 0.01ms; }
}

/* ---- Alert ------------------------------------------------------------ */
/* Modelled on the iOS system alert: a narrow frosted card, centred, with the
   action separated by a hairline rule. */
.alert {
  /* Matches what showModal applies, so the pre-script open state and the real
     modal sit in exactly the same place. Without this the alert renders in the
     document flow first and visibly jumps from the top to the centre. */
  position: fixed;
  inset: 0;
  margin: auto;
  width: 270px;
  height: fit-content;
  max-width: calc(100vw - 3rem);
  max-height: calc(100dvh - 3rem);
  padding: 0;
  border: 0;
  border-radius: 14px;
  background: var(--glass);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  color: var(--ink);
  font-family: inherit;
  overflow: hidden;
  box-shadow: 0 1rem 3rem rgba(10, 22, 51, 0.28);
}

/* The dialog is focused programmatically so the OK button does not light up.
   It is a container, not a control, so it needs no ring of its own. */
.alert:focus,
.alert:focus-visible { outline: none; }

.alert::backdrop {
  background: var(--scrim);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

.alert[open] {
  animation: alert-in 0.22s var(--ease);
}

.alert[open]::backdrop {
  animation: backdrop-in 0.22s var(--ease);
}

/* iOS alerts settle in from slightly oversized rather than growing from zero. */
@keyframes alert-in {
  from { opacity: 0; transform: scale(1.14); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.alert__body {
  padding: 1.25rem 1rem 1.15rem;
  text-align: center;
}

.alert__title {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

.alert__text {
  margin: 0.3rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ink-soft);
}

.alert__list {
  margin: 0.45rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.4rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  text-align: left;
}

.alert__actions {
  margin: 0;
  border-top: 1px solid var(--hairline);
}

.alert__ok {
  display: block;
  width: 100%;
  min-height: 2.75rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font-family: inherit;
  font-size: 1.0625rem;
  font-weight: 700;
  cursor: pointer;
}

.alert__ok:active { background: var(--tint); }

.alert__ok:focus-visible {
  outline: none;
  background: var(--current);
  box-shadow: inset 0 0 0 2px var(--accent);
}

@media (prefers-reduced-motion: reduce) {
  .alert[open],
  .alert[open]::backdrop { animation-duration: 0.01ms; }
}

/* ---- Secondary actions ------------------------------------------------ */
/* The dock now carries a primary button plus a quiet alternative. */
.dock {
  display: grid;
  gap: 0.25rem;
  justify-items: center;
}

.dock__quiet {
  display: grid;
  place-items: center;
  min-height: 2.75rem;
  padding: 0 0.75rem;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  font-weight: 700;
  text-decoration: none;
}

.dock__quiet:active { color: var(--accent); }

.dock__quiet:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 0.75rem;
}

.switch {
  margin: 1.5rem 0 0;
  font-size: 0.9375rem;
  color: var(--ink-soft);
  text-align: center;
}

.switch__link,
.switch__button {
  color: var(--accent);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  text-decoration: none;
}

.switch__button {
  min-height: 2.75rem;
  padding: 0 0.75rem;
  border: 0;
  background: none;
  cursor: pointer;
}

.switch__link:focus-visible,
.switch__button:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 0.5rem;
}

/* ---- Top bar ---------------------------------------------------------- */
.topbar {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 3.5rem;
  padding: calc(env(safe-area-inset-top) + 0.5rem) 0.75rem 0.5rem;
}

.topbar__title {
  flex: 1;
  min-width: 0;
  margin: 0 0 0 0.75rem;
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 1.3;
  color: var(--heading);
  overflow-wrap: anywhere;
}

.topbar__menu {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 0.85rem;
  background: none;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Scoped to the direct child: the animated hamburger next to it is a player
   that draws its own svg, and this rule's stroke would repaint it. */
.topbar__menu > svg {
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
}

/* The animated hamburger. Both icons sit in the button and exactly one shows.
   The player only exists once script has upgraded the element, and a looping
   icon is precisely what someone asking for less motion turned off, so the
   static bars stay the fallback for both -- and stay the only icon that can
   morph into the close X, which the player has no frames for. */
.topbar__menu-anim { display: none; }

/* Larger than the static icon's 1.5rem because it is not measuring the same
   thing: the bars fill the svg's viewBox, but occupy only the middle ~44% of
   the lottie's 400x400 canvas. Matching the box sizes would draw the animated
   bars a third smaller than the ones they replace. */
.js .topbar__menu-anim {
  display: block;
  width: 2.5rem;
  height: 2.5rem;
}

.js .topbar__menu > svg { display: none; }

.topbar__menu-anim dotlottie-player {
  display: block;
  width: 100%;
  height: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .js .topbar__menu-anim { display: none; }
  .js .topbar__menu > svg { display: block; }
}

/* Dark mode only. The bars are already near-white at full opacity, so this is
   not fixing a dim icon -- it is giving a flat one the same lit treatment the
   drawer edges have, which is what makes it read as deliberate rather than
   just pale. A halo also survives the busy artwork on the loops page, where a
   plain white line lands on whatever the card behind it happens to be.
   Two shadows: a tight core to thicken the bars, a wide one for the bloom.
   Light mode wants neither -- a glow on porcelain is a smudge.
   Applied to both icons, so the reduced-motion fallback is lit too. */
:root:not([data-theme="light"]) .topbar__menu-anim,
:root:not([data-theme="light"]) .topbar__menu > svg {
  filter: drop-shadow(0 0 3px rgba(127, 168, 255, 0.9))
          drop-shadow(0 0 9px rgba(76, 148, 255, 0.55));
}

.topbar__menu {
  transition: background-color 180ms ease, transform 180ms ease;
}

.topbar__menu:active {
  background: var(--tint);
  transform: scale(0.92);
}

.topbar__menu[aria-expanded="true"] { background: var(--tint); }

.menu-bar {
  transform-box: view-box;
  transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 120ms ease;
}

.menu-bar--top { transform-origin: 12px 7px; }
.menu-bar--middle { transform-origin: 12px 12px; }
.menu-bar--bottom { transform-origin: 12px 17px; }

.topbar__menu[aria-expanded="true"] .menu-bar--top {
  transform: translateY(5px) rotate(45deg);
}

.topbar__menu[aria-expanded="true"] .menu-bar--middle {
  opacity: 0;
  transform: scaleX(0.2);
}

.topbar__menu[aria-expanded="true"] .menu-bar--bottom {
  transform: translateY(-5px) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .topbar__menu, .menu-bar { transition: none; }
}

.topbar__menu:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.topbar__logo {
  display: grid;
  place-items: center;
  flex: 0 0 2.75rem;
  width: 2.75rem;
  height: 2.75rem;
  margin-left: 0.75rem;
  padding: 0.3rem;
  overflow: hidden;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--line);
  box-shadow: 0 2px 8px rgba(0, 8, 40, 0.1);
}

.topbar__logo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.panel--flush { padding-top: 0.5rem; }

/* ---- Pine wallet ------------------------------------------------------ */
.wallet { padding: 0.75rem 1.25rem calc(2rem + env(safe-area-inset-bottom)); }
.wallet__eyebrow {
  display: block;
  color: var(--accent);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.wallet-welcome { text-align: center; }
.wallet-welcome__animation {
  display: block;
  width: 11rem;
  height: 11rem;
  margin: 0.25rem auto 1rem;
}
.wallet-welcome h2 {
  max-width: 22ch;
  margin: 0.625rem auto;
  font-size: clamp(1.5rem, 6vw, 1.875rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.035em;
  color: var(--heading);
  overflow-wrap: anywhere;
}
.wallet-welcome__intro { margin: 0 auto; color: var(--ink-soft); font-size: 0.875rem; line-height: 1.6; max-width: 36ch; }
.wallet-benefits { display: grid; gap: 0.75rem; list-style: none; padding: 0; margin: 1.5rem 0; text-align: left; }
.wallet-benefits li {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  padding: 0.875rem;
  border: 1px solid var(--line);
  border-radius: 1rem;
  background: var(--card);
}
.wallet-benefits__number {
  display: grid;
  place-items: center;
  flex: 0 0 2rem;
  height: 2rem;
  border-radius: 0.625rem;
  background: var(--current);
  color: var(--accent);
  font-size: 0.6875rem;
  font-weight: 800;
}
.wallet-benefits h3 { margin: 0 0 0.25rem; font-size: 0.8125rem; font-weight: 800; }
.wallet-benefits p { margin: 0; color: var(--ink-soft); font-size: 0.75rem; line-height: 1.5; }
.wallet__action, .splash-retry button {
  display: flex;
  width: 100%;
  min-height: 3.25rem;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  padding: 0.8rem 1rem;
  border: 1px solid rgba(115, 157, 230, 0.35);
  border-radius: 1rem;
  background: linear-gradient(120deg, #0053E6, #0030A4);
  box-shadow: 0 6px 22px rgba(0, 66, 205, 0.22);
  color: #fff;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 800;
  text-decoration: none;
  cursor: pointer;
}
.wallet__action:hover { background: var(--blue-lift); }
.wallet__action:disabled { opacity: 0.65; cursor: wait; }
.wallet__action:focus-visible, .splash-retry button:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.wallet-welcome__note { margin: 0.875rem 0 0; color: var(--ink-soft); font-size: 0.6875rem; }
.wallet__error { color: var(--red-deep); font-size: 0.8125rem; line-height: 1.5; }
.wallet__unavailable { padding: 2rem 0; text-align: center; }
.wallet__unavailable h2 { color: var(--heading); font-size: 1.5rem; }
.wallet__unavailable p { color: var(--ink-soft); line-height: 1.6; }
.wallet-balance {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 18rem;
  isolation: isolate;
  overflow: hidden;
  margin-top: 1rem;
  padding: 1.5rem;
  border: 1px solid rgba(126, 174, 255, 0.4);
  border-radius: 1.5rem;
  background-color: #07162E;   /* fallback, and the ground the artwork sits on */
  box-shadow: 0 12px 30px rgba(0, 35, 99, 0.2);
  color: #fff;
}

/* The artwork carries the card, so it gets its own layer: a filter here lifts
   the image without ever touching the balance text, which stays above it.
   The gradient is only a scrim -- the balance sits left of centre, where the
   image's own glow lines run, so the left edge is darkened hardest and the
   right is left almost untouched. The parent's `isolation` is what keeps this
   behind the text instead of behind the whole card. */
.wallet-balance::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(100deg, rgba(4, 13, 31, 0.8) 0%, rgba(5, 18, 41, 0.5) 45%, rgba(6, 22, 48, 0.08) 100%),
    url("../images/wallet_bg.png");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  filter: brightness(1.2) saturate(1.05);
}
.wallet-balance__top { display: flex; align-items: center; min-height: 1.625rem; padding-right: 5rem; }
.wallet-balance .wallet__eyebrow { color: #BBD5FF; font-size: 1.25rem; font-weight: 800; line-height: 1.3; letter-spacing: -.02em; text-transform: none; }
.wallet-balance h2 { margin: 0 0 0.3rem; color: #BBD5FF; font-size: 0.8125rem; font-weight: 500; }
.wallet-balance__label { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.3rem; }
.wallet-balance__label h2 { margin: 0; }
.wallet-balance__visibility { display: grid; place-items: center; flex: none; width: 2rem; height: 2rem; margin: -0.4rem 0; padding: 0.35rem; border: 0; border-radius: 50%; color: #BBD5FF; background: transparent; cursor: pointer; }
.wallet-balance__visibility[hidden] { display: none; }
.wallet-balance__visibility:hover { background: rgba(187, 213, 255, 0.12); }
.wallet-balance__visibility:focus-visible { outline: 2px solid #BBD5FF; outline-offset: 2px; }
.wallet-balance__visibility svg { width: 1.2rem; height: 1.2rem; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.wallet-balance__mask, .wallet-balance__eye-slash { display: none; }
[data-wallet-balances-hidden="true"] .wallet-balance__number { display: none; }
[data-wallet-balances-hidden="true"] .wallet-balance .wallet-balance__mask { display: inline; }
[data-wallet-balances-hidden="true"] .wallet-balance .wallet-balance__eye-slash { display: block; }
.wallet-balance__amount { margin: 0; font-size: clamp(2rem, 10vw, 3rem); font-weight: 800; letter-spacing: -0.045em; line-height: 1.2; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.wallet-balance__equivalent { margin: 0.5rem 0 0; color: #BBD5FF; font-size: 0.9375rem; font-weight: 700; line-height: 1.5; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.wallet-balance__details { display: grid; flex: 1; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 0.75rem; row-gap: 1.75rem; margin-top: 2rem; }
.wallet-balance__values { min-width: 0; }
.wallet-balance__owner { grid-column: 1; grid-row: 2; margin: 0; min-width: 0; color: #BBD5FF; font-size: 0.75rem; overflow-wrap: anywhere; }
.wallet-card-actions { grid-column: 2; grid-row: 1 / span 2; align-self: end; display: flex; flex-direction: column; }
.wallet-balance .wallet-add {
  padding: 0.45rem 0.35rem;
  gap: 0.25rem;
  border: 1px solid rgba(216, 231, 255, 0.32);
  background: linear-gradient(145deg, rgba(216, 231, 255, 0.16), rgba(216, 231, 255, 0.05));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 4px 12px rgba(0, 8, 28, 0.18);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transition: background 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.wallet-balance .wallet-add:not(:disabled):hover {
  border-color: rgba(216, 231, 255, 0.6);
  background: linear-gradient(145deg, rgba(216, 231, 255, 0.24), rgba(216, 231, 255, 0.1));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 4px 14px rgba(0, 8, 28, 0.24);
}
.wallet-balance .wallet-add__animation,
.wallet-balance .wallet-add__fallback { width: 2.5rem; height: 2.5rem; transform: scale(1.44); }
.wallet-add--deposit { position: absolute; top: 1.25rem; right: 1.5rem; }
.wallet-balance .wallet-add { width: 4.25rem; }
.wallet-add--history { position: absolute; top: 50%; right: 1.5rem; transform: translateY(-50%); height: 3.5rem; align-content: center; text-decoration: none; }
.wallet-add--history .wallet-history__loading { display: none; }
.wallet-add--history .wallet-history__icon { transform: scale(1.9); }
.wallet-add--history.is-loading .wallet-history__icon { display: none; }
.wallet-add--history.is-loading .wallet-history__loading { display: block; }
.wallet-add--withdraw:disabled { cursor: default; opacity: 1; -webkit-text-fill-color: currentColor; }
.wallet-add { display: grid; justify-items: center; gap: 0.15rem; flex: none; padding: 0.25rem 0.5rem; border: 0; border-radius: 0.75rem; background: transparent; color: #D8E7FF; font: inherit; font-size: 0.6875rem; font-weight: 700; cursor: pointer; }
.wallet-add:not(:disabled):hover { background: rgba(126, 174, 255, 0.12); }
.wallet-add:focus-visible { outline: 2px solid #BBD5FF; outline-offset: 3px; }
.wallet-add__animation { display: block; width: 3rem; height: 3rem; transform: scale(1.2); pointer-events: none; }
.wallet-add__fallback { display: none; width: 3rem; height: 3rem; transform: scale(1.2); fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.wallet-deposit { width: min(calc(100% - 2rem), 26rem); }
.wallet-deposit[open] .modal__panel {
  transform-origin: center center;
  animation: deposit-enter 320ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.wallet-deposit[open]::backdrop {
  background: radial-gradient(ellipse at 50% 40%, rgba(35, 98, 215, 0.38), rgba(8, 30, 85, 0.76));
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: deposit-backdrop-enter 320ms ease-out both;
}
@keyframes deposit-enter {
  from { opacity: 0; transform: translateY(18px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes deposit-backdrop-enter {
  from { opacity: 0; }
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .wallet-deposit[open] .modal__panel,
  .wallet-deposit[open]::backdrop { animation: none; }
}
.wallet-deposit__options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; padding: 0.25rem 0 0.5rem; }
.wallet-deposit__options > :only-child { grid-column: 1 / -1; }
.wallet-deposit__option { display: flex; flex-direction: column; align-items: flex-start; gap: 0.6rem; min-width: 0; min-height: 15.5rem; padding: 1rem; overflow: hidden; border: 1px solid rgba(225, 191, 110, 0.35); border-radius: 1rem; background-color: #0A1424; background-size: cover; background-position: center; background-repeat: no-repeat; box-shadow: 0 6px 18px rgba(0, 8, 25, 0.2); color: #FFFFFF; font: inherit; text-align: left; opacity: 1; -webkit-text-fill-color: currentColor; }
.wallet-deposit__option--crypto { background-image: linear-gradient(180deg, rgba(6, 14, 27, 0.12) 0%, rgba(6, 14, 27, 0.25) 30%, rgba(6, 14, 27, 0.87) 65%, #07101E 100%), url("../images/deposit-crypto.png"); }
.wallet-deposit__option--local { background-image: linear-gradient(180deg, rgba(6, 14, 27, 0.12) 0%, rgba(6, 14, 27, 0.25) 30%, rgba(6, 14, 27, 0.87) 65%, #07101E 100%), url("../images/deposit-local.png"); }
a.wallet-deposit__option { position: relative; text-decoration: none; cursor: pointer; transition: border-color 180ms ease, box-shadow 180ms ease; }
a.wallet-deposit__option:hover { border-color: #F5DFAB; box-shadow: 0 6px 22px rgba(225, 191, 110, 0.18); }
a.wallet-deposit__option:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.wallet-deposit__loading { display: none; position: absolute; inset: 0; z-index: 1; flex-direction: column; align-items: center; justify-content: center; gap: 1rem; padding: 1rem; border-radius: inherit; background: rgba(5, 14, 30, 0.72); backdrop-filter: blur(2px); color: #FFFFFF; font-size: 0.8125rem; font-weight: 700; }
.wallet-deposit__option.is-loading { cursor: wait; }
.wallet-deposit__option.is-loading > :not(.wallet-deposit__loading) { visibility: hidden; }
.wallet-deposit__option.is-loading .wallet-deposit__loading { display: flex; }
.wallet-deposit__loading .loader__dot { background: #91BEFF; }
.wallet-deposit__loading .loader__dot:nth-child(2) { background: #F5DFAB; }
.wallet-deposit__loading .loader__dot:nth-child(3) { background: #A7F3D0; }
@media (prefers-reduced-motion: reduce) {
  .wallet-deposit__loading .loader__dot { animation: none; }
}
.wallet-deposit__name { margin-top: auto; font-size: 0.875rem; font-weight: 800; text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); }
.wallet-deposit__description { min-height: 2.25rem; margin-bottom: 0.25rem; font-size: 0.75rem; line-height: 1.5; color: #D6E3F5; }
.wallet-deposit__badge { margin-top: 0.25rem; padding: 0.2rem 0.5rem; border: 1px solid rgba(255, 226, 156, 0.3); border-radius: 999px; background: rgba(255, 226, 156, 0.08); font-size: 0.625rem; font-weight: 700; color: #F5DFAB; }
.wallet-deposit__hints { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.wallet-deposit__hints h3 { margin: 0 0 0.5rem; font-size: 0.8125rem; font-weight: 800; color: var(--ink); }
.wallet-deposit__hints p,
.wallet-deposit__hints li { font-size: 0.75rem; line-height: 1.6; color: var(--ink-soft); }
.wallet-deposit__hints p { margin: 0 0 0.65rem; }
.wallet-deposit__hints ul { margin: 0; padding-left: 1rem; }
.wallet-deposit__hints li + li { margin-top: 0.35rem; }
.wallet-deposit__hints li::marker { color: var(--accent); }

/* Local deposit: a short search followed by country-specific results. */
.local-deposit { padding: 1.5rem 1.25rem calc(2rem + env(safe-area-inset-bottom)); }
.local-deposit__search,
.local-deposit__result { text-align: center; padding: 1.5rem 0; }
.hosted-checkout__details { padding: 1.5rem 0; }
.hosted-checkout__details h2 { margin-bottom: 1rem; }
.hosted-checkout #checkout-heading { outline: none; }
.hosted-checkout .is-checking span { transform: scaleX(0.5); animation: checkout-progress 1.6s ease-in-out infinite alternate; }
@keyframes checkout-progress { from { transform: translateX(-60%) scaleX(0.5); } to { transform: translateX(80%) scaleX(0.5); } }
@media (prefers-reduced-motion: reduce) { .hosted-checkout .is-checking span { animation: none; } }
.local-deposit [hidden] { display: none !important; }
.local-deposit__animation { display: block; width: min(100%, 16rem); aspect-ratio: 625 / 481; margin: 0 auto 1rem; }
.local-deposit__eyebrow { margin: 0 0 0.75rem; color: var(--accent); font-size: 0.6875rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; }
.local-deposit h2 { margin: 0 auto 0.75rem; max-width: 24rem; color: var(--ink); font-size: clamp(1.35rem, 5vw, 1.75rem); line-height: 1.3; letter-spacing: -0.025em; }
#deposit-result-title:focus { outline: none; }
.local-deposit__message { margin: 0 auto 1rem; max-width: 23rem; color: var(--ink-soft); font-size: 0.875rem; line-height: 1.7; }
.local-deposit__notice { margin: 0.75rem 0 0; color: var(--ink-soft); font-size: 0.75rem; line-height: 1.6; }
.local-deposit__progress { width: min(100%, 14rem); height: 4px; margin: 1.5rem auto 0; overflow: hidden; border-radius: 99px; background: var(--tint); }
.local-deposit__progress span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #4C94FF, #8A81F8); transform: scaleX(0); transform-origin: left; }
.local-deposit__timer { margin: 0.65rem 0 0; font-size: 0.6875rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.local-deposit__result-icon { display: grid; place-items: center; width: 3.5rem; height: 3.5rem; margin: 0 auto 1.25rem; background: #D1FAE5; color: #047857; border-radius: 50%; }
.local-deposit__result-icon--empty { background: var(--current); color: var(--accent); }
.local-deposit__result-icon svg { width: 1.9rem; height: 1.9rem; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.local-deposit__networks { display: grid; gap: 0.75rem; margin: 1.5rem 0; padding: 0; list-style: none; text-align: left; }
.local-deposit__network { display: flex; align-items: center; gap: 1rem; padding: 1rem; border: 1px solid var(--line); border-radius: 1rem; background: var(--card); color: var(--ink); font-size: 0.9375rem; font-weight: 800; }
.local-deposit__network-logo { position: relative; display: block; flex: 0 0 5rem; width: 5rem; height: 3.5rem; overflow: hidden; border-radius: 0.65rem; background: #fff; }
.local-deposit__network-logo img { position: absolute; inset: 0; display: block; width: 4rem; height: 2.5rem; margin: auto; object-fit: contain; object-position: 50% 50%; }
.local-deposit__network--unavailable { border-style: dashed; color: var(--ink-soft); }
.local-deposit__network--unavailable img { filter: grayscale(1); opacity: 0.6; }
.local-deposit__network-details { display: grid; justify-items: start; gap: 0.4rem; min-width: 0; }
.local-deposit__network-status { padding: 0.2rem 0.55rem; border: 1px solid var(--line); border-radius: 999px; font-size: 0.6875rem; font-weight: 700; line-height: 1.4; }
.local-deposit__network-name { min-width: 0; }
.local-deposit__network--select { width: 100%; text-align: left; font-family: inherit; cursor: pointer; transition: border-color 180ms ease, background 180ms ease; }
.local-deposit__network--select:hover { border-color: var(--accent); background: var(--current); }
.local-deposit__network--select:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.payment-deposit__brand { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-bottom: 1.25rem; }
.payment-deposit__brand img { display: block; width: 5.5rem; height: 4rem; padding: 0.65rem; border-radius: 1rem; background: #fff; object-fit: contain; }
.payment-deposit__brand strong { color: var(--ink); font-size: 1rem; }
.payment-deposit__intro, .payment-deposit__privacy { margin: 0 0 1rem; font-size: 0.8125rem; line-height: 1.6; color: var(--ink-soft); }
.payment-deposit__fields { display: flex; flex-direction: column; min-width: 0; margin: 0; padding: 0; border: 0; }
.payment-deposit__fields label { margin: 1rem 0 0.5rem; color: var(--ink); font-size: 0.8125rem; font-weight: 800; }
.payment-deposit__fields label:first-child { margin-top: 0; }
.payment-deposit__fields label span { color: var(--ink-soft); font-weight: 500; }
.payment-deposit__fields input { box-sizing: border-box; width: 100%; min-width: 0; padding: 0.9rem 1rem; border: 1px solid var(--line); border-radius: 0.8rem; background: var(--ground); color: var(--ink); font: inherit; font-size: 1rem; font-variant-numeric: tabular-nums; }
.payment-deposit__fields input:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.payment-deposit__fields #payment-amount { font-weight: 800; }
.payment-deposit__fields input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.payment-deposit__fields input[type="number"]::-webkit-inner-spin-button,
.payment-deposit__fields input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.payment-deposit__fields small { margin-top: 0.45rem; color: var(--ink-soft); font-size: 0.6875rem; line-height: 1.6; }
.payment-deposit__estimate { margin: 0.6rem 0 0; color: var(--accent); font-size: 0.75rem; line-height: 1.5; }
.payment-deposit__estimate:empty { display: none; }
.payment-deposit__estimate:not(:empty) { animation: payment-credit-enter 280ms cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes payment-credit-enter {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .payment-deposit__estimate:not(:empty) { animation: none; }
}
.payment-deposit__fees { margin: 1rem 0; padding: 0.8rem 1rem; border-radius: 0.8rem; background: var(--current); color: var(--ink-soft); font-size: 0.75rem; line-height: 1.65; }
.payment-deposit__fees strong { color: var(--ink); }
.payment-deposit__submit, .payment-deposit__check, .payment-deposit__wallet { display: block; width: 100%; padding: 0.9rem 1rem; border: 0; border-radius: 999px; background: var(--blue); color: #fff; font: inherit; font-size: 0.875rem; font-weight: 800; text-align: center; text-decoration: none; cursor: pointer; }
.payment-deposit__submit:disabled, .payment-deposit__check:disabled { opacity: 0.6; cursor: wait; }
.payment-deposit__check, .payment-deposit__wallet { margin-top: 0.75rem; background: var(--tint); color: var(--ink); }
.payment-deposit__status { margin: 1rem 0 0; padding: 1rem; border-radius: 0.8rem; color: var(--ink); background: var(--current); font-size: 0.8125rem; line-height: 1.65; }
.payment-deposit__status.is-error { border: 1px solid var(--line); }
.payment-deposit__countdown { margin: 1rem 0 0; color: var(--accent); font-size: 0.8125rem; font-weight: 800; line-height: 1.6; text-align: center; font-variant-numeric: tabular-nums; }
.payment-deposit__privacy { margin: 1rem 0 0; font-size: 0.6875rem; text-align: center; }
.payment-deposit [hidden] { display: none !important; }
.payment-deposit__waiting { display: grid; place-items: center; min-height: 9rem; margin: 0.5rem 0 1rem; }
.payment-deposit__waiting dotlottie-player { display: block; width: 9rem; height: 9rem; }
.payment-deposit__waiting-fallback { display: none; width: 1.5rem; height: 1.5rem; border: 0.3rem solid var(--line); border-top-color: var(--accent); border-radius: 50%; }
@media (prefers-reduced-motion: reduce) {
  .payment-deposit__waiting dotlottie-player { display: none; }
  .payment-deposit__waiting-fallback { display: block; }
}
.local-deposit__network-live { display: grid; place-items: center; flex: 0 0 3rem; width: 3rem; height: 3rem; margin-left: auto; }
.local-deposit__network-live dotlottie-player { display: block; width: 3rem; height: 3rem; }
.local-deposit__hints { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--line); text-align: left; }
.local-deposit__hints h3 { margin: 0 0 0.75rem; color: var(--ink); font-size: 0.875rem; font-weight: 800; }
.local-deposit__hints ul { margin: 0; padding-left: 1.1rem; color: var(--ink-soft); font-size: 0.8125rem; line-height: 1.7; }
.local-deposit__hints li + li { margin-top: 0.65rem; }
.local-deposit__hints li::marker { color: var(--accent); }
.local-deposit__network-live-fallback { display: none; width: 0.65rem; height: 0.65rem; border-radius: 50%; background: #704cff; box-shadow: 0 0 0 0.3rem rgba(112, 76, 255, 0.18); }
.local-deposit__back { display: inline-block; margin-top: 1.5rem; padding: 0.75rem 1rem; border-radius: 0.75rem; color: var(--accent); font-size: 0.8125rem; font-weight: 800; text-decoration: none; }
.local-deposit__back:hover { background: var(--current); }
.local-deposit__back:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .local-deposit__network-live dotlottie-player { display: none; }
  .local-deposit__network-live-fallback { display: block; }
  .wallet-add__animation { display: none; }
  .wallet-add__fallback { display: block; }
}
@media (max-width: 360px) {
  .wallet-deposit__options { grid-template-columns: 1fr; }
}


.wallet-creating {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 1.5rem;
  border: 0;
  background: var(--ground);
  color: var(--ink);
}
.wallet-creating:focus { outline: none; }
.wallet-creating::backdrop { background: var(--ground); }
.wallet-creating__content { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100%; max-width: 23rem; margin: auto; text-align: center; }
.wallet-creating__logo { display: grid; place-items: center; width: 7rem; height: 7rem; padding: 0.75rem; margin-bottom: 2rem; border-radius: 50%; background: #fff; box-shadow: 0 0 45px rgba(76, 148, 255, 0.25); }
.wallet-creating__logo img { display: block; width: 100%; height: auto; }
.wallet-creating h2 { margin: 1.5rem 0 0.5rem; font-size: 1.5rem; letter-spacing: -0.025em; color: var(--heading); }
.wallet-creating p { color: var(--ink-soft); font-size: 0.875rem; line-height: 1.6; }
.wallet-creating__progress { width: 11rem; height: 3px; margin-top: 1.5rem; overflow: hidden; border-radius: 999px; background: var(--line); }
.wallet-creating__progress span { display: block; width: 100%; height: 100%; transform-origin: left; background: linear-gradient(90deg, #4C94FF, #F45C75); }
.wallet-creating[open] .wallet-creating__progress span { animation: wallet-create-progress 7s linear both; }
@keyframes wallet-create-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) { .wallet-creating[open] .wallet-creating__progress span { animation: none; } }
/* ---- Welcome, after sign up -------------------------------------------- */
/* The same shape as the wallet's creating screen, so the two moments read as
   one family. The bar's run time is set from the page, in --welcome-seconds,
   so the script and the animation cannot drift apart. */
.welcome-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  max-width: 23rem;
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 1.5rem) 1.5rem calc(env(safe-area-inset-bottom) + 1.5rem);
  text-align: center;
}
.welcome-screen__logo { display: grid; place-items: center; width: 7rem; height: 7rem; padding: 0.75rem; margin-bottom: 2rem; border-radius: 50%; background: #fff; box-shadow: 0 0 45px rgba(76, 148, 255, 0.25); }
.welcome-screen__logo img { display: block; width: 100%; height: auto; }
.welcome-screen__eyebrow { margin: 0; font-size: 0.75rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft); }
.welcome-screen h1 { margin: 0.5rem 0 0.5rem; font-size: clamp(1.75rem, 8vw, 2.25rem); font-weight: 800; letter-spacing: -0.03em; line-height: 1.15; color: var(--heading); }
.welcome-screen p { margin: 0; max-width: 28ch; color: var(--ink-soft); font-size: 0.9375rem; line-height: 1.6; }
.welcome-screen .loader { margin-top: 1.75rem; }
.welcome-screen__progress { width: 11rem; height: 3px; margin-top: 1.5rem; overflow: hidden; border-radius: 999px; background: var(--line); }
.welcome-screen__progress span { display: block; width: 100%; height: 100%; transform-origin: left; background: linear-gradient(90deg, #4C94FF, #F45C75); animation: welcome-progress var(--welcome-seconds, 15s) linear both; }
@keyframes welcome-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.welcome-screen__hint { margin-top: 1.25rem; font-size: 0.8125rem; }
@media (prefers-reduced-motion: reduce) { .welcome-screen__progress span { animation: none; transform: scaleX(1); } }

.splash-retry { max-width: 20rem; text-align: center; color: var(--ink-soft); font-size: 0.875rem; line-height: 1.5; }
.stage .loader[hidden] { display: none; }

/* ---- Pine Loops offers ------------------------------------------------ */
.loops {
  padding: 1rem 1.25rem calc(2rem + env(safe-area-inset-bottom));
}

/* ---- Tabs -------------------------------------------------------------- */
/* Without script the strip cannot switch anything, so it is not shown at all
   and every panel stays open -- a page that reads straight through instead of
   a control that does nothing. */
.tabs__list {
  position: relative;
  display: none;
  margin-bottom: 1.25rem;
}

.js .tabs__list {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}

/* The rail, and over it the lit indicator. Half width and one translate is
   enough while there are two tabs; a third would want its width and offset
   driven from the tab count instead. */
.tabs__list::before,
.tabs__list::after {
  content: "";
  position: absolute;
  bottom: 0;
  height: 1px;
  pointer-events: none;
}

.tabs__list::before {
  left: 0;
  right: 0;
  background: var(--hairline);
}

.tabs__list::after {
  left: 0;
  width: 50%;
  height: 2px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #4C94FF 25%, #8A81F8 55%, #F45C75 85%, transparent);
  box-shadow: 0 0 8px rgba(76, 148, 255, 0.5);
  transform: translateX(0);
  transition: transform 300ms var(--ease);
}

.tabs__list[data-active="1"]::after { transform: translateX(100%); }

.tabs__tab {
  min-height: 2.75rem;
  padding: 0.5rem 0.35rem 0.7rem;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1.3;
  cursor: pointer;
  transition: color 180ms var(--ease);
}

.tabs__tab[aria-selected="true"] { color: var(--accent); }

.tabs__tab:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
  border-radius: 0.75rem;
}

/* No display of its own, so the hidden attribute script sets still lands. The
   class is what holds the panel closed between the js class going on -- before
   the first paint -- and the script actually running. */
.js .tabs__panel:not(.is-current) { display: none; }

.js .tabs__panel.is-current { animation: tab-in-forward 280ms var(--ease) both; }
.tabs[data-dir="back"] .tabs__panel.is-current { animation-name: tab-in-back; }

@keyframes tab-in-forward {
  from { opacity: 0; transform: translateX(14px); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes tab-in-back {
  from { opacity: 0; transform: translateX(-14px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* The slide is the whole effect here, so it goes rather than being shortened. */
@media (prefers-reduced-motion: reduce) {
  .tabs__list::after { transition: none; }
  .js .tabs__panel.is-current { animation: none; }
}

/* ---- Contracts and Perpetual loops -------------------------------------- */
.contracts,
.perpetual { padding: 1rem 1.25rem calc(2rem + env(safe-area-inset-bottom)); }
.withdraw { padding: 1rem 1.25rem calc(2rem + env(safe-area-inset-bottom)); }

.withdraw__available {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  padding: 1.1rem;
  border: 1.5px solid var(--line);
  border-radius: 1.25rem;
  background: var(--card);
  color: var(--ink-soft);
  font-size: 0.8125rem;
}

.withdraw__available strong {
  color: var(--ink);
  font-size: 1.5rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.replenish-records__intro { margin: 0 0 1rem; color: var(--ink-soft); font-size: 0.8125rem; }
.replenish-records { display: grid; gap: 0.5rem; margin: 0; padding: 0; list-style: none; }
/* The card is a button: the whole record opens its own modal. */
.replenish-record { display: grid; gap: 0.35rem; width: 100%; padding: 0.85rem 1rem; border: 1px solid var(--line); border-radius: 1.25rem; background: var(--card); color: inherit; font: inherit; text-align: left; cursor: pointer; transition: border-color 0.15s var(--ease); }
.replenish-record:hover { border-color: var(--accent); }
.replenish-record:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.replenish-record__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
.replenish-record__type { color: var(--ink); font-size: 0.875rem; font-weight: 800; }
.replenish-record__when { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; color: var(--ink-soft); font-size: 0.75rem; }
.replenish-record__chevron { flex: none; width: 1rem; height: 1rem; fill: none; stroke: var(--ink-soft); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.replenish-record__status { padding: 0.25rem 0.6rem; border-radius: 999px; font-size: 0.625rem; font-weight: 800; line-height: 1.4; }
.replenish-record__status--success { background: #D1FAE5; color: #065F46; }
.replenish-record__status--failed { background: #FEE2E2; color: #991B1B; }
.replenish-record__status--review { background: #FEF3C7; color: #92400E; }
.replenish-record__status--pending { background: var(--current); color: var(--accent); }
.replenish-record__amount { display: block; margin: 0; color: var(--ink); font-size: clamp(1.15rem, 4.6vw, 1.5rem); font-weight: 800; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
/* A finished loop wears the picture; a deposit record shares the class and
   must not, which is what the modifier is for. `overflow` is what clips the
   art to the radius the card already has, and `isolation` is what keeps the
   layer behind the text rather than behind the whole card. */
.replenish-record--art {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-color: rgba(255, 255, 255, 0.18);
  /* The ground the artwork sits on, and what the card falls back to if the
     picture never arrives -- the text above is forced white either way, so
     the pale light-theme card underneath would strand it. */
  background-color: #07162E;
}
/* The picture carries its subject on the right and leaves the left empty --
   which is exactly where every line of this card sits. So the scrim is
   darkest on the left and thins out to almost nothing on the right, over the
   coin, rather than dimming the whole image evenly. */
.replenish-record--art::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(95deg, rgba(4, 13, 31, 0.92) 0%, rgba(5, 18, 41, 0.72) 42%, rgba(6, 22, 48, 0.18) 100%),
    url("../images/complete.png");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: right center;
}
/* Over dark art the card cannot read from the theme: in light mode --ink is
   near-black and every line would vanish into the navy. These are the wallet
   card's colours, which sits on its own art the same way. */
.replenish-record--art .replenish-record__type,
.replenish-record--art .replenish-record__amount { color: #FFF; }
.replenish-record--art .replenish-record__when { color: #BBD5FF; }
.replenish-record--art .replenish-record__chevron { stroke: #BBD5FF; }
.replenish-record__details { display: grid; gap: 0.7rem; margin: 1rem 0 0; padding-top: 1rem; border-top: 1px solid var(--line); font-size: 0.75rem; line-height: 1.5; }
.replenish-record__details > div { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: 0.75rem; }
.replenish-record__details dt { color: var(--ink-soft); }
.replenish-record__details dd { margin: 0; color: var(--ink); text-align: right; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.replenish-record__reference dd { font-size: 0.6875rem; }
/* The modal shows the record the card was hiding. */
#record-body .replenish-record__status { display: inline-block; margin-bottom: 0.75rem; }
#record-body .replenish-record__amount { margin-bottom: 0.25rem; }

/* Sentinel for the scroller: it has to occupy space to be observed. */
.replenish-more { display: grid; justify-items: center; gap: 0.6rem; padding: 1.5rem 0 0.5rem; color: var(--ink-soft); font-size: 0.8125rem; }
.replenish-more p { margin: 0; }
.replenish-more__spinner { width: 1.5rem; height: 1.5rem; border: 2px solid var(--line); border-top-color: var(--accent); border-radius: 50%; animation: replenish-spin 0.7s linear infinite; }
.replenish-more__retry { padding: 0.5rem 0.9rem; border: 0; border-radius: 0.7rem; background: var(--current); color: var(--accent); font: inherit; font-size: 0.8125rem; font-weight: 800; cursor: pointer; }
@keyframes replenish-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .replenish-more__spinner { animation-duration: 2.4s; } }
.replenish-more[hidden] { display: none; }

.replenish-records__pages { display: flex; justify-content: space-between; gap: 1rem; margin-top: 1.25rem; }
.replenish-records__pages a { padding: 0.6rem 0.8rem; border-radius: 0.7rem; background: var(--current); color: var(--accent); font-size: 0.8125rem; font-weight: 800; text-decoration: none; }
.replenish-records__pages a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Not named for either page: the same card now stands in for whichever list is
   still empty, so it belongs to none of them. */
.empty-state {
  padding: 3rem 1.25rem;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 1.25rem;
  background: var(--card);
}

.empty-state svg {
  width: 2.75rem;
  height: 2.75rem;
  margin-bottom: 1rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.build-team {
  width: 100%;
  padding: 1.5rem 1rem;
  text-align: center;
}

.build-team h2 {
  margin: 0 0 0.5rem;
  color: var(--heading);
  font-size: 1.0625rem;
}

.build-team p {
  margin: 0 auto;
  color: var(--ink-soft);
  font-size: 0.8125rem;
  line-height: 1.6;
}

.build-team__animation {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 1;
  margin: 0 auto 1rem;
}

.empty-state h2 { margin: 0 0 0.5rem; color: var(--heading); font-size: 1.0625rem; }
.empty-state p { margin: 0 auto; max-width: 32ch; color: var(--ink-soft); font-size: 0.8125rem; line-height: 1.6; }

.loops__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.875rem;
}

.loop-card {
  display: flex;
  align-items: flex-end;
  min-width: 0;
  aspect-ratio: 4 / 5;
  padding: 1rem;
  overflow: hidden;
  border: 1px solid rgba(140, 173, 230, 0.3);
  border-radius: 1.125rem;
  background-color: #0A1633;
  background-size: cover;
  background-position: center;
  box-shadow: 0 6px 20px rgba(0, 8, 40, 0.16);
  /* A link now, not an article: no underline on the duration. */
  text-decoration: none;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease),
              border-color 0.18s var(--ease);
}

/* Only the real cards light up. The detail hero borrows these classes for its
   artwork but is not something you can press. */
a.loop-card:hover, a.loop-card:focus-visible { transform: translateY(-2px); }
a.loop-card:active { transform: translateY(0) scale(0.985); }

a.loop-card--short:hover,
a.loop-card--short:focus-visible,
a.loop-card--short:active {
  border-color: rgba(236, 0, 11, 0.85);
  box-shadow: 0 0 0 1px rgba(236, 0, 11, 0.45),
              0 0 1.5rem rgba(236, 0, 11, 0.45),
              0 0.75rem 2rem rgba(140, 0, 8, 0.35);
}

a.loop-card--long:hover,
a.loop-card--long:focus-visible,
a.loop-card--long:active {
  border-color: rgba(232, 185, 89, 0.95);
  box-shadow: 0 0 0 1px rgba(232, 185, 89, 0.5),
              0 0 1.5rem rgba(232, 185, 89, 0.42),
              0 0.75rem 2rem rgba(150, 110, 30, 0.35);
}

a.loop-card:focus-visible { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .loop-card { transition: box-shadow 0.18s linear, border-color 0.18s linear; }
  a.loop-card:hover, a.loop-card:focus-visible, a.loop-card:active { transform: none; }
}

/* The same waiting state the wallet cards use, in the card that was tapped. */
.loop-card { position: relative; }
.loop-card__loading {
  display: none; position: absolute; inset: 0; z-index: 1;
  flex-direction: column; align-items: center; justify-content: center; gap: 0.85rem;
  border-radius: inherit; background: rgba(5, 14, 30, 0.74);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  color: #fff; font-size: 0.75rem; font-weight: 700;
}
.loop-card.is-loading { cursor: wait; }
.loop-card.is-loading > :not(.loop-card__loading) { visibility: hidden; }
.loop-card.is-loading .loop-card__loading { display: flex; }
.loop-card--short .loop-card__loading .loader__dot { background: #FF8A8A; }
.loop-card--long .loop-card__loading .loader__dot { background: #F5DFAB; }
@media (prefers-reduced-motion: reduce) {
  .loop-card__loading .loader__dot { animation: none; }
}

.loop-card--short {
  background-image: linear-gradient(180deg, transparent 30%, rgba(3, 9, 24, 0.94) 100%),
    url("../images/bearish.png");
}

.loop-card--long {
  border-color: rgba(232, 185, 89, 0.5);
  background-image: linear-gradient(180deg, transparent 30%, rgba(3, 9, 24, 0.94) 100%),
    url("../images/big-profits.png");
}

.loop-card__title {
  margin: 0;
  color: #fff;
  font-size: clamp(1.125rem, 5vw, 1.5rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.025em;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.loop-card__label {
  display: block;
  margin-bottom: 0.375rem;
  color: #E1E9F8;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.loops__long-term { margin-top: 1.75rem; }

.loops__divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, #78A8FF 25%, #F5D88F 70%, transparent);
  box-shadow: 0 0 8px rgba(120, 168, 255, 0.65), 0 0 18px rgba(245, 216, 143, 0.3);
}

.loops__heading {
  margin: 1.5rem 0 1rem;
  color: var(--heading);
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

/* ---- Loop explanations ------------------------------------------------ */
.loops__info {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.75rem;
  margin: -0.75rem 0 0.75rem;
  padding: 0.35rem 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 0.75rem;
  font-weight: 700;
  cursor: pointer;
}

.loops__info svg {
  width: 1.125rem;
  height: 1.125rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

.loops__info:hover { text-decoration: underline; text-underline-offset: 3px; }
.loops__info:focus-visible, .loop-info button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 0.5rem;
}

.loop-info { width: min(calc(100% - 2rem), 26rem); }
.loop-info[open] { animation: loop-info-in 240ms var(--ease); }
.loop-info[open]::backdrop { animation: backdrop-in 240ms var(--ease); }
.loop-info .modal__body { color: var(--ink); }

.loop-info__badge {
  display: inline-block;
  margin-bottom: 0.875rem;
  padding: 0.4rem 0.65rem;
  border-radius: 999px;
  background: rgba(236, 0, 11, 0.09);
  color: var(--red-deep);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.loop-info--long .loop-info__badge {
  background: var(--current);
  color: var(--accent);
}

:root:not([data-theme="light"]) .loop-info--short .loop-info__badge {
  background: rgba(244, 92, 117, 0.12);
  color: #FF8A99;
}

.loop-chart {
  margin: 1.25rem 0 1rem;
  padding: 0.5rem 0.5rem 0.875rem;
  border: 1px solid rgba(115, 157, 230, 0.3);
  border-radius: 1rem;
  background: radial-gradient(ellipse at top, #152D54, #080F20 80%);
  color: #CBD8EE;
}

.loop-chart__svg { display: block; width: 100%; height: auto; }
.loop-chart__grid { fill: none; stroke: #8DAAD4; stroke-opacity: 0.12; stroke-width: 1; }
.loop-chart__line, .loop-chart__moves {
  fill: none;
  stroke: #4C94FF;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.loop-chart__moves { stroke: #F45C75; }
.loop-info--long .loop-chart__plot { transform: translateY(208px) scaleY(-1); }
.loop-info--long .loop-chart__line { stroke: #F45C75; }
.loop-info--long .loop-chart__moves { stroke: #4C94FF; }
.loop-chart__point { fill: #F45C75; }
.loop-chart__halo { fill: #F45C75; opacity: 0.2; }
.loop-info--long .loop-chart__point, .loop-info--long .loop-chart__halo { fill: #4C94FF; }
.loop-info[open] .loop-chart__line, .loop-info[open] .loop-chart__moves {
  stroke-dasharray: 1;
  animation: loop-chart-draw 1.2s ease both;
}
.loop-chart__legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1rem;
  font-size: 0.625rem;
}
.loop-chart__legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.loop-chart__key { width: 0.5rem; height: 0.5rem; border-radius: 50%; }
.loop-chart__key--blue { background: #4C94FF; }
.loop-chart__key--red { background: #F45C75; }
.loop-chart figcaption { margin-top: 0.75rem; text-align: center; font-size: 0.625rem; line-height: 1.5; }
.loop-info__durations { margin: 0; color: var(--ink-soft); font-size: 0.75rem; line-height: 1.6; text-align: center; }
.loop-info__done {
  width: 100%;
  min-height: 2.75rem;
  border: 0;
  border-radius: 0.75rem;
  background: var(--blue);
  color: #fff;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}
.loop-info__done:hover { background: var(--blue-lift); }
@keyframes loop-info-in {
  from { opacity: 0; transform: translateY(12px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes loop-chart-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) {
  .loop-info[open], .loop-info[open]::backdrop,
  .loop-info[open] .loop-chart__line, .loop-info[open] .loop-chart__moves { animation: none; }
}

/* ---- Menu drawer ------------------------------------------------------ */
.menu {
  /* Pinned to the left edge of the app column, not the browser window, so on a
     desktop it slides inside the phone shell instead of off the screen edge. */
  position: fixed;
  top: 0;
  bottom: 0;
  left: max(0px, calc((100vw - var(--shell)) / 2));
  width: min(17.5rem, calc(100vw - 3.5rem));
  max-width: var(--shell);
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--card);
  color: var(--ink);
  overflow: hidden;
  box-shadow: 0 0 3rem rgba(10, 22, 51, 0.22);
}

.menu::backdrop {
  background: var(--scrim);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

.menu[open] { animation: menu-in 0.28s var(--ease); }
.menu[open]::backdrop { animation: backdrop-in 0.28s var(--ease); }

.menu.is-closing { animation: menu-out 0.2s var(--ease) forwards; }
.menu.is-closing::backdrop { animation: backdrop-out 0.2s var(--ease) forwards; }

@keyframes menu-in {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}

@keyframes menu-out {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}

@keyframes backdrop-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

.menu:focus,
.menu:focus-visible { outline: none; }

.menu__panel {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* ---- Drawer header ---------------------------------------------------- */
.menu__head {
  position: relative;
  padding: calc(env(safe-area-inset-top) + 1.75rem) 1.25rem 1.5rem;
  /* The bull sits under a brand-blue wash. The overlay is not decoration: the
     artwork is busy enough that white text on it alone would be unreadable. */
  background-color: var(--heading);
  background-image:
    linear-gradient(165deg, rgba(0, 42, 140, 0.62), rgba(0, 16, 66, 0.90)),
    url("../icons/bullish.png");
  background-size: cover, cover;
  background-position: center, center 45%;
  background-repeat: no-repeat, no-repeat;
  color: #fff;
  /* The mirror of the theme picker at the other end of the drawer: that one
     rises from the foot, this one hangs from the head, so the nav sits between
     two lit edges. Same glow, flipped. */
  border-radius: 0 0 1.25rem 1.25rem;
  box-shadow: 0 10px 26px -14px rgba(76, 148, 255, 0.55);
}

/* Hairline tracing the bottom edge and both corners, faded out as it runs back
   up the sides. The head is far taller than the picker, so the fade is over a
   much shorter run of it -- carried the full height it would read as a box
   drawn around the artwork rather than as a lit edge. */
.menu__head::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid rgba(127, 168, 255, 0.5);
  border-radius: inherit;
  -webkit-mask: linear-gradient(0deg, #000 0, #000 12%, transparent 38%);
  mask: linear-gradient(0deg, #000 0, #000 12%, transparent 38%);
  pointer-events: none;
}

.menu__head::after {
  content: "";
  position: absolute;
  bottom: -2px;
  left: 12%;
  right: 12%;
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #4C94FF 28%, #8A81F8 52%, #F45C75 78%, transparent);
  filter: blur(4px);
  pointer-events: none;
}

/* The header keeps its dark artwork in both themes, so its edge stays lit. Only
   the bloom that spills past it onto the drawer is dimmed, which is where the
   light palette would otherwise show a smudge. */
:root[data-theme="light"] .menu__head {
  box-shadow: 0 10px 24px -16px rgba(0, 66, 205, 0.3);
}

:root[data-theme="light"] .menu__head::after { opacity: 0.55; }

.menu__close {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 0.5rem);
  right: 0.5rem;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
}

.menu__close svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.menu__close:active { background: rgba(255, 255, 255, 0.18); }

.menu__close:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 1px;
}

.menu__avatar {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: 0.85rem;
  border-radius: 50%;
  padding: 0.3rem;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.96);
  border: 1.5px solid rgba(255, 255, 255, 0.7);
  box-shadow: 0 3px 12px rgba(0, 8, 40, 0.18);
}

.menu__avatar-logo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.menu__name {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  text-shadow: 0 1px 3px rgba(0, 8, 40, 0.5);
}

.menu__email {
  margin: 0.15rem 0 0;
  font-size: 0.8125rem;
  color: rgba(255, 255, 255, 0.85);
  word-break: break-all;
  text-shadow: 0 1px 3px rgba(0, 8, 40, 0.5);
}

.menu__pill {
  display: inline-block;
  margin-top: 0.7rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.28);
  font-size: 0.75rem;
  font-weight: 700;
  backdrop-filter: blur(4px);
}

.menu__pill--ok {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.65rem 0.3rem 0.4rem;
  background: #064E3B;
  border-color: #34D399;
  color: #A7F3D0;
  box-shadow: 0 2px 10px rgba(16, 185, 129, 0.2);
}

.menu__verified-icon {
  flex: none;
  width: 1rem;
  height: 1rem;
  color: #6EE7B7;
}

/* ---- Drawer body ------------------------------------------------------ */
.menu__nav {
  flex: 1;
  padding: 0.75rem;
  overflow-y: auto;
}

.menu__item,
.menu__install,
.menu__logout {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: 100%;
  min-height: 3rem;
  padding: 0 0.85rem;
  border: 0;
  border-radius: 0.85rem;
  background: none;
  color: var(--ink);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.menu__item:active,
.menu__install:active,
.menu__logout:active { background: var(--tint); }

.menu__install[hidden], .menu__install-status[hidden] { display: none; }
.menu__install:disabled { opacity: 0.6; cursor: wait; }
.menu__install-status { margin: 0.5rem 0.85rem; color: var(--ink-soft); font-size: 0.8125rem; }

/* A tap on Log out has no row to make current, so it keeps a pressed state of
   its own for the moment before the page goes. */
.menu__logout.is-going { background: var(--tint); }

/* ---- Navigation loader -------------------------------------------------- */
.loading {
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  display: none;             /* <dialog> handles its own showing */
  place-items: center;
}

.loading[open] { display: grid; }

/* Lighter than a normal scrim on purpose: this one lands on top of the drawer,
   and the row you just tapped has to stay legible underneath it. */
.loading::backdrop {
  background: var(--veil);
  backdrop-filter: blur(1px);
}

.loading .loader {
  padding: 1.1rem 1.4rem;
  border-radius: 1.25rem;
  background: var(--glass);
  box-shadow: 0 1rem 2.5rem var(--scrim);
  height: auto;
}

.menu__item.is-current {
  background: var(--current);
  color: var(--heading);
}

.menu__icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Holds the icon and the animation in one cell so the pulse sits behind the
   glyph without changing the row's height. */
.menu__glyph {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

.menu__glyph .menu__icon { position: relative; z-index: 1; }

.menu__pulse {
  position: absolute;
  inset: -0.75rem;
  pointer-events: none;
}

.menu__pulse dotlottie-player {
  display: block;
  width: 100%;
  height: 100%;
}

/* The pulse marks the current page, so it only ever runs on that one row. */
.menu__item:not(.is-current) .menu__pulse { display: none; }

/* An indefinite loop is a distraction for anyone who asked for less motion. */
@media (prefers-reduced-motion: reduce) {
  .menu__pulse { display: none; }
}

.menu__version {
  margin: 0;
  padding: 0.25rem 0.95rem 0.9rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--ink-soft);
  opacity: 0.75;
}

.menu__version span { font-weight: 500; }

.menu__foot {
  margin: 0;
  padding: 0.75rem 0.75rem calc(0.75rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
}

.menu__logout { color: var(--red-deep); }

.menu__item:focus-visible,
.menu__install:focus-visible,
.menu__logout:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
  .menu[open],
  .menu[open]::backdrop,
  .menu.is-closing,
  .menu.is-closing::backdrop { animation-duration: 0.01ms; }
}

/* ---- Dark theme -------------------------------------------------------- */
/* Dark is the default. The light palette in :root only takes effect once
   someone explicitly asks for it, so a first visit is always dark. */
:root:not([data-theme="light"]) {
  color-scheme: dark;

  --ground:      #0A1224;
  --card:        #131C31;
  --ink:         #E8EDF7;
  --ink-soft:    #93A0BC;
  --line:        #253148;

  --accent:      #7FA8FF;
  --heading:     #A9C4FF;
  --tint:        rgba(255, 255, 255, 0.08);
  --hairline:    rgba(255, 255, 255, 0.12);
  --placeholder: #66748F;
  --glass:       rgba(28, 38, 60, 0.9);
  --sheen:       rgba(255, 255, 255, 0.04);
  --current:     rgba(127, 168, 255, 0.16);
  --focus-ring:  rgba(127, 168, 255, 0.22);
  --focus-glow:  rgba(127, 168, 255, 0.38);
  --scrim:       rgba(2, 6, 18, 0.6);
  --veil:        rgba(2, 6, 18, 0.3);
}

:root[data-theme="light"] {
  color-scheme: light;
}

/* ---- Theme picker ------------------------------------------------------ */
/* The picker caps the foot of the drawer, so it is shaped like a panel rising
   from the bottom: rounded on the top corners only, lit along that edge. The
   glow is the same blue-violet-red used by the divider and the scrollbar
   thumb, so it reads as the house glow rather than a new accent. */
.theme {
  position: relative;
  margin-top: 0.5rem;
  /* Bottom padding keeps the control clear of the log out divider. */
  padding: 1rem 0.75rem 1.25rem;
  border-radius: 1.25rem 1.25rem 0 0;
  /* Fades out downward, so the panel has no hard bottom edge to collide with
     the version line and the log out rule below it. */
  background: linear-gradient(180deg, rgba(127, 168, 255, 0.12), transparent 62%);
  box-shadow: 0 -10px 26px -14px rgba(76, 148, 255, 0.55);
}

/* A hairline tracing the top edge and both corners. It is masked to fade out
   as it runs down the sides -- a border alone would stop dead partway down the
   drawer and read as an unfinished box. */
.theme::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid rgba(127, 168, 255, 0.45);
  border-radius: inherit;
  -webkit-mask: linear-gradient(180deg, #000 0, #000 22%, transparent 80%);
  mask: linear-gradient(180deg, #000 0, #000 22%, transparent 80%);
  pointer-events: none;
}

/* The bloom itself, sitting on the top edge and inset so it starts and stops
   inside the corner arcs instead of running past them. */
.theme::after {
  content: "";
  position: absolute;
  top: -2px;
  left: 12%;
  right: 12%;
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #4C94FF 28%, #8A81F8 52%, #F45C75 78%, transparent);
  filter: blur(4px);
  pointer-events: none;
}

/* The bloom is what sells it on a dark ground. On porcelain the same glow
   reads as a smudge, so light mode keeps the shape and dims the light --
   the same trade the divider makes. */
:root[data-theme="light"] .theme {
  background: linear-gradient(180deg, rgba(0, 66, 205, 0.05), transparent 62%);
  box-shadow: 0 -10px 24px -16px rgba(0, 66, 205, 0.3);
}

:root[data-theme="light"] .theme::before { border-color: rgba(0, 66, 205, 0.2); }
:root[data-theme="light"] .theme::after { opacity: 0.4; }

.theme__label {
  display: block;
  margin: 0 0 0.5rem 0.2rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--ink-soft);
}

/* The drawer's fold reuses the manual key's panel wholesale, but its control
   is a quiet section heading here rather than the call to action it is on the
   two-step page. */
.menu__more { margin-top: 0.25rem; }

.js .menu__more > .reveal__summary {
  margin-left: 0.2rem;
  padding: 0.35rem 0;
  color: var(--ink-soft);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.menu__more > .reveal__summary .reveal__caret { width: 0.8rem; height: 0.8rem; }

/* Segmented control: the selected mode is visible at a glance, which a plain
   switch cannot show when there are three states. */
.theme__group {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.25rem;
  padding: 0.25rem;
  border-radius: 0.85rem;
  background: var(--tint);
}

.theme__option {
  display: grid;
  place-items: center;
  gap: 0.15rem;
  min-height: 3rem;
  padding: 0.35rem 0.2rem;
  border: 0;
  border-radius: 0.65rem;
  background: none;
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.6875rem;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease);
}

.theme__option svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.theme__option[aria-pressed="true"] {
  background: var(--card);
  color: var(--accent);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.14);
}

.theme__option:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -2px;
}

/* ---- Theme cross-fade -------------------------------------------------- */
/* Only applied while a switch is happening. Leaving these transitions on
   permanently would make every hover, focus and press feel sluggish, and would
   fight the drawer and alert animations. */
:root.theme-switching,
:root.theme-switching *,
:root.theme-switching *::before,
:root.theme-switching *::after {
  transition: background-color 300ms ease,
              background-image 300ms ease,
              color 300ms ease,
              border-color 300ms ease,
              outline-color 300ms ease,
              fill 300ms ease,
              stroke 300ms ease,
              box-shadow 300ms ease !important;
  transition-delay: 0s !important;
}

@media (prefers-reduced-motion: reduce) {
  :root.theme-switching,
  :root.theme-switching *,
  :root.theme-switching *::before,
  :root.theme-switching *::after {
    transition-duration: 0.01ms !important;
  }
}

/* ---- Install prompt ---------------------------------------------------- */
.install {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem 0.9rem;
  width: min(100%, 24rem);
  margin: 0 auto 1rem;
  padding: 1rem;
  border: 1.5px solid var(--line);
  border-radius: 1.25rem;
  background: var(--card);
  text-align: left;
}
.install__icon { width: 2.75rem; height: 2.75rem; border-radius: 0.85rem; }
.install__body { min-width: 0; }
.install__title { margin: 0 0 0.25rem; font-size: 0.9375rem; font-weight: 800; color: var(--ink); }
.install__line { margin: 0; font-size: 0.8125rem; line-height: 1.5; color: var(--ink-soft); }
.install__steps { margin: 0.5rem 0 0; padding-left: 1.1rem; font-size: 0.8125rem; line-height: 1.7; color: var(--ink-soft); }
.install__steps strong { color: var(--ink); }
.install__actions { grid-column: 1 / -1; display: grid; gap: 0.4rem; }
.install__actions .button { min-height: 3rem; font-size: 0.9375rem; }
.install__later {
  padding: 0.6rem; border: 0; background: none; color: var(--ink-soft);
  font: inherit; font-size: 0.8125rem; font-weight: 700; cursor: pointer;
}
.install[hidden], .install [hidden] { display: none; }
.install-help {
  width: min(calc(100% - 2rem), 24rem);
  max-height: calc(100% - 2rem);
  margin: auto;
  padding: 1.5rem;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 1.25rem;
  background: var(--card);
  color: var(--ink);
  font: inherit;
}
.install-help::backdrop { background: rgba(3, 9, 24, 0.7); }
.install-help h2 { margin: 1rem 0 0.5rem; font-size: 1.25rem; }
.install-help .install__actions { margin-top: 1.25rem; }
.install-help button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
body[data-phase="welcome"] .install { flex: none; width: min(calc(100% - 2 * var(--step)), 24rem); }

/* ---- One loop ---------------------------------------------------------- */
.loop-detail { padding: 0.75rem 1.25rem calc(2rem + env(safe-area-inset-bottom)); }
.loop-detail__back { display: inline-block; margin-bottom: 1rem; color: var(--accent); font-size: 0.8125rem; font-weight: 800; text-decoration: none; }
.loop-detail__back:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Cinematic: the art runs to both edges and dissolves into the page instead
   of sitting in a framed box. The picture lives on a pseudo-element so the
   mask fades the image alone -- masking the header would fade the title too. */
.loop-detail__hero {
  position: relative;
  isolation: isolate;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 0.6rem;
  min-height: 17rem;
  /* Bleed back out through the page's own side padding. */
  margin: 0 -1.25rem 0.5rem;
  padding: 1.25rem 1.25rem 3.25rem;
}

.loop-detail__hero::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background-size: cover; background-position: center;
  /* Opaque through the title, then gone by the bottom edge. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 76%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 76%, transparent 100%);
}

/* The scrim keeps the title on dark ground in either theme, while the mask
   below it takes the picture down to whatever the page is. */
.loop-detail__hero--short::before {
  background-image: linear-gradient(180deg, rgba(3, 9, 24, 0) 30%, rgba(3, 9, 24, 0.88) 72%, rgba(3, 9, 24, 0.88) 100%),
    url("../images/bearish.png");
}

.loop-detail__hero--long::before {
  background-image: linear-gradient(180deg, rgba(3, 9, 24, 0) 30%, rgba(3, 9, 24, 0.88) 72%, rgba(3, 9, 24, 0.88) 100%),
    url("../images/big-profits.png");
}
.loop-detail__term {
  align-self: flex-start; padding: 0.25rem 0.65rem; border-radius: 999px;
  background: rgba(10, 22, 51, 0.72); color: #DCE7FF;
  font-size: 0.625rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
}
.loop-detail__title {
  margin: 0; color: #fff; font-size: clamp(1.5rem, 7vw, 2rem); font-weight: 800;
  line-height: 1.15; letter-spacing: -0.025em; text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

/* ---- Starting a loop --------------------------------------------------- */
.loop-start { margin-top: 1.25rem; }
.loop-start__title { margin: 0 0 1rem; font-size: 1.0625rem; font-weight: 800; color: var(--ink); }
/* The balance and the amount sit side by side, as two halves of one decision:
   what you have, and how much of it to put in. */
.loop-start__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
.loop-start__cell {
  display: flex; flex-direction: column; justify-content: space-between; gap: 0.5rem;
  min-width: 0; margin: 0; padding: 0.85rem 0.9rem;
  border: 1.5px solid var(--line); border-radius: 1rem; background: var(--card);
}
.loop-start__cell--field {
  background: var(--ground);
  caret-color: var(--accent);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

/* Tapping in lights the whole tile, not just its outline. */
.loop-start__cell--field:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring),
              0 0 1.5rem var(--focus-glow),
              0 0.5rem 1.75rem var(--focus-ring);
}

@media (prefers-reduced-motion: reduce) {
  .loop-start__cell--field { transition: none; }
}
.loop-start__cell-label { display: block; font-size: 0.6875rem; font-weight: 700; color: var(--ink-soft); }
.loop-start__cell-label span { font-weight: 500; }
.loop-start__cell-value,
.loop-start__input {
  color: var(--ink); font-family: inherit; font-weight: 800;
  font-size: clamp(1.25rem, 6.5vw, 1.6rem); letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.loop-start__field { display: flex; align-items: baseline; gap: 0.1rem; min-width: 0; }
.loop-start__currency { flex: none; color: var(--ink-soft); font-size: clamp(1.1rem, 5.5vw, 1.4rem); font-weight: 800; }
.loop-start__input { width: 100%; min-width: 0; padding: 0; border: 0; background: none; }
@media (max-width: 22rem) { .loop-start__grid { grid-template-columns: minmax(0, 1fr); } }
.loop-start__input:focus-visible { outline: none; }
.loop-start__input::placeholder { color: var(--placeholder); }
.loop-start__hint { display: block; margin-top: 0.5rem; font-size: 0.75rem; color: var(--ink-soft); }
.loop-start__error { margin: 0.65rem 0 0; font-size: 0.8125rem; font-weight: 700; color: var(--red-deep); }
:root:not([data-theme="light"]) .loop-start__error { color: #FF8A8A; }
.loop-start__figures { display: grid; gap: 0.75rem; margin: 1.25rem 0 0; padding: 1rem; border: 1px solid var(--line); border-radius: 1rem; background: var(--card); }
.loop-start__figures > div { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.loop-start__figures dt { font-size: 0.8125rem; color: var(--ink-soft); }
.loop-start__figures dt span { color: var(--accent); font-weight: 700; }
.loop-start__figures dd { margin: 0; color: var(--ink); font-size: 1.0625rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.loop-start__split { margin: 1.5rem 0 0.5rem; font-size: 0.9375rem; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); }
.loop-start__explain { margin: 0 0 0.85rem; font-size: 0.8125rem; line-height: 1.65; color: var(--ink-soft); }
.loop-start__explain strong { color: var(--ink); }
/* Three shares read as one set of facts, so they are ruled like a table. */
.loop-table {
  width: 100%; margin: 0.85rem 0 0;
  border-collapse: collapse; table-layout: fixed;
  font-size: 0.75rem; line-height: 1.55;
}
.loop-table thead th {
  padding: 0 0.5rem 0.5rem 0; border-bottom: 1px solid var(--line);
  font-size: 0.625rem; font-weight: 800; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-soft); text-align: left;
}
.loop-table tbody th,
.loop-table tbody td {
  padding: 0.7rem 0.5rem 0.7rem 0; border-bottom: 1px solid var(--hairline);
  vertical-align: top; text-align: left;
}
.loop-table tbody tr:last-child th,
.loop-table tbody tr:last-child td { border-bottom: 0; }
.loop-table tbody th { width: 4.75rem; font-weight: 800; color: var(--ink); }
.loop-table tbody td { color: var(--ink-soft); }
.loop-table td:last-child, .loop-table th:last-child { padding-right: 0; }
.loop-table__share { width: 3.25rem; font-variant-numeric: tabular-nums; }
.loop-table tbody .loop-table__share { font-weight: 800; color: var(--ink); }
.loop-table__row--yours th,
.loop-table__row--yours .loop-table__share { color: var(--accent); }
.loop-start__footnote { margin: 0.75rem 0 0; font-size: 0.6875rem; line-height: 1.6; color: var(--ink-soft); }
.loop-start__pending { margin-top: 1.25rem; font-size: 0.8125rem; color: var(--ink-soft); }
/* Three shares of one whole, so they are read across rather than down. */
.loop-start__shares {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem;
  margin: 0.5rem 0 0; padding: 0; list-style: none;
}
.loop-start__share {
  display: grid; gap: 0.15rem; justify-items: center; align-content: center;
  min-width: 0; padding: 0.85rem 0.4rem;
  /* Width kept, colour dropped: the tile reads by its ground, not an outline,
     and nothing shifts when the owner's card takes a colour. */
  border: 1.5px solid transparent; border-radius: 1rem; background: var(--card);
  text-align: center;
}
.loop-start__share strong {
  color: var(--ink); font-size: clamp(1.05rem, 5.5vw, 1.35rem); font-weight: 800;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.loop-start__share span { font-size: 0.6875rem; line-height: 1.3; color: var(--ink-soft); }
.loop-start__share--yours { background: var(--current); }
.loop-start__share--yours strong { color: var(--accent); }
.loop-detail__profit {
  position: absolute; top: 1rem; right: 1.25rem; z-index: 1;
  margin: 0; padding: 0.4rem 0.75rem; border-radius: 999px;
  background: rgba(5, 14, 30, 0.5);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  font-size: 0.6875rem; font-weight: 800; letter-spacing: 0.05em;
  text-transform: uppercase; color: #C7D6F0;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
}
.loop-detail__hero--short .loop-detail__profit span { color: #FF9A9A; }
.loop-detail__hero--long .loop-detail__profit span { color: #F5DFAB; }

/* The balance is the one figure on this page that is already yours. */
.loop-start__cell--wallet {
  position: relative;
  overflow: hidden;
  /* Width kept so it stays level with the field beside it. */
  border-color: transparent;
  background:
    linear-gradient(135deg, rgba(232, 185, 89, 0.16), rgba(232, 185, 89, 0.05) 48%, transparent 72%),
    var(--card);
}
/* --red-deep's problem in reverse: pale gold vanishes on porcelain, so the
   light theme keeps the deep tone and dark mode lifts it. */
.loop-start__cell--wallet .loop-start__cell-value { color: #846619; }
:root:not([data-theme="light"]) .loop-start__cell--wallet .loop-start__cell-value { color: #F5DFAB; }

/* Above the sweep, which is a positioned pseudo-element. */
.loop-start__cell--wallet > * { position: relative; z-index: 1; }

.loop-start__cell--wallet::after {
  content: "";
  position: absolute; top: -60%; bottom: -60%; left: 0; width: 38%;
  z-index: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 240, 205, 0.26), transparent);
  transform: translateX(-200%) skewX(-18deg);
  animation: wallet-shine 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes wallet-shine {
  0%, 62% { transform: translateX(-200%) skewX(-18deg); }
  100% { transform: translateX(330%) skewX(-18deg); }
}

@media (prefers-reduced-motion: reduce) {
  .loop-start__cell--wallet::after { animation: none; opacity: 0; }
}

/* ---- Create a loop ------------------------------------------------------ */
.loop-go {
  position: relative; isolation: isolate; overflow: hidden;
  display: grid; place-items: center;
  width: 100%; min-height: 3.5rem; margin-top: 1.1rem; padding: 0 1.25rem;
  border: 0; border-radius: 1.75rem; background: var(--red); color: #fff;
  font-family: inherit; font-size: 1.0625rem; font-weight: 700; letter-spacing: -0.01em;
  cursor: pointer; box-shadow: 0 0.5rem 1.25rem rgba(236, 0, 11, 0.28);
  transition: opacity 0.18s var(--ease), transform 0.18s var(--ease);
}
.loop-go:active { transform: scale(0.99); }
.loop-go:disabled { opacity: 0.45; cursor: not-allowed; box-shadow: none; }
/* The animation runs behind the label, so the words ride its motion. */
.loop-go__motion { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; opacity: 0.55; }
.loop-go:disabled .loop-go__motion { opacity: 0; }
.loop-go__label { position: relative; z-index: 1; text-shadow: 0 1px 6px rgba(90, 0, 6, 0.45); }
@media (prefers-reduced-motion: reduce) { .loop-go__motion { display: none; } }

.loop-summary { display: grid; gap: 0.65rem; margin: 0 0 1rem; font-size: 0.8125rem; }
.loop-summary > div { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.loop-summary dt { color: var(--ink-soft); }
.loop-summary dd { margin: 0; color: var(--ink); font-weight: 800; font-variant-numeric: tabular-nums; }
.loop-summary__lock { margin: 0; padding: 0.85rem 1rem; border-radius: 0.9rem; background: var(--tint); font-size: 0.75rem; line-height: 1.65; color: var(--ink-soft); }
.loop-summary__lock strong { color: var(--ink); }
.loop-summary__error { margin: 0.85rem 0 0; font-size: 0.8125rem; font-weight: 700; color: var(--red-deep); }
:root:not([data-theme="light"]) .loop-summary__error { color: #FF8A8A; }

/* ---- Running loops ----------------------------------------------------- */
.perpetual__intro { margin: 0 0 1rem; color: var(--ink-soft); font-size: 0.8125rem; }
.perpetual__list { display: grid; gap: 0.75rem; margin: 0; padding: 0; list-style: none; }
.perpetual__loop { padding: 1.1rem; border: 1.5px solid var(--line); border-radius: 1.25rem; background: var(--card); }
.perpetual__head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.perpetual__head h2 { margin: 0; font-size: 0.9375rem; font-weight: 800; color: var(--ink); }
.perpetual__badge { padding: 0.25rem 0.6rem; border-radius: 999px; background: var(--current); color: var(--accent); font-size: 0.625rem; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; }
.perpetual__amount { margin: 0.75rem 0 0; font-size: clamp(1.35rem, 6vw, 1.75rem); font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }

/* The sum sits dead centre of the globe, so it reads as money held inside it
   rather than captioned underneath. The player is absolute so only the amount
   sizes the stage. */
.perpetual__globe {
  position: relative;
  isolation: isolate;
  /* The sphere is the ruler the figure inside it is measured against. */
  container-type: inline-size;
  display: grid;
  place-items: center;
  width: min(78%, 13rem);
  margin: 0.35rem auto 0.15rem;
  aspect-ratio: 1;
}
/* The mesh draws over the figure, near wires and far alike, which is the whole
   of the illusion: money seen through a sphere rather than labelled on one.
   The art is transparent, so what crosses the digits is only the lines. */
.perpetual__globe dotlottie-player {
  position: absolute; inset: 0;
  z-index: 2;
  width: 100%; height: 100%;
  pointer-events: none;
}
/* What the globe holds: the sum, and the lock saying it is not coming back
   out before the term does. Both scale off this one font-size, so the lock
   never drifts out of proportion with the figure. */
.perpetual__holding {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 0.34rem;
  color: var(--ink);
  /* A long figure is set smaller so it still clears the sphere's walls. Every
     character now carries full width, so the constant leaves less slack than
     it did when the mark and the cents were set small.
     The plain clamp stands in wherever container units are not understood. */
  font-size: clamp(1.1rem, 6vw, 1.75rem);
  font-size: clamp(0.8rem, calc(95cqi / var(--digits, 6)), 1.75rem);
}

/* Not a plate to sit on -- a soft core the mesh passes across. It fades out
   long before the closest side, so the sphere never gains a visible lid. */
/* One solid figure: mark, dollars and cents all at one size and one weight,
   so the sum reads as a single object held in the sphere. 800 is the heaviest
   Manrope this app loads. */
.perpetual__globe .perpetual__amount {
  margin: 0;
  padding: 0.05rem 0.6rem;
  font-size: inherit;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  background: radial-gradient(closest-side, var(--card) 30%, transparent 100%);
  text-shadow: 0 1px 14px var(--card), 0 0 4px var(--card);
}

.perpetual__lock {
  width: 0.62em;
  height: 0.62em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.6;
}

/* An endless spin is exactly the sort of motion someone turns this off for.
   The amount is not, so it falls back to a plain figure. */
@media (prefers-reduced-motion: reduce) {
  .perpetual__globe { width: auto; margin: 0.75rem 0 0; aspect-ratio: auto; justify-items: start; }
  .perpetual__globe dotlottie-player { display: none; }
  .perpetual__holding { justify-items: start; }
  .perpetual__globe .perpetual__amount { padding: 0; background: none; text-shadow: none; }
}

/* ---- A running loop wearing its term's art ------------------------------ */
/* A photograph cannot follow the theme, so a card carrying one stops trying:
   every colour below is pinned light-on-dark in both themes, the way the
   browsing cards on Pine Loops already are. */
.perpetual__loop--art {
  overflow: hidden;
  /* No frame. A border turns a photograph into a widget; without one the art
     runs to the corners and the card reads as a still. */
  border: none;
  background-color: #0A1633;
  background-size: cover;
  box-shadow: 0 10px 30px rgba(0, 8, 40, 0.38);
  /* Lit from the right, with a weaker fill on the left so the near edge does
     not fall away into black. Both are aimed high: the facts along the bottom
     are white and right-aligned, and a glow down there would eat them. */
  background-image:
    radial-gradient(118% 82% at 100% 18%, var(--key) 0%, transparent 58%),
    radial-gradient(92% 74% at 0% 62%, var(--fill) 0%, transparent 54%),
    linear-gradient(180deg, rgba(3, 9, 24, 0.6) 0%, rgba(3, 9, 24, 0.4) 40%, rgba(3, 9, 24, 0.88) 100%),
    var(--scene);
}
.perpetual__loop--art .perpetual__head h2,
.perpetual__loop--art .perpetual__holding,
.perpetual__loop--art .perpetual__facts dd { color: #FFF; }
.perpetual__loop--art .perpetual__facts dt { color: #C2CDE4; }
.perpetual__loop--art .perpetual__clock { color: #9FC4FF; }
.perpetual__loop--art .perpetual__clock[data-finished] { color: #C2CDE4; }
.perpetual__loop--art .perpetual__facts { border-top-color: rgba(255, 255, 255, 0.18); }
.perpetual__loop--art .perpetual__badge {
  background: rgba(255, 255, 255, 0.16);
  color: #FFF;
}
/* The core behind the sum was the card's own colour; over art it has to be
   its own dark, or it punches a pale disc through the picture. */
.perpetual__loop--art .perpetual__globe .perpetual__amount {
  background: radial-gradient(closest-side, rgba(6, 14, 34, 0.82) 30%, transparent 100%);
  text-shadow: 0 1px 14px rgba(6, 14, 34, 0.95), 0 0 4px rgba(6, 14, 34, 0.95);
}

/* Both pictures carry their subject on the left, so the crop holds it there
   rather than centring on empty sky. Each term lights its scene in its own
   colour: the crystal field in magenta, the bull in the gold of its sun. */
.perpetual__loop--short {
  --scene: url("../images/short_loop_bg.png");
  --key: rgba(255, 176, 228, 0.34);
  --fill: rgba(226, 190, 255, 0.16);
  background-position: left bottom;
}

.perpetual__loop--long {
  --scene: url("../images/longmarket_bg.png");
  --key: rgba(255, 214, 140, 0.34);
  --fill: rgba(255, 233, 190, 0.14);
  background-position: left center;
}
.perpetual__loop--long .perpetual__clock { color: #F5DFAB; }
/* Centred under the globe it belongs to, and large enough to be the second
   thing read after the sum itself. */
.perpetual__clock { margin: 0.35rem 0 1rem; text-align: center; font-size: clamp(1.25rem, 5.5vw, 1.5rem); font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
.perpetual__clock[data-finished] { color: var(--ink-soft); }

/* pre keeps the space in "1 day 04:05:06" from collapsing once every
   character is its own inline-block. */
.perpetual__clock-cell { display: inline-block; white-space: pre; }
.perpetual__clock-cell.is-rolling { animation: clock-roll 0.4s var(--ease); }

@keyframes clock-roll {
  from { transform: translateY(-0.45em); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* A digit moving every second is the clearest case there is for sitting
   still when asked. The clock still counts; it just stops moving. */
@media (prefers-reduced-motion: reduce) {
  .perpetual__clock-cell.is-rolling { animation: none; }
}
.perpetual__facts { display: grid; gap: 0.6rem; margin: 0; padding-top: 0.9rem; border-top: 1px solid var(--hairline); font-size: 0.75rem; }
.perpetual__facts > div { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.perpetual__facts dt { color: var(--ink-soft); }
.perpetual__facts dd { margin: 0; color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---- Account type ------------------------------------------------------ */
/* Two cards, one per kind of account. The investor card is a link; the
   trader card is the same shape but muted and badged, so what is coming is
   shown without ever reading as something that can be tapped. */
.choices {
  display: grid;
  gap: 0.85rem;
  width: 100%;
  margin-top: 1.5rem;
  text-align: left;
}

.choice {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.1rem;
  border-radius: 1.25rem;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: inherit;
  text-decoration: none;
  transition: transform 0.2s var(--ease), border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

a.choice:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 0.7rem 1.4rem -0.6rem var(--focus-glow);
}
a.choice:active { transform: scale(0.98); }
a.choice:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

.choice__icon {
  flex: none;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 1rem;
  object-fit: contain;
  background: var(--current);
  padding: 0.4rem;
}

.choice__text {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.choice__title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.choice__hint {
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

.choice__chevron {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-left: auto;
  fill: none;
  stroke: var(--ink-soft);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}


@media (prefers-reduced-motion: reduce) {
  .choice { transition: none; }
  a.choice:hover { transform: none; }
}

/* ---- Traders page -------------------------------------------------------- */
/* The picture runs edge to edge across the shell above the copy, fading
   into the ground at its foot so the heading sits on the page, not on a
   hard photo edge. The back arrow floats over it. */
.panel--traders { padding-top: 0; }
.trader-hero {
  position: relative;
  width: calc(100% + 2 * var(--step));
  margin: 0 calc(-1 * var(--step)) 0.5rem;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.trader-hero img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.trader-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 45%, var(--ground) 100%);
  pointer-events: none;
}
/* The animated button is the backdrop and the figure is text laid over it.
   The box keeps the animation's own 184:71 shape so nothing is squashed;
   the pill colours stand in until the player upgrades. */
.trader-share {
  position: relative;
  display: grid;
  place-items: center;
  width: min(17rem, 80%);
  aspect-ratio: 184 / 71;
  margin-top: 1rem;
  border-radius: 999px;
  background: var(--current);
  color: var(--accent);
  overflow: hidden;
}
.trader-share__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.js .trader-share:has(.trader-share__art) { background: transparent; }
.trader-share__text {
  position: relative;
  padding: 0 1rem;
  font-size: 0.9375rem;
  font-weight: 800;
  letter-spacing: 0.01em;
  text-align: center;
  color: #FFFFFF;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

/* ---- Supported trading tools ------------------------------------------ */
/* One tool per row: a logo tile on the left, the name and what PineLoop does
   with it on the right. Tiles are dark so a white mark reads on them in
   both themes. */
.tools {
  width: 100%;
  margin-top: 2rem;
  text-align: left;
}
.tools__title {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--heading);
}
.tools__intro {
  margin: 0.5rem 0 1rem;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-soft);
}
.tools__list {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.tool {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem;
  border-radius: 1.25rem;
  border: 1.5px solid var(--line);
  background: var(--card);
}
.tool__logo {
  display: grid;
  place-items: center;
  flex: none;
  width: 3.75rem;
  height: 3.75rem;
  border-radius: 1rem;
  background: #0A1224;
  overflow: hidden;
}
.tool__logo img { display: block; }
.tool__logo--mt5 img { width: 100%; height: 100%; object-fit: cover; }
.tool__logo--tradingview img { width: 2.1rem; height: 2.1rem; }
.tool__text {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}
.tool__name {
  font-size: 0.9375rem;
  font-weight: 800;
  color: var(--ink);
}
.tool__hint {
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* ---- Trader application ------------------------------------------------ */
/* Built from the same fields as sign up. What is new: a multi-line box for
   the strategy, a row of tool checkboxes, and the confirmation that takes the
   form's place once it is sent. */
.field__input--area {
  min-height: 7rem;
  padding-top: 0.85rem;
  resize: vertical;
  line-height: 1.5;
}
.field__box--area { align-items: flex-start; }
.field__box--area .field__icon { margin-top: 0.95rem; }
.checks {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  width: 100%;
  margin-top: 0.35rem;
}
.checks .check {
  margin: 0;
  padding: 0.75rem 0.9rem;
  border-radius: 1rem;
  border: 1.5px solid var(--line);
  background: var(--card);
  align-items: center;
}
.checks .check:focus-within { border-color: var(--accent); }
.checks .check__text { font-size: 0.875rem; font-weight: 700; }
.apply-sent {
  width: 100%;
  margin-top: 1.5rem;
  padding: 1.5rem 1.25rem;
  border-radius: 1.25rem;
  border: 1.5px solid var(--line);
  background: var(--card);
  text-align: center;
}
.apply-sent__tick {
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  margin: 0 auto 1rem;
  border-radius: 50%;
  background: rgba(74, 222, 128, 0.16);
  color: #15803D;
}
:root:not([data-theme="light"]) .apply-sent__tick { color: #4ADE80; }
.apply-sent__tick svg { width: 1.6rem; height: 1.6rem; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.apply-sent h2 { margin: 0 0 0.5rem; font-size: 1.25rem; font-weight: 800; letter-spacing: -0.02em; color: var(--heading); }
.apply-sent p { margin: 0; font-size: 0.9375rem; line-height: 1.55; color: var(--ink-soft); }
.apply-sent .button { margin-top: 1.25rem; }

/* ---- Trader application: steps, brokers, files ------------------------- */
.steps { width: 100%; margin-bottom: 0.5rem; text-align: left; }
.steps__label { margin: 0 0 0.5rem; font-size: 0.8125rem; font-weight: 800; color: var(--ink-soft); }
.steps__label #steps-name { color: var(--heading); }
.steps__bar { display: block; width: 100%; height: 0.4rem; border-radius: 999px; background: var(--hairline); overflow: hidden; }
.steps__fill { display: block; width: 100%; height: 100%; border-radius: inherit; transform-origin: left center; background: linear-gradient(90deg, var(--blue), var(--red)); transition: transform 0.4s var(--ease); }

.step { margin: 0; padding: 0; border: 0; min-width: 0; }
.step[hidden] { display: none; }
.step__legend { padding: 0; margin: 0.75rem 0 0.25rem; font-size: 1.0625rem; font-weight: 800; letter-spacing: -0.01em; color: var(--heading); text-align: left; width: 100%; }

.form__nav { display: flex; gap: 0.75rem; width: 100%; margin-top: 1.5rem; }
.form__nav .button { flex: 1; margin: 0; }
.form__nav [hidden] { display: none; }
.field__hint--lead { margin: 0 0 0.6rem; }

.field__box--file { padding-right: 0.75rem; }
.field__input--file { padding: 0.9rem 0; font-size: 0.875rem; cursor: pointer; }
.field__input--file::file-selector-button {
  margin-right: 0.75rem;
  padding: 0.45rem 0.8rem;
  border: 0;
  border-radius: 999px;
  background: var(--current);
  color: var(--accent);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 800;
  cursor: pointer;
}

/* Broker cards: a white tile keeps each mark in its own colours, and the
   picked card takes the accent border the way a focused field does. */
.brokers { display: grid; gap: 0.6rem; width: 100%; }
.broker {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.8rem 0.9rem;
  border-radius: 1.1rem;
  border: 1.5px solid var(--line);
  background: var(--card);
  cursor: pointer;
  transition: border-color 0.2s var(--ease);
}
.broker:has(.broker__pick:checked) { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
.broker:has(.broker__pick:focus-visible) { outline: 3px solid var(--accent); outline-offset: 3px; }
.broker__pick { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.broker__logo { display: grid; place-items: center; flex: none; width: 3.25rem; height: 3.25rem; padding: 0.45rem; border-radius: 0.85rem; background: #FFFFFF; }
.broker__logo img { display: block; width: 100%; height: 100%; object-fit: contain; }
.broker__logo--bank { background: var(--current); color: var(--accent); }
.broker__logo--bank svg { width: 1.6rem; height: 1.6rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.broker__text { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.broker__name { font-size: 0.9375rem; font-weight: 800; color: var(--ink); }
.broker__tag { font-size: 0.75rem; line-height: 1.4; color: var(--ink-soft); }

.kyc-note {
  width: 100%;
  margin: 0.75rem 0 1rem;
  padding: 1rem 1.1rem;
  border-radius: 1.1rem;
  background: var(--current);
  text-align: left;
}
.kyc-note h2 { margin: 0 0 0.4rem; font-size: 1rem; font-weight: 800; color: var(--heading); }
.kyc-note p { margin: 0.5rem 0 0; font-size: 0.875rem; line-height: 1.55; color: var(--ink); }
.kyc-note strong { color: var(--accent); }
.apply-error { width: 100%; margin: 1rem 0 0; text-align: left; }
.apply-error[hidden] { display: none; }
