/* ================================================================
   Hosted auth pages.

   Design brief: docs/design/auth-pages-brief.md

   A left-anchored measured column on the product's own background –
   deliberately not a card floating in a grey field, which is the
   generic auth page and reads as third-party. Hierarchy comes from
   type weight and space, per the family's design principles, and the
   accent is spent on exactly one thing: the primary button.
   ================================================================ */

@font-face {
  font-family: "bely";
  src: url("/assets/fonts/Bely-Regular.woff2") format("woff2"),
       url("/assets/fonts/Bely-Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "bely";
  src: url("/assets/fonts/Bely-Bold.woff2") format("woff2"),
       url("/assets/fonts/Bely-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "bely-display";
  src: url("/assets/fonts/BelyDisplay-Regular.woff2") format("woff2"),
       url("/assets/fonts/BelyDisplay-Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Fallbacks, so a page rendered with no product theme is still coherent
   rather than unstyled. Matches the Contentious base.

   These MUST sit inside @layer tokens. Unlayered declarations beat every
   layered one in the cascade, so as plain :root rules they silently overrode
   the product themes in @layer theme and every product rendered in limestone.
   Inside the tokens layer they do what they are meant to: apply only when no
   theme has been loaded. */
/* The defaults now come from @contentious/ui, resolved at build time into
   theme.generated.css and copied beside this file. They used to be typed here
   by hand and four of the six checked had drifted off-brand — --primary was
   #c24e4a against fire-500's #D5544F, and --ring was #4a7fa5, a blue, where the
   brand's focus ring is wave. A sign-in page is the first branded surface a user
   sees, so it has no business inventing the brand.

   --ring itself no longer exists as of @contentious/ui v0.8.0, which measured
   both values in circulation against the 3:1 floor for a non-text indicator and
   failed them both (wave-500 at 2.30:1). The focus ring is now
   --focus-ring-on-light (wave-650) or --focus-ring-on-dark (wave-450); these
   pages are light, so they take the former. The drift story above is kept
   because it records why these values are generated rather than typed, which is
   still the point.

   It is linked from the shell, immediately after tokens.css and before any
   product theme, NOT @imported from here. An @import is only valid before every
   other rule, and the @font-face blocks above it in this file are rules — so an
   import here parses as invalid and is dropped silently, taking every token with
   it and leaving the page on a white canvas. Linking it is also one less
   render-blocking round trip. */

/* Spacing is ours, not the design system's, so it stays unlayered. */
:root {
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;
  --space-3xl: 64px;
}

*,
*::before,
*::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font-family: "bely", Georgia, serif;
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.page {
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-xl);
  padding: var(--space-lg) clamp(var(--space-lg), 6vw, var(--space-3xl));

  /* The whole stack is centred as one composition - identity, form and
     family line share a left edge and sit together in the middle of the
     page. The type inside stays left-aligned: centring a form's labels
     makes every row start in a different place and the eye has nothing
     to track down. */
  margin-inline: auto;
  max-width: 100%;
  justify-items: center;
}

.identity,
.column,
.family {
  width: 100%;
  max-width: 24rem;
}

/* ── Product identity ───────────────────────────────────────────
   The answer to "where am I?", placed before the question is asked.
   Unlike the product's own navigation, the name is never hidden on
   small screens: on an unfamiliar domain the name IS the reassurance. */
.identity {
  display: flex;
  align-items: center;
  gap: 10px;
}

.identity img {
  width: 36px;
  height: 36px;
  object-fit: contain;
}

.identity-name {
  font-family: "bely-display", Georgia, serif;
  font-size: 1.25rem;
  letter-spacing: 0.01em;
}

/* ── The column ─────────────────────────────────────────────────
   Left-anchored, measure-limited. Large screens get more space
   around it, not a wider column.

   Sits in the optical upper-middle rather than dead centre: centred
   in a tall viewport it floats, and reads as sparse rather than
   generous. Print does not centre a page of text vertically either. */
.column {
  width: 100%;
  max-width: 24rem;
  align-self: start;
  margin-top: clamp(var(--space-md), 7vh, var(--space-2xl));
}


h1 {
  font-family: "bely-display", Georgia, serif;
  font-weight: 400;
  font-size: clamp(2rem, 1.6rem + 1.6vw, 2.75rem);
  line-height: 1.1;
  margin: 0 0 var(--space-md);
}

.intro {
  margin: 0 0 var(--space-xl);
  color: var(--muted-foreground);
  max-width: 34ch;
}

/* Whatever follows the heading gets the same breath, whether that is the
   form or the Google button. */
h1 + form,
h1 + .social,
h1 + .stack { margin-top: var(--space-xl); }

.social + .divider { margin-top: var(--space-lg); }

/* ── Form ───────────────────────────────────────────────────────── */
.field { margin-bottom: var(--space-lg); }

.field-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: 6px;
}

label {
  display: block;
  font-size: 0.9375rem;
  margin-bottom: 6px;
}

.field-header label { margin-bottom: 0; }

input[type="email"],
input[type="password"],
input[type="text"] {
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: 1rem;
  color: inherit;
  background: color-mix(in srgb, var(--background) 60%, white);
  border: 1px solid var(--input);
  border-radius: var(--radius);
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}

/* ── Password reveal ────────────────────────────────────────────
   The toggle sits inside the field, and the input reserves room for it
   so a long password never runs underneath the word. */
.password-wrap { position: relative; }

.password-wrap input { padding-right: 4.5rem; }

.reveal {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  padding: 6px 8px;
  font: inherit;
  font-size: 0.875rem;
  color: var(--muted-foreground);
  background: none;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.reveal:hover { color: var(--foreground); }

.reveal:focus-visible {
  outline: none;
  color: var(--foreground);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus-ring-on-light) 35%, transparent);
}

input:focus-visible {
  outline: none;
  border-color: var(--focus-ring-on-light);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus-ring-on-light) 25%, transparent);
}

/* ── Buttons ────────────────────────────────────────────────────
   Exactly one filled button per page. The accent works because it
   is rare; spending it twice halves it. */
.btn {
  display: block;
  width: 100%;
  padding: 12px 16px;
  font: inherit;
  font-size: 1rem;
  text-align: center;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 120ms ease-out, border-color 120ms ease-out;
}

.btn-primary {
  background: var(--primary);
  color: var(--primary-foreground);
}
.btn-primary:hover { background: color-mix(in srgb, var(--primary) 88%, black); }

.btn-secondary {
  background: transparent;
  color: inherit;
  border-color: var(--border);
  text-decoration: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.btn-secondary:hover { border-color: var(--muted-foreground); }

.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus-ring-on-light) 35%, transparent);
}

.btn[disabled] { opacity: 0.6; cursor: default; }

/* ── Divider ────────────────────────────────────────────────────── */
.divider {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-md);
  margin: var(--space-lg) 0;
  color: var(--muted-foreground);
  font-size: 0.875rem;
}
.divider::before,
.divider::after {
  content: "";
  height: 1px;
  background: var(--border);
}

/* ── Links ──────────────────────────────────────────────────────── */
a {
  color: inherit;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
a:hover { text-decoration-thickness: 2px; }

.link-quiet {
  font-size: 0.9375rem;
  color: var(--muted-foreground);
}

.after-form {
  margin: var(--space-lg) 0 0;
  font-size: 0.9375rem;
  color: var(--muted-foreground);
}

/* ── Errors ─────────────────────────────────────────────────────
   Inline, next to the field at fault. Never a banner, never a modal. */
.error {
  margin: var(--space-md) 0 0;
  padding: 10px 13px;
  font-size: 0.9375rem;
  color: var(--destructive);
  background: color-mix(in srgb, var(--destructive) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--destructive) 25%, transparent);
  border-radius: var(--radius);
  animation: settle 160ms ease-out;
}

.error[hidden] { display: none; }

@keyframes settle {
  from { opacity: 0; transform: translateY(-2px); }
  to { opacity: 1; transform: none; }
}

/* ── Family line ────────────────────────────────────────────────
   Load-bearing: this is the answer to "what is contentious.ltd".
   Not to be trimmed for tidiness. */
.family {
  border-top: 1px solid var(--border);
  padding-top: var(--space-md);
  color: var(--muted-foreground);
  font-size: 0.875rem;
}
.family p { margin: 0; }

/* ── Notice, hint and message pages ─────────────────────────────
   The pages that are all message: a link sent, an email to verify,
   an expired token. Type and space rather than an alert box. */
.hint {
  margin: calc(-1 * var(--space-md)) 0 var(--space-lg);
  font-size: 0.875rem;
  color: var(--muted-foreground);
}

.notice {
  margin: 0 0 var(--space-lg);
  padding: var(--space-lg);
  background: color-mix(in srgb, var(--background) 55%, white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.notice p { margin: 0 0 var(--space-md); }
.notice p:last-child { margin-bottom: 0; }
.notice .btn { margin-top: var(--space-md); }

.notice-problem {
  background: color-mix(in srgb, var(--destructive) 6%, var(--background));
  border-color: color-mix(in srgb, var(--destructive) 22%, transparent);
}

.link-button {
  font: inherit;
  font-size: 0.9375rem;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.link-button:hover { text-decoration-thickness: 2px; }

.product-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-sm);
}
.product-list a {
  display: block;
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--border);
  font-family: "bely-display", Georgia, serif;
  font-size: 1.125rem;
  text-decoration: none;
}
.product-list a:hover { color: var(--primary); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
