@import url("./tokens.css");

/* Shared by login, signup, verify, set-password, create-password and
   reset-password. The palette, type and pill button match index.html so the
   auth pages read as the same site; the accent below is what carries through
   into the app. */

body {
  margin: 0;
  /* `svh` — the viewport at its smallest, with the phone's browser toolbar
     showing — and not `vh`, which is the viewport at its largest, with the
     toolbar hidden: that measure makes the page a toolbar taller than the
     screen it is on, so every one of these pages scrolls by that much with
     nothing under the fold to scroll to. Not `dvh` either, which would track
     the toolbar and so re-centre the card mid-keystroke when a phone's keyboard
     opens over the form. Falling short of a hidden toolbar costs nothing here:
     the background below is on body itself and propagates to the canvas, so it
     paints whatever this does not reach. */
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--color-body);
  background-color: var(--color-page);
  background-image: radial-gradient(ellipse at 50% 0%, rgba(197, 231, 255, 0.28), transparent 62%);
}

/* Matches the app's --color-selection (the accent, mixed low so it reads as a neutral grey band).
   No color override: forcing dark text here read fine on light sections but
   put dark text on the tint over dark buttons too, which is unreadable.
   Leaving color unset keeps each element's own already-contrast-correct text
   color under the highlight. */
::selection { background-color: color-mix(in srgb, var(--color-accent) 28%, transparent); }
::-moz-selection { background-color: color-mix(in srgb, var(--color-accent) 28%, transparent); }

/* The doorways in — signup and login — wear the demo's ground. On body itself
   rather than a layer over it: body's background propagates to
   the canvas, which `body.leaving`'s opacity does not touch, so the ground this
   paints is still there through the fade and is the same one /demo/tutorial
   comes up on. Only the card crosses. */
body[data-demo-surface] {
  background-color: var(--color-demo-ground);
  background-image:
    radial-gradient(820px 520px at 14% 4%, rgba(255, 255, 255, 0.98), transparent 70%),
    radial-gradient(560px 340px at 72% 9%, rgba(255, 255, 255, 0.72), transparent 70%),
    radial-gradient(700px 430px at 30% 17%, rgba(255, 255, 255, 0.92), transparent 70%),
    radial-gradient(620px 380px at 86% 23%, rgba(255, 255, 255, 0.8), transparent 70%),
    radial-gradient(760px 470px at 10% 30%, rgba(255, 255, 255, 0.96), transparent 70%),
    radial-gradient(660px 400px at 55% 37%, rgba(255, 255, 255, 0.76), transparent 70%),
    radial-gradient(700px 430px at 88% 44%, rgba(255, 255, 255, 0.88), transparent 70%),
    radial-gradient(780px 480px at 22% 50%, rgba(255, 255, 255, 0.94), transparent 70%),
    radial-gradient(600px 370px at 66% 57%, rgba(255, 255, 255, 0.78), transparent 70%),
    radial-gradient(720px 440px at 12% 64%, rgba(255, 255, 255, 0.86), transparent 70%),
    radial-gradient(680px 420px at 80% 70%, rgba(255, 255, 255, 0.9), transparent 70%),
    radial-gradient(740px 450px at 38% 77%, rgba(255, 255, 255, 0.82), transparent 70%),
    radial-gradient(620px 380px at 90% 84%, rgba(255, 255, 255, 0.76), transparent 70%),
    radial-gradient(700px 430px at 20% 91%, rgba(255, 255, 255, 0.9), transparent 70%),
    radial-gradient(720px 440px at 78% 14%, rgba(197, 231, 255, 0.42), transparent 70%),
    radial-gradient(640px 400px at 20% 25%, rgba(186, 198, 255, 0.22), transparent 70%),
    radial-gradient(700px 430px at 74% 34%, rgba(161, 216, 255, 0.28), transparent 70%),
    radial-gradient(680px 420px at 15% 45%, rgba(197, 231, 255, 0.32), transparent 70%),
    radial-gradient(720px 440px at 60% 62%, rgba(186, 198, 255, 0.24), transparent 70%),
    radial-gradient(700px 430px at 35% 88%, rgba(161, 216, 255, 0.2), transparent 70%),
    linear-gradient(180deg, var(--color-demo-ground) 0%, color-mix(in srgb, var(--color-demo-ground) 65%, var(--color-demo-ground-deep)) 35%, color-mix(in srgb, var(--color-demo-ground) 35%, var(--color-demo-ground-deep)) 70%, var(--color-demo-ground-deep) 100%);
}

/* The same grain the marketing pages carry (site.css). Fixed and at z-index -1:
   body's own background propagates to the canvas, so this paints over that and
   under every element on the page. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.12;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.4' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23grain)'/%3E%3C/svg%3E");
}
* { box-sizing: border-box; }
a { color: inherit; text-decoration: none; cursor: pointer; }

.card { width: 100%; max-width: 420px; }

.brand {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 15px; font-weight: 600; letter-spacing: -0.025em; color: var(--color-ink);
  margin-bottom: 36px;
}

.head { text-align: center; margin-bottom: 32px; }
.head h1 {
  font-family: 'Playfair Display', Georgia, 'Times New Roman', serif;
  font-size: 32px; font-weight: 600; line-height: 1.2; letter-spacing: -0.025em;
  color: var(--color-ink); margin: 0 0 10px;
}
.head p { font-size: 15px; line-height: 1.6; color: var(--color-faint); margin: 0; }

form { display: flex; flex-direction: column; gap: 14px; }
label.field { display: block; position: relative; }

input[type="email"],
input[type="text"],
input[type="password"] {
  width: 100%; padding: 14px 16px;
  font-family: inherit; font-size: 15px; color: var(--color-ink);
  background-color: var(--color-white); border: var(--border-width-standard) solid var(--color-line); border-radius: var(--radius-control);
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
input::placeholder { color: var(--color-dim); }
input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 var(--focus-ring-width) color-mix(in srgb, var(--accent) 22%, transparent);
}
input.invalid { border-color: var(--color-danger); }

/* The eye toggle sits inside the field, so the input reserves room on the right. */
.field.with-toggle input { padding-right: 48px; }
.reveal {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  background: none; border: none; cursor: pointer; color: var(--color-faint);
  transition: color 200ms ease;
}
.reveal:hover { color: var(--color-hover-ink); }

.code {
  text-align: center; font-size: 26px; font-weight: 600;
  letter-spacing: 0.4em; text-indent: 0.4em;
}

.cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  background-color: var(--color-navy); color: var(--color-white); border: var(--border-width-standard) solid var(--color-navy); border-radius: 9999px;
  font-family: inherit; font-weight: 500; font-size: 15px; padding: 14px 32px; cursor: pointer;
  transition: background-color 200ms ease, border-color 200ms ease;
}
.cta:hover:not(:disabled):not([aria-disabled="true"]) { background-color: var(--color-navy-lift); border-color: var(--color-navy-lift); }
.cta:disabled, .cta[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }

.cta-alt {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  background-color: var(--color-white); color: var(--color-ink); border: var(--border-width-standard) solid var(--color-line); border-radius: 9999px;
  font-family: inherit; font-weight: 500; font-size: 15px; padding: 13px 32px; cursor: pointer;
  transition: border-color 200ms ease, background-color 200ms ease;
}
.cta-alt:hover:not(:disabled) { border-color: var(--color-faint); background-color: var(--color-hover); }
.cta-alt:disabled { opacity: 0.45; cursor: not-allowed; }

.quiet {
  background: none; border: none; padding: 0; cursor: pointer; font-family: inherit;
  font-size: 14px; color: var(--color-faint); transition: color 200ms ease;
}
.quiet:hover:not(:disabled) { color: var(--color-hover-ink); }
.quiet:disabled { color: var(--color-dim); cursor: not-allowed; }

.link { color: var(--accent-deep); font-weight: 500; }
.link:hover { text-decoration: underline; }

.rule { display: flex; align-items: center; gap: 14px; color: var(--color-dim); font-size: 12px; }
.rule::before, .rule::after { content: ''; flex: 1; height: 1px; background-color: var(--color-hairline); }

.alert {
  padding: 12px 14px; font-size: 14px; line-height: 1.5;
  color: var(--color-danger); background-color: var(--color-danger-soft); border-left: var(--focus-ring-width) solid var(--color-danger); border-radius: var(--radius-compact);
}
.alert[hidden] { display: none; }

.note { font-size: 14px; line-height: 1.6; color: var(--color-faint); text-align: center; margin: 0; }
.fine { font-size: 12px; line-height: 1.6; color: var(--color-dim); text-align: center; margin: 0; }

.badge {
  width: 72px; height: 72px; margin: 0 auto 24px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 20px;
}
.badge-mail { background-color: var(--accent-soft); border: var(--border-width-standard) solid var(--accent); color: var(--accent-deep); }
.badge-done { background-color: var(--color-success-soft); border: var(--border-width-standard) solid var(--color-success); color: var(--color-success); }

.checks { display: flex; flex-direction: column; gap: 7px; margin-top: 12px; }
.check { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--color-faint); }
.check[data-met="true"] { color: var(--color-success); }
.check[data-met="false"] { color: var(--color-danger); }

/* The fill's width is set in JS; data-level only picks --tone, which colours
   the bar and the word beside it together. */
.strength { --tone: var(--color-line); margin-bottom: 12px; }
.strength-head {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: 12.5px; color: var(--color-dim); margin-bottom: 7px;
}
.strength-level { font-weight: 600; color: var(--tone); transition: color 200ms ease; }
.strength-bar {
  height: 4px; border-radius: 9999px;
  background-color: var(--color-hairline); overflow: hidden;
}
.strength-fill {
  width: 0; height: 100%; border-radius: 9999px;
  background-color: var(--tone);
  transition: width 260ms ease, background-color 200ms ease;
}
.strength[data-level="1"] { --tone: var(--color-danger); }
.strength[data-level="2"] { --tone: var(--color-warning); }
.strength[data-level="3"] { --tone: var(--accent); }
.strength[data-level="4"] { --tone: var(--color-success); }

/* Played when the form is submitted with a password the rules reject — the
   bar is what the answer is about, so the bar is what moves. */
@keyframes strength-nudge {
  20% { transform: translateX(-6px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}
.strength.nudge { animation: strength-nudge 420ms ease-in-out; }

@media (prefers-reduced-motion: reduce) {
  .strength-fill { transition: none; }
  .strength.nudge { animation: none; }
}

/* Signup fades the page out before handing the visitor to the demo, so the two
   screens read as one step rather than a swap. Only the card and the grain go:
   body's own background propagates to the canvas, which is painted outside this
   opacity and so holds the ground steady across the navigation. */
body.leaving { opacity: 0; transition: opacity 260ms ease; }

.stack { display: flex; flex-direction: column; gap: 14px; align-items: center; margin-top: 26px; }

/* Sign-in is the tallest of these — a brand line, two fields, two buttons and
   the rule between them — and on the smallest phones in use it came to more
   than the screen, which is the other way a page ends up scrolling. Everything
   here is space between things rather than the things themselves: enough to
   bring it inside a 375x667 phone with the toolbar showing, and nothing that
   changes what the page says or offers. The design canvas these pages were
   drawn from (Web/auth-canvas/) has no build step pointed at site/, so it does
   not carry this. */
@media (max-width: 480px) {
  body { padding: 24px 20px; }
  .head h1 { font-size: 27px; }
  .brand { margin-bottom: 24px; }
  .head { margin-bottom: 24px; }
  form { gap: 12px; }
}
