/* ---------------------------------------------------------------------------
 * Browser pages rendered by the server
 * ---------------------------------------------------------------------------
 * Synapse is a native application. Nothing here is a product surface: this
 * stylesheet dresses the three transactional authorization pages and the
 * public policy/support documents required by the native app and app stores.
 *
 * Each is one card on an empty canvas, so the file stays small on purpose.
 * Sizes come from the tokens below and hold from a 320 pixel phone to a
 * desktop window; the single breakpoint gives the card more padding once
 * there is room, and changes nothing else.
 *
 * Product interaction belongs in the application, not here. Public documents
 * add typography and navigation in `legal.css` without introducing account or
 * learning-data features in the browser.
 * ------------------------------------------------------------------------ */
:root {
  color-scheme: light dark;
  --canvas: #f6f7f9;
  --panel: #ffffff;
  --panel-strong: #ffffff;
  --ink: #10151c;
  --muted: #5c6675;
  --faint: #7c8797;
  --line: #e2e5ea;
  --line-strong: #cbd2dc;
  --neutral-soft: #f6f7f9;
  --neutral-strong: #1878d2;
  --accent: #208aef;
  --accent-soft: #e9f4ff;
  --on-accent: #ffffff;
  --danger: #c0392b;
  --danger-soft: #fdedea;
  --focus: rgb(32 138 239 / 30%);
  --card-shadow: 0 1.25rem 3.5rem rgb(16 21 28 / 8%),
    0 0.25rem 0.9rem rgb(16 21 28 / 5%);
  --provider-background: #ffffff;
  --provider-border: #747775;
  --provider-hover: #f8fafd;
  --provider-text: #1f1f1f;
  --radius-small: 0.875rem;
  --radius: 1.25rem;

  /* Type. `--text-xs` is the readability floor: nothing in the interface is
     allowed below it, whatever its role. Reducing the *number* of things on
     screen is the way to gain room, not reducing their size. */
  --text-xs: 0.8125rem;
  --text-sm: 0.875rem;
  --text-md: 0.9375rem;
  --text-lg: 1.0625rem;
  --text-title: clamp(1.75rem, 1.3rem + 2vw, 2.125rem);

  /* Controls. `--tap` is the touch-target floor of `SPEC.md` §9.11. */
  --tap: 3.25rem;

  background: var(--canvas);
  color: var(--ink);
  font-family:
    ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
    "Segoe UI", sans-serif;
  font-synthesis: none;
}

@media (prefers-color-scheme: dark) {
  :root {
    --canvas: #0d1117;
    --panel: #161b22;
    --panel-strong: #1b222c;
    --ink: #f0f3f6;
    --muted: #9aa5b1;
    --faint: #7d8996;
    --line: #2a3441;
    --line-strong: #3a4655;
    --neutral-soft: #202833;
    --neutral-strong: #358bd9;
    --accent: #4fa3f7;
    --accent-soft: #172b3f;
    --on-accent: #071b2c;
    --danger: #f0776a;
    --danger-soft: #3b1e1c;
    --focus: rgb(79 163 247 / 35%);
    --card-shadow: 0 1.25rem 3.5rem rgb(0 0 0 / 34%),
      0 0.25rem 0.9rem rgb(0 0 0 / 22%);
    --provider-background: #131314;
    --provider-border: #8e918f;
    --provider-hover: #202124;
    --provider-text: #e3e3e3;
  }
}

* {
  box-sizing: border-box;
}

html {
  min-width: 320px;
  overflow-x: clip;
  background: var(--canvas);
  -webkit-text-size-adjust: 100%;
}

body {
  /* `svh` is the viewport with the mobile browser chrome *shown*, so the page
     never extends under the address bar on first paint. */
  min-height: 100svh;
  margin: 0;
  overflow-x: clip;
  background: var(--canvas);
  color: var(--ink);
  font-size: var(--text-md);
}

main,
section,
article,
aside,
header,
nav,
div,
li,
form,
label {
  min-width: 0;
}

img,
svg,
iframe {
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

/* Wrapping policy. `overflow-wrap: anywhere` also collapses a box's intrinsic
   minimum width to a single character, which lets a grid or flex column shrink
   below its longest word and then splits that word across two lines.
   `break-word` breaks a word only when it
   genuinely cannot fit and leaves intrinsic sizing alone, so a column still
   claims the width of its longest word. Strings with no break opportunity at
   all — identifiers, hashes, URLs — opt into the harsher rule explicitly. */
p,
h1,
h2,
h3,
h4,
li,
dt,
dd,
summary,
strong,
em,
span,
a {
  overflow-wrap: break-word;
}

code,
pre {
  overflow-wrap: anywhere;
}

button,
input,
select,
textarea {
  font: inherit;
}

button {
  display: inline-flex;
  min-height: var(--tap);
  align-items: center;
  justify-content: center;
  padding: 0.8rem 1.25rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius-small);
  background: var(--accent);
  color: var(--on-accent);
  cursor: pointer;
  font-weight: 680;
  line-height: 1.2;
  text-align: center;
}

button:hover {
  background: var(--neutral-strong);
  border-color: var(--neutral-strong);
}

button:disabled {
  cursor: wait;
  opacity: 0.6;
}

.secondaryButton {
  border-color: var(--line-strong);
  background: var(--panel-strong);
  color: var(--ink);
}

.secondaryButton:hover {
  background: var(--neutral-soft);
}

:where(a, button, input, select, textarea, summary):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

::selection {
  background: var(--accent-soft);
}

.brandMark {
  display: block;
  width: 4rem;
  height: 4rem;
  border-radius: 1.15rem;
  object-fit: contain;
}

input,
select {
  width: 100%;
  min-height: var(--tap);
  padding: 0.65rem 0.78rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-small);
  background: var(--panel-strong);
  color: var(--ink);
}

input::placeholder {
  color: var(--faint);
}

.authCard h1 {
  margin: 0;
  font-size: var(--text-title);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.08;
  text-wrap: balance;
}

.eyebrow {
  margin: 0 0 0.4rem;
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: 720;
  letter-spacing: 0.025em;
}

.emptyState {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1.1rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  background: rgb(255 255 255 / 72%);
}

.emptyState p {
  margin: 0.35rem 0 0;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.55;
}

.profileForm label {
  display: grid;
  gap: 0.35rem;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 630;
}

.centeredPage {
  display: grid;
  min-height: 100svh;
  align-items: center;
  justify-items: center;
  padding: max(1.25rem, env(safe-area-inset-top))
    max(1.25rem, env(safe-area-inset-right))
    max(1.25rem, env(safe-area-inset-bottom))
    max(1.25rem, env(safe-area-inset-left));
}

.authCard {
  width: 100%;
  max-width: 30rem;
  padding: 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--card-shadow);
}

.authCard .brandMark {
  margin-bottom: 1.35rem;
}

.lead {
  max-width: 40rem;
  margin: 0.75rem 0 0;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.55;
}

.authCard form {
  margin-top: 1.25rem;
}

.wideButton {
  width: 100%;
}

.googleButton {
  position: relative;
  border-color: var(--provider-border);
  background: var(--provider-background);
  color: var(--provider-text);
}

.googleButton:hover {
  border-color: var(--provider-border);
  background: var(--provider-hover);
}

.providerLogo {
  position: absolute;
  left: 1rem;
  width: 1.25rem;
  height: 1.25rem;
}

.oauthScopeList {
  display: grid;
  gap: 0.5rem;
  padding: 0;
  margin: 1rem 0;
  list-style: none;
}

.oauthScopeList li {
  display: grid;
  grid-template-columns: 1.35rem minmax(0, 1fr);
  gap: 0.5rem;
  padding: 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--accent-soft);
  font-size: var(--text-sm);
}

.oauthScopeList li span {
  color: var(--accent);
  font-weight: 760;
}

.consentActions {
  display: grid;
  gap: 0.5rem;
}

.profileForm {
  display: grid;
  gap: 0.85rem;
  margin-top: 1.2rem;
}

/* First visit.

   The identity row is a statement, not a control: the provider already knows
   who this is, and the page confirms it rather than asking again. */
.identityRow {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: 1.2rem;
  padding: 0.8rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--neutral-soft);
}

.identityAvatar {
  flex: 0 0 auto;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  object-fit: cover;
}

.identityText {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}

.identityText strong {
  overflow: hidden;
  font-size: var(--text-sm);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.identityProvider {
  color: var(--muted);
  font-size: var(--text-xs);
}

/* The `@` sits inside the field rather than in the label: it is part of the
   value the user is composing, and showing it removes the question of whether
   to type it. */
.handleField {
  display: flex;
  align-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-small);
  background: var(--panel-strong);
}

.handleField:focus-within {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

.handlePrefix {
  padding-left: 0.78rem;
  color: var(--faint);
}

.handleField input {
  padding-left: 0.15rem;
  border: none;
  background: none;
}

.handleField input:focus-visible {
  outline: none;
}

/* Label, field, hint and status are one thing, and read as one: the form's own
   grid gap would space them like unrelated rows. */
.fieldGroup {
  display: grid;
  gap: 0.35rem;
}

/* Empty until there is something to say, so the layout does not jump when the
   first answer arrives. */
.fieldStatus {
  min-height: 1.2em;
  margin: 0;
  color: var(--muted);
  font-size: var(--text-xs);
}

.fieldStatus[data-state="available"] {
  color: var(--accent);
}

.fieldStatus[data-state="taken"],
.fieldStatus[data-state="invalid"] {
  color: var(--danger);
}

.fieldHint {
  margin: 0;
  color: var(--faint);
  font-size: var(--text-xs);
  font-weight: 450;
}

.formMessage {
  padding: 0.7rem;
  margin: 0;
  border-radius: var(--radius-small);
  font-size: var(--text-sm);
}

.formError {
  background: var(--danger-soft);
  color: var(--danger);
}

/* One column becomes two. Nothing here changes a size — sizes come from the
   tokens — only how many things sit side by side. */
@media (min-width: 40rem) {
  .authCard {
    padding: 2rem;
  }
}
