/* Minervine login, v2 — "the owl in the doorway".
   One light, off to the right (68% / 52%, where bg.png and the landing variants keep it).
   A dark slab stands in front of it; the slab's rim catches the light on whichever edge is
   nearest. The owl stands in Threshold's doorway, lit from beyond the sill. Nothing chases you.

   HOW THIS FILE WINS, and why it is quiet about it.
   Every Element auth rule ships inside `@layer app-web` (compound in `@layer compound-web`).
   Unlayered CSS beats layered CSS whatever the specificity, so this file needs no !important
   against Element's stylesheet. As braces for a release that drops the layers, selectors here are
   at least as specific as Element's and this file loads after the theme links.
   !important appears ONLY where a React inline style has to be beaten:
     .mx_AuthPage        style="background: center/cover fixed url(bg.png)"
     .mx_AuthPage_modal  style="background: initial"
   Three declarations, nowhere else. checks/run.js enforces the count.

   THE HARD RULE (2026-09-18): do not fight Element's layout. On Element's own nodes this file sets
   colour, border, radius, shadow and type — never display (except `none`), flex, order, position,
   margin, padding, width or height. Composition lives in nodes login.js injects (.mv-*), and in one
   absolutely-positioned, pointer-events:none pseudo-element. checks/run.js enforces that too.

   Every selector is scoped to .mx_AuthPage (or to our own nodes), so nothing leaks into the app
   after sign-in. If Element renames a class, the rule matches nothing and that part falls back
   to Element's themed default — never to a broken page. */

:root {
  --mv-deep: #050e1a;
  --mv-ground: #0a1929;
  --mv-prussian: #003153;
  --mv-accent: #0097fa;
  --mv-ink: #f2faff;
  --mv-ink-2: rgba(242, 250, 255, 0.76);
  --mv-ink-3: rgba(242, 250, 255, 0.58);      /* smallest text. The brief's 0.46 dim measures 4.45:1 here; AA wants 4.5 */
  --mv-line: rgba(159, 179, 196, 0.22);
  --mv-card: #0a1726;
  --mv-well: #060f1a;
  --mv-alert: #ff8f88;
  --mv-lx: 68%;                                /* where the one light lives */
  --mv-ly: 52%;
  --mv-field: radial-gradient(120vmax 90vmax at var(--mv-lx) var(--mv-ly), #0e2a49 0%, #0a1929 42%, #050e1a 100%);
  --mv-pool: radial-gradient(62vmax 62vmax at var(--mv-lx) var(--mv-ly), rgba(0, 151, 250, 0.14) 0%, rgba(0, 151, 250, 0.05) 45%, rgba(0, 151, 250, 0) 100%);
  --mv-vignette: radial-gradient(ellipse 85% 85% at 50% 45%, rgba(2, 6, 12, 0) 55%, rgba(2, 6, 12, 0.5) 100%);
}

/* ── the field ───────────────────────────────────────────────────────────────────────────
   Without login.js the page itself carries a still composition: same light, same place.
   With it, the page goes clear and the living layers underneath show through. */
.mx_AuthPage {
  background: var(--mv-vignette), var(--mv-pool), var(--mv-field) !important;
  scrollbar-color: rgba(242, 250, 255, 0.18) transparent;
}
body.mv-auth .mx_AuthPage { background: transparent !important; }

/* Ours. z-index -1: above the page colour, beneath the whole app — and #matrixchat is
   `contain: strict`, one stacking context, so no Element node needs lifting over it. */
#mv-login-bg {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: -1;
  overflow: hidden; pointer-events: none;
  background: var(--mv-field);
}
#mv-login-bg .mv-lamp, #mv-login-bg .mv-light, #mv-login-bg .mv-lift,
#mv-login-bg .mv-points, #mv-login-bg .mv-grain, #mv-login-bg .mv-shade { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/* The lamp leans ±1.5% away from the pointer. The pool is still ~4% opaque at the viewport's edge, so a
   viewport-sized layer would drag a hard seam into view: the carrier overhangs 12% on every side,
   and the light's centre is re-expressed in the carrier's own box so it does not move. */
#mv-login-bg .mv-lamp { top: -12%; left: -12%; width: 124%; height: 124%; will-change: transform; }
#mv-login-bg .mv-light {
  background: radial-gradient(62vmax 62vmax at calc((12% + var(--mv-lx)) / 1.24) calc((12% + var(--mv-ly)) / 1.24), rgba(0, 151, 250, 0.14) 0%, rgba(0, 151, 250, 0.05) 45%, rgba(0, 151, 250, 0) 100%);
}
#mv-login-bg .mv-lift {
  background: radial-gradient(40vmax 40vmax at calc((12% + var(--mv-lx)) / 1.24) calc((12% + var(--mv-ly)) / 1.24), rgba(0, 151, 250, 0.08), rgba(0, 151, 250, 0) 100%);
  opacity: 0; transition: opacity 1.4s ease;
}
#mv-login-bg.mv-near .mv-lift { opacity: 1; }          /* a field has focus: the light steadies up */
#mv-login-bg .mv-grain { opacity: 0.03; background-size: 128px 128px; }   /* dither: kills gradient banding */
#mv-login-bg .mv-shade { background: var(--mv-vignette); }

@keyframes mv-arrive { from { opacity: 0; } to { opacity: 1; } }
@keyframes mv-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes mv-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.84; } }
#mv-login-bg .mv-light { animation: mv-arrive 1.8s ease-out both, mv-breathe 16s ease-in-out 1.8s infinite; }
#mv-login-bg .mv-points { animation: mv-arrive 2.4s ease-out both; }
#mv-login-bg.mv-asleep .mv-light { animation-play-state: paused; }

/* ── the slab ────────────────────────────────────────────────────────────────────────────
   Opaque on purpose. Element lays an opaque, 40px-blurred copy of bg.png over the modal
   (.mx_AuthPage_modalBlur), so glass here was never visible and cost a blur per frame. A solid
   face also makes every contrast figure exact instead of a guess over a moving field. The
   `fixed` layer is the same light, in viewport space: a whisper of it reaches the near face. */
.mx_AuthPage .mx_AuthPage_modalBlur { display: none; }
.mx_AuthPage .mx_AuthPage_modal {
  background:
    radial-gradient(40vmax 40vmax at var(--mv-lx) var(--mv-ly), rgba(0, 151, 250, 0.075), rgba(0, 151, 250, 0) 70%) fixed,
    var(--mv-card) !important;
  border: 1px solid var(--mv-line);
  border-radius: 16px;
  box-shadow:
    inset 0 1px 0 rgba(242, 250, 255, 0.05),
    0 0 0 1px rgba(0, 0, 0, 0.3),
    0 30px 80px -20px rgba(0, 0, 0, 0.7);
}
.mx_AuthPage .mx_AuthPage_modal .mx_AuthPage_modalContent,
.mx_AuthPage .mx_AuthPage_modal .mx_AuthBody {
  background: transparent;
  box-shadow: none;
}

/* The rim: the same light again, masked down to the 1px edge, so the slab is brightest
   wherever its edge passes nearest the light — at any window size, with no script.
   Paint only: absolutely positioned, takes no clicks, changes no box. */
@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
  .mx_AuthPage .mx_AuthPage_modal::after {
    content: "";
    position: absolute; top: -1px; right: -1px; bottom: -1px; left: -1px; z-index: 2;
    padding: 1px; border-radius: inherit; pointer-events: none;
    background: radial-gradient(34vmax 34vmax at var(--mv-lx) var(--mv-ly), rgba(96, 190, 255, 0.95) 0%, rgba(0, 151, 250, 0.4) 38%, rgba(0, 151, 250, 0) 100%) fixed;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  }
}

/* ── our masthead (login.js builds it; Element's logo strip yields only once it exists) ── */
body.mv-branded .mx_AuthPage .mx_AuthHeader { display: none; }

.mv-brand {
  margin: 6px 0 26px;
  min-width: min(340px, calc(100vw - 72px));   /* on a phone Element shrink-wraps the card: give it something to wrap */
  text-align: center;
  animation: mv-rise 0.9s ease-out both;
}
.mv-door {                                       /* Threshold's door: an arch, open at the foot */
  position: relative; box-sizing: border-box;
  width: 84px; height: 100px; margin: 0 auto;
  display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: 8px;
  border: 1px solid var(--mv-line); border-bottom: 0;
  border-radius: 42px 42px 0 0;
  background: radial-gradient(58px 72px at 50% 100%, rgba(0, 151, 250, 0.22), rgba(0, 151, 250, 0) 100%);
}
.mv-door::after {                                /* the sill, and the light under it */
  content: ""; position: absolute; left: -40px; right: -40px; bottom: 0; height: 1px;
  background: linear-gradient(90deg, rgba(0, 151, 250, 0), rgba(64, 178, 255, 0.8) 50%, rgba(0, 151, 250, 0));
}
.mv-owl {
  display: block; width: 60px; height: 60px; object-fit: contain;
  filter: drop-shadow(0 0 10px rgba(0, 151, 250, 0.32));
}
.mv-word {
  margin-top: 14px; padding-left: 0.24em;         /* tracking trails the last letter; this re-centres it */
  font-family: Comfortaa, Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px; line-height: 18px; font-weight: 400;
  letter-spacing: 0.24em; text-transform: lowercase;
  color: var(--mv-ink-2);
}
.mv-tag {
  margin: 8px auto 0; max-width: 30em;
  font-size: 12.5px; line-height: 19px; letter-spacing: 0.01em;
  color: var(--mv-ink-3);
  text-wrap: balance;
}
/* other auth screens (forgot password…) are taller and carry their own icon: wordmark only */
.mx_AuthBody_forgot-password .mv-door,
.mx_AuthBody_forgot-password .mv-tag,
.mv-brand:not(.mv-login) .mv-tag { display: none; }

/* ── type ─────────────────────────────────────────────────────────────────────────────── */
.mx_AuthPage .mx_AuthPage_modal .mx_AuthBody { color: var(--mv-ink-2); }
.mx_AuthPage .mx_AuthPage_modal .mx_AuthBody h1 {
  color: var(--mv-ink);
  font-weight: 500;                              /* Element ships Inter 400–700; 300 was silently 400 */
  letter-spacing: -0.015em;
}
.mx_AuthPage ::selection { background: rgba(0, 151, 250, 0.35); color: var(--mv-ink); }

/* ── fields: a well in the slab, a halo when it has your attention ─────────────────────── */
.mx_AuthPage .mx_AuthBody .mx_Field {
  background: var(--mv-well);
  border-color: rgba(159, 179, 196, 0.52);     /* 3:1 against the slab, as a control's edge should be; v1's 0.28 was 1.77:1 */
  transition: border-color 0.25s, box-shadow 0.25s;
}
.mx_AuthPage .mx_AuthBody .mx_Field:hover { border-color: rgba(159, 179, 196, 0.7); }
.mx_AuthPage .mx_AuthBody .mx_Field:focus-within {
  border-color: var(--mv-accent);
  box-shadow: 0 0 0 3px rgba(0, 151, 250, 0.16), 0 0 28px rgba(0, 151, 250, 0.1);
}
.mx_AuthPage .mx_AuthBody .mx_Field input,
.mx_AuthPage .mx_AuthBody .mx_Field select {
  background: transparent;
  color: var(--mv-ink);
  caret-color: var(--mv-accent);
}
.mx_AuthPage .mx_AuthBody .mx_Field label { color: var(--mv-ink-3); }
.mx_AuthPage .mx_AuthBody .mx_Field input:focus + label { color: #5cbcff; }
/* The floated label straddles the border and needs an OPAQUE patch to notch it — transparent
   (v1) ran the border through 10px text. Slab above the line, well below it: invisible. */
.mx_AuthPage .mx_AuthBody .mx_Field input:focus + label,
.mx_AuthPage .mx_AuthBody .mx_Field input:not(:placeholder-shown) + label,
.mx_AuthPage .mx_AuthBody .mx_Field select + label,
.mx_AuthPage .mx_AuthBody .mx_Field_labelAlwaysTopLeft label {
  background: linear-gradient(to bottom, var(--mv-card) 0, var(--mv-card) 6px, var(--mv-well) 6px, var(--mv-well) 100%);
}
/* a password manager must not repaint the wells pale yellow every morning */
.mx_AuthPage .mx_AuthBody .mx_Field input:-webkit-autofill,
.mx_AuthPage .mx_AuthBody .mx_Field input:-webkit-autofill:hover,
.mx_AuthPage .mx_AuthBody .mx_Field input:-webkit-autofill:focus {
  -webkit-text-fill-color: #f2faff;
  -webkit-box-shadow: 0 0 0 1000px #060f1a inset;
  box-shadow: 0 0 0 1000px #060f1a inset;
  caret-color: var(--mv-accent);
  transition: background-color 99999s ease-out 0s;
}
.mx_AuthPage .mx_AuthBody .mx_Field input:autofill {
  box-shadow: 0 0 0 1000px #060f1a inset;
  caret-color: var(--mv-accent);
}
/* the theme's #d24b4e alert measures 4.17:1 on the slab — under AA, for the one message that matters */
.mx_AuthPage .mx_AuthBody .mx_Login_error,
.mx_AuthPage .mx_AuthBody .mx_Field_invalid.mx_Field label,
.mx_AuthPage .mx_AuthBody .mx_Field_invalid.mx_Field:focus-within label { color: var(--mv-alert); }
.mx_AuthPage .mx_AuthBody .mx_Field_invalid.mx_Field,
.mx_AuthPage .mx_AuthBody .mx_Field_invalid.mx_Field:focus-within { border-color: var(--mv-alert); }

/* ── forgot password: a link that reads as one ─────────────────────────────────────────── */
.mx_AuthPage .mx_AuthBody .mx_Login_forgot {
  color: var(--mv-ink-2);
  font-weight: 500;
  text-decoration-color: rgba(0, 151, 250, 0.7);
  text-underline-offset: 3px;
  transition: color 0.2s;
}
.mx_AuthPage .mx_AuthBody .mx_Login_forgot:hover { color: var(--mv-ink); }

/* ── the one action ────────────────────────────────────────────────────────────────────── */
.mx_AuthPage .mx_AuthBody .mx_Login_submit {
  background: linear-gradient(180deg, #2aa9ff 0%, #0097fa 60%, #0089e6 100%);
  color: #04121f;
  border-radius: 8px;                            /* the wells' radius; the slab's is twice it */
  letter-spacing: 0.01em;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24), 0 8px 24px -10px rgba(0, 151, 250, 0.6);
  transition: box-shadow 0.2s, filter 0.2s;
}
.mx_AuthPage .mx_AuthBody .mx_Login_submit:hover {
  filter: brightness(1.07);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 10px 30px -8px rgba(0, 151, 250, 0.75);
}
.mx_AuthPage .mx_AuthBody .mx_Login_submit:active { filter: brightness(0.94); }
/* disabled colours are Compound's (!important inside a layer outranks us); just drop our glow */
.mx_AuthPage .mx_AuthBody .mx_Login_submit[aria-disabled="true"],
.mx_AuthPage .mx_AuthBody .mx_Login_submit:disabled { box-shadow: none; filter: none; }

.mx_AuthPage .mx_AuthBody .mx_Login_forgot:focus-visible,
.mx_AuthPage .mx_AuthBody .mx_Login_submit:focus-visible,
.mx_AuthPage .mx_AuthFooter a:focus-visible {
  outline: 2px solid var(--mv-ink);
  outline-offset: 3px;
  border-radius: 8px;
}

/* ── what this server does not offer ───────────────────────────────────────────────────────
   One homeserver, one language. The sign-up prompt goes only on the sign-in view: the same
   class is also "Sign in here" and "Go back" on /#/register, and hiding those strands people.
   (Better at the source: "UIFeature.registration": false in config.json — see the report.) */
.mx_AuthPage .mx_ServerPicker,
.mx_AuthPage .mx_AuthBody_language,
.mv-brand.mv-login ~ .mx_AuthBody_changeFlow { display: none; }
.mx_AuthPage .mx_Login_underlinedServerName { border-bottom-color: transparent; }

/* ── footer: quiet, and legible over the brightest ground it can sit on ────────────────── */
.mx_AuthPage .mx_AuthFooter {
  background: none;
  opacity: 1;
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--mv-ink-3);
}
.mx_AuthPage .mx_AuthFooter a:link,
.mx_AuthPage .mx_AuthFooter a:visited { color: var(--mv-ink-3); transition: color 0.2s; }
.mx_AuthPage .mx_AuthFooter a:hover { color: var(--mv-ink); }

/* ── a short laptop (1366×620): a smaller door, same composition ───────────────────────── */
@media (max-height: 700px) {
  .mv-brand { margin: 2px 0 20px; }
  .mv-door { width: 66px; height: 78px; border-radius: 33px 33px 0 0; padding-bottom: 6px; }
  .mv-owl { width: 48px; height: 48px; }
  .mv-word { margin-top: 10px; }
  .mv-tag { margin-top: 6px; }
}
/* ── a phone: Element pins the card to the top edge, so let it hang from it ────────────── */
@media (max-width: 480px) {
  .mx_AuthPage .mx_AuthPage_modal { border-top-color: transparent; border-top-left-radius: 0; border-top-right-radius: 0; }
  .mv-brand { margin-top: 18px; }
}

/* ── stillness, and other preferences ──────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  #mv-login-bg .mv-light, #mv-login-bg .mv-points, .mv-brand { animation: none; }
  #mv-login-bg .mv-lift { transition: none; }
}
@media (prefers-contrast: more) {
  :root { --mv-ink-2: rgba(242, 250, 255, 0.92); --mv-ink-3: rgba(242, 250, 255, 0.8); --mv-line: rgba(159, 179, 196, 0.55); }
}

/* ── scripting off entirely: Element cannot run, but the door should still look like ours ─
   (inert when scripting is on — the browser never renders <noscript> then) */
body > noscript {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 20px; padding: 24px; text-align: center;
  background: var(--mv-vignette), var(--mv-pool), var(--mv-field);
  color: rgba(242, 250, 255, 0.76);
  font: 400 15px/1.6 Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
}
body > noscript::before {
  content: ""; width: 60px; height: 60px;
  background: url(/minervine/owl-light.png) center / contain no-repeat;
}
