/* Nabih design system — «لؤلؤ» by day, «فجر» by night.
   Every page (site, /app, /admin, legal, /otp) links this file first and builds
   on its tokens; nothing outside it defines a colour, a radius or a duration.
   Theme: follows the OS, unless the user picks one (html[data-theme]). */

:root {
  /* Pearl — day */
  --bg: #f7f8fc;
  --bg-2: #eff1f8;
  --surface: #ffffff;
  --surface-2: #f3f5fb;
  --glass: rgb(255 255 255 / 0.72);
  --ink: #0d1424;
  --muted: #586179;
  --faint: #8a91a5;
  --line: #e3e6ef;
  --line-strong: #cfd4e2;
  --accent: #2146e0;
  --accent-hover: #1a39bd;
  --accent-ink: #ffffff;
  --accent-soft: #e8edff;
  --ok: #13865a;
  --ok-soft: #e3f5ec;
  --warn: #a35f00;
  --warn-soft: #fdf1df;
  --danger: #c2302f;
  --danger-soft: #fdeaea;
  --aurora-1: #8ea6ff;
  --aurora-2: #ffc6dd;
  --scrim: rgb(13 20 36 / 0.38);
  --shadow-sm: 0 1px 2px rgb(13 20 36 / 0.05);
  --shadow-md:
    0 1px 2px rgb(13 20 36 / 0.04), 0 12px 28px -14px rgb(33 70 224 / 0.2);
  --shadow-lg:
    0 2px 6px rgb(13 20 36 / 0.05), 0 30px 70px -28px rgb(33 70 224 / 0.32);

  --radius-xs: 8px;
  --radius-sm: 12px;
  --radius: 16px;
  --radius-lg: 22px;
  --radius-xl: 30px;

  /* Motion — timings from the motion-design tables: controls 120–180ms,
     panels 300–400ms, ambient in seconds. One curve for "arriving". */
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast: 150ms;
  --t: 240ms;
  --t-slow: 380ms;

  --font: "Readex Pro", "IBM Plex Sans Arabic", system-ui, sans-serif;
  --font-num: "Readex Pro", system-ui, sans-serif;
  color-scheme: light;
}

/* Dawn — night. Same token names, so components never branch on theme. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0a0f1e;
    --bg-2: #0e1427;
    --surface: #121a30;
    --surface-2: #18213b;
    --glass: rgb(255 255 255 / 0.055);
    --ink: #eef2ff;
    --muted: #9aa5c8;
    --faint: #6f7aa0;
    --line: rgb(255 255 255 / 0.09);
    --line-strong: rgb(255 255 255 / 0.16);
    --accent: #8fa8ff;
    --accent-hover: #a9bcff;
    --accent-ink: #0a0f1e;
    --accent-soft: rgb(143 168 255 / 0.14);
    --ok: #7be0b4;
    --ok-soft: rgb(123 224 180 / 0.12);
    --warn: #f2c46b;
    --warn-soft: rgb(242 196 107 / 0.12);
    --danger: #ff8f8f;
    --danger-soft: rgb(255 143 143 / 0.12);
    --aurora-1: #3a5bff;
    --aurora-2: #c9772f;
    --scrim: rgb(0 0 0 / 0.55);
    --shadow-sm: 0 1px 0 rgb(255 255 255 / 0.04) inset;
    --shadow-md:
      0 1px 0 rgb(255 255 255 / 0.05) inset, 0 16px 40px -20px rgb(0 0 0 / 0.7);
    --shadow-lg:
      0 1px 0 rgb(255 255 255 / 0.06) inset, 0 30px 80px -24px rgb(0 0 0 / 0.8);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #0a0f1e;
  --bg-2: #0e1427;
  --surface: #121a30;
  --surface-2: #18213b;
  --glass: rgb(255 255 255 / 0.055);
  --ink: #eef2ff;
  --muted: #9aa5c8;
  --faint: #6f7aa0;
  --line: rgb(255 255 255 / 0.09);
  --line-strong: rgb(255 255 255 / 0.16);
  --accent: #8fa8ff;
  --accent-hover: #a9bcff;
  --accent-ink: #0a0f1e;
  --accent-soft: rgb(143 168 255 / 0.14);
  --ok: #7be0b4;
  --ok-soft: rgb(123 224 180 / 0.12);
  --warn: #f2c46b;
  --warn-soft: rgb(242 196 107 / 0.12);
  --danger: #ff8f8f;
  --danger-soft: rgb(255 143 143 / 0.12);
  --aurora-1: #3a5bff;
  --aurora-2: #c9772f;
  --scrim: rgb(0 0 0 / 0.55);
  --shadow-sm: 0 1px 0 rgb(255 255 255 / 0.04) inset;
  --shadow-md:
    0 1px 0 rgb(255 255 255 / 0.05) inset, 0 16px 40px -20px rgb(0 0 0 / 0.7);
  --shadow-lg:
    0 1px 0 rgb(255 255 255 / 0.06) inset, 0 30px 80px -24px rgb(0 0 0 / 0.8);
  color-scheme: dark;
}

/* ---------- Base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 1rem/1.75 var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1,
h2,
h3,
h4 {
  line-height: 1.3;
  margin: 0;
  font-weight: 600;
  text-wrap: balance;
  letter-spacing: -0.005em;
}
p {
  margin: 0;
  text-wrap: pretty;
}
a {
  color: var(--accent);
  text-underline-offset: 3px;
}
img,
svg,
video {
  max-width: 100%;
}
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}
::selection {
  background: var(--accent-soft);
  color: var(--ink);
}
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}
[hidden] {
  display: none !important;
}
.num,
time,
.tabular {
  font-variant-numeric: tabular-nums;
}
bdi[dir="ltr"],
.ltr {
  direction: ltr;
  unicode-bidi: isolate;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Buttons ---------- */
.btn {
  --btn-h: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--btn-h);
  padding-inline: 20px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-weight: 500;
  font-size: 0.95rem;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition:
    background-color var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    box-shadow var(--t) var(--ease),
    transform var(--t-fast) var(--ease);
}
.btn:active:not(:disabled) {
  transform: scale(0.97);
}
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}
.btn--primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 8px 22px -12px var(--accent);
}
.btn--primary:hover:not(:disabled) {
  background: var(--accent-hover);
  box-shadow: 0 12px 28px -12px var(--accent);
}
.btn--ghost {
  background: var(--surface);
  border-color: var(--line-strong);
  color: var(--ink);
}
.btn--ghost:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}
.btn--quiet {
  background: transparent;
  color: var(--ink);
}
.btn--quiet:hover:not(:disabled) {
  background: var(--surface-2);
}
.btn--danger {
  background: var(--danger-soft);
  color: var(--danger);
}
.btn--danger:hover:not(:disabled) {
  background: var(--danger);
  color: #fff;
}
.btn--sm {
  --btn-h: 36px;
  padding-inline: 14px;
  font-size: 0.875rem;
  border-radius: var(--radius-xs);
}
.btn--lg {
  --btn-h: 52px;
  padding-inline: 28px;
  font-size: 1rem;
}
.btn--block {
  width: 100%;
}
.btn--icon {
  padding-inline: 0;
  width: var(--btn-h);
}
/* Busy: keeps its width, shows a spinner, refuses a second click. */
.btn.is-busy {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.btn.is-busy::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-color: var(--accent-ink) var(--accent-ink) transparent transparent;
  animation: n-spin 0.7s linear infinite;
}
.btn--ghost.is-busy::after,
.btn--quiet.is-busy::after {
  border-color: var(--accent) var(--accent) transparent transparent;
}

/* ---------- Fields ---------- */
.field {
  display: grid;
  gap: 6px;
}
.field > label,
.label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink);
}
.hint {
  font-size: 0.8rem;
  color: var(--muted);
}
.input,
.field input:not([type="checkbox"]):not([type="radio"]),
.field select,
.field textarea {
  width: 100%;
  min-height: 46px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--ink);
  transition:
    border-color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease);
}
.field textarea {
  min-height: 96px;
  resize: vertical;
}
.input::placeholder,
.field input::placeholder,
.field textarea::placeholder {
  color: var(--faint);
}
.input:hover,
.field input:hover,
.field select:hover,
.field textarea:hover {
  border-color: var(--faint);
}
.input:focus,
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.field.has-error input,
.field.has-error select,
.field.has-error textarea,
.input[aria-invalid="true"] {
  border-color: var(--danger);
}
.field-error {
  font-size: 0.8rem;
  color: var(--danger);
}

/* ---------- Surfaces ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.glass {
  background: var(--glass);
  border: 1px solid var(--line);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
}

/* Status pills: state is carried by colour AND text, never colour alone. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 500;
  white-space: nowrap;
  background: var(--surface-2);
  color: var(--muted);
}
.pill--ok {
  background: var(--ok-soft);
  color: var(--ok);
}
.pill--warn {
  background: var(--warn-soft);
  color: var(--warn);
}
.pill--danger {
  background: var(--danger-soft);
  color: var(--danger);
}
.pill--accent {
  background: var(--accent-soft);
  color: var(--accent);
}

/* ---------- Ambient aurora (decorative, behind content) ---------- */
.aurora {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: -1;
}
.aurora::before,
.aurora::after {
  content: "";
  position: absolute;
  width: min(70vw, 760px);
  aspect-ratio: 1;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.4;
}
.aurora::before {
  background: var(--aurora-1);
  inset-block-start: -30%;
  inset-inline-start: -12%;
  animation: n-drift 20s var(--ease-in-out) infinite alternate;
}
.aurora::after {
  background: var(--aurora-2);
  inset-block-end: -40%;
  inset-inline-end: -18%;
  opacity: 0.3;
  animation: n-drift 26s var(--ease-in-out) infinite alternate-reverse;
}

/* ---------- The orb: Nabih's presence ----------
   Day: a pearl (iridescent ring + soft core). Night: Dawn's breathing blue
   sphere, exactly as the owner picked it. .orb--thinking speeds it up. */
.orb {
  --size: 120px;
  display: inline-block;
  vertical-align: middle;
  position: relative;
  width: var(--size);
  aspect-ratio: 1;
  border-radius: 50%;
  flex: none;
  background: conic-gradient(
    from 0deg,
    #cfe0ff,
    #ffd6e8,
    #d9fff1,
    #e5dcff,
    #cfe0ff
  );
  animation:
    n-spin 9s linear infinite,
    n-glow-day 4.2s ease-in-out infinite;
}
.orb::after {
  content: "";
  position: absolute;
  inset: 10%;
  border-radius: 50%;
  background: radial-gradient(
    circle at 40% 35%,
    #fff,
    rgb(255 255 255 / 0.55) 60%,
    rgb(255 255 255 / 0.2)
  );
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .orb {
    background: radial-gradient(
      circle at 35% 30%,
      #fff 0 6%,
      #b9d3ff 14%,
      #4d6bff 48%,
      #1b2150 75%
    );
    animation: n-breathe 4.2s ease-in-out infinite;
  }
  :root:not([data-theme="light"]) .orb::after {
    display: none;
  }
}
:root[data-theme="dark"] .orb {
  background: radial-gradient(
    circle at 35% 30%,
    #fff 0 6%,
    #b9d3ff 14%,
    #4d6bff 48%,
    #1b2150 75%
  );
  animation: n-breathe 4.2s ease-in-out infinite;
}
:root[data-theme="dark"] .orb::after {
  display: none;
}
.orb--thinking {
  animation-duration: 3s, 1.4s;
}
.orb--sm {
  --size: 28px;
}
.orb--md {
  --size: 44px;
}

/* ---------- Toasts ----------
   One place for every confirmation and error, fixed to the viewport, so the
   message appears where the user is looking — never at the top of a long
   page they have scrolled away from. Bottom-centre at every width: a
   sidebar sits at the inline-start edge, so a corner toast would cover it.
   Created by nabih-ui.js (window.toast). */
.toasts {
  position: fixed;
  z-index: 1000;
  inset-inline: 16px;
  inset-block-end: calc(16px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: min(440px, 100%);
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--bg);
  box-shadow: var(--shadow-lg);
  font-size: 0.925rem;
  line-height: 1.6;
  animation: n-toast-in var(--t-slow) var(--ease) both;
}
.toast.is-leaving {
  animation: n-toast-out var(--t) var(--ease) both;
}
.toast__icon {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 0.75rem;
  font-weight: 700;
  margin-block-start: 1px;
}
.toast--ok .toast__icon {
  background: var(--ok);
  color: #fff;
}
.toast--error .toast__icon {
  background: var(--danger);
  color: #fff;
}
.toast--info .toast__icon {
  background: var(--accent);
  color: var(--accent-ink);
}
.toast__close {
  flex: none;
  margin-inline-start: 4px;
  background: none;
  border: 0;
  color: inherit;
  opacity: 0.6;
  cursor: pointer;
  width: 24px;
  height: 24px;
  border-radius: 6px;
}
.toast__close:hover {
  opacity: 1;
}
/* One action on the toast itself («تراجع»), where the user is already looking. */
.toast__action {
  flex: none;
  align-self: center;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 6px;
}
.toast__action:focus-visible {
  outline: 2px solid currentColor;
}

/* ---------- Loading ---------- */
.skeleton {
  border-radius: var(--radius-sm);
  background: linear-gradient(
      100deg,
      var(--surface-2) 30%,
      var(--bg-2) 50%,
      var(--surface-2) 70%
    )
    0 0 / 200% 100%;
  animation: n-shimmer 1.4s linear infinite;
}
.spinner {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--line-strong);
  border-top-color: var(--accent);
  animation: n-spin 0.7s linear infinite;
}

/* ---------- Scroll reveal ----------
   Content is visible by default; only when nabih-ui.js has marked the page
   (html.reveal-on) do below-the-fold blocks start lowered and rise in. A page
   without JS, a crawler or a thumbnail sees everything. */
.reveal-on [data-reveal]:not(.is-in) {
  opacity: 0;
  transform: translateY(18px);
}
.reveal-on [data-reveal] {
  transition:
    opacity 600ms var(--ease),
    transform 600ms var(--ease);
  transition-delay: var(--delay, 0ms);
}

/* ---------- Keyframes ---------- */
@keyframes n-spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes n-drift {
  to {
    transform: translate(10%, 12%) scale(1.15);
  }
}
@keyframes n-glow-day {
  0%,
  100% {
    box-shadow: 0 20px 50px -20px rgb(33 70 224 / 0.45);
  }
  50% {
    box-shadow: 0 0 70px -4px rgb(120 150 255 / 0.75);
  }
}
@keyframes n-breathe {
  0%,
  100% {
    transform: scale(1);
    box-shadow:
      0 0 60px -6px #5e7bff,
      0 0 120px -30px #f2b880;
  }
  50% {
    transform: scale(1.05);
    box-shadow:
      0 0 80px 0 #5e7bff,
      0 0 160px -20px #f2b880;
  }
}
@keyframes n-shimmer {
  to {
    background-position: -200% 0;
  }
}
@keyframes n-toast-in {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.98);
  }
}
@keyframes n-toast-out {
  to {
    opacity: 0;
    transform: translateY(8px) scale(0.98);
  }
}
@keyframes n-rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal-on [data-reveal]:not(.is-in) {
    opacity: 1;
    transform: none;
  }
}

/* Theme toggles carry both glyphs; aria-pressed (set by nabih-ui.js) picks one. */
[data-theme-toggle] .i-sun,
[data-theme-toggle][aria-pressed="true"] .i-moon {
  display: none;
}
[data-theme-toggle][aria-pressed="true"] .i-sun {
  display: inline-block;
}
.field [aria-invalid="true"] {
  border-color: var(--danger) !important;
  box-shadow: 0 0 0 4px var(--danger-soft) !important;
}
