/* ============================================================================
   Isnaad Certificates — app-shell chrome.
   Right sidebar (260px, flush to the edge) + a detached navbar card + a centred
   content column + an off-canvas drawer below xl. Borders-not-shadows.
   Mirrors the shell the QM HelpDesk builds from the same design system.
   ============================================================================ */

.qm-shell { display: flex; min-height: 100vh; background: var(--bs-body-bg); }

/* ---- Sidebar (right in RTL — first DOM child, flush to the edge) ----
   The edge goes on inline-END. `.qm-shell` is a flex row and the sidebar is its
   FIRST child, so it always sits at main-start: physical right in RTL, physical
   left in LTR. Either way the viewport hugs its inline-start and the content
   seam is its inline-end. This was inline-start, which in Arabic painted a
   stray hairline against the screen edge and left no divider beside the
   content; only the LTR mirror further down was landing it correctly. Stating
   it as inline-end is right in both directions, so that mirror is gone. */
.qm-sidebar {
  width: var(--sidebar-w); flex: none; background: var(--bs-paper-bg);
  border-inline-end: 1px solid var(--bs-border-color);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.qm-brand {
  padding: 18px; display: flex; align-items: center; gap: 12px;
  border-bottom: 1px solid var(--bs-border-color); text-decoration: none;
}
.qm-brand-logo {
  width: 42px; height: 42px; flex: none; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(var(--bs-primary-rgb), .1); color: var(--bs-primary); font-size: 22px;
  overflow: hidden;
}
/* The mark is an uploaded file now, not a glyph. It brings its own rounded
   plate and its own colours, so the tinted square behind it would only show as
   a rim — the container goes transparent whenever it holds an image, and keeps
   the tint for the icon fallback. */
.qm-brand-logo:has(img) { background: none; }
.qm-brand-logo img { width: 100%; height: 100%; object-fit: contain; border-radius: inherit; }
.qm-brand-title { font-weight: var(--fw-extrabold); font-size: 16px; color: var(--bs-heading-color); line-height: 1.25; }
.qm-brand-sub   { font-size: 10.5px; font-weight: var(--fw-bold); color: var(--gold-text); line-height: 1.35; margin-top: 2px; }

.qm-nav { flex: 1; padding: 6px 0 16px; }
.nav-section {
  font-size: 11px; font-weight: var(--fw-extrabold); color: var(--bs-gray-500);
  padding: 18px 16px 6px; letter-spacing: .3px;
}
.nav-item {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px;
  border-radius: var(--r-xs); font-size: 14px; font-weight: var(--fw-bold);
  color: var(--bs-gray-700); cursor: pointer; position: relative;
  transition: var(--transition); margin: 1px 8px; text-decoration: none;
}
.nav-item:hover { background: var(--bs-tertiary-bg); color: var(--bs-heading-color); }
.nav-item i { font-size: 20px; width: 22px; text-align: center; flex: none; }
.nav-item.active { background: var(--bs-primary); color: #fff; }
.nav-item .nb {
  margin-inline-start: auto; font-size: 11px; font-weight: var(--fw-bold);
  background: rgba(var(--bs-primary-rgb), .12); color: var(--bs-primary);
  border-radius: var(--r-pill); padding: 1px 9px;
}
.nav-item.active .nb { background: rgba(255, 255, 255, .22); color: #fff; }

/* ---- Nav groups ------------------------------------------------------------
   A collapsible heading that owns its links, matching the reference helpdesk's
   sidebar. <details>/<summary>, so collapsing needs no JavaScript.

   Deliberately NOT `data-qm-menu`: app.js treats those as pop-up menus, so an
   outside click would collapse every group at once and opening one would force
   the rest shut. A navigation group is not a pop-up.

   `.nav-section` above stays — the admin hub uses it for its own group
   headings, so it is not sidebar-private.
   ---------------------------------------------------------------------------- */
.nav-group > summary.nav-group-head {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  margin: 2px 8px; padding: 9px 12px;
  border-radius: var(--r-xs);
  font-size: 12.5px; font-weight: var(--fw-extrabold); letter-spacing: .2px;
  color: var(--bs-heading-color);
  transition: background .2s ease-in-out;
}
.nav-group > summary.nav-group-head::-webkit-details-marker { display: none; }
.nav-group > summary.nav-group-head::marker { content: ''; }
.nav-group > summary.nav-group-head:hover { background: var(--bs-tertiary-bg); }
.nav-group-head > i:first-child { font-size: 19px; width: 20px; text-align: center; flex: none; color: var(--bs-gray-600); }
.nav-group-head > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Caret at the far end via a LOGICAL auto margin, so it lands on the correct
   edge in both directions. One glyph rotated rather than two swapped. */
.nav-group-head .nav-caret { margin-inline-start: auto; font-size: 16px; color: var(--bs-gray-500); transition: transform .2s ease-in-out; }
.nav-group[open] > .nav-group-head .nav-caret { transform: rotate(180deg); }

/* The rail the children hang off. 30px lands it under the CENTRE of the heading
   icon (8 margin + 12 padding + half of the 20px icon). Logical properties: in
   RTL the sidebar is on the right and the rail moves to the other edge with it. */
.nav-group-body {
  margin-inline-start: 30px;
  border-inline-start: 1px solid var(--bs-border-color);
}
/* Spacing only — the active fill stays with .nav-item.active, which is earlier
   in the file and would otherwise lose the tie on equal specificity. */
.nav-group-body .nav-item { margin-inline: 6px 8px; padding-block: 8px; }

/* Sidebar user row — a native <details> dropdown, no JS dependency. */
.qm-sidebar-user {
  padding: 14px 18px; border-top: 1px solid var(--bs-border-color);
  display: flex; align-items: center; gap: 10px;
}
.qm-sidebar-user .nm { font-weight: var(--fw-extrabold); font-size: 13px; color: var(--bs-heading-color); }
.qm-sidebar-user .rl { font-size: 11px; color: var(--bs-gray-600); }

.qm-sidebar-usermenu { position: relative; }
.qm-sidebar-usermenu > summary { list-style: none; cursor: pointer; }
.qm-sidebar-usermenu > summary::-webkit-details-marker { display: none; }
.qm-sidebar-usermenu > .qm-usermenu-pop {
  position: absolute; bottom: calc(100% + 8px);
  inset-inline-start: 12px; inset-inline-end: 12px; top: auto;
}

/* ---- Main column + centred content container ---- */
.qm-main { flex: 1; min-width: 0; background: var(--bs-body-bg); }
.qm-page {
  width: 100%; max-width: var(--page-max); margin-inline: auto;
  padding-inline: var(--page-gutter); min-height: 100vh;
  display: flex; flex-direction: column;
}

/* Detached navbar — a rounded card floating over the page background. */
.qm-navbar {
  height: var(--navbar-h); flex: none; background: var(--bs-paper-bg);
  border: 1px solid var(--bs-border-color); border-radius: var(--r-sm);
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 0 16px; margin-top: 16px; position: relative; z-index: 20;
}
.qm-navleft { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.qm-navtitle {
  font-size: 14px; font-weight: var(--fw-bold); color: var(--bs-heading-color);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qm-navbar-actions { display: flex; align-items: center; gap: 4px; }

.qm-iconbtn {
  width: 38px; height: 38px; border-radius: var(--r-xs); border: 1px solid transparent;
  background: transparent; color: var(--bs-gray-600); display: inline-flex;
  align-items: center; justify-content: center; cursor: pointer; font-size: 20px;
  position: relative; text-decoration: none; transition: var(--transition);
}
.qm-iconbtn:hover { background: var(--bs-tertiary-bg); color: var(--bs-heading-color); text-decoration: none; }

.qm-avatar {
  position: relative; width: 40px; height: 40px; border-radius: 50%;
  background: rgba(var(--bs-primary-rgb), .12); color: var(--bs-primary);
  display: flex; align-items: center; justify-content: center;
  font-weight: var(--fw-extrabold); margin-inline-start: 6px; flex: none;
}
.qm-avatar.lg { border: 2px solid var(--bs-primary); }

/* Theme-toggle spin — ported from HaramApp's navbar switcher. */
@keyframes qm-theme-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.qm-theme-spinning { animation: qm-theme-spin .45s cubic-bezier(.4, 0, .2, 1); }

/* User menu — native <details>, closed on outside-click/Esc by app.js. */
.qm-usermenu { position: relative; }
.qm-usermenu > summary { list-style: none; cursor: pointer; }
.qm-usermenu > summary::-webkit-details-marker { display: none; }
.qm-usermenu-pop {
  position: absolute; top: calc(100% + 16px); inset-inline-end: 0; min-width: 210px;
  background: var(--bs-paper-bg); border: 1px solid var(--bs-border-color);
  border-radius: var(--r-sm); padding: 6px; z-index: var(--z-pop);
  display: flex; flex-direction: column; gap: 2px;
}
.qm-usermenu-pop a,
.qm-usermenu-pop button {
  padding: 9px 12px; border-radius: var(--r-xs); font-size: 13.5px;
  font-weight: var(--fw-bold); color: var(--bs-gray-700); text-decoration: none;
  display: flex; align-items: center; gap: 9px; background: none; border: 0;
  width: 100%; font-family: inherit; cursor: pointer; text-align: start;
}
.qm-usermenu-pop a:hover,
.qm-usermenu-pop button:hover { background: var(--bs-tertiary-bg); color: var(--bs-heading-color); }
.qm-usermenu-pop .danger { color: var(--danger-text); }
.qm-usermenu-pop .danger:hover { background: rgba(var(--bs-danger-rgb), .10); color: var(--danger-text); }
.qm-usermenu-head {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px 10px;
  margin-bottom: 4px; border-bottom: 1px solid var(--bs-border-color);
}
.qm-usermenu-head .nm { font-weight: var(--fw-extrabold); font-size: 13.5px; color: var(--bs-heading-color); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qm-usermenu-head .rl { font-size: 12px; color: var(--bs-gray-500); }

.qm-content { flex: 1; padding: 22px 0; }

/* Page title + breadcrumb row */
.qm-pagehead { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
.qm-pagetitle { font-size: 22px; font-weight: var(--fw-extrabold); color: var(--bs-heading-color); margin: 0; }
.qm-pagehead-actions { display: inline-flex; align-items: center; gap: 8px; margin-inline-start: auto; flex-wrap: wrap; }
.qm-crumb {
  display: flex; align-items: center; gap: 7px; font-size: 12.5px;
  color: var(--bs-gray-600); margin-inline-start: auto;
}
.qm-crumb i { color: var(--bs-primary); }
.qm-crumb .sep { color: var(--bs-gray-400); }
.qm-crumb .cur { font-weight: var(--fw-bold); color: var(--bs-heading-color); }
.qm-crumb a { display: inline-flex; align-items: center; gap: 5px; color: inherit; text-decoration: none; }
.qm-crumb a:hover, .qm-crumb a:focus-visible { color: var(--bs-primary); text-decoration: none; }
/* When a breadcrumb and actions share the row, only the first takes the auto margin. */
.qm-crumb + .qm-pagehead-actions { margin-inline-start: 0; }

/* The page trail is a row of its own, above the title (certificates/base.html).
   The auto margin above was for the shared row it no longer lives in, and left
   in place it would collapse the trail to fit-content at the far inline end —
   so it is cleared here, and the same 10px the admin uses separates it from the
   heading it introduces. */
.qm-page-crumb {
  margin-inline-start: 0;
  margin-bottom: var(--sp-2_5, 10px);
}

/* Back button — mirrors under LTR only (the arrow is authored RTL-first). */
.qm-back-btn {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  color: var(--bs-heading-color); font-size: 20px; text-decoration: none; transition: color .15s;
}
.qm-back-btn:hover, .qm-back-btn:focus-visible { color: var(--bs-primary); text-decoration: none; }
.qm-nav-back-ic { display: inline-flex; }
html[dir="ltr"] .qm-nav-back-ic { transform: scaleX(-1); }

/* Footer — copyright at the inline start, build version at the inline end. */
.qm-footer {
  padding: 16px 4px 22px; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; font-size: 12.5px; color: var(--bs-gray-600); flex-wrap: wrap;
}
.qm-footer .ver { font-weight: var(--fw-bold); color: var(--bs-gray-500); }
.qm-footer a { color: inherit; text-decoration: none; }
.qm-footer a:hover, .qm-footer a:focus-visible { color: var(--bs-primary); text-decoration: none; }

/* ============================================================================
   Auth screens (login / logged out) — centred card, no shell.
   ============================================================================ */
.qm-auth-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 30px; background: var(--bs-body-bg); position: relative; overflow: hidden;
}
.qm-auth-inner { position: relative; z-index: 1; width: 100%; max-width: 460px; padding-bottom: 24px; }

/* ---- Zakhrafa ornament, cresting the top of the login card -----------------
   The real ornament from the HaramApp icon set, carried as a MASK rather than
   an <img>: the file hard-codes `fill:#315b4d`, and a mask throws the colour
   away and keeps only the shape, so the tint comes from a token here and
   follows the theme instead of staying a fixed green in dark mode.

   Anchored to the card's own column, not the viewport, so it sits BEHIND the
   card: three quarters of it are covered, and the remaining quarter stands
   above the card's top edge. That is the whole geometry — `top` is a negative
   quarter of the ornament's own height, which is why the size is a variable
   rather than a literal repeated in two places.

   Staying narrower than the 460px column is what keeps the sides hidden; an
   ornament wider than the card would spill past its edges and the visible part
   would no longer be only the crown. */
.qm-auth-inner::before {
  --zakhrafa: min(168px, 44vw);
  /* How much of the ornament stands above the card, as a fraction of its own
     height. The lift is stated as a fraction, which means the crest scales WITH
     the ornament — so a size change alone keeps the same proportion above the
     card, which is what "smaller, same placing" asks for.

     History, since the fraction looks arbitrary: 280px at .30 crested 84px;
     shrinking to 224px while raising the crest 25% to 105px gave 105/224 = .47.
     168px keeps that .47, so the crest follows down to ~79px and the ornament
     is a uniform 25% smaller. */
  --zakhrafa-rise: .47;
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  width: var(--zakhrafa); height: var(--zakhrafa);
  top: calc(var(--zakhrafa) * var(--zakhrafa-rise) * -1);
  /* PHYSICAL left/translateX: this is symmetric centring, which reads the same
     in both directions. The logical pair would not — `inset-inline-start: 50%`
     flips to `right` under RTL while `translateX(-50%)` still moves physically
     left, putting the ornament off-centre in Arabic. */
  left: 50%; transform: translateX(-50%);
  background-color: var(--bs-primary); opacity: .13;
  -webkit-mask: url("../img/zakhrafa.svg") center / contain no-repeat;
          mask: url("../img/zakhrafa.svg") center / contain no-repeat;
}
/* The card paints over it: both are positioned children of `.qm-auth-inner` at
   the same z-index, so tree order decides, and the card comes second. */

/* The ornament is decoration; anyone who has asked for more contrast still
   gets a clean card. */
@media (prefers-contrast: more) {
  .qm-auth-inner::before { display: none; }
}
.qm-auth-card {
  position: relative; width: 100%; background: var(--bs-paper-bg);
  border: 1px solid var(--bs-border-color); border-radius: var(--r-sm); padding: 2.5rem;
}
/* Credit line under the card. `--bs-gray-600` is the same quiet step the shell
   footer uses, and it sits on the page ground rather than on paper — it belongs
   to the page, not to the card, which is why it lives outside it. `relative`
   with a z-index because `.qm-auth-inner::before` paints the zakhrafa watermark
   over this area otherwise. */
.qm-auth-credit {
  position: relative; z-index: 1;
  margin: 16px 0 0; text-align: center;
  font-size: 12.5px; color: var(--bs-gray-600);
}

.qm-auth-theme {
  position: absolute; top: 12px; inset-inline-end: 12px; z-index: 5;
  width: 36px; height: 36px; border-radius: var(--r-xs); border: 1px solid var(--bs-border-color);
  background: var(--bs-body-bg); color: var(--bs-body-color); font-size: 18px;
  display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition);
}
.qm-auth-theme:hover { border-color: var(--bs-primary); background: rgba(var(--bs-primary-rgb), .08); color: var(--bs-primary); }
.qm-auth-brand { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 8px; padding-top: 14px; }
.qm-auth-logo {
  width: 72px; height: 72px; border-radius: 16px; background: rgba(var(--bs-primary-rgb), .08);
  display: flex; align-items: center; justify-content: center; color: var(--bs-primary);
  overflow: hidden;
}
.qm-auth-logo:has(img) { background: none; }
.qm-auth-logo img { width: 100%; height: 100%; object-fit: contain; border-radius: inherit; }
.qm-auth-title {
  font-size: 20px; font-weight: var(--fw-bold); color: var(--bs-primary);
  text-align: center; line-height: 1.55; margin-top: 18px;
}
.qm-auth-sub { font-size: 12.5px; color: var(--bs-gray-600); text-align: center; line-height: 1.4; }
.qm-auth-form { margin-top: 30px; display: flex; flex-direction: column; gap: 22px; }
.qm-auth-input { position: relative; }
.qm-auth-input > i {
  position: absolute; inset-inline-end: 14px; top: 50%; transform: translateY(-50%);
  color: var(--bs-gray-500); font-size: 18px; pointer-events: none;
}
.qm-auth-input .inp { height: 48px; }
/* PHYSICAL icon-side padding — resolved from the page dir, not the input's own. */
html[dir="rtl"] .qm-auth-input .inp { padding-left: 42px; padding-right: 14px; }
html[dir="ltr"] .qm-auth-input .inp { padding-right: 42px; padding-left: 14px; }
.qm-auth-form .inp:focus { border-color: var(--bs-primary); border-width: 2px; box-shadow: none; }
/* The reveal button sits at the field's inline-END corner — the same corner the
   other fields put their icon in, which is why the password field has no icon
   of its own. So the text clears the button on that side and starts at the
   normal 14px on the other.

   Stated PHYSICALLY and per direction, like the icon-side padding just above.
   The logical `padding-inline-start` this replaced lost to
   `html[dir="rtl"] .qm-auth-input .inp` — (0,3,1) against its (0,3,0), setting
   the very same physical side — so the dots kept their 14px and ran straight
   underneath the button. Both sides are named here so neither is inherited
   from the generic icon rule. */
html[dir="rtl"] .qm-auth-input.has-toggle .inp { padding-left: 46px; padding-right: 14px; }
html[dir="ltr"] .qm-auth-input.has-toggle .inp { padding-right: 46px; padding-left: 14px; }
.qm-auth-toggle {
  position: absolute; inset-inline-end: 4px; top: 1px; bottom: 1px; width: 40px;
  display: flex; align-items: center; justify-content: center; color: var(--bs-gray-500);
  cursor: pointer; background: transparent; border: 0; z-index: 2; font-size: 18px;
  padding: 0; border-radius: var(--r-xs, 8px);
}
.qm-auth-toggle:hover { color: var(--bs-primary); }
.qm-auth-submit { height: 48px; width: 100%; margin-top: 6px; }
.qm-auth-alert {
  border: 1px solid var(--bs-border-color); border-inline-start: 3px solid var(--bs-danger);
  background: rgba(var(--bs-danger-rgb), .06); color: var(--danger-text);
  border-radius: var(--r-xs); padding: 10px 14px; font-size: 13px; margin-bottom: 4px;
}
.qm-auth-alert.warn { border-inline-start-color: var(--bs-warning); background: rgba(var(--bs-warning-rgb), .10); color: var(--warning-text); }
.qm-auth-alert.ok   { border-inline-start-color: var(--bs-success); background: rgba(var(--bs-success-rgb), .08); color: var(--success-text); }
.qm-auth-back {
  display: flex; align-items: center; justify-content: center; gap: 7px; margin-top: 20px;
  font-size: 13.5px; font-weight: var(--fw-bold); color: var(--bs-gray-600);
  text-decoration: none; transition: color .2s ease;
}
.qm-auth-back:hover { color: var(--bs-primary); }

/* ============================================================================
   Off-canvas drawer < xl (physical props so it cannot drift)
   ============================================================================ */
.qm-burger { display: none; }
.qm-backdrop { display: none; }
.qm-drawer-close { display: none; }

@media (max-width: 1199.98px) {
  .qm-burger { display: inline-flex; }

  .qm-drawer-close {
    display: inline-flex; align-items: center; justify-content: center;
    position: absolute; top: 12px; inset-inline-end: 12px; z-index: 2;
    width: 40px; height: 40px; border-radius: var(--r-xs);
    border: 1px solid var(--bs-border-color); background: var(--bs-paper-bg);
    color: var(--bs-gray-600); cursor: pointer; font-size: 20px;
  }
  .qm-drawer-close:hover { color: var(--bs-heading-color); background: var(--bs-tertiary-bg); }

  /* A closed drawer hidden with `transform` ALONE is still in the a11y tree and
     the tab order — a keyboard user would walk the whole menu off-screen before
     reaching the page. `visibility` is what actually removes it, transitioned
     together with the transform so it does not vanish mid-slide. */
  .qm-sidebar {
    position: fixed; top: 0; bottom: 0; right: 0; width: var(--sidebar-w-drawer);
    max-width: 86vw; height: 100dvh; z-index: var(--z-sidebar);
    transform: translateX(100%); visibility: hidden;
    transition: transform var(--transition-menu), visibility var(--transition-menu);
  }
  html[dir="ltr"] .qm-sidebar { right: auto; left: 0; transform: translateX(-100%); }
  .qm-sidebar.is-open { transform: translateX(0); visibility: visible; }

  .qm-backdrop {
    display: block; position: fixed; inset: 0; background: rgba(0, 0, 0, .45);
    z-index: var(--z-backdrop); opacity: 0; visibility: hidden;
    transition: opacity .25s ease, visibility .25s ease;
  }
  .qm-backdrop.is-open { opacity: 1; visibility: visible; }

  /* Drawer nav rows meet the 44px touch target. */
  .nav-item { padding-block: 12px; }
}

/* ============================================================================
   Keyboard focus ring. The custom controls reset the UA outline, so
   :focus-visible must be defined explicitly (WCAG 2.4.7). An outline — not a
   shadow — keeps the borders-not-shadows rule and mirrors in RTL for free.
   ============================================================================ */
.qm-iconbtn:focus-visible, .nav-item:focus-visible, .qm-back-btn:focus-visible,
.pg:focus-visible, .tab:focus-visible, .btn:focus-visible, .btn-o:focus-visible,
.chip:focus-visible, .lnk:focus-visible, .qm-act:focus-visible,
.qm-usermenu > summary:focus-visible, .qm-sidebar-usermenu > summary:focus-visible,
.nav-group > summary:focus-visible,
.qm-crumb a:focus-visible, .qm-brand:focus-visible, .qm-footer a:focus-visible,
.qm-disc > summary:focus-visible {
  outline: 2px solid var(--bs-primary); outline-offset: 2px; border-radius: var(--r-xs);
}

/* Skip link — first focusable element on every page, off-screen until focused. */
.qm-skip {
  position: absolute; inset-inline-start: 8px; top: -60px; z-index: 2000;
  padding: 10px 16px; border-radius: var(--r-xs);
  background: var(--bs-primary); color: #fff; font-weight: var(--fw-bold);
  font-size: 14px; text-decoration: none; transition: top .15s ease;
}
.qm-skip:focus { top: 8px; color: #fff; outline: 2px solid var(--bs-gold); outline-offset: 2px; }

/* Honour the OS "reduce motion" preference (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ============================================================================
   Responsive tier. Placed LAST so it wins the cascade over the base rules
   (media queries add no specificity — source order decides).
   ============================================================================ */

/* Fluid page title — never oversized or cramped on a phone. */
.qm-pagetitle { font-size: clamp(1.25rem, 4.5vw, 22px); }

@media (max-width: 767.98px) {
  .qm-page { padding-inline: 14px; }
  .qm-navbar { margin-top: 12px; }
  .qm-content { padding: 16px 0; }
  .qm-footer { justify-content: center; text-align: center; }
}

@media (max-width: 480px) {
  .qm-auth-wrap { padding: 16px; }
  .qm-auth-card { padding: 1.5rem; }
}

/* Dense standalone controls meet the 44px touch target on touch devices. */
@media (max-width: 767.98px), (pointer: coarse) {
  .qm-act, .pg, .qm-iconbtn, .qm-auth-theme { min-width: 44px; min-height: 44px; }
}

/* Avatar variants used inside the two user menus. */
.qm-avatar-sm    { width: 38px; height: 38px; margin-inline-start: 0; font-size: 13px; }
.qm-avatar-flush { margin-inline-start: 0; }
.qm-usermenu-caret { margin-inline-start: auto; color: var(--bs-gray-500); }

/* ============================================================================
   Language switcher (AR / EN) — a native <details> dropdown, no JS dependency
   beyond the shared outside-click handler. Ported from the reference shell.
   ============================================================================ */
.qm-langmenu { position: relative; }
.qm-langmenu > summary { list-style: none; cursor: pointer; }
.qm-langmenu > summary::-webkit-details-marker { display: none; }
.qm-langmenu-pop {
  /* +18px: the 38px trigger sits ~9px above the 56px navbar's bottom edge, so a
     smaller offset would land the popup on the navbar border. */
  position: absolute; top: calc(100% + 18px); inset-inline-end: 0; min-width: 170px;
  background: var(--bs-paper-bg); border: 1px solid var(--bs-border-color);
  border-radius: var(--r-sm); padding: 6px; z-index: var(--z-pop);
  display: flex; flex-direction: column; gap: 2px;
}
.qm-langmenu-pop button {
  padding: 9px 12px; border-radius: var(--r-xs); font-size: 13.5px;
  font-weight: var(--fw-bold); color: var(--bs-gray-700); text-decoration: none;
  display: flex; align-items: center; gap: 9px; background: none; border: 0;
  width: 100%; font-family: inherit; cursor: pointer; text-align: start;
}
.qm-langmenu-pop button:hover { background: var(--bs-tertiary-bg); color: var(--bs-heading-color); }
.qm-langmenu-pop button.active { background: rgba(var(--bs-primary-rgb), .12); color: var(--bs-primary); }
.qm-langmenu-pop .flag { font-size: 12px; font-weight: var(--fw-extrabold); letter-spacing: .04em; opacity: .75; }
.qm-langmenu > summary:focus-visible { outline: 2px solid var(--bs-primary); outline-offset: 2px; border-radius: var(--r-xs); }

/* On the auth card the switcher lives in the opposite top corner to the theme
   toggle, so its popup must open toward the inline-start edge. */
.qm-auth-lang { position: absolute; top: 12px; inset-inline-start: 12px; z-index: 6; }
.qm-auth-lang .qm-iconbtn {
  width: 36px; height: 36px; border-radius: var(--r-xs); border: 1px solid var(--bs-border-color);
  background: var(--bs-body-bg); color: var(--bs-body-color); font-size: 13px; font-weight: var(--fw-extrabold);
}
.qm-auth-lang .qm-iconbtn:hover { border-color: var(--bs-primary); background: rgba(var(--bs-primary-rgb), .08); color: var(--bs-primary); }
.qm-auth-lang .qm-langmenu-pop { inset-inline-end: auto; inset-inline-start: 0; top: calc(100% + 8px); }

/* ============================================================================
   LTR (English) corrections. The layout is authored with logical properties, so
   it mirrors on its own; these are the few places that carried a deliberate
   RTL-first decision and need the mirror image stated explicitly.
   ============================================================================ */
.qm-langmenu-pop form { margin: 0; display: block; }
.qm-lang-check { margin-inline-start: auto; color: var(--bs-primary); }
