/* Sign-in, code entry, password reset and join.
 *
 * One stylesheet because these four pages had drifted into three different
 * looks: login and reset sat on slate #1E2A3A, confirm sat on deep forest and
 * used Plus Jakarta Sans (a font on no other page in the product), and join had
 * its own third treatment. All of them were dark, and none of them looked like
 * mirajoco.org.
 *
 * The tokens below are lifted from the homepage (index.html) unchanged, so
 * these pages read as the same product as the site someone just came from.
 * Changing a colour here changes all four together, which is the point.
 *
 * Layout classes stay in each page - the markup genuinely differs. What lives
 * here is the palette, the type, and the form controls they all share.
 */

:root {
  --forest: #1B2E1D;
  --sage:   #6E8570;
  --tan:    #C7AF87;
  --lime:   #6DC48A;
  --ivory:  #FAF9F6;
  --mist:   #F1EFE9;
  --ink:    #2E2E2E;
  --muted:  #6B6B62;
  --line:   rgba(27, 46, 29, 0.12);
  --white:  #fff;

  /* Neither is on the homepage, which has no error state. Both are mixed
     toward the palette so they read as part of it rather than bootstrap red. */
  --danger:  #A63D3D;
  --success: #1B2E1D;

  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

  --radius: 14px;
  --radius-sm: 8px;
  --radius-pill: 24px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: var(--font-body);
  background: var(--ivory);
  color: var(--ink);
  min-height: 100vh;
  min-height: 100dvh;          /* mobile browser chrome must not clip the card */

  /* Grid, not flex, and this is the whole point of the rule.
   *
   * This was `display:flex; align-items:center; justify-content:center`. When a
   * centred flex item is TALLER than its container, the part that overflows
   * past the container's start edge cannot be scrolled to - scrolling only
   * travels toward the end. On a phone this card is tall (logo, two path
   * cards, two social buttons, email, password, submit), and a shorter visible
   * viewport is exactly what an on-screen keyboard or a phone with more browser
   * chrome produces. Grid centring does not have that failure: overflow stays
   * reachable in both directions.
   *
   * Reported by Miranda 2026-08-04 on iPhone 17: having to rotate the phone to
   * reach the Login button. Rotation changes the card's height and the visible
   * viewport at once, which is the kind of thing that makes an overflow trap
   * come and go. Not reproduced here, so this is the sound fix for the trap
   * that is definitely in this rule, not a confirmed fix for that report.
   */
  display: grid;
  place-items: center;

  /* The home indicator and the browser's bottom bar sit over the page on a
   * modern iPhone. There was no safe-area padding on any auth page, so the
   * bottom 24px of breathing room was the only thing between the submit button
   * and hardware. max() keeps the original 24px everywhere that reports no
   * inset, including every desktop browser.
   */
  padding: 24px;
  padding-top: max(24px, env(safe-area-inset-top));
  padding-bottom: max(24px, env(safe-area-inset-bottom));
  padding-left: max(24px, env(safe-area-inset-left));
  padding-right: max(24px, env(safe-area-inset-right));
  -webkit-font-smoothing: antialiased;
}

/* Each page already has its own name for these, and the JS toggles some of them
 * by class (.form-error gets .show, .login-form gets .visible). Renaming the
 * markup would mean renaming the script in four files for no gain, so the
 * stylesheet answers to both the semantic name and the name each page uses.
 *
 *   .auth-card    <- .card        .join-card     .confirm-card
 *   .auth-title   <- .card-title  .join-title    .confirm-title
 *   .auth-sub     <- .card-sub    .join-sub      .confirm-sub
 *   .auth-logo    <- .logo        .confirm-logo
 *   .auth-error   <- .form-error  .confirm-error
 *   .auth-success <- .form-success
 *   .btn-secondary<- .btn-social
 *   .auth-divider <- .divider
 *   .auth-foot    <- .back-link
 *   .auth-inline-link <- .forgot-link
 */
.auth-card, .card, .join-card, .confirm-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 36px 32px;
  width: 100%;
  max-width: 420px;
  box-shadow: 0 1px 2px rgba(27, 46, 29, 0.04), 0 12px 32px rgba(27, 46, 29, 0.06);
}

.auth-logo, .logo, .confirm-logo {
  display: block;
  height: 34px;
  width: auto;
  margin: 0 auto 24px;
}

.auth-title, .card-title, .join-title, .confirm-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 27px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-align: center;
  color: var(--forest);
  margin-bottom: 6px;
}

.auth-sub, .card-sub, .join-sub, .confirm-sub {
  text-align: center;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
  margin-bottom: 24px;
}

/* FORM CONTROLS */
.form-group { margin-bottom: 14px; }

.form-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sage);
  margin-bottom: 6px;
}

.form-input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  font-size: 15px;              /* 16px or above stops iOS zooming on focus;
                                   15px with the -webkit rule below is enough */
  font-family: var(--font-body);
  color: var(--ink);
  outline: none;
  transition: border-color .18s, box-shadow .18s;
  -webkit-text-size-adjust: 100%;
}
.form-input::placeholder { color: #A8A89E; }
.form-input:focus {
  border-color: var(--forest);
  box-shadow: 0 0 0 3px rgba(109, 196, 138, 0.25);
}

.btn-primary {
  width: 100%;
  padding: 14px;
  background: var(--lime);
  color: var(--forest);
  border: none;
  border-radius: var(--radius);
  font-size: 15px;
  font-weight: 700;
  font-family: var(--font-body);
  cursor: pointer;
  margin-top: 4px;
  transition: filter .15s, transform .1s;
}
.btn-primary:hover:not(:disabled) { filter: brightness(1.06); }
.btn-primary:active:not(:disabled) { transform: scale(0.985); }
.btn-primary:disabled { opacity: .5; cursor: not-allowed; }

.btn-secondary, .btn-social {
  width: 100%;
  padding: 12px;
  background: var(--white);
  color: var(--forest);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 600;
  font-family: var(--font-body);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 10px;
  transition: border-color .18s, background .18s;
}
.btn-secondary:hover, .btn-social:hover { border-color: var(--sage); background: var(--mist); }

/* FEEDBACK
 * Hidden until a .show class is added, matching what these pages already do. */
.auth-error, .auth-success, .form-error, .form-success, .confirm-error {
  display: none;
  margin-top: 12px;
  font-size: 13.5px;
  line-height: 1.55;
  text-align: center;
}
.auth-error.show, .auth-success.show, .form-error.show, .form-success.show, .confirm-error.show { display: block; }
.auth-error, .form-error, .confirm-error { color: var(--danger); }
.auth-success, .form-success {
  padding: 13px 15px;
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--success);
}

.auth-divider, .divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0;
  color: var(--muted);
  font-size: 12px;
}
.auth-divider::before, .auth-divider::after, .divider::before, .divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
}

.auth-link {
  color: var(--forest);
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 600;
  cursor: pointer;
}
.auth-link:hover { color: var(--sage); }

.auth-foot, .back-link {
  display: block;
  text-align: center;
  margin-top: 18px;
  font-size: 13px;
  color: var(--muted);
}

/* "Forgot password?" is the single most-needed link on this page - the members
   who cannot get in are, by definition, the ones who need it. It was 12.5px
   muted grey, which is how a link looks when it is trying not to be found.
   Now green and semibold, at body-copy weight. Still right-aligned and still
   secondary to Sign In; just findable by someone who is already frustrated. */
.auth-inline-link, .forgot-link {
  display: block;
  text-align: right;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--forest);
  text-decoration: none;
  margin: -6px 0 14px;
}
.auth-inline-link:hover, .forgot-link:hover { color: var(--forest); text-decoration: underline; }

/* Keyboard users need to see focus. The homepage uses a forest ring; the same
   one here reads correctly on both the white card and the ivory ground. */
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.auth-link:focus-visible,
.auth-inline-link:focus-visible {
  outline: 3px solid var(--forest);
  outline-offset: 3px;
}

@media (max-width: 480px) {
  /* Keeps the safe-area floor from the base rule. A plain `padding: 16px` here
   * would override all four longhands set above and put the submit button back
   * under the home indicator on exactly the devices this matters on. */
  body {
    padding: 16px;
    padding-top: max(16px, env(safe-area-inset-top));
    padding-bottom: max(16px, env(safe-area-inset-bottom));
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
  }
  .auth-card, .card, .join-card, .confirm-card { padding: 28px 20px; }
  .auth-title, .card-title, .join-title, .confirm-title { font-size: 24px; }
}

/* Respects a reduced-motion preference for the spinners these pages use. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* .back-link wraps a link in login and reset-password. */
.auth-foot a, .back-link a { color: var(--forest); text-decoration: none; font-weight: 600; }
.auth-foot a:hover, .back-link a:hover { text-decoration: underline; }

/* ============================================================
   AUTH QUOTE
   Injected by /js/auth-quote.js as the last child of the body grid.

   Two forms, by viewport width:
     wide   - a full-height panel down the left, card centred in what is left
     narrow - one quiet centred line under the card

   It is decorative (aria-hidden in the script), so in either form it must
   never compete with the submit button for attention.
   ============================================================ */

/* --- NARROW: the default. One line under the card. --- */
.auth-quote {
  max-width: 420px;
  margin-top: 26px;
  padding: 0 8px;
  text-align: center;
  animation: authQuoteIn .7s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: .25s;
}
.auth-quote-line {
  font-family: var(--font-display);
  font-size: 17px;
  line-height: 1.45;
  color: var(--sage);
  letter-spacing: -0.005em;
}
/* The lime rule is the only brand colour on an otherwise quiet block. */
.auth-quote-line::before {
  content: "";
  display: block;
  width: 26px;
  height: 2px;
  background: var(--lime);
  margin: 0 auto 14px;
  border-radius: 2px;
}
.auth-quote-mark { display: none; }

@keyframes authQuoteIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* Height, not width, is the constraint that matters in this form. The card is
 * already tall on a phone, and body is a centred grid, so a second row can push
 * the submit button toward the fold on a short viewport. That is the failure the
 * grid-centring comment at the top of this file exists to prevent, so the quote
 * is dropped rather than allowed to reintroduce it. */
@media (max-height: 760px) and (max-width: 1059px) {
  .auth-quote { display: none; }
}

/* --- WIDE: full-height panel. ---
 * position:fixed rather than a grid column so the body's grid centring, and the
 * overflow behaviour that depends on it, are left exactly as they are. The card
 * is pushed clear with padding-left instead. 1060px is where a 44% panel still
 * leaves the 420px card room to breathe.
 */
@media (min-width: 1060px) {
  body {
    padding-left: calc(44% + 40px);
    padding-right: 40px;
    justify-items: start;
  }
  .auth-quote {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 44%;
    max-width: none;
    margin: 0;
    padding: 56px 5.5% 44px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    text-align: left;
    /* Light, not forest. A full-height block of #1B2E1D read as a slab next to
       a white card on ivory. Contrast comes from the type instead. */
    background: linear-gradient(168deg, #E4F3E9 0%, #CDE8D9 55%, #B7DFC7 100%);
    border-right: 1px solid rgba(27, 46, 29, 0.08);
    overflow: hidden;
  }
  /* One soft bloom so a tall tinted panel does not read as flat. */
  .auth-quote::after {
    content: "";
    position: absolute;
    top: -14%; right: -22%;
    width: 68%; aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(109,196,138,0.30), rgba(109,196,138,0) 68%);
    pointer-events: none;
  }
  .auth-quote-line {
    position: relative;
    font-size: clamp(30px, 3.2vw, 44px);
    line-height: 1.16;
    letter-spacing: -0.018em;
    color: var(--forest);
    max-width: 15ch;
  }
  .auth-quote-line::before {
    width: 40px;
    height: 3px;
    margin: 0 0 26px;
    background: var(--forest);
  }
  .auth-quote-mark {
    display: block;
    position: relative;
    margin-top: 30px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--sage);
  }
}
