*{box-sizing:border-box;}
html,body{margin:0;padding:0;height:100%;}
body{
  font-family:-apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
  color:var(--body);
  background:
    radial-gradient(ellipse 900px 500px at 50% -10%, var(--brand-tint) 0%, transparent 60%),
    var(--bg-soft);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  min-height:100vh;
  display:flex;
  align-items:flex-start;
  justify-content:center;
  padding:96px 20px 56px;
}
/* The light theme's top-of-page glow uses --brand-tint at full strength,
   which is tuned to sit on a white/near-white page — on the dark theme's
   near-black --bg-soft that same pastel-pink wash reads as too bright, so
   it's dimmed here rather than left to inherit. */
:root[data-theme="dark"] body{
  background:
    radial-gradient(ellipse 900px 500px at 50% -10%, var(--glow-page-dark) 0%, transparent 60%),
    var(--bg-soft);
}

.wrap{
  width:100%;
  max-width:376px;
  display:flex;
  flex-direction:column;
  align-items:center;
  animation:rise .5s cubic-bezier(.16,1,.3,1);
}

@keyframes rise{
  from{ opacity:0; transform:translateY(10px); }
  to{ opacity:1; transform:translateY(0); }
}

.brand{
  display:flex;
  flex-direction:column;
  align-items:center;
  margin-bottom:36px;
}

.brand-mark{ display:flex; align-items:center; gap:10px; text-decoration:none; }
.brand-logo{ width:40px; height:40px; flex:none; }
.brand-word{ font-family:var(--font-brand); font-size:30px; font-weight:800; letter-spacing:-.01em; line-height:1; }
.brand-net{ color:var(--ink); }
/* Static gradient-text fill (no animation/movement): teal into blue.
   --logo-start is a darker teal in light mode, the welcome banner's
   bright teal in dark mode. */
.brand-lense{
  background:linear-gradient(90deg, var(--logo-start), var(--brand) 55%, var(--brand-dark));
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
}
.brand-tagline{
  font-size:12.5px;
  color:var(--body);
  text-align:center;
  margin:14px 0 0;
}

.login-card{
  width:100%;
  background:var(--bg);
  border:1px solid rgba(0,0,0,.04);
  border-radius:20px;
  padding:44px 36px;
  box-shadow:0 24px 48px -28px rgba(0,0,0,.16), 0 2px 6px -2px rgba(0,0,0,.04);
  display:flex;
  flex-direction:column;
}
.login-card h1{
  font-size:26px;
  color:var(--ink);
  margin:0 0 8px;
  font-weight:600;
  letter-spacing:-.02em;
  text-align:center;
}
.login-card .sub{
  font-size:14px;
  color:var(--body);
  margin:0 0 30px;
  line-height:1.5;
  text-align:center;
}

.field{
  display:flex;
  flex-direction:column;
  margin-bottom:16px;
}
/* Hidden-attribute override for .field's display:flex (also covered by the
   global [hidden] rule in app.css, which the sign-in pages don't load). */
.field[hidden]{ display:none; }
.login-card label{
  font-size:12.5px;
  font-weight:600;
  color:var(--ink);
  margin-bottom:7px;
}
.login-card input{
  font-family:inherit;
  font-size:15px;
  padding:13px 14px;
  border:1px solid var(--line);
  border-radius:10px;
  color:var(--ink);
  background:var(--field-bg);
  transition:border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.login-card input::placeholder{ color:var(--text-placeholder); }
.login-card input:hover{ border-color:var(--line-strong); }
.login-card input:focus{
  outline:none;
  border-color:var(--brand);
  background:var(--bg);
  box-shadow:0 0 0 4px var(--brand-tint);
}
.field input.invalid{
  border-color:var(--danger);
}
.field input.invalid:focus{
  box-shadow:0 0 0 4px var(--danger-tint);
}

/* A <select> styled exactly like the text inputs (box, hover, focus, invalid),
   with appearance:none and its own chevron so it's the same size as them. */
.login-card select{
  font-family:inherit;
  font-size:15px;
  padding:13px 44px 13px 14px;
  border:1px solid var(--line);
  border-radius:10px;
  color:var(--ink);
  appearance:none;
  -webkit-appearance:none;
  cursor:pointer;
  background:url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none"%3E%3Cpath d="M6 8l4 4 4-4" stroke="%236e6e73" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/%3E%3C/svg%3E') no-repeat right 14px center/14px 14px, var(--field-bg);
  transition:border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.login-card select:hover{ border-color:var(--line-strong); }
.login-card select:focus{
  outline:none;
  border-color:var(--brand);
  background:url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none"%3E%3Cpath d="M6 8l4 4 4-4" stroke="%236e6e73" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/%3E%3C/svg%3E') no-repeat right 14px center/14px 14px, var(--bg);
  box-shadow:0 0 0 4px var(--brand-tint);
}
.field select.invalid{
  border-color:var(--danger);
}
.field select.invalid:focus{
  box-shadow:0 0 0 4px var(--danger-tint);
}

.field-error{
  font-size:12px;
  color:var(--danger-dark);
  margin:6px 0 0;
  line-height:1.4;
}
.field-hint{
  font-size:12px;
  color:var(--body);
  margin:6px 0 0;
  line-height:1.4;
}

.login-card button{
  font-family:inherit;
  font-size:15px;
  font-weight:600;
  color:var(--text-on-color);
  background:var(--brand);
  border:none;
  border-radius:10px;
  padding:13px 14px;
  margin-top:8px;
  cursor:pointer;
  transition:background .15s ease, transform .1s ease, box-shadow .15s ease;
}
.login-card button:hover{ background:var(--brand-dark); box-shadow:0 8px 20px -10px color-mix(in srgb, var(--brand) 50%, transparent); }
.login-card button:active{ transform:scale(.99); }
.login-card button:disabled{ opacity:1; background:var(--line); color:var(--body); cursor:not-allowed; box-shadow:none; }

/* Password-strength helper text — register.js/profile.js toggle .met on
   each <span> as its own criterion (length/uppercase/number/symbol) is
   satisfied; shared here (login.css loads on both register.html and
   profile.html) rather than duplicated per page. */
.password-strength-hint{
  font-size:12px;
  color:var(--body);
  margin:6px 0 0;
  line-height:1.6;
}
.password-strength-hint span{ transition:color .15s ease; }
.password-strength-hint span.met{ color:var(--success-text); font-weight:600; }

.login-card button.secondary{
  color:var(--ink);
  background:var(--field-bg);
  box-shadow:none;
}
.login-card button.secondary:hover{ background:var(--surface-hover); box-shadow:none; }

.password-wrap{ position:relative; display:flex; }
.password-wrap input{ width:100%; padding-right:44px; }
.password-wrap .eye-btn{
  position:absolute;
  top:0;
  right:0;
  width:40px;
  height:100%;
  display:flex;
  align-items:center;
  justify-content:center;
  background:transparent;
  border:none;
  border-radius:0;
  padding:0;
  margin:0;
  color:var(--body);
  cursor:pointer;
  box-shadow:none;
  transition:color .15s ease;
}
.password-wrap .eye-btn:hover,
.password-wrap .eye-btn:focus-visible{ background:transparent; color:var(--ink); box-shadow:none; }
.password-wrap .eye-btn:active{ transform:none; }
.eye-icon{ width:19px; height:19px; display:block; }
.eye-icon[hidden]{ display:none; }

.remember-row{
  display:flex;
  align-items:center;
  gap:8px;
  font-size:13.5px;
  color:var(--ink);
  cursor:pointer;
  user-select:none;
}
.remember-row input{
  width:16px;
  height:16px;
  margin:0;
  accent-color:var(--brand);
  cursor:pointer;
}

/* Wraps .remember-row + the "Forgot password?" link on the same line —
   .remember-row's own margin moved here so this row carries the spacing
   whether or not the link is present. */
.login-options-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  margin:2px 0 20px;
}
.forgot-link{
  font-size:13.5px;
  font-weight:600;
  color:var(--brand);
  text-decoration:none;
}
.forgot-link:hover{ color:var(--brand-dark); text-decoration:underline; }

/* .login-card sets its own display:flex, which otherwise out-specifies the
   UA stylesheet's [hidden] rule — forgot-password.js toggles between the
   two step forms via the `hidden` attribute, so this has to be restated
   explicitly for it to actually take effect (same issue documented in
   profile.css for .nav-item[hidden]). */
.login-card[hidden]{ display:none; }

/* --- Forgot Password: OTP input + countdown --- */
.otp-input{
  text-align:center;
  font-size:22px;
  font-weight:700;
  letter-spacing:.5em;
  padding-left:22px; /* offsets the letter-spacing so the digits look centered, not shifted right */
}
.otp-countdown{
  font-weight:700;
  color:var(--brand);
}
.otp-countdown.expired{ color:var(--danger-dark); }
.otp-countdown.verified{ color:var(--success-text); }
.switch-email-link{
  display:block;
  text-align:center;
  font-size:13px;
  color:var(--body);
  text-decoration:none;
  margin-top:16px;
}
.switch-email-link:hover{ color:var(--ink); text-decoration:underline; }

.request-access{
  display:block;
  text-align:center;
  font-size:13.5px;
  color:var(--body);
  text-decoration:none;
  margin-top:20px;
}
.request-access span{
  color:var(--brand);
  font-weight:600;
}
.request-access:hover span{ color:var(--brand-dark); text-decoration:underline; }

.error{
  font-size:13px;
  color:var(--danger-dark);
  background:var(--danger-tint);
  border-radius:10px;
  padding:10px 13px;
  margin:-4px 0 16px;
}

.success{
  font-size:13px;
  color:var(--ink);
  background:var(--field-bg);
  border:1px solid var(--line);
  border-radius:10px;
  padding:10px 13px;
  margin:-4px 0 16px;
}

.footnote{
  font-size:12.5px;
  color:var(--body);
  text-align:center;
  margin:32px 0 0;
  line-height:1.6;
  max-width:300px;
}

@media (max-width: 420px){
  .login-card{ padding:34px 26px; border-radius:18px; }
}

/* ===================================================================
   Sign-in pages (login / register / forgot-password / set-password): a
   50/50 split screen, the form on a plain white panel on the left and a dark
   brand panel on the right. Up to 900px wide the page uses the phone look
   (no brand panel, no in-between banner). Scoped under body.auth-page
   so it never affects the other pages that load login.css for its shared
   field/button rules. login.html adds a two-step welcome -> form reveal
   (#auth-panel[hidden] below, auth-ui.js).
   =================================================================== */
body.auth-page{
  display:block;
  padding:0;
  min-height:100vh;
  height:auto;
  background:var(--white);
}

.auth-split{
  display:flex;
  min-height:100vh;
}

.auth-panel-left{
  flex:1 1 50%;
  min-width:0;
  display:flex;
  /* True vertical centering by default — this is what every actual form
     (sign-in, forgot-password, request-access) wants. Only login.html's
     welcome/landing step (headline+buttons, paired with the logo) pins to
     a shared top offset instead, via the :has() override below, so a
     short landing view and a much taller form don't have to share one
     fixed position. */
  align-items:center;
  justify-content:center;
  background:var(--white);
  padding:48px 20px;
  /* Visually on the right, dark brand panel on the left — swapped via
     `order` rather than reordering the HTML, so the form panel stays
     first in source/tab order (it's the interactive half) regardless of
     which side it's drawn on. */
  order:2;
}

/* Brand panel (drawn on the left): teal-to-blue gradient with a moving
   network on a canvas (auth-network.js). Up to 900px it is hidden (the
   phone look below). */
.auth-panel-right{
  flex:1 1 50%;
  position:relative;
  overflow:hidden;
  color:#fff;
  background:linear-gradient(135deg, var(--auth-panel-1) 0%, var(--auth-panel-2) 62%, var(--auth-panel-3) 100%);
  order:1;
}
.auth-panel-right canvas{ position:absolute; inset:0; width:100%; height:100%; }
.auth-brand-mark{
  position:relative;
  height:100%;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  padding:48px 56px;
}
.auth-brand-mark .brand-mark{ gap:14px; }
/* The app's gradient tile would blend into this gradient panel, so here it gets a white outline. */
.auth-brand-mark .brand-logo{ width:56px; height:56px; padding:8px; background:linear-gradient(135deg, var(--brand-light), var(--brand)); border-radius:14px; box-shadow:0 0 0 2px rgba(255,255,255,.75), 0 6px 20px -8px rgba(0,0,0,.5); }
.auth-brand-mark .brand-word{ font-size:34px; color:#fff; }
.auth-brand-mark .brand-net,
.auth-brand-mark .brand-lense{ color:#fff; background:none; }
.auth-brand-copy{ text-shadow:0 2px 18px rgba(4,30,60,.55); }
.auth-brand-copy h2{ font-family:var(--font-brand); font-size:44px; line-height:1.1; margin:0 0 14px; font-weight:700; letter-spacing:-1px; max-width:460px; }
.auth-brand-copy p{ font-size:17px; line-height:1.5; margin:0; max-width:420px; opacity:.88; }
.auth-brand-foot{ font-size:13px; opacity:.7; }
/* The form side is pure black in the dark theme (theme.js sets it). */
:root[data-theme="dark"] .auth-panel-left{ background:var(--bg-soft); }

/* Phones and tablets, up to 900px (Isuri's boss, 2026-10-16; tablets too
   since 2026-10-20, no half-way banner): no brand banner. The page is centred
   on the screen with the logo on top, and the network (auth-network.js) is
   drawn faintly in brand blue behind it, filling the screen. */
.auth-phone-logo{ display:none; }
@media (max-width:900px){
  .auth-split{ flex-direction:column; min-height:100dvh; }
  .auth-panel-right{ display:block; position:fixed; inset:0; z-index:0; background:none; pointer-events:none; }
  .auth-panel-right .auth-brand-mark{ display:none; }
  .auth-panel-right canvas{ --network-line:var(--brand); --network-glow:var(--brand-light); opacity:.6; }
  :root[data-theme="dark"] body.auth-page{ background:var(--bg-soft); }
  .auth-phone-logo{ display:block; width:56px; height:56px; margin:0 0 22px; border-radius:14px; box-shadow:0 8px 22px -12px rgba(0,0,0,.45); }
  #auth-shell[data-step="welcome"]{ align-items:center; }
  #auth-shell[data-step="welcome"] .auth-intro,
  #auth-shell[data-step="welcome"] .footnote{ align-items:center; text-align:center; }
}
@media (prefers-reduced-motion:reduce){
  .auth-panel-right canvas{ display:none; }
}

body.auth-page .wrap{
  width:100%;
  max-width:392px;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  text-align:left;
  animation:rise .5s cubic-bezier(.16,1,.3,1);
}

.auth-intro{
  width:100%;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  text-align:left;
  transition:opacity .32s cubic-bezier(.16,1,.3,1), transform .32s cubic-bezier(.16,1,.3,1);
}
body.auth-page .brand{
  align-items:flex-start;
  margin-bottom:28px;
}
.auth-headline{
  font-family:var(--font-brand);
  font-size:30px;
  font-weight:800;
  line-height:1.2;
  letter-spacing:-.02em;
  color:var(--ink);
  margin:0 0 12px;
  text-wrap:balance;
}
/* Same red/pink/maroon gradient family as the right panel's animated
   logo — ties the two panels' accent color together instead of the
   functional side using a flat --brand against the brand side's gradient. */
/* Static gradient (no animation) — the moving version was distracting on
   a short word sitting in running text, unlike the logo where the motion
   reads as a deliberate hero effect. */
.auth-headline .accent{
  background:linear-gradient(90deg, var(--brand-light), var(--brand) 55%, var(--brand-dark));
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
}
.auth-subcopy{
  font-size:15px;
  line-height:1.6;
  color:var(--body);
}

.auth-cta-row{
  display:flex;
  gap:10px;
  width:100%;
  margin:28px 0 0;
}
.btn{
  flex:1;
  font-family:inherit;
  font-size:14px;
  font-weight:600;
  padding:11px 16px;
  border-radius:10px;
  cursor:pointer;
  text-decoration:none;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  transition:background .15s ease, border-color .15s ease, box-shadow .15s ease, transform .1s ease;
}
.btn:active{ transform:scale(.98); }
.btn-primary{
  background:var(--brand);
  color:var(--text-on-color);
  border:1px solid transparent;
}
.btn-primary:hover{ background:var(--brand-dark); box-shadow:0 8px 20px -10px color-mix(in srgb, var(--brand) 35%, transparent); }
.btn-outline{
  background:transparent;
  color:var(--ink);
  border:1px solid var(--line);
}
.btn-outline:hover{ background:var(--brand-tint); border-color:var(--line-strong); }

.auth-panel{
  width:100%;
  display:flex;
  flex-direction:column;
  transition:opacity .32s cubic-bezier(.16,1,.3,1), transform .32s cubic-bezier(.16,1,.3,1);
}
/* login.html shows .auth-intro and #auth-panel one at a time via the
   `hidden` attribute (toggled by auth-ui.js). Both already set their own
   `display`, which otherwise out-specifies the UA [hidden] rule — same
   issue already documented above for .login-card[hidden]. */
.auth-intro[hidden]{ display:none; }
.auth-panel[hidden]{ display:none; }
/* Pre-transition state for whichever view auth-ui.js is about to
   reveal/has just hidden — kept a separate class (not baked into
   [hidden]) so the fade/slide has something to transition from/to. */
.auth-offset{ opacity:0; transform:translateY(16px); pointer-events:none; }

.back-to-welcome{
  align-self:flex-start;
  display:inline-flex;
  align-items:center;
  gap:5px;
  font-size:13px;
  font-weight:600;
  color:var(--body);
  background:none;
  border:none;
  padding:0;
  margin:0 0 18px;
  cursor:pointer;
  box-shadow:none;
}
/* Beats the generic `.login-card button` red-button styling (higher
   specificity: element+class vs a single class) so this reads as a
   quiet text link, not another primary button. */
.login-card button.back-to-welcome{
  background:none;
  color:var(--body);
  font-weight:600;
  padding:0;
  margin:0 0 18px;
  box-shadow:none;
}
.login-card button.back-to-welcome:hover{ background:none; color:var(--brand); box-shadow:none; }
.back-to-welcome svg{ width:14px; height:14px; }

/* Request Access, Step 4 (success/under-review) — the one auth step that
   stays centered, since an icon + confirmation message reads better
   centered than left-aligned. */
.auth-success{
  align-items:center;
  text-align:center;
}
.success-icon{
  width:60px;
  height:60px;
  border-radius:50%;
  background:var(--brand-tint);
  color:var(--brand);
  display:flex;
  align-items:center;
  justify-content:center;
  margin:0 0 20px;
}
.success-icon svg{ width:30px; height:30px; }
.auth-success button{ width:100%; }

/* The form sits directly in the white panel, not inside a nested card —
   neutralize .login-card's default white-card chrome (border/shadow/
   padding) for auth pages only. Text/input/label colors need no override
   at all here: the base (non-auth) rules earlier in this file already
   assume a light surface + dark ink, which is exactly this design. */
body.auth-page .login-card{
  background:transparent;
  border:none;
  box-shadow:none;
  padding:0;
  width:100%;
  position:relative;
}
/* Taken out of flow and floated above the card instead of sitting inline
   above the h1 — in flow, its own height pushed "Sign in" ~40px lower
   than "Forgot password"/"Request access" on the other two auth pages,
   breaking the shared top alignment those get from .auth-panel-left's
   padding-top. Absolute positioning keeps the h1 as the first in-flow
   element on every step, so all three pages' headings land on one line
   regardless of whether that step has a Back link. */
body.auth-page .back-to-welcome{
  position:absolute;
  top:-38px;
  left:0;
  margin:0;
}
body.auth-page .login-card h1,
body.auth-page .login-card .sub{
  text-align:left;
}
body.auth-page .footnote{
  text-align:left;
  max-width:392px;
}

/* Phones and tablets (no brand banner above): room for the Back link, which
   sits 38px above the form, and the light/dark button in the top corner. */
@media (max-width:900px){
  /* Centred on the screen. The Sign in step is taller than the welcome
     step, so the logo's place changes when switching: auth-ui.js slides it. */
  .auth-panel-left{ position:relative; z-index:1; flex:1 1 auto; background:transparent; padding:80px 24px 40px; }
  .auth-phone-logo{ align-self:center; }
  body.auth-page .back-to-welcome{ position:static; margin:0 0 18px; }
  /* Dark theme: see-through too (its own rule paints it black), lighter lines. */
  :root[data-theme="dark"] .auth-panel-left{ background:transparent; }
  :root[data-theme="dark"] .auth-panel-right canvas{ --network-line:var(--brand-light); }
}
@media (max-width: 420px){
  .auth-headline{ font-size:25px; }
  .auth-cta-row{ flex-direction:column; }
}

/* Light/dark switch (auth-theme.js), top-right of the page. */
.auth-theme-btn{
  position:fixed;
  top:16px;
  right:16px;
  z-index:5;
  width:40px;
  height:40px;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius:50%;
  border:1px solid var(--line);
  background:var(--bg);
  color:var(--body);
  cursor:pointer;
  padding:0;
}
.auth-theme-btn:hover{ color:var(--brand); border-color:var(--line-strong); }
.auth-theme-btn svg{ width:20px; height:20px; }
