/* The four doors: sign in, sign up, ask for a password, set a password.
 *
 * They were two designs that agreed on nothing, and neither used the app's
 * tokens — so neither followed dark mode. Both also read variables that were
 * never defined anywhere (`--accent`, `--text`, `--bg-light`, `--border`),
 * which is why the submit button rendered with NO background: the declaration
 * was `background: var(--accent)` and there was nothing behind it. Measured on
 * /session/new before this: the button's computed background was
 * rgba(0, 0, 0, 0).
 *
 * Everything here reads the semantic layer (ADR 016), which is what makes the
 * three dark-mode states work with no rule of their own. */

.auth-screen {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  min-height: 100vh;
  background: var(--nt-color-background, #ffffff);
  color: var(--nt-color-foreground, #24292f);
}

/* ---------------------------------------------------------- the showcase */

/* The ground is the product's own gradient — the two colours of the ntabs
 * icon — not a stock purple-to-blue. It is the one saturated surface in the
 * app, and it is here because this is the only screen whose job is to say
 * what the thing is. */
.auth-showcase {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2.5rem;
  padding: 3rem;
  background: linear-gradient(140deg, #5b63c9 0%, #707def 42%, #c98fdd 100%);
  color: #ffffff;
}

/* A slow wash over the gradient so it does not read as a flat swatch. */
.auth-showcase::after {
  content: "";
  position: absolute;
  inset: -30%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.22), transparent 70%);
  transform: translate(18%, -22%);
  pointer-events: none;
}

.auth-stage {
  perspective: 1600px;
  display: flex;
  justify-content: center;

  /* The spread reaches below and to both sides of the front page. Without the
   * room, the pages behind land on top of the pitch — measured by looking:
   * the headline read through two pages of the deck. */
  padding-bottom: 10.5rem;
}

/* The deck is one box; the slides stack inside it and take turns. Its height
 * comes from the tallest slide, so the ground below never jumps between two
 * pages of different length. */
.auth-deck {
  position: relative;
  width: min(100%, 27rem);
  display: grid;
}

/* One page in front and centred, the other three cascading down behind it —
 * close together side to side, spread out top to bottom, so the deck reads
 * as a run of pages rather than a pile at one corner.
 *
 * They keep the same angle. An earlier version gave each its own rotation in
 * alternating directions and the whole thing read as crooked; the tilt is the
 * scene's, not each page's.
 *
 * `data-depth` says how far back a page stands (0 in front); the controller
 * moves the attribute and the four rules below do the rest. Four explicit
 * rules rather than arithmetic over a custom property: a layout you can see
 * is easier to read when each position is written down. */
.auth-page {
  grid-area: 1 / 1;
  align-self: start;
  border-radius: 14px;
  overflow: hidden;
  background: #ffffff;
  color: #1f2328;
  transform-origin: 50% 40%;
  box-shadow: 0 40px 80px -20px rgba(16, 18, 40, 0.55), 0 8px 24px rgba(16, 18, 40, 0.25);
  transition: transform 620ms cubic-bezier(0.22, 0.8, 0.28, 1), opacity 420ms ease;
}

/* Centre, in front. */
.auth-page[data-depth="0"] {
  transform: perspective(1600px) rotateY(-13deg) rotateX(5deg) rotateZ(-1.5deg);
  opacity: 1;
  z-index: 10;
}

/* Slightly right, further down. */
.auth-page[data-depth="1"] {
  transform: perspective(1600px) translate(10%, 25%) scale(0.84) rotateY(-13deg) rotateX(5deg) rotateZ(-1.5deg);
  opacity: 0.92;
  z-index: 9;
}

/* Slightly left, further down still. */
.auth-page[data-depth="2"] {
  transform: perspective(1600px) translate(-10%, 45%) scale(0.76) rotateY(-13deg) rotateX(5deg) rotateZ(-1.5deg);
  opacity: 0.88;
  z-index: 8;
}

/* Last, at the bottom of the cascade. */
.auth-page[data-depth="3"] {
  transform: perspective(1600px) translate(3%, 63%) scale(0.68) rotateY(-13deg) rotateX(5deg) rotateZ(-1.5deg);
  opacity: 0.82;
  z-index: 7;
}

/* Clicking a page behind brings it forward. It is a shortcut for the pointer,
 * not the only way in: the marks below do the same thing, they are real
 * buttons with names, and they are what a keyboard reaches. That is why these
 * can stay out of the reading order — the function is already exposed. */
.auth-page[aria-hidden="true"] { cursor: pointer; }

/* The one in front has nowhere to go, so it takes no clicks and shows no
 * hand — and the text inside it stays selectable. */
.auth-page[aria-hidden="false"] { cursor: default; }

.auth-page[aria-hidden="true"]:hover { opacity: 1; }

.auth-page-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  background: #f4f5f8;
  border-bottom: 1px solid #e3e5ec;
}

.auth-dot { width: 9px; height: 9px; border-radius: 50%; background: #d4d7e0; }
.auth-dot:first-child { background: #f2a5a0; }
.auth-dot:nth-child(2) { background: #f4d08a; }
.auth-dot:nth-child(3) { background: #a8d6a4; }

.auth-url {
  margin-left: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  color: #7b8194;
}

.auth-page-body { padding: 22px 24px 26px; }

.auth-kicker {
  margin: 0 0 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #b4531a;
}

.auth-title {
  margin: 0 0 8px;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: #1f2328;
}

.auth-text { margin: 0 0 14px; font-size: 12.5px; line-height: 1.5; color: #4a5160; }
.auth-text-muted { margin: 0; display: flex; gap: 6px; }

.auth-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; }

.auth-card {
  padding: 10px 12px;
  border: 1px solid #e3e5ec;
  border-radius: 8px;
  background: #f8f9fb;
}

.auth-card b { display: block; font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.auth-card span { font-size: 11px; color: #7b8194; }

/* Six bars, no library: the product's chart block in miniature. */
.auth-chart {
  display: flex;
  align-items: flex-end;
  gap: 7px;
  height: 74px;
  padding: 10px 12px;
  margin-bottom: 12px;
  border: 1px solid #e3e5ec;
  border-radius: 8px;
  background: #f8f9fb;
}

/* The bars grow when the slide arrives: the block being read, in one second.
 * Height comes from `--h` on the element, so the markup carries the data and
 * the stylesheet carries the motion. */
.auth-chart span {
  flex: 1;
  height: 0;
  border-radius: 3px 3px 0 0;
  background: #2a78d6;
  transition: height 620ms cubic-bezier(0.22, 0.8, 0.28, 1);
}

.auth-chart span:nth-child(even) { background: #6ea3e4; }
.auth-page[aria-hidden="false"] .auth-chart span { height: var(--h); }
.auth-page[aria-hidden="false"] .auth-chart span:nth-child(2) { transition-delay: 60ms; }
.auth-page[aria-hidden="false"] .auth-chart span:nth-child(3) { transition-delay: 120ms; }
.auth-page[aria-hidden="false"] .auth-chart span:nth-child(4) { transition-delay: 180ms; }
.auth-page[aria-hidden="false"] .auth-chart span:nth-child(5) { transition-delay: 240ms; }
.auth-page[aria-hidden="false"] .auth-chart span:nth-child(6) { transition-delay: 300ms; }

.auth-pill {
  display: inline-block;
  padding: 2px 9px;
  border: 1px solid #e3e5ec;
  border-radius: 999px;
  background: #f8f9fb;
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #7b8194;
}

.auth-pill-accent { color: #b4531a; border-color: #e8c3a8; background: transparent; }

/* ------------------------------------------------ a theme per slide
 * Each example page carries its own palette, because that difference is the
 * pitch: the same markdown, four looks. Local variables rather than four
 * copies of every rule. */
.auth-page-blog {
  background: #fbfaf7;
  color: #24201b;
}

.auth-page-blog .auth-page-bar { background: #f2efe9; border-bottom-color: #e5e0d6; }
.auth-page-blog .auth-kicker { color: #9a5b2a; }
.auth-page-blog .auth-title { font-family: "Iowan Old Style", Palatino, Georgia, serif; font-weight: 600; letter-spacing: -0.01em; }
.auth-page-blog .auth-text { font-family: "Iowan Old Style", Palatino, Georgia, serif; font-size: 13px; color: #4a443c; }
.auth-page-blog .auth-pill { background: #f2efe9; border-color: #e5e0d6; color: #6d665c; }
.auth-page-blog .auth-pill-accent { color: #9a5b2a; border-color: #dcc3a8; background: transparent; }

.auth-quote {
  margin: 0 0 12px;
  padding: 2px 0 2px 12px;
  border-left: 2px solid #9a5b2a;
  font-family: "Iowan Old Style", Palatino, Georgia, serif;
  font-size: 13.5px;
  font-style: italic;
  color: #3a352e;
}

.auth-page-chat { background: #f3f1ec; color: #111b21; }
.auth-page-chat .auth-page-bar { background: #e9e6df; border-bottom-color: #dcd8cf; }
.auth-page-chat .auth-kicker { color: #00745f; }
.auth-page-chat .auth-pill { background: #e9e6df; border-color: #dcd8cf; color: #5c6b63; }
.auth-page-chat .auth-pill-accent { color: #00745f; border-color: #a9cfc3; background: transparent; }

.auth-thread { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }

.auth-bubble {
  align-self: flex-start;
  max-width: 76%;
  padding: 7px 10px;
  border-radius: 12px 12px 12px 4px;
  background: #ffffff;
  font-size: 12px;
  line-height: 1.4;
  color: #111b21;
  box-shadow: 0 1px 1px rgba(17, 27, 33, 0.08);
}

.auth-bubble-me {
  align-self: flex-end;
  border-radius: 12px 12px 4px 12px;
  background: #d5f0e4;
}

.auth-bubble code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; }

.auth-page-dark { background: #0f1115; color: #e8e8e6; }
.auth-page-dark .auth-page-bar { background: #171a20; border-bottom-color: #262a33; }
.auth-page-dark .auth-url { color: #8d94a3; }
.auth-page-dark .auth-dot { background: #333844; }
.auth-page-dark .auth-dot:first-child { background: #b4655f; }
.auth-page-dark .auth-dot:nth-child(2) { background: #b3924f; }
.auth-page-dark .auth-dot:nth-child(3) { background: #5f8f5c; }
.auth-page-dark .auth-kicker { color: #ff8a3d; }
.auth-page-dark .auth-title { color: #f2f2f0; }
.auth-page-dark .auth-text { color: #9aa0a6; }
.auth-page-dark .auth-card { background: #171a20; border-color: #262a33; }
.auth-page-dark .auth-card span { color: #8d94a3; }
.auth-page-dark .auth-chart { background: #171a20; border-color: #262a33; }
.auth-page-dark .auth-chart span { background: #ff8a3d; }
.auth-page-dark .auth-chart span:nth-child(even) { background: #b8632c; }
.auth-page-dark .auth-pill { background: #171a20; border-color: #262a33; color: #8d94a3; }
.auth-page-dark .auth-pill-accent { color: #ff8a3d; border-color: #6b3a1c; background: transparent; }

.auth-pitch { position: relative; z-index: 1; max-width: 30rem; margin: 0 auto; }

.auth-pitch-title {
  margin: 0 0 0.6rem;
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  text-wrap: balance;
}

.auth-pitch-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.35rem; }

.auth-pitch-list li {
  position: relative;
  padding-left: 1.15rem;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.88);
}

.auth-pitch-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.75);
}

.auth-pitch-list b { color: #ffffff; font-weight: 650; }

/* Where the deck is, not a control: four marks that follow the rotation. A
 * clickable dot here would be reachable by mouse and by nothing else, since
 * the whole showcase is hidden from assistive tech. */
.auth-ticks { display: flex; gap: 6px; margin-top: 1.4rem; }

.auth-tick {
  width: 22px;
  height: 3px;
  padding: 0;
  border: 0;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.32);
  cursor: pointer;
  transition: background 300ms ease, width 300ms ease;

  /* A 3px-tall control is impossible to hit. The bar is what you see; the
   * target around it is 24px tall, which is what a finger and a shaky mouse
   * actually need. */
  position: relative;
}

.auth-tick::before {
  content: "";
  position: absolute;
  inset: -11px -3px;
}

.auth-tick:hover { background: rgba(255, 255, 255, 0.6); }
.auth-tick.is-active { width: 34px; background: rgba(255, 255, 255, 0.9); }

.auth-tick:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 4px;
}

/* ---------------------------------------------------------- the form */

.auth-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2.5rem 2rem;
}

.auth-form-wrap { width: 100%; max-width: 22rem; }

.auth-brand {
  display: inline-block;
  margin-bottom: 2rem;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--nt-color-foreground, #24292f);
  text-decoration: none;
}

.auth-heading {
  margin: 0 0 0.4rem;
  font-size: 1.6rem;
  font-weight: 680;
  letter-spacing: -0.025em;
  color: var(--nt-color-foreground, #24292f);
  text-wrap: balance;
}

.auth-subtitle {
  margin: 0 0 1.6rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--nt-color-muted-foreground, #586069);
}

.auth-heading + .auth-form { margin-top: 1.6rem; }

.auth-form { display: flex; flex-direction: column; gap: 1.1rem; }

.form-group { display: flex; flex-direction: column; gap: 0.4rem; }

.form-group label {
  font-size: 0.85rem;
  font-weight: 620;
  color: var(--nt-color-foreground, #24292f);
}

.auth-hint {
  font-weight: 400;
  font-size: 0.8rem;
  color: var(--nt-color-muted-foreground, #586069);
}

.form-control {
  width: 100%;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--nt-color-border, #d0d7de);
  border-radius: var(--nt-radius, 6px);
  background: var(--nt-color-background, #ffffff);
  color: var(--nt-color-foreground, #24292f);
  font: inherit;
  font-size: 0.95rem;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.form-control::placeholder { color: var(--nt-color-muted-foreground, #586069); opacity: 0.75; }

.form-control:focus {
  outline: none;
  border-color: var(--nt-color-accent, #007acc);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--nt-color-accent, #007acc) 22%, transparent);
}

/* The username field is one control made of two boxes; the focus ring has to
 * be drawn on the wrapper or it lands around half of it. */
.input-wrapper {
  display: flex;
  align-items: center;
  border: 1px solid var(--nt-color-border, #d0d7de);
  border-radius: var(--nt-radius, 6px);
  background: var(--nt-color-background, #ffffff);
  overflow: hidden;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.input-wrapper:focus-within {
  border-color: var(--nt-color-accent, #007acc);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--nt-color-accent, #007acc) 22%, transparent);
}

.domain-prefix {
  padding: 0.7rem 0.15rem 0.7rem 0.8rem;
  font-size: 0.95rem;
  font-weight: 600;
  white-space: nowrap;
  color: var(--nt-color-muted-foreground, #586069);
}

.input-wrapper .form-control {
  border: 0;
  border-radius: 0;
  padding-left: 0.15rem;
  background: transparent;
}

.input-wrapper .form-control:focus { box-shadow: none; }

.btn {
  padding: 0.75rem 1.2rem;
  border: 1px solid transparent;
  border-radius: var(--nt-radius, 6px);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 650;
  cursor: pointer;
  transition: filter 120ms ease;
}

.btn:hover { filter: brightness(1.06); }

.btn:focus-visible {
  outline: 2px solid var(--nt-color-accent, #007acc);
  outline-offset: 2px;
}

/* The label is the GROUND, not white. White on the light accent is 4.51:1,
 * which passes; white on the dark accent (#58a6ff) is 2.53:1, which does
 * not — measured. Taking the background token inverts the pair with the
 * scheme: white on #007acc in light, near-black on #58a6ff in dark, and both
 * read. A button whose label vanishes in one scheme is exactly the failure
 * this token layer exists to prevent. */
.btn-primary {
  width: 100%;
  background: var(--nt-color-accent, #007acc);
  color: var(--nt-color-background, #ffffff);
}

.auth-links {
  margin-top: 1.5rem;
  display: grid;
  gap: 0.3rem;
  font-size: 0.88rem;
  color: var(--nt-color-muted-foreground, #586069);
}

.auth-links p { margin: 0; }
.auth-links a { color: var(--nt-color-accent, #007acc); text-decoration: none; }
.auth-links a:hover { text-decoration: underline; }

.auth-alert,
.auth-notice {
  margin: 0 0 1.2rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid;
  border-radius: var(--nt-radius, 6px);
  font-size: 0.88rem;
}

.auth-alert { border-color: #f0b4b0; background: #fdf0ef; color: #8a2b22; }
.auth-notice { border-color: #a8d6a4; background: #eff8ee; color: #1f6b3a; }

.field-error { margin: 0; font-size: 0.82rem; color: #a3352a; }

.password-strength { height: 4px; border-radius: 99px; background: var(--nt-color-surface, #f6f8fa); }

/* Dark: only what a dark ground needs. The rest is already tokens. */
[data-theme="dark"] .auth-alert { border-color: #6b2b26; background: #2a1613; color: #f5b8b2; }
[data-theme="dark"] .auth-notice { border-color: #2c5c3a; background: #10231a; color: #a9e0bd; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .auth-alert { border-color: #6b2b26; background: #2a1613; color: #f5b8b2; }
  :root:not([data-theme="light"]) .auth-notice { border-color: #2c5c3a; background: #10231a; color: #a9e0bd; }
}

/* ---------------------------------------------------------- narrow */

/* The showcase is the pitch, not the door. Below the split it goes, rather
 * than pushing the form under a fold — somebody who came here to sign in
 * should not have to scroll past an advertisement to do it. */
/* The same showcase, stacked. The examples are the pitch, so a phone gets
 * them too — the earlier version hid them and put an abstract field of
 * coloured tiles in their place, which was decoration standing in for the
 * product. Now it is one component in two layouts.
 *
 * The card was also pinned to the top, which left a block of dead colour
 * below it: measured 380px of nothing on a 390x844 phone, and 65% of a tall
 * one. The deck fills that space with something worth looking at. */
@media (max-width: 900px) {
  .auth-screen {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    background: linear-gradient(160deg, #5b63c9 0%, #707def 46%, #c98fdd 100%);
  }

  .auth-showcase {
    padding: 1.25rem 1.25rem 0;
    gap: 0.85rem;
    justify-content: flex-start;
    overflow: visible;
  }

  /* Less turn at this size: a page 300px wide reads as a shape rather than
   * as a screen once it is rotated far. */
  .auth-deck { width: 100%; margin-left: 0; }

  /* Less turn and a tighter stack at this size: a page 300px wide reads as a
   * shape rather than as a screen once it is rotated far. */
  /* One page at a time here. The fan needs room to the left and below, and
   * there is none; with the crop on top, the cards behind showed their text
   * through the faded edge of the one in front — two headlines and a chat
   * bubble reading through each other. */
  .auth-page {
    transform-origin: 50% 45%;
    transform: perspective(1200px) rotateY(-5deg) rotateX(2deg) rotateZ(-0.8deg);
  }

  /* Invisible here, so not clickable either: a hit area over nothing is a
   * dead click. The marks remain. */
  .auth-page[data-depth="1"],
  .auth-page[data-depth="2"],
  .auth-page[data-depth="3"] { opacity: 0; pointer-events: none; }

  /* Cropped, with the bottom fading out: an example page that continues past
   * the cut says "this is a page" more honestly than a shrunken whole one,
   * and it buys the room the form needs. Measured before the cap: on a
   * 390x844 phone the submit button of the sign-up form sat at 953px — below
   * the fold, on the screen whose only job is that button. */
  .auth-page {
    max-height: 12rem;
    -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
  }

  .auth-page-body { padding: 16px 18px 18px; }
  .auth-title { font-size: 17px; }
  .auth-text { font-size: 12px; margin-bottom: 10px; }
  .auth-cards { gap: 8px; margin-bottom: 10px; }
  .auth-card b { font-size: 17px; }
  .auth-chart { height: 58px; margin-bottom: 10px; }
  .auth-thread { gap: 5px; margin-bottom: 10px; }
  .auth-bubble { font-size: 11.5px; }
  .auth-quote { font-size: 12.5px; margin-bottom: 10px; }

  /* The bullets are desktop copy; on a phone they push the form under the
   * fold. The line and the marks are enough to say what is being shown. */
  .auth-pitch { margin: 0; }
  .auth-pitch-list { display: none; }
  .auth-pitch-title { font-size: 1.15rem; margin-bottom: 0.45rem; }
  .auth-ticks { margin-top: 0; }

  .auth-panel {
    padding: 1.4rem 1.25rem 2.5rem;
    align-items: flex-start;
  }

  /* A sheet over the gradient: the form needs its own ground, or the colour
   * behind it reads straight through the labels. */
  .auth-form-wrap {
    padding: 1.5rem 1.3rem 1.6rem;
    border-radius: 16px;
    background: var(--nt-color-background, #ffffff);
    box-shadow: 0 30px 60px -24px rgba(16, 18, 40, 0.6), 0 6px 18px rgba(16, 18, 40, 0.18);
  }

  .auth-brand { margin-bottom: 1.2rem; }
}

/* Short screens, and the focused screens at any height: the examples are the
 * first thing to go, because the form is why somebody is here. */
@media (max-width: 900px) {
  .auth-screen.is-focused > .auth-showcase { display: none; }
  .auth-screen.is-focused { grid-template-rows: 1fr; }
  .auth-screen.is-focused .auth-panel { align-items: center; padding-top: 2rem; }
}

@media (max-width: 900px) and (max-height: 680px) {
  .auth-showcase { display: none; }
  .auth-screen { grid-template-rows: 1fr; }
  .auth-panel { align-items: center; padding-top: 2rem; }
}

@media (prefers-reduced-motion: reduce) {
  .form-control, .input-wrapper, .btn, .auth-ticks span { transition: none; }

  /* No turning, no growing. The controller also declines to start on its
   * own, so this is belt and braces — but the marks still work, because
   * choosing a page is the person's own decision. */
  .auth-page, .auth-chart span { transition: none; }
  .auth-page[aria-hidden="false"] .auth-chart span { height: var(--h); }
}
