/* ------------------------------------------------------------------
   Forms. Instrument-panel inputs: thin, lit, and legible.
   ------------------------------------------------------------------ */

.card {
  position: relative;
  padding: clamp(1.4rem, 3.2vw, 2.4rem);
  border: 1px solid var(--line);
  border-radius: 4px;
  background: linear-gradient(165deg, rgba(17, 29, 39, 0.72), rgba(7, 12, 18, 0.86));
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.42);
}

.card__title {
  font-family: var(--font-paper);
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  line-height: 1.2;
  color: var(--text-0);
  margin-bottom: .55rem;
}
.card__sub { font-size: .95rem; color: var(--text-1); margin-bottom: 1.5rem; }

.field { display: flex; flex-direction: column; gap: .4rem; margin-bottom: 1.05rem; }

/* A label at this size, spaced this far out and set in small capitals, needs
   more contrast than running text does, not less -- it was the dimmest thing
   on the page and the hardest to read. */
.field > label {
  font-family: var(--font-hud);
  font-size: .64rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--label);
}
.field__hint { font-size: .8rem; color: var(--text-1); }

/* ⚠️ `:not(.digits__box)` because a digit box is not an ordinary field and
   must not be dressed as one. `.field input[type="text"]` is specificity
   0-2-1 and `.digits__box` is 0-1-0, so WITHOUT this the generic rule won
   outright: the boxes were taking this font-size, this padding and this
   width: 100%, and every measurement set on them below was being ignored.
   That is why the digits looked small inside their own boxes. */
.field input[type="text"]:not(.digits__box),
.field input[type="email"],
.field input[type="password"],
.field input[type="date"],
.field input[type="number"],
.field select,
.field textarea {
  width: 100%;
  padding: .66rem .8rem;
  font-size: .95rem;
  color: var(--text-0);
  background: rgba(4, 7, 10, 0.68);
  border: 1px solid var(--line);
  border-radius: 3px;
  transition: border-color var(--t-state) var(--ease-out),
              box-shadow var(--t-state) var(--ease-out),
              background var(--t-state) var(--ease-out);
}
.field textarea { min-height: 8rem; resize: vertical; line-height: 1.6; font-family: var(--font-ui); }
.field textarea.mono { font-family: var(--font-hud); font-size: .88rem; }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 0;
  border-color: var(--accent-deep);
  background: rgba(4, 7, 10, 0.9);
  box-shadow: 0 0 0 1px var(--accent-deep), 0 0 18px var(--accent-faint);
}
.field input::placeholder, .field textarea::placeholder { color: var(--text-2); }

/* The reveal button sits INSIDE the field's border, one pixel in on every
   side, with no background of its own -- so the focus glow still reads as one
   continuous ring around the input rather than being clipped by a chip laid
   over it. The input's right padding is what keeps the text out from under it. */
.peek { position: relative; display: flex; }
/* ⚠️ `.field .peek`, not `.peek` -- the padding has to out-rank
   `.field input[type="password"]` above, which is a class plus an attribute
   plus an element. Written as `.peek > input` it loses, silently, and a long
   password slides underneath the eye instead of stopping short of it. */
.field .peek > input { padding-right: 3.2rem; }

/* No border and no background: the eye sits in the same box as the password
   rather than in a compartment of its own.

   ⚠️ The accent belongs to ONE state -- the password is readable -- and
   nothing else may borrow it. Hover used to light the eye green, which
   meant moving the pointer over a closed eye showed the colour of an open
   one, and the colour stopped answering the only question it is there to
   answer. Hover and focus brighten the grey instead. */
.peek__btn {
  position: absolute;
  top: 1px;
  right: 1px;
  bottom: 1px;
  width: 2.6rem;
  display: grid;
  place-items: center;
  color: var(--text-2);
  background: none;
  border: 0;
  border-radius: 0 2px 2px 0;
  cursor: pointer;
  transition: color var(--t-state) var(--ease-out);
}
.peek__btn:hover { color: var(--text-1); }
.peek__btn:focus-visible {
  outline: 0;
  color: var(--text-1);
  box-shadow: inset 0 0 0 1px var(--accent-deep);
}

/* Readable: accent. Hidden: grey. Last in the file so it wins over both
   of the rules above -- the state outranks the pointer, whatever the
   pointer is doing. */
.peek__btn[aria-pressed="true"],
.peek__btn[aria-pressed="true"]:hover,
.peek__btn[aria-pressed="true"]:focus-visible { color: var(--accent); }

/* One eye, drawn once. The slash is part of the same icon and is simply
   faded in when the password is readable, so the two states cannot drift
   apart and the markup is identical in every field that uses it. */
.peek__eye {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* ⚠️ The slash belongs to the HIDDEN state, and the default is therefore
   on. The icon describes the password, not the button: crossed out and
   grey while it cannot be read, plain and accent while it can. Written
   the other way round it reads as a label for what the press will do,
   and the two readings point in opposite directions. */
.peek__slash {
  opacity: 1;
  transition: opacity var(--t-state) var(--ease-out);
}
.peek__btn[aria-pressed="true"] .peek__slash { opacity: 0; }
.field.is-bad input, .field.is-bad select, .field.is-bad textarea { border-color: var(--danger); }
.field.is-good input { border-color: var(--accent-deep); }

.field__msg { font-size: .8rem; color: var(--danger); min-height: 1.1em; }
.field.is-good .field__msg { color: var(--accent); }

.field select {
  appearance: none;
  padding-right: 2.2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-1) 50%),
                    linear-gradient(135deg, var(--text-1) 50%, transparent 50%);
  background-position: calc(100% - 1.05rem) 50%, calc(100% - .72rem) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.field select option { background: var(--void-2); color: var(--text-0); }

/* A row of two, collapsing on narrow screens. */
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
@media (max-width: 560px) { .pair { grid-template-columns: 1fr; } }

/* The optional half of a form, folded away until asked for. */
.more { border: 0; padding: 0; margin-bottom: 1.05rem; }

/* It used to be a disclosure. Two fields are not worth a click, and a
   collapsed thing reads as a thing being withheld from the person filling
   the form in rather than offered to them. */
.more__head {
  margin: 0;
  font-family: var(--font-hud);
  font-size: .64rem;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--accent);
}
.more > summary {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  cursor: pointer;
  font-family: var(--font-hud);
  font-size: .62rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-2);
  list-style: none;
  padding: .3rem 0;
  transition: color var(--t-state) var(--ease-out);
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary::before { content: '+'; color: var(--accent); font-size: .9rem; line-height: 1; }
.more[open] > summary::before { content: '\2212'; }
.more > summary:hover { color: var(--accent); }
.more__in { padding-top: .9rem; }

/* Checkboxes, as lit cells. */
.check {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  padding: .6rem .75rem;
  margin-bottom: .5rem;
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
  transition: border-color var(--t-state) var(--ease-out), background var(--t-state) var(--ease-out);
}
.check:hover { border-color: var(--accent-dark); background: var(--accent-faint); }
.check input { margin-top: .22rem; accent-color: var(--accent); width: 1rem; height: 1rem; flex: 0 0 auto; }
.check__t { display: flex; flex-direction: column; gap: .15rem; }
.check__t b { font-size: .92rem; font-weight: 500; color: var(--text-0); }
.check__t span { font-size: .8rem; color: var(--text-2); }

/* Buttons. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .7rem 1.25rem;
  font-family: var(--font-hud);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--void-0);
  background: var(--accent);
  border-radius: 3px;
  transition: background var(--t-state) var(--ease-out),
              transform var(--t-state) var(--ease-out),
              box-shadow var(--t-state) var(--ease-out);
}
.btn:hover { background: var(--accent-pale); box-shadow: 0 0 24px var(--accent-glow); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }

.btn--ghost {
  color: var(--text-1);
  background: transparent;
  border: 1px solid var(--line);
}
.btn--ghost:hover { color: var(--accent); border-color: var(--accent-dark); background: var(--accent-faint); box-shadow: none; }

.btn--bad { background: var(--danger); color: #1a0604; }
.btn--bad:hover { background: #ff8a80; box-shadow: 0 0 24px rgba(255, 107, 94, .3); }

.btn--wide { width: 100%; }
.btn--sm { padding: .45rem .8rem; font-size: .64rem; }

/* A working button says so, without spinning for long. */
.btn.is-busy { pointer-events: none; opacity: .75; }
.btn.is-busy::after {
  content: '';
  width: .8em; height: .8em;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 620ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.formfoot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  margin-top: 1.2rem;
}
.formfoot small { font-size: .78rem; color: var(--text-2); }
.formfoot a { color: var(--text-1); border-bottom: 1px solid var(--line); }
.formfoot a:hover { color: var(--accent); border-color: var(--accent-dark); }

/* Swapping between sign in and sign up without leaving the page. */
.swap { display: flex; gap: .3rem; margin-bottom: 1.6rem; padding: .25rem; border: 1px solid var(--line); border-radius: 3px; }
.swap button {
  flex: 1 1 0;
  padding: .55rem;
  font-family: var(--font-hud);
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-2);
  border-radius: 2px;
  transition: color var(--t-state) var(--ease-out), background var(--t-state) var(--ease-out);
}
.swap button:hover { color: var(--text-0); }
.swap button[aria-selected="true"] { color: var(--void-0); background: var(--accent); }

/* Two-factor box on the account page (account.php). */
.tf .check.is-off { opacity: .5; cursor: default; }
.tf__setup { margin-top: 1.2rem; padding-top: 1.2rem; border-top: 1px solid var(--line, rgba(255,255,255,.08)); }
.tf__setup > p { color: var(--text-1); font-size: .92rem; }
/* White behind the code, whatever the theme: scanners want dark on light. */
.tf__qr { width: 216px; max-width: 100%; margin: .8rem 0 1rem; padding: 10px; background: #fff; border-radius: 6px; line-height: 0; }
.tf__qr svg { width: 100%; height: auto; display: block; }
.tf__or { font-size: .85rem; }
.tf__key { font-family: var(--font-hud); font-size: 1.15rem; letter-spacing: .1em; color: var(--text-0); margin: .3rem 0 1rem; word-break: break-all; }
.tf__codes { margin: 0 0 1.2rem; padding: 1rem 1.1rem; border: 1px solid var(--accent); border-radius: 6px; background: var(--accent-faint, rgba(37,234,181,.06)); }
.tf__codes p { font-size: .92rem; color: var(--text-1); }
.tf__codes ul { list-style: none; padding: 0; margin: .8rem 0 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr)); gap: .35rem .8rem; font-family: var(--font-hud); color: var(--text-0); }
.tf__change, .tf__more { margin-top: 1rem; }
.tf__more summary { cursor: pointer; font-size: .85rem; color: var(--text-2); }
.tf__more form { margin-top: .8rem; }

/* A button that reads as a link: "Send another code", beside small print. */
.linkbtn { background: none; border: 0; padding: 0; font: inherit; font-size: .85rem; color: var(--accent); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.linkbtn:hover { color: var(--text-0); }
/* The method choice at sign-in: two full-width buttons, one above the other. */
.tfpick .btn + .btn { margin-top: .6rem; }

/* ------------------------------------------------------------------
   A code, one digit to a box.

   The real field is still there, carrying the value and doing the
   submitting -- it is only hidden. With no script at all you get the plain
   box the page has always had.
   ------------------------------------------------------------------ */

.digits {
  display: flex;
  gap: clamp(.35rem, 2vw, .6rem);
  margin: .2rem 0 .1rem;
}

.digits__box {
  flex: 1 1 0;
  min-width: 0;
  max-width: 3.4rem;
  aspect-ratio: 3 / 4;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: rgba(4, 7, 10, .75);
  color: var(--text-0);
  font-family: var(--font-hud);
  /* ⭐ The digit fills the box (his call, 2026-10-28: the numbers
     "should be larger to fit the boxes properly"). A small digit in a tall
     box reads as a field that happens to be narrow; a large one reads as a
     digit. */
  font-size: clamp(1.6rem, 7vw, 2.2rem);
  text-align: center;
  caret-color: var(--accent);
  transition: border-color var(--t-state) var(--ease-out),
              background var(--t-state) var(--ease-out),
              box-shadow var(--t-state) var(--ease-out);
}

/* A box with something in it has been dealt with; the one you are on is the
   one lit. Both said at once, so the row reads as progress. */
.digits__box:not(:placeholder-shown),
.digits__box[value]:not([value=""]) { border-color: var(--accent-dark); }

.digits__box:focus {
  outline: none;
  border-color: var(--accent);
  background: rgba(37, 234, 181, .07);
  box-shadow: 0 0 0 1px var(--accent), 0 0 18px var(--accent-faint);
}

/* All six in: the row lights together for a beat before it goes. */
.digits.is-full .digits__box { border-color: var(--accent-dark); }
.digits.is-sending .digits__box {
  border-color: var(--accent);
  animation: digitsGo .5s var(--ease-both);
}
@keyframes digitsGo {
  0%   { box-shadow: 0 0 0 0 var(--accent-glow); }
  60%  { box-shadow: 0 0 0 5px rgba(37, 234, 181, 0); }
  100% { box-shadow: 0 0 0 0 rgba(37, 234, 181, 0); }
}

/* Hidden, never removed: it is what the form posts. */
.digits__real {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* Unless a recovery code is being typed, when it is the field again. */
.digits__real.is-plain {
  position: static;
  width: 100%;
  height: auto;
  padding: .6rem .75rem;
  margin: 0;
  overflow: visible;
  clip-path: none;
  white-space: normal;
}

.digits__alt {
  margin-top: .5rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-2);
  font-family: var(--font-hud);
  font-size: .6rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.digits__alt:hover { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .digits__box { transition: none; }
  .digits.is-sending .digits__box { animation: none; }
}
