/* ============================================================
   Qudra Assessment Platform — Design System
   Apple-inspired: minimal, editorial, premium, high-trust.
   RTL-aware via [dir="rtl"] + CSS logical properties.
   ============================================================ */

:root {
  --bg: #f5f5f7;
  --surface: #ffffff;
  --text-primary: #1d1d1f;
  --text-secondary: #6e6e73;
  --accent: #0071e3;
  --accent-hover: #0077ed;
  --dark: #0a0a0a;
  --success: #1d8a4a;
  --warning: #b5651d;
  --danger: #d53f3f;
  --border: #d2d2d7;
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.06);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08);
  --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.12);
  --font-en: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Helvetica, Arial, sans-serif;
  --font-ar: -apple-system, BlinkMacSystemFont, "SF Arabic", "Segoe UI", "Tahoma", sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text-primary);
  font-family: var(--font-en);
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
  /* Global overflow containment (Section A/L): a single unexpectedly long
     value (long name, raw URL, security-test payload string) must never be
     able to widen <html>/<body> and cause page-level horizontal scroll. */
  max-width: 100%;
  overflow-x: hidden;
}

/* Any flex/grid child anchor for width-constrained content. Applied
   selectively below to the specific containers that historically broke
   (cards, table cells, alerts, form controls) rather than globally, so we
   never silently truncate content the user actually needs to read. */
.min-w-0 { min-width: 0; }

html[dir="rtl"] body,
html[lang="ar"] body {
  font-family: var(--font-ar);
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.container { max-width: 1080px; margin: 0 auto; padding: 0 24px; }
.container-narrow { max-width: 720px; margin: 0 auto; padding: 0 24px; }

/* ---------- Top bar / language switch ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  background: rgba(245, 245, 247, 0.8);
  backdrop-filter: saturate(180%) blur(20px);
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.topbar .brand {
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}
.lang-switch {
  display: flex;
  gap: 4px;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 999px;
  padding: 4px;
}
.lang-switch button {
  border: none;
  background: transparent;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  color: var(--text-secondary);
  transition: all 0.2s ease;
}
.lang-switch button.active {
  background: var(--surface);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}

/* ---------- Hero / editorial typography ---------- */
.hero {
  padding: 96px 0 64px;
  text-align: center;
}
.hero h1 {
  font-size: clamp(2.25rem, 5vw, 3.5rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 16px;
}
.hero p.subtitle {
  color: var(--text-secondary);
  font-size: 1.2rem;
  margin: 0 auto 32px;
  max-width: 640px;
}

/* ---------- Cards / surfaces ---------- */
.card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 32px;
  box-shadow: var(--shadow-sm);
  border: 1px solid rgba(0, 0, 0, 0.04);
  /* Containment (Section A/8): a card is a flex/grid item in some layouts
     (grid-2/grid-3, admin-main). Without min-width:0 a long unbroken string
     inside it (URL, long name) can force the card — and its ancestor row —
     wider than the viewport. max-width:100% + overflow-wrap covers the
     remaining case of long text inside a card that ISN'T a flex/grid item. */
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.card + .card { margin-top: 16px; }
.card-dark {
  background: var(--dark);
  color: #f5f5f7;
  border-radius: var(--radius-lg);
  padding: 40px;
}
.card-dark .text-secondary { color: #a1a1a6; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: none;
  border-radius: 980px;
  padding: 12px 28px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, opacity 0.15s ease;
  font-family: inherit;
}
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-primary:disabled { background: var(--border); color: var(--text-secondary); cursor: not-allowed; }
.btn-secondary { background: rgba(0, 0, 0, 0.06); color: var(--text-primary); }
.btn-secondary:hover { background: rgba(0, 0, 0, 0.09); }
.btn-ghost { background: transparent; color: var(--accent); padding: 12px 16px; }
.btn:active { transform: scale(0.97); }
.btn-block { width: 100%; }
.btn-sm { padding: 8px 18px; font-size: 0.85rem; }
.btn-danger { background: var(--danger); color: #fff; }

/* ---------- Forms ---------- */
label { display: block; font-size: 0.85rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 6px; }
input, select, textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
  font-family: inherit;
  background: var(--surface);
  color: var(--text-primary);
  transition: border-color 0.15s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.15);
}
.form-group { margin-bottom: 18px; min-width: 0; max-width: 100%; }
.form-error { color: var(--danger); font-size: 0.85rem; margin-top: 6px; overflow-wrap: anywhere; }

/* Long option text inside <select> is clipped by the browser natively and
   is not a page-overflow risk, but the <select> itself must never grow
   past its form-group / grid cell (Section G: "long org names don't break
   selects"). */
select { max-width: 100%; text-overflow: ellipsis; }
input, textarea { max-width: 100%; }

/* ---------- Progress ---------- */
.progress-track {
  height: 6px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.08);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width 0.3s ease;
}
.progress-meta {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

/* ---------- Question ---------- */
.question-card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 40px;
  box-shadow: var(--shadow-md);
  max-width: 640px;
  margin: 0 auto;
}
.question-number {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 12px;
}
.question-text {
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.4;
  margin-bottom: 28px;
}
.option-list { display: flex; flex-direction: column; gap: 10px; }
.option-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.option-item:hover { border-color: var(--accent); background: rgba(0, 113, 227, 0.04); }
.option-item.selected { border-color: var(--accent); background: rgba(0, 113, 227, 0.08); }
.option-key-badge {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.85rem;
  flex-shrink: 0;
  color: var(--text-secondary);
}
.option-item.selected .option-key-badge { background: var(--accent); color: #fff; }
.option-text { font-size: 1rem; }

.nav-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 640px;
  margin: 28px auto 0;
}

/* ---------- Grid / table ---------- */
/* minmax(0,1fr) instead of 1fr (Section A/L): a bare `1fr` track can still
   grow past the available space to fit an unbreakable child (e.g. a raw
   URL or a 100+ char name with no wrap opportunity) — `minmax(0, 1fr)`
   caps the track at the grid's own width so children are forced to wrap
   or ellipsis instead of expanding the grid itself. */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 720px) {
  .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Tables ----------
   Root cause of the reported overflow bug: a plain HTML table has no
   intrinsic width limit — a single long, unbreakable cell value (a raw
   invitation URL, a 100+ character candidate name, or a security-test
   payload string like "AAAA...AAAA" or "<script>...") stretches that <td>,
   the whole table, its parent .card, and ultimately the page itself,
   producing page-level horizontal scroll at every breakpoint.

   Fix strategy:
   - table-layout:fixed  -> column widths are distributed by the table's
     own width, not dictated by the widest cell content.
   - .table-responsive wrapper -> the ONLY element allowed horizontal
     scroll is this wrapper (an explicit, contained, "internal" scrollbar
     for genuinely dense tables at narrow widths), never the page shell.
   - td default: wrap + break long tokens instead of forcing table width.
   - .cell-truncate: explicit opt-in for columns that should show an
     ellipsis with the full value available on hover/click (long
     names/URLs/tokens) rather than wrapping to multiple lines. */
.table-responsive {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
table { width: 100%; max-width: 100%; border-collapse: collapse; font-size: 0.9rem; table-layout: fixed; }
th, td {
  padding: 10px 12px;
  text-align: start;
  border-bottom: 1px solid var(--border);
  overflow-wrap: anywhere;
  word-break: break-word;
  vertical-align: middle;
}
th { color: var(--text-secondary); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.03em; }

/* Ellipsis-with-tooltip pattern for columns holding potentially very long
   single tokens (names, emails, campaign/assessment titles, tokens/URLs).
   `title` attribute on the same element provides the native-browser
   "full value on hover" affordance; a `.cell-expand` details/summary
   variant (below) covers touch devices where hover isn't available. */
.cell-truncate {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Explicit expand-on-demand for touch/keyboard users who cannot rely on
   hover to reveal a truncated value (Section A: "ellipsis + tooltip OR
   details/expand view"). */
details.cell-expand { max-width: 100%; }
details.cell-expand > summary {
  cursor: pointer;
  list-style: none;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--accent);
}
details.cell-expand > summary::-webkit-details-marker { display: none; }
details.cell-expand[open] > summary { white-space: normal; overflow-wrap: anywhere; color: var(--text-primary); }
details.cell-expand .cell-expand-full {
  margin-top: 4px;
  font-size: 0.85rem;
  color: var(--text-secondary);
  overflow-wrap: anywhere;
  word-break: break-word;
  font-family: monospace;
}

/* LTR-forced inline span for emails/URLs/tokens embedded inside an RTL
   document (Section: "emails must preserve LTR reading direction even
   inside Arabic RTL UI"). Distinct from .ltr-nums (numerals only). */
.ltr-text { unicode-bidi: isolate; direction: ltr; display: inline-block; max-width: 100%; overflow-wrap: anywhere; }

/* ---------- Badges ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  max-width: 100%;
  overflow-wrap: anywhere;
}
.badge-a { background: rgba(29, 138, 74, 0.12); color: var(--success); }
.badge-b { background: rgba(0, 113, 227, 0.12); color: var(--accent); }
.badge-c { background: rgba(181, 101, 29, 0.12); color: var(--warning); }
.badge-d { background: rgba(213, 63, 63, 0.12); color: var(--danger); }
.badge-neutral { background: rgba(0, 0, 0, 0.06); color: var(--text-secondary); }

/* ---------- Score bars ---------- */
.score-row { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; max-width: 100%; }
.score-label { flex: 0 0 180px; min-width: 0; max-width: 220px; font-size: 0.9rem; font-weight: 600; overflow-wrap: anywhere; word-break: break-word; }
.score-bar-track { flex: 1; min-width: 40px; height: 10px; border-radius: 999px; background: rgba(0,0,0,0.06); overflow: hidden; }
.score-bar-fill { height: 100%; border-radius: 999px; background: var(--accent); }
.score-value { flex: 0 0 56px; text-align: end; font-weight: 700; font-size: 0.9rem; }

/* On narrow viewports the fixed 180px label + 56px value left almost no room
   for the bar track (it could shrink to a sliver or vanish entirely below
   ~420px). Stack label+value above the bar so the track always gets full
   width. Verified: no more collapsed/invisible bars at 320-430px. */
@media (max-width: 480px) {
  .score-row { flex-wrap: wrap; gap: 6px; margin-bottom: 20px; }
  .score-label { flex: 1 1 auto; order: 1; }
  .score-value { flex: 0 0 auto; order: 2; }
  .score-bar-track { flex: 1 1 100%; order: 3; }
}

/* ---------- Sidebar / admin shell ---------- */
.admin-shell { display: flex; min-height: 100vh; }
.admin-sidebar {
  width: 240px;
  background: var(--dark);
  color: #f5f5f7;
  padding: 24px 16px;
  flex-shrink: 0;
}
.admin-sidebar .brand { font-weight: 700; font-size: 1.05rem; margin-bottom: 32px; padding: 0 8px; }
.admin-nav a {
  display: block;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  color: #a1a1a6;
  font-size: 0.9rem;
  font-weight: 500;
  margin-bottom: 2px;
}
.admin-nav a:hover, .admin-nav a.active { background: rgba(255,255,255,0.08); color: #fff; text-decoration: none; }
.admin-main {
  flex: 1;
  padding: 32px 40px;
  max-width: 1100px;
  /* min-width:0 alone is not sufficient here: the CONTENTS of admin-main
     (tables, cards) also need their own containment rules (added above) —
     min-width:0 only removes flex's default "never shrink below content
     size" behavior on this container itself. Both are required together. */
  min-width: 0;
  width: 100%;
  overflow-x: hidden;
}
.admin-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 28px;
  flex-wrap: wrap;
  gap: 8px;
  max-width: 100%;
}
.admin-header h1 { font-size: 1.6rem; font-weight: 700; margin: 0; overflow-wrap: anywhere; }

/* .admin-shell itself must never exceed the viewport width regardless of
   sidebar (fixed 240px) + main content sizing — this is the outermost
   guard against page-level horizontal scroll on the Admin console at
   every desktop breakpoint (1024/1280/1366/1440/1920px). */
.admin-shell { max-width: 100vw; overflow-x: hidden; }

/* On phones the fixed 240px sidebar next to flex:1 main content caused
   horizontal page overflow (240px + main's own min-content width, plus
   32-40px padding, exceeds a 320-375px viewport). Stack sidebar above
   main content instead of side-by-side below 720px. Verified: no more
   horizontal overflow at 320/375/390/430px on the admin dashboard. */
@media (max-width: 720px) {
  .admin-shell { flex-direction: column; min-height: 0; }
  .admin-sidebar { width: 100%; }
  .admin-main { padding: 20px 16px; max-width: 100%; }
}

/* ---------- Utility ---------- */
.text-secondary { color: var(--text-secondary); }
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.hidden { display: none !important; }
.spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid rgba(0,0,0,0.1); border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.alert {
  padding: 14px 18px;
  border-radius: var(--radius-md);
  font-size: 0.9rem;
  margin-bottom: 16px;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.alert-error { background: rgba(213, 63, 63, 0.08); color: var(--danger); }
.alert-success { background: rgba(29, 138, 74, 0.08); color: var(--success); }
.alert-info { background: rgba(0, 113, 227, 0.08); color: var(--accent); }

/* ---------- Invitation link component ----------
   Replaces the old "raw giant URL string in an alert box" pattern. The
   full secure tokenized URL is never rendered as free text on the page —
   only exposed via Copy Link (clipboard) / Open Link (new tab), per the
   explicit product requirement. An optional short preview may be shown
   truncated with ellipsis. */
.invite-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  padding: 18px 20px;
  border-radius: var(--radius-md);
  background: rgba(29, 138, 74, 0.06);
  border: 1px solid rgba(29, 138, 74, 0.18);
  max-width: 100%;
}
.invite-card .invite-status {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 1 1 220px;
}
.invite-card .invite-status .invite-icon {
  color: var(--success);
  font-size: 1.1rem;
  flex-shrink: 0;
}
.invite-card .invite-status .invite-text { min-width: 0; }
.invite-card .invite-status .invite-title { font-weight: 700; font-size: 0.95rem; }
.invite-card .invite-status .invite-preview {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.8rem;
  color: var(--text-secondary);
  font-family: monospace;
}
.invite-card .invite-actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }

footer.site-footer {
  text-align: center;
  padding: 40px 24px;
  color: var(--text-secondary);
  font-size: 0.85rem;
}

/* RTL number/percentage tweak: keep numerals LTR inside RTL text */
.ltr-nums { unicode-bidi: isolate; direction: ltr; display: inline-block; }

/* ---------- Mobile table pattern (320-430px) ----------
   table-layout:fixed keeps a table from overflowing, but at very narrow
   widths (320-430px) a 4-6 column table becomes unreadably cramped even
   without overflowing. Below 600px, tables that opt into `.table-stack`
   render as a stacked list of label:value rows instead — used by the new
   Admin Results/Campaigns/Candidates tables (Phase D), added here so the
   CSS foundation exists ahead of that markup. */
@media (max-width: 600px) {
  table.table-stack thead { display: none; }
  table.table-stack, table.table-stack tbody, table.table-stack tr, table.table-stack td {
    display: block;
    width: 100%;
  }
  table.table-stack tr {
    border-bottom: 1px solid var(--border);
    padding: 12px 0;
  }
  table.table-stack td {
    border-bottom: none;
    padding: 4px 0;
    display: flex;
    justify-content: space-between;
    gap: 12px;
  }
  table.table-stack td[data-label]::before {
    content: attr(data-label);
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    flex-shrink: 0;
  }
}

/* ---------- Print / PDF foundation ----------
   Deliberate print styling (Section 21: "do not accept an accidental
   browser print layout as a premium report"). Report-specific page-break
   rules (avoiding split radar/cards) are added alongside the report
   markup in Phase C; this lays the shared foundation now. */
@media print {
  .no-print { display: none !important; }
  body { background: #fff; }
  .admin-sidebar, .topbar .lang-switch { display: none !important; }
  .card, .report-page-section {
    box-shadow: none !important;
    border: none !important;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  a { text-decoration: none; color: inherit; }
}
@page {
  size: A4;
  margin: 16mm 14mm;
}
