
/* The sign-in page in the apps' calm look (2026-11), as the site and the subscription page wear it
   (backend/web/shared/calm.css holds the same tokens; this page is served by the backend and shares no build with
   them, so the ones it needs are repeated here). Light only (Tomas, 2026-11-11): no dark values, no theme switch.
   Space Grotesk for the interface, Lora for the title, Geist Mono for a typed password. */
@font-face { font-family: 'Space Grotesk'; font-weight: 400 700; font-display: swap; src: url('/auth-assets/space-grotesk-latin-var.woff2') format('woff2'); }
@font-face { font-family: 'Lora'; font-weight: 400 700; font-display: swap; src: url('/auth-assets/lora-latin-var.woff') format('woff'); }
@font-face { font-family: 'Geist Mono'; font-weight: 100 900; font-display: swap; src: url('/auth-assets/geist-mono-latin-var.woff2') format('woff2'); }

:root {
  color-scheme: light;
  --sans: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --serif: 'Lora', 'Iowan Old Style', 'Palatino Linotype', Georgia, serif;
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --paper: #F7F3EE;
  --card: #FFFDF9;
  --card-head: #FBF8F3;
  --well: rgb(42 36 32 / 0.06);
  --ink: #2A2420;
  --text-2: rgb(42 36 32 / 0.70);
  --text-3: rgb(42 36 32 / 0.66);
  --text-off: rgb(42 36 32 / 0.40);
  --line: rgb(42 36 32 / 0.10);
  --line-strong: rgb(42 36 32 / 0.20);
  --coral-ink: #B0431E;
  --coral-tint: #FDF1EA;
  --coral-line: #EBCDBE;
  --ok: #2E7D6B; --ok-tint: #E6F2EE; --ok-line: rgb(46 125 107 / 0.35);
  --bad: #C0362C;
  --focus: #E0603A;
  --ring: rgb(255 122 77 / 0.24);
  --primary: #2A2420;
  --primary-hover: #3D3530;
  --on-primary: #FFFDF9;
  /* The pods under the lifted one, as the mark draws them; the field at the foot of the page reads them too. */
  --pod-top: #EFE6D8;
  --pod-left: #DCCBB4;
  --pod-right: #C8B399;
  --shadow-pop: 0 2px 6px rgb(42 36 32 / 0.05), 0 14px 40px rgb(42 36 32 / 0.10);
  --ease: cubic-bezier(0.22, 0.8, 0.26, 1);
}

* { box-sizing: border-box; }
html { background: var(--paper); }
body {
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  font-family: var(--sans); font-size: 16px; line-height: 1.5; color: var(--ink); background: var(--paper);
  -webkit-font-smoothing: antialiased;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The stage: the lockup at the top, the panel in the middle of what is left, the footer at the bottom, and behind
   them the pods rising at the foot of the page (drawn by the script; the page reads the same without it). */
.stage { position: relative; flex: 1; display: grid; grid-template-rows: auto 1fr auto; min-height: 640px; overflow: hidden; }
.field { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.top, main, .foot { position: relative; z-index: 1; }
.top { width: 100%; max-width: 1212px; margin-inline: auto; padding: 18px max(20px, env(safe-area-inset-right, 0px)) 18px max(20px, env(safe-area-inset-left, 0px)); }

/* The lockup (Tomas, 2026-11-11): the name in Space Grotesk 600 at -0.04em; in ems of the name's size the mark is 1.56
   wide and the gap 0.44, as the apps and the site set it. */
.brand { display: inline-flex; align-items: center; gap: 0.44em; font-size: 22px; }
.brand__word { font-weight: 600; letter-spacing: -0.04em; line-height: 1; }
.mark { display: block; overflow: visible; }
.brand .mark { width: 1.56em; height: 1.707em; }
.mark polygon { stroke-width: 0.6; stroke-linejoin: miter; }
.p-t { fill: var(--pod-top); stroke: var(--pod-top); }
.p-l { fill: var(--pod-left); stroke: var(--pod-left); }
.p-r { fill: var(--pod-right); stroke: var(--pod-right); }

main { display: grid; place-items: center; padding: 12px 16px 28px; }
.panel {
  width: 100%; max-width: 432px; padding: 34px 32px 28px; display: grid; gap: 14px; text-align: center;
  background: var(--card); border: 1px solid var(--line); border-radius: 32px; box-shadow: var(--shadow-pop);
}
/* The mark on the panel. Its glowing pod lifts a little once you are signed in. */
.panel__mark { width: 58px; height: 64px; margin: 0 auto 2px; }
.hot { transition: transform 0.9s cubic-bezier(0.2, 0.9, 0.2, 1); }
.panel.is-done .hot { transform: translateY(-9px); }
h1 { margin: 0; font-family: var(--serif); font-weight: 500; font-size: clamp(30px, 4vw, 37px); line-height: 1.06; letter-spacing: -0.024em; text-wrap: balance; }
.description { margin: -6px 0 0; color: var(--text-2); }

/* Providers: three equal pills, each the provider's own mark and nothing else, as their brand rules allow a button
   without their wording (assets/auth/README.md); the name is the button's label and its tooltip. One the server
   hasn't configured is dashed and faint. */
.providers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 8px; }
.provider {
  display: grid; place-items: center; min-height: 50px; padding: 0; cursor: pointer;
  background: var(--card); border: 1px solid var(--line-strong); border-radius: 999px;
  transition: background-color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.provider:hover:not(:disabled) { background: var(--card-head); border-color: var(--text-3); }
.provider.is-off { border-style: dashed; cursor: default; }
.provider.is-off > * { opacity: 0.4; filter: grayscale(1); }
.provider img { display: block; }
/* The Apple mark is a padded 180 px PNG: cropped in a 20×24 window. */
.apple-mark { position: relative; width: 20px; height: 24px; overflow: hidden; }
.apple-mark img { position: absolute; left: 50%; top: calc(50% + 3px); width: 48px; height: 48px; max-width: none;
  mix-blend-mode: multiply; transform: translate(-50%, -50%); }

.or { display: flex; align-items: center; gap: 12px; margin: 14px 0 0; color: var(--text-3); font-size: 13.5px; }
.or::before, .or::after { content: ''; flex: 1; height: 1px; background: var(--line-strong); }

form { display: grid; gap: 10px; text-align: left; }
.names { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
label { display: grid; gap: 6px; min-width: 0; font-size: 13.5px; font-weight: 500; color: var(--text-2); }
.names label > span { padding-left: 20px; }
/* Fields are pills, as the apps'. */
input {
  width: 100%; min-width: 0; height: 50px; padding: 0 20px; font: inherit; font-size: 16px; font-weight: 400; color: var(--ink);
  background: var(--card); border: 1px solid var(--line-strong); border-radius: 999px; outline: none;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
input::placeholder { color: var(--text-3); opacity: 1; }
input:focus { border-color: var(--focus); box-shadow: 0 0 0 4px var(--ring); }
/* The password's eye (2026-10-30): inside the field's right end, the field's text kept clear of it. */
.secret { position: relative; display: block; }
.secret input { padding-right: 52px; }
.secret input:not(:placeholder-shown) { font-family: var(--mono); letter-spacing: 0.06em; }
.reveal {
  position: absolute; top: 5px; right: 5px; width: 40px; height: 40px; display: grid; place-items: center;
  padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--text-3); cursor: pointer;
}
.reveal:hover { color: var(--ink); background: var(--well); }
.reveal:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); color: var(--ink); }
.reveal svg { width: 18px; height: 18px; }
.reveal[aria-pressed="true"] .eye, .reveal[aria-pressed="false"] .eye-off { display: none; }

/* The primary pill: ink on paper, as the apps' "New agent". */
.primary {
  min-height: 54px; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 0 26px; cursor: pointer;
  font: inherit; font-size: 16.5px; font-weight: 500; color: var(--on-primary);
  background: var(--primary); border: 1px solid transparent; border-radius: 999px;
  transition: background-color 0.18s var(--ease), transform 0.18s var(--ease);
}
.primary:hover:not(:disabled) { background: var(--primary-hover); }
.primary:active:not(:disabled) { transform: scale(0.98); }
.primary:focus-visible, .provider:focus-visible, .link:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
/* Busy: the button stays itself, dimmed, with a spinner; everything else is disabled. */
.primary.is-busy { opacity: 0.72; cursor: progress; }
.primary.is-busy::before { content: ''; width: 14px; height: 14px; border-radius: 50%; border: 2px solid rgb(255 253 249 / 0.3); border-top-color: var(--on-primary); animation: spin .8s linear infinite; }
.primary:disabled:not(.is-busy) { background: var(--well); color: var(--text-off); cursor: default; }
@keyframes spin { to { transform: rotate(360deg); } }

/* The email already given, with Change: a well, as the apps' inline values. */
.email-summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 50px; padding: 0 8px 0 20px;
  background: var(--well); border-radius: 999px; text-align: left;
}
.email-summary span { overflow-wrap: anywhere; min-width: 0; }

.links { display: grid; justify-items: center; gap: 4px; margin-top: 4px; font-size: 14.5px; color: var(--text-2); }
.switch { margin: 0; display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 4px 8px; }
.link { background: none; border: 0; border-radius: 8px; padding: 6px 4px; font: inherit; font-weight: 500; color: var(--coral-ink); cursor: pointer; }
.link:hover:not(:disabled) { text-decoration: underline; text-underline-offset: 3px; }
.link.quiet { color: var(--text-2); font-weight: 400; }
.link:disabled { color: var(--text-off); cursor: default; }

/* Messages. Neutral news sits in a well, good news in green, a failure in coral. */
.message { margin: 0; padding: 11px 16px; border-radius: 16px; font-size: 14.5px; line-height: 1.45; text-align: left; border: 1px solid var(--line); background: var(--well); color: var(--ink); }
.message.ok { background: var(--ok-tint); border-color: var(--ok-line); }
.message.bad { background: var(--coral-tint); border-color: var(--coral-line); color: var(--bad); }
.message b { font-weight: 600; }

.foot { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 10px; padding: 44px 20px 16px; font-size: 13px; color: var(--text-3); background: linear-gradient(to bottom, transparent, var(--paper) 62%); }
.foot a { color: inherit; text-decoration: none; padding: 6px 2px; }
.foot span { padding: 6px 0; }
.foot a:hover { color: var(--ink); }

@media (max-width: 480px) {
  .panel { padding: 28px 20px 22px; border-radius: 28px; }
  .names { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .primary.is-busy::before { animation: none; }
  .hot, .provider, .primary, input { transition: none; }
}
#message:empty { display: none; }
[hidden] { display: none !important; }
