/* ============================================================================
 * login.css — the logged-out Login page (Phase 2 Task 11).
 *
 * Pixel source: project/login/login-screens.jsx (the bundle's VarGraph login —
 * neuron hero + side sign-in panel). The page lives OUTSIDE the portal shell
 * (no rail / no topbar): a standalone surface that still consumes the Phase-1
 * --tp-* tokens and self-hosted fonts. Token-pure: no hardcoded palette hex
 * except the on-ink text whites the design system already allowlists for
 * solid fills and the Microsoft brand squares (a vendor glyph, not a token).
 *
 * D-085: no inline JS, no inline style="" — the show/hide toggle, tagline
 * rotation, sign-in button state, and the (CSP-clean canvas) hero animation
 * all live in static/js/login.js bound through data-* hooks. element.style
 * written by JS is allowed; this stylesheet supplies every static rule.
 *
 * OWNER DECISION (2026-06-17): the identifier field renders as a full Email
 * (multi-org / multi-domain), not the bundle's "Username / firstname.lastname".
 * Visual styling matches the bundle field exactly. (docs/design-deltas.md.)
 *
 * Hero background: the bundle uses a Three.js WebGL neuron field. The strict
 * CSP (no CDN, default-src 'self') + proportionality favored a vendor-free
 * 2D-canvas neuron field driven from login.js over self-hosting Three.js; it
 * renders on a static brand gradient that also stands alone with JS off or
 * under prefers-reduced-motion. (design-delta logged.)
 * ========================================================================= */

.lg-page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  background: var(--tp-surface);
  font-family: var(--tp-font-ui);
  color: var(--tp-ink);
}

/* ---- left hero pane (desktop) ----------------------------------------------
 * The dark neuron pane: a radial brand gradient with the canvas painted over
 * it, the brand mark top-left, the headline block centered, the version tag
 * bottom-left. Stacks above the form on phone. */
/* DEVICE CHROME (safe-area sweep 2026-08-06, finding 3 — the Phase 4.6
 * "letterboxed /login-as-first-screen inset audit"). This page is the installed
 * PWA's first screen: start_url is `/`, and an unauthenticated launch lands
 * here. It sits OUTSIDE the shell, so nothing above it absorbs an inset the way
 * the topbar does for .tp-content — and until this pass login.css contained
 * ZERO --tp-safe-* references on any axis.
 *
 * Which edges each column really touches drives which terms it takes. In the
 * default ROW layout the hero is the LEFT column and the panel the RIGHT one,
 * so each takes top + bottom plus its OWN outer side; the seam between them is
 * interior and takes nothing — reserving there would pad against no device edge
 * (the .adm-drill-header reasoning). The <768 stacked layout below re-states
 * both shorthands with the edges THAT layout has.
 *
 * Operators per the sweep's two-axis rule: max() on the sides (the notch inset
 * already IS the clearance — and the shipped 56px landscape gutter was 3px
 * SHORT of a 59px notch, which is what put the brand lockup under it), calc()
 * on the vertical (the designed 44/40px has to survive on top of the reserved
 * band; the portrait lockup rendered at y 24-58, wholly inside the 59px Island
 * band, and the panel's last row ended 22px above a 34px home indicator).
 * The hero's dark gradient still runs to the glass — this pads CONTENT only.
 * Every inset is 0 in a browser tab, so the designed 44/56 and 40/56 render
 * unchanged there. */
.lg-hero {
  position: relative;
  flex: 1 1 56%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: calc(44px + var(--tp-safe-top)) 56px
    calc(44px + var(--tp-safe-bottom)) max(56px, var(--tp-safe-left));
  color: #FFFFFF; /* on-ink text (design-system allowlisted on solid fills) */
  /* The bundle's radial cast: #16243F -> #070B14. Kept as literals: this is the
   * sanctioned dark hero surface (like RAPID), not part of the light palette. */
  background:
    radial-gradient(120% 130% at 50% 6%, #16243F 0%, #070B14 72%);
}

/* The vignette the bundle lays over the neuron field (focuses the center). */
.lg-hero-vignette {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(78% 66% at 50% 42%, rgba(7, 11, 20, 0) 18%, rgba(7, 11, 20, 0.74) 100%);
}

/* The CSP-clean 2D-canvas neuron field; sits between the gradient and the
 * vignette. login.js sizes + paints it (element.style writes are allowed). */
.lg-hero-canvas {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.lg-hero-inner {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* ---- brand mark (BrandMark tone="light") ----------------------------------- */
.lg-brand {
  display: flex;
  align-items: center;
  gap: 11px;
}

/* The hero lockup renders via the .st-* brand layer (brand.css, dark-GROUND
   set — D-153); only the text stack + byline colour live here. */
.lg-brand-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  line-height: 1.25;
}

.lg-brand-org {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.6);
}

/* ---- hero copy block (Hero tone="dark") ------------------------------------ */
.lg-hero-copy {
  flex: 1;
  display: flex;
  align-items: center;
}

.lg-hero-stack {
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: 540px;
}

.lg-h1 {
  margin: 0;
  font-size: 54px;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.04;
  color: #FFFFFF;
  text-wrap: balance;
}

.lg-sub {
  margin: 0;
  font-size: 18.5px;
  line-height: 1.5;
  font-weight: 450;
  max-width: 460px;
  color: rgba(255, 255, 255, 0.74);
}

/* Rotating tagline row: bolt glyph + italic line, cross-fading in login.js. */
.lg-tagline {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-top: 6px;
  height: 48px;
  overflow: hidden;
}

.lg-tagline-icon {
  color: var(--tp-brand);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  margin-top: 2px;
  transition: opacity 0.45s;
}

.lg-tagline-text {
  font-size: 13.5px;
  font-style: italic;
  font-weight: 500;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.6);
  transition: opacity 0.45s, transform 0.45s;
}

/* The cross-fade state class login.js toggles between tagline swaps. */
.lg-tagline.is-fading .lg-tagline-icon,
.lg-tagline.is-fading .lg-tagline-text {
  opacity: 0;
}

.lg-tagline.is-fading .lg-tagline-text {
  transform: translateY(4px);
}

/* ---- version tag (VersionTag tone="dark") ---------------------------------- */
.lg-version {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--tp-font-mono);
  font-size: 10.5px;
  color: rgba(255, 255, 255, 0.42);
  letter-spacing: 0.2px;
}

.lg-version-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--tp-radius-pill);
  background: var(--tp-ok);
}

.lg-version-sep {
  opacity: 0.5;
}

/* ---- right sign-in panel ---------------------------------------------------- */
.lg-panel {
  flex: 0 0 44%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Device chrome — the RIGHT column's own edges (see the .lg-hero block).
     The bottom term is also what reserves the scroll end: at 844x390 the form
     is taller than the viewport, so the page scrolls and this padding is the
     last thing above the home indicator. */
  padding: calc(40px + var(--tp-safe-top)) max(56px, var(--tp-safe-right))
    calc(40px + var(--tp-safe-bottom)) 56px;
  background: var(--tp-surface);
}

.lg-panel-inner {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.lg-panel-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.lg-panel-title {
  font-size: 23px;
  font-weight: 750;
  color: var(--tp-ink);
  letter-spacing: -0.015em;
}

.lg-panel-welcome {
  font-size: 14px;
  color: var(--tp-muted);
}

/* ---- error banner ----------------------------------------------------------- */
.lg-error {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0;
  padding: 11px 13px;
  border-radius: var(--tp-radius-control);
  background: var(--tp-danger-soft);
  color: var(--tp-danger);
  border: 1px solid var(--tp-danger);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
}

.lg-error i {
  margin-top: 1px;
  flex-shrink: 0;
}

/* ---- the form --------------------------------------------------------------- */
.lg-form {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.lg-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.lg-field-label {
  display: flex;
  align-items: center;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tp-ink-2);
}

/* The Show/Hide password toggle sits at the end of the password label row. */
.lg-show-toggle {
  margin-left: auto;
  border: none;
  background: transparent;
  color: var(--tp-muted);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  font-family: var(--tp-font-ui);
  padding: 0;
}

.lg-input {
  height: 46px;
  border-radius: 11px;
  border: 1px solid var(--tp-hairline);
  box-shadow: none;
  background: var(--tp-surface);
  padding: 0 13px;
  font-size: 14.5px;
  color: var(--tp-ink);
  font-family: var(--tp-font-ui);
  outline: none;
  width: 100%;
  transition: border 0.15s, box-shadow 0.15s;
}

.lg-input::placeholder {
  color: var(--tp-muted);
}

.lg-input:focus {
  border-color: var(--tp-brand);
  box-shadow: 0 0 0 3px var(--tp-brand-soft);
}

/* Keep autofilled fields on the surface background. Browsers paint their own
   blue/yellow wash on an autofilled input, which made the (autofilled) email box
   read with a different background than the password box on mobile — owner redline
   2026-06-23. The inset box-shadow trick repaints the fill with the surface token
   and forces the text colour back to ink, so every field matches. Token-pure. */
.lg-input:-webkit-autofill,
.lg-input:-webkit-autofill:hover,
.lg-input:-webkit-autofill:focus,
.lg-input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--tp-ink);
  -webkit-box-shadow: 0 0 0 100px var(--tp-surface) inset;
  box-shadow: 0 0 0 100px var(--tp-surface) inset;
  caret-color: var(--tp-ink);
}

.lg-input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 100px var(--tp-surface) inset, 0 0 0 3px var(--tp-brand-soft);
  box-shadow: 0 0 0 100px var(--tp-surface) inset, 0 0 0 3px var(--tp-brand-soft);
}

/* ---- forgot link ------------------------------------------------------------ */
.lg-forgot-row {
  display: flex;
  justify-content: flex-end;
  margin-top: -4px;
}

.lg-forgot {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tp-brand);
  text-decoration: none;
  white-space: nowrap;
}

.lg-forgot:hover {
  text-decoration: underline;
}

/* ---- primary sign-in button (INK fill, never brand-blue) -------------------- */
.lg-submit {
  height: 50px;
  border-radius: 12px;
  border: 1px solid var(--tp-ink);
  background: var(--tp-ink);
  color: #FFFFFF;
  font-size: 15px;
  font-weight: 650;
  font-family: var(--tp-font-ui);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  white-space: nowrap;
  transition: opacity 0.2s;
}

.lg-submit:disabled {
  cursor: default;
}

/* The three faces, swapped by the data-lg-state attribute login.js writes. */
.lg-submit-face {
  display: none;
  align-items: center;
  gap: 10px;
}

.lg-submit[data-lg-state="idle"] .lg-submit-face--idle,
.lg-submit[data-lg-state="signing"] .lg-submit-face--signing,
.lg-submit[data-lg-state="done"] .lg-submit-face--done {
  display: inline-flex;
}

.lg-submit[data-lg-state="done"] {
  opacity: 0.9;
}

/* The signing spinner (reuses the spinner duration token). */
.lg-spin {
  width: 15px;
  height: 15px;
  border-radius: var(--tp-radius-pill);
  border: 2px solid var(--tp-spinner-track-on-fill);
  border-top-color: #FFFFFF;
  animation: lg-spin var(--tp-spin-dur) linear infinite;
}

@keyframes lg-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .lg-spin { animation: none; }
}

/* ---- OR divider ------------------------------------------------------------- */
.lg-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 2px 0;
}

.lg-divider-line {
  flex: 1;
  height: 1px;
  background: var(--tp-hairline);
}

.lg-divider-text {
  font-size: 11.5px;
  color: var(--tp-muted);
  font-weight: 500;
}

/* ---- Continue with Microsoft (surface + hairline) --------------------------- */
.lg-ms {
  height: 48px;
  border-radius: 12px;
  border: 1px solid var(--tp-hairline);
  background: var(--tp-surface);
  color: var(--tp-ink-2);
  font-size: 14.5px;
  font-weight: 600;
  font-family: var(--tp-font-ui);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  text-decoration: none;
}

.lg-ms:hover {
  background: var(--tp-bg);
}

/* Microsoft 4-square glyph — a vendor brand mark (its 4 colors are not tokens). */
.lg-ms-glyph {
  display: grid;
  grid-template-columns: 7px 7px;
  gap: 2px;
}

.lg-ms-sq {
  width: 7px;
  height: 7px;
  border-radius: 1px;
}

.lg-ms-sq--r { background: #F25022; }
.lg-ms-sq--g { background: #7FBA00; }
.lg-ms-sq--b { background: #00A4EF; }
.lg-ms-sq--y { background: #FFB900; }

/* ---- footer ----------------------------------------------------------------- */
.lg-footer {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--tp-muted);
  line-height: 1.5;
  text-align: center;
}

/* ---- responsive: stack the hero above the form on phone --------------------- */
@media (max-width: 767.98px) {
  /* Phone: hero on top FILLS the space above the form so the version tag pins to
     the hero's bottom edge and the page fits the viewport without scrolling on the
     common phone range; the form panel is content-sized at the bottom. (Owner
     redline 2026-06-23: brand→headline margin, version to the bottom, nudge the
     copy down, no scroll on various smartphones.) */
  .lg-page {
    flex-direction: column;
    min-height: 100dvh;
  }

  /* Stacked: the hero owns top + both sides, the panel owns bottom + both
     sides, and the seam between them is interior. Re-stated in full (not
     patched per-side) because each shorthand replaces the base one outright. */
  .lg-hero {
    flex: 1 1 auto;
    min-height: 0;
    padding: calc(24px + var(--tp-safe-top)) max(22px, var(--tp-safe-right)) 18px
      max(22px, var(--tp-safe-left));
  }

  /* Fill the flex-grown hero so the version tag pins to its bottom edge (height:100%
     does not resolve against a flex-sized parent in every engine — use flex-grow). */
  .lg-hero-inner {
    flex: 1 1 auto;
    min-height: 0;
  }

  /* Breathing room between the brand mark and the headline; the copy stays
     centered in the (growing) hero space below that gap. */
  .lg-hero-copy {
    margin-top: 16px;
  }

  .lg-hero-stack {
    gap: 11px;
  }

  /* Compacted so the headline + sub + quip + the brand gap all fit above the form
     without scrolling, down to ~360x740 phones. */
  .lg-h1 {
    font-size: 27px;
  }

  .lg-sub {
    font-size: 14px;
    line-height: 1.45;
  }

  .lg-tagline {
    height: 44px;
    margin-top: 2px;
  }

  .lg-tagline-text {
    font-size: 12.5px;
  }

  /* Sits at the hero's bottom edge (the copy above is flex:1). */
  .lg-version {
    margin-top: 16px;
  }

  .lg-panel {
    flex: 0 0 auto;
    align-items: stretch;
    justify-content: flex-start;
    padding: 18px max(22px, var(--tp-safe-right)) calc(22px + var(--tp-safe-bottom))
      max(22px, var(--tp-safe-left));
  }

  /* Slightly tighter form rhythm so the whole page clears the shortest target
     viewport (down to ~360x740) without scrolling. */
  .lg-form {
    gap: 12px;
  }

  .lg-panel-inner {
    max-width: 100%;
  }

  /* On phone the bundle drops the side panel's "Sign in" heading (the hero
   * already framed the page); keep the form-first layout. */
  .lg-panel-head {
    display: none;
  }
}
