/* ==========================================================================
   ScenariGO entry surface: sign in, register, forgot and reset password,
   accept invite, verify email.
   Stage K of the adaptive mobile programme, 2026-08-26.
   Ticket: agent-reviews/Closed/2026-08-26-adaptive-mobile-stage-k-entry-and-account.md

   WHY THIS FILE EXISTS.

   These six pages each carried their own inline <style> block, 3.5KB to 4.8KB,
   near-duplicates of one another, and not one contained a single media query.
   Six copies of one thing is the drift this programme keeps finding, and the F0
   band registry reads linked stylesheets, so it could not see any of them.

   WHAT THE CATALOGUE FOUND, before any of this was written.

   28 distinct selectors across the six blocks. 23 appeared on two or more
   pages, and exactly 2 of those 23 carried differing declarations:

     - :root, where forgot-password and verify-email added --success. Additive,
       not a disagreement: the other four never referenced the token. It is
       defined once below and changes nothing for the pages that ignore it.
     - .login-card button on verify-email, which turned out not to be a styling
       difference at all. That page nested a <button> inside an <a href>, which
       HTML forbids, and the extra declarations existed to style it. Corrected
       first, as its own measured change, under
       agent-reviews/Closed/2026-08-26-nested-buttons-inside-links.md.

   Every other difference between the six blocks was presence or absence, and
   every one is explained by what the page contains: verify-email has no form,
   only login has a "forgot password" line, only accept-invite has a readonly
   prefilled address. So no page needs a modifier class. Each rule below is
   scoped to a class or attribute that only exists on the pages that use it,
   which is why this extraction has no page-specific overrides and does not
   depend on source order.

   NAMING. Not styles.css. login-public is mounted at the server root, ahead of
   public/ (server/app.js), so a file of that name here would be served for
   /styles.css and shadow the learner app's own stylesheet, which public/
   index.html loads by exactly that path.
   ========================================================================== */

:root {
  /* THEME ADOPTION (Stage 2C, 2026-09-17, agent-reviews/Open/2026-08-25-app-wide-
     dark-and-light-theme-options.md). The six entry pages' own token names are
     kept; their values now come from shared-public/theme.css.

     DARK DOES NOT MOVE, apart from two measured contrast corrections Codex
     approved: text links (#3b82f6 was 4.03:1 on the card) and error text
     (#f87171 was 4.25:1 on its tint). Every other token whose dark value equals
     a --sg-theme-* value is pointed at it; --success keeps its dark literal. */
  color-scheme: dark;
  --border: var(--sg-theme-border);
  --accent: var(--sg-theme-accent);
  --accent-bright: var(--sg-theme-accent-bright);
  --text: var(--sg-theme-text);
  --muted: var(--sg-theme-muted);
  --danger: var(--sg-theme-danger);
  --success: #34d399;
  --sg-bg-elevated: var(--sg-theme-bg-elevated);
  --sg-bg-page: var(--sg-theme-bg-page);
  --sg-bg-glow: var(--sg-theme-bg-glow);
  --on-accent: var(--sg-theme-on-accent);
  /* Correction 1: links use the shared legible accent-text colour, 5.82:1 on
     the dark card (was #3b82f6, 4.03:1). */
  --link: var(--sg-theme-accent-text);
  /* Correction 2: error text lifted toward white, 5.16:1 on the unchanged 16%
     danger tint (was #f87171, 4.25:1). The box itself is untouched. */
  --danger-text: color-mix(in srgb, #f87171 80%, #fcfcfc);
  /* The card's hairline edge on dark. */
  --card-border: color-mix(in srgb, var(--border) 30%, transparent);
  --keyboard-inset: 0px;
}

/* Light. At 30% the card edge would measure 1.36:1 on white and vanish, so light
   uses the full border (3.31:1 on the card, 3.09:1 against the page) and no
   shadow, as Super Admin does. The body glow collapses onto the page colour. */
:root[data-theme="light"] {
  color-scheme: light;
  --success: var(--sg-theme-success);
  --sg-bg-glow: var(--sg-theme-bg-page);
  --danger-text: var(--sg-theme-danger);
  --card-border: var(--border);
}

/* The wordmark pair. White is the default, so a page whose theme script never
   ran still shows the right one on the dark fallback. */
.login-card__logo--light { display: none; }
:root[data-theme="light"] .login-card__logo--dark { display: none; }
:root[data-theme="light"] .login-card__logo--light { display: block; }

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  /* The bottom edge yields to the keyboard so the submit button and the back
     link can be scrolled to while a field is focused. With no keyboard the
     inset is 0 and this computes to exactly the 1.5rem it replaced. */
  padding: 1.5rem 1.5rem calc(1.5rem + var(--keyboard-inset));
  background-color: var(--sg-bg-page);
  background-image:
    radial-gradient(ellipse at top, var(--sg-bg-glow) 0%, var(--sg-bg-page) 65%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
  background-attachment: fixed;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-family: "SG Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--text);
}

/* accept-invite, forgot-password, reset-password and verify-email hide their
   own states; harmless on the two that do not. */
[hidden] {
  display: none !important;
}

/* --------------------------------------------------------------------------
   The card
   -------------------------------------------------------------------------- */

.login-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 340px;
  padding: 2.25rem 2rem 2rem;
  text-align: center;
  background: var(--sg-bg-elevated);
  border: 1px solid var(--card-border);
  border-radius: 14px;
}

.login-card__logo {
  height: 30px;
  width: auto;
  margin: 0 auto 1.5rem;
}

.login-card__title {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 700;
}

.login-card__subtitle {
  margin: 0.35rem 0 1.5rem;
  color: var(--muted);
  font-size: 0.88rem;
}

/* --------------------------------------------------------------------------
   States
   -------------------------------------------------------------------------- */

.login-card__error {
  margin: 0 0 1rem;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent);
  color: var(--danger-text);
  font-size: 0.85rem;
  text-align: left;
}

/* forgot-password and verify-email. */
.login-card__success {
  margin: 0 0 1rem;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--success) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--success) 40%, transparent);
  color: var(--success);
  font-size: 0.85rem;
  text-align: left;
}

/* --------------------------------------------------------------------------
   Form
   -------------------------------------------------------------------------- */

.login-card__label {
  text-align: left;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
  margin: 0 0 0.35rem;
}

.login-card__label:not(:first-of-type) {
  margin-top: 1rem;
}

.login-card input {
  font: inherit;
  width: 100%;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--sg-bg-page) 60%, var(--sg-bg-elevated) 40%);
  color: var(--text);
}

.login-card input:focus {
  outline: none;
  border-color: var(--accent-bright);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-bright) 25%, transparent);
}

/* accept-invite: the invited address is shown but cannot be edited. */
.login-card input[readonly] {
  color: var(--muted);
  cursor: not-allowed;
}

/* accept-invite. */
.login-card__hint {
  margin: 0.35rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
  text-align: left;
}

/* --------------------------------------------------------------------------
   Actions
   -------------------------------------------------------------------------- */

.login-card button {
  font: inherit;
  margin-top: 1.5rem;
  width: 100%;
  padding: 0.65rem 1.25rem;
  border-radius: var(--sg-control-radius, 12px);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--on-accent);
  cursor: pointer;
}

.login-card button:disabled {
  opacity: 0.7;
  cursor: default;
}

/* verify-email's Continue: a link that navigates, wearing the button recipe.
   It used to be a <button> nested inside this anchor. line-height is pinned
   because a <button> takes normal from the user agent where an <a> inherits
   the page's. See the ticket named at the top of this file. */
.login-card__button {
  font: inherit;
  line-height: normal;
  display: block;
  box-sizing: border-box;
  margin-top: 0.5rem;
  width: 100%;
  padding: 0.65rem 1.25rem;
  border-radius: var(--sg-control-radius, 12px);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--on-accent);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   Footer navigation
   -------------------------------------------------------------------------- */

.login-card__footer {
  margin: 1.25rem 0 0;
  font-size: 0.82rem;
  color: var(--muted);
}

/* :not(.sg-back-button) is load-bearing, and the extraction's before/after
   measurement is the only reason it is here. reset-password and verify-email
   put a .sg-back-button inside this footer, and neither page previously
   defined .login-card__footer a at all - so the back button's own colour was
   the only one on offer. Giving all six pages the footer rule handed those two
   a selector of higher specificity (0,1,1 against 0,1,0), which turned the
   back button from --text to --accent-bright on 33 measured combinations. The
   back button carries a complete recipe of its own; this rule is for ordinary
   footer links, and now says so. */
.login-card__footer a:not(.sg-back-button) {
  color: var(--link);
  text-decoration: none;
}

.login-card__footer a:not(.sg-back-button):hover {
  text-decoration: underline;
}

/* login only. */
.login-card__forgot {
  margin: 0.5rem 0 0;
  text-align: right;
  font-size: 0.8rem;
}

.login-card__forgot a {
  color: var(--link);
  text-decoration: none;
}

.login-card__forgot a:hover {
  text-decoration: underline;
}

/* The app-wide back-navigation recipe (2026-08-14 back-navigation audit),
   matching author-public and portal-public. reset-password and verify-email. */
.sg-back-button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 40px;
  padding: 0.5rem 0.9rem;
  border-radius: var(--sg-control-radius, 12px);
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--sg-bg-elevated) 70%, transparent);
  color: var(--text);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.sg-back-button:hover {
  background: color-mix(in srgb, var(--sg-bg-elevated) 85%, var(--accent) 15%);
  border-color: var(--accent);
}

.sg-back-button:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
}

.sg-back-button svg {
  flex-shrink: 0;
}

/* ==========================================================================
   K1: touch targets.

   Measured before this block: every text input 39px, every inline link 17px,
   16 of the 23 controls across the six pages below the 44px floor. The figures
   were identical at 320px and at 1280px, because nothing on these pages
   responded to width at all.

   Gated on pointer capability, not width, and raising heights only - touch is
   not a width question, and no mouse-driven geometry may move. Measured as a
   separate delta from the extraction above, so a regression is attributable to
   the right change.
   ========================================================================== */

@media (pointer: coarse) {
  .login-card input,
  .login-card button,
  .login-card__button {
    min-height: 44px;
  }

  /* An inline element has no box, so a min-height on it does nothing at all -
     the trap Stages F, I and J each met. These links are the 17px ones. */
  .login-card__footer a,
  .login-card__forgot a,
  .sg-back-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    /* Giving a text element a flex box makes its contents flex items, which
       then refuse to shrink. Stage J measured that squeezing a badge to 22px
       around 66px of text. The box exists for the target, not to re-lay out
       what is inside it. */
    flex-wrap: wrap;
    min-width: 0;
  }
}
