/* =============================================================
 * Masar University — sign-in pages
 *
 * Hand-written CSS, not the portal bundle. A sign-in page is one form, and
 * it is the page a student reaches when something has already gone wrong -
 * an expired session, a forgotten password, a bad connection. Shipping a
 * 300 kB application shell to render a form means that when the bundle
 * fails, the way back in fails with it.
 *
 * The values come from the official brand guideline: teal #048aa4, bronze
 * #b67c4e, Cairo for Arabic and Poppins for Latin. The portal that is live
 * uses #007D86 and Tajawal, which I took for the brand and defended before
 * reading the guideline. It was not.
 * ============================================================= */

:root {
  --masar-600: #048aa4;
  --masar-700: #06718a;
  --masar-400: #35aec5;
  --masar-300: #6fccdc;
  --gold-600: #b67c4e;
  --ink-950: #07171a;

  --auth-card: rgb(255 255 255 / 0.055);
  --auth-card-border: rgb(255 255 255 / 0.11);
  --auth-field: rgb(255 255 255 / 0.05);
  --auth-field-border: rgb(255 255 255 / 0.13);
  --auth-text: #eaf5f6;
  --auth-muted: rgb(234 245 246 / 0.6);
  --auth-faint: rgb(234 245 246 / 0.38);

  --font-ar: "Cairo", ui-sans-serif, system-ui, sans-serif;
  --font-en: "Poppins", ui-sans-serif, system-ui, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  min-block-size: 100%;
}

/* The gradient is on body, so an overscroll bounce past it would show the
   browser's default white. Painting html the darkest stop of the same gradient
   means the page has no edge. */
html {
  background: #061419;
}

body {
  position: relative;
  min-block-size: 100dvh;
  display: grid;
  place-items: center;
  padding: 1.25rem;
  overflow-x: hidden;

  font-family: var(--font-ar);
  /* Arabic sits low in the em box; the extra leading keeps diacritics clear
     of the line below. */
  line-height: 1.75;
  color: var(--auth-text);

  /* Depth rather than a uniform wash: the top corner falls almost to black
     and the teal blooms out of the far corner, with the certificate's gold
     warming the near one. A single flat gradient reads as a coloured sheet;
     this reads as a space with a light in it. */
  background:
    radial-gradient(1200px 700px at 82% 96%, rgb(53 180 189 / 0.3), transparent 62%),
    radial-gradient(760px 460px at 8% 6%, rgb(196 137 79 / 0.14), transparent 55%),
    radial-gradient(900px 900px at 50% 50%, rgb(13 154 164 / 0.08), transparent 70%),
    linear-gradient(152deg, #03090c 0%, #051a21 34%, #073640 66%, #0a5260 100%);
  background-attachment: fixed;
}

:lang(en) {
  font-family: var(--font-en);
}

/* ─── the backdrop ───
   An inline SVG, not a tiled background image. The current has to run ALONG
   the traces, and stroke-dashoffset on individual paths is the only way to do
   that. The version this replaces nudged a tiled image 4.5% over ninety
   seconds: technically animated, and invisible, which amounts to the same
   thing as not animated at all.

   Everything is stroked in currentColor, so the whole field recolours from
   one declaration. */
.auth-field-art {
  position: fixed;
  inset: 0;
  z-index: 0;
  inline-size: 100%;
  block-size: 100%;
  pointer-events: none;
  color: #6fd8de;
  opacity: 0.4;
  mask-image: radial-gradient(ellipse 88% 76% at 50% 46%, #000 0%, transparent 82%);
}

/* The traces are drawn as a long dash chasing a longer gap, so what travels
   the line is a bright segment rather than a marching-ants border. */
.trace {
  stroke-width: 1.6;
  stroke-dasharray: 120 620;
  opacity: 0.85;
  animation: current 9s linear infinite;
}
.trace-b { animation-duration: 13s; animation-delay: -4s; }
.trace-c { animation-duration: 16s; animation-delay: -9s; }
.trace-d { animation-duration: 11s; animation-delay: -6s; }

@keyframes current {
  from { stroke-dashoffset: 740; }
  to   { stroke-dashoffset: 0; }
}

/* A node lights as the current reaches it - visibly, not as a hint. */
.node {
  opacity: 0.35;
  animation: node-pulse 3.4s ease-in-out infinite;
}
.node-b { animation-duration: 4.6s; animation-delay: -1.5s; }
.node-c { animation-duration: 5.8s; animation-delay: -3s; }

@keyframes node-pulse {
  0%, 100% { opacity: 0.25; r: 4; }
  45%      { opacity: 1;    r: 7; }
}

/* Chevrons and caps drift, and the drift is large enough to read as motion. */
.chev-field { color: #7fe0e6; opacity: 0.5; }
.cap-field  { color: #e0b98c; opacity: 0.55; }

.drift {
  animation: drift 11s ease-in-out infinite;
  transform-box: fill-box;
  transform-origin: center;
}
.drift-b { animation-duration: 15s; animation-delay: -5s; }
.drift-c { animation-duration: 19s; animation-delay: -11s; }

@keyframes drift {
  0%, 100% { transform: translateY(0) rotate(0deg); opacity: 0.55; }
  50%      { transform: translateY(-22px) rotate(4deg); opacity: 1; }
}

/* A few slow motes, so the page is not entirely still. */
.auth-mote {
  position: fixed;
  z-index: 0;
  inline-size: 5px;
  block-size: 5px;
  border-radius: 50%;
  background: var(--masar-300);
  opacity: 0.22;
  animation: mote 14s ease-in-out infinite;
  pointer-events: none;
}
.auth-mote:nth-of-type(1) { inset-block-start: 14%; inset-inline-start: 22%; animation-delay: 0s; }
.auth-mote:nth-of-type(2) { inset-block-start: 62%; inset-inline-start: 9%;  animation-delay: -5s; }
.auth-mote:nth-of-type(3) { inset-block-start: 30%; inset-inline-end: 14%;   animation-delay: -9s; }
.auth-mote:nth-of-type(4) { inset-block-end: 16%;   inset-inline-end: 26%;   animation-delay: -3s; }

@keyframes mote {
  0%, 100% { transform: translateY(0); opacity: 0.16; }
  50%      { transform: translateY(-16px); opacity: 0.4; }
}

/* ─── layout ─── */

.auth-shell {
  position: relative;
  z-index: 1;
  inline-size: 100%;
  max-inline-size: 27rem;
  text-align: center;
}

/* The page assembles itself rather than appearing all at once: the mark, then
   the words, then the card. Short and staggered by 90ms - long enough to feel
   composed, far too short to feel like waiting. */
.auth-mark   { animation: rise 0.55s cubic-bezier(0.22, 1, 0.36, 1) both; }
.auth-title  { animation: rise 0.55s cubic-bezier(0.22, 1, 0.36, 1) 0.09s both; }
.auth-title-en,
.auth-sub    { animation: rise 0.55s cubic-bezier(0.22, 1, 0.36, 1) 0.16s both; }
.auth-card   { animation: rise 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.24s both; }
.auth-foot   { animation: rise 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.34s both; }

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

.auth-lang {
  position: fixed;
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-block-size: 44px;
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  border: 1px solid var(--auth-card-border);
  background: var(--auth-card);
  color: var(--auth-text);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  backdrop-filter: blur(8px);
  transition: background 0.2s ease, border-color 0.2s ease;
}
.auth-lang:hover {
  background: rgb(255 255 255 / 0.1);
  border-color: rgb(255 255 255 / 0.24);
}

/* The mark, with a glow behind it. */
.auth-mark {
  position: relative;
  display: inline-grid;
  place-items: center;
  inline-size: 5.25rem;
  block-size: 5.25rem;
  margin-block-end: 1.25rem;
}
.auth-mark::before {
  content: "";
  position: absolute;
  inset: -22%;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(53 180 189 / 0.34), transparent 66%);
  filter: blur(6px);
  /* Slow, like a seal catching the light - not a pulse asking for attention. */
  animation: seal 4.2s ease-in-out infinite;
}

@keyframes seal {
  0%, 100% { opacity: 0.55; transform: scale(0.94); }
  50%      { opacity: 1;    transform: scale(1.16); }
}
.auth-mark img,
.auth-mark svg {
  position: relative;
  inline-size: 3.4rem;
  block-size: auto;
}

.auth-title {
  margin: 0;
  font-size: 1.85rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: #fff;
}

.auth-title-en {
  margin: 0.1rem 0 0;
  font-family: var(--font-en);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--auth-faint);
}

.auth-sub {
  margin: 0.75rem 0 0;
  font-size: 0.9375rem;
  color: var(--auth-muted);
}

/* ─── the card ─── */

.auth-card {
  position: relative;
  overflow: hidden;
  margin-block-start: 1.75rem;
  padding: 1.5rem;
  text-align: start;
  border-radius: 1.25rem;
  border: 1px solid var(--auth-card-border);
  background: var(--auth-card);
  box-shadow: 0 24px 60px -24px rgb(0 0 0 / 0.6);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.auth-field + .auth-field {
  margin-block-start: 1rem;
}

.auth-label {
  display: block;
  margin-block-end: 0.4rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--auth-muted);
}

.auth-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.auth-input-wrap svg {
  position: absolute;
  inset-inline-start: 0.9rem;
  inline-size: 1.125rem;
  block-size: 1.125rem;
  color: var(--auth-faint);
  pointer-events: none;
}

.auth-input {
  inline-size: 100%;
  min-block-size: 3rem;
  padding-block: 0.7rem;
  padding-inline: 2.75rem 1rem;
  border-radius: 0.875rem;
  border: 1px solid var(--auth-field-border);
  background: var(--auth-field);
  color: var(--auth-text);
  font: inherit;
  font-size: 0.9375rem;
  transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.auth-input::placeholder {
  color: var(--auth-faint);
}
.auth-input:focus {
  outline: none;
  border-color: var(--masar-400);
  background: rgb(255 255 255 / 0.08);
  box-shadow: 0 0 0 3px rgb(53 180 189 / 0.18);
}

/* An email address and a password are Latin runs. Marking them keeps the
   caret and the placeholder on the correct side inside an RTL page. */
.auth-input[type="email"],
.auth-input[type="password"],
.auth-input[type="text"] {
  direction: ltr;
  text-align: start;
  font-family: var(--font-en);
}

.pw-toggle {
  position: absolute;
  inset-inline-end: 0.35rem;
  display: inline-grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border: 0;
  border-radius: 0.65rem;
  background: transparent;
  color: var(--auth-faint);
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease;
}
.pw-toggle:hover {
  color: var(--auth-text);
  background: rgb(255 255 255 / 0.07);
}
.pw-toggle svg {
  position: static;
  inline-size: 1.125rem;
  block-size: 1.125rem;
  color: inherit;
}

/* ─── the role picker, staff page only ─── */

.auth-roles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.5rem;
  margin-block-start: 0.4rem;
}

.auth-role {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-block-size: 44px;
  padding: 0.5rem 0.6rem;
  border-radius: 0.75rem;
  border: 1px solid var(--auth-field-border);
  background: var(--auth-field);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--auth-muted);
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}
.auth-role input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.auth-role:has(input:checked) {
  border-color: var(--masar-400);
  background: rgb(53 180 189 / 0.16);
  color: #fff;
}
.auth-role:has(input:focus-visible) {
  outline: 2px solid var(--masar-300);
  outline-offset: 2px;
}

/* ─── the button ─── */

.auth-submit {
  position: relative;
  inline-size: 100%;
  min-block-size: 3rem;
  margin-block-start: 1.25rem;
  border: 0;
  border-radius: 0.875rem;
  background: linear-gradient(100deg, var(--masar-700), var(--masar-600) 55%, var(--masar-400));
  color: #fff;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 10px 26px -12px rgb(0 125 134 / 0.85);
  transition: filter 0.2s ease, transform 0.12s ease, box-shadow 0.2s ease;
}
.auth-submit:hover:not(:disabled) {
  filter: brightness(1.08);
  box-shadow: 0 14px 32px -12px rgb(0 125 134 / 0.95);
}
.auth-submit:active:not(:disabled) {
  transform: translateY(1px);
}
.auth-submit:disabled {
  cursor: progress;
  filter: saturate(0.6) brightness(0.85);
}

.auth-submit.loading .auth-submit-text {
  visibility: hidden;
}
.auth-submit.loading::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 1.15rem;
  block-size: 1.15rem;
  margin-block-start: -0.575rem;
  margin-inline-start: -0.575rem;
  border-radius: 50%;
  border: 2px solid rgb(255 255 255 / 0.35);
  border-block-start-color: #fff;
  animation: spin 0.7s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ─── messages ─── */

.auth-alert {
  margin-block-start: 1rem;
  padding: 0.75rem 0.9rem;
  border-radius: 0.75rem;
  border: 1px solid rgb(244 63 94 / 0.36);
  background: rgb(244 63 94 / 0.13);
  color: #ffd4da;
  font-size: 0.875rem;
}
.auth-alert:empty {
  display: none;
}
.auth-alert.is-ok {
  border-color: rgb(16 185 129 / 0.38);
  background: rgb(16 185 129 / 0.13);
  color: #c8f5e4;
}

.auth-links {
  margin-block-start: 1.1rem;
  text-align: center;
  font-size: 0.875rem;
}
.auth-links a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-block-size: 44px;
  color: var(--masar-300);
  text-decoration: none;
  font-weight: 600;
}
.auth-links a:hover {
  text-decoration: underline;
}

.auth-note {
  margin-block-start: 1.25rem;
  padding: 0.85rem 1rem;
  border-radius: 0.75rem;
  background: rgb(255 255 255 / 0.04);
  border: 1px solid rgb(255 255 255 / 0.07);
  font-size: 0.8125rem;
  color: var(--auth-muted);
  text-align: start;
}
.auth-note ul {
  margin: 0.4rem 0 0;
  padding-inline-start: 1.1rem;
}

.auth-foot {
  position: relative;
  z-index: 1;
  margin-block-start: 1.5rem;
  font-size: 0.75rem;
  color: var(--auth-faint);
}

*:focus-visible {
  outline: 2px solid var(--masar-300);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* One pass of light across the card after it settles, then never again. A
   loop here would pull the eye away from the field the person is filling in. */
.auth-card::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inline-size: 45%;
  inset-inline-start: -55%;
  background: linear-gradient(100deg, transparent, rgb(255 255 255 / 0.07), transparent);
  animation: sweep 1.5s ease-out 0.9s 1 both;
  pointer-events: none;
}

@keyframes sweep {
  to { inset-inline-start: 115%; }
}

/* ─── phones ─── */

/* The backdrop is drawn 1440 wide and cropped to the screen; nothing of it may
   count toward the page's width, or a phone lays the page out wider than
   itself and shrinks it to fit. */
html { overflow-x: hidden; }
.auth-field-art { overflow: clip; contain: paint; }

@media (max-width: 30rem) {
  body { padding: 1rem; }
  .auth-card { padding: 1.25rem; }
  .auth-label { font-size: 0.875rem; }
  /* 16px: below it, iOS zooms the page in on focus and leaves it there. */
  .auth-input { font-size: 1rem; }
}

/* A phone showing the "desktop site" lays the page out ~980px wide and
   shrinks it to the screen, so the card reads at a third of the width. fit.js
   measures that and sets --auth-zoom; the card is scaled back to phone size. */
.auth-fit .auth-shell,
.auth-fit .auth-lang { zoom: var(--auth-zoom, 1); }
