/* ============================================================================
 * COMPONENT — Dropdown
 * ----------------------------------------------------------------------------
 * Behaviour: shared/assets/js/ui.js  (delegated — no per-element wiring)
 *
 * A trigger and a panel that opens beneath it. Used by the language switcher,
 * and by the user menu and notification list as those arrive.
 *
 *   <div class="dropdown">
 *     <button data-dropdown="menu-id" aria-expanded="false" aria-haspopup="true">…</button>
 *     <div class="dropdown__menu" id="menu-id" data-dropdown-menu hidden>…</div>
 *   </div>
 *
 * The panel is `hidden` rather than display:none in CSS, so it is removed from
 * the accessibility tree and from tab order while closed — a menu whose links
 * are still tabbable when invisible is a genuinely confusing thing to land in.
 * ========================================================================== */

.dropdown {
  position: relative;
  /* The wrapper is usually a flex item (the header actions row). Without this
     it shrinks to min-content and the trigger's label wraps onto its own line. */
  flex: 0 0 auto;
}

.dropdown__menu {
  position: absolute;
  inset-block-start: calc(100% + var(--sp-2));
  /* Trailing edge: right in English, left in Urdu and Arabic, from one rule. */
  inset-inline-end: 0;
  z-index: var(--z-dropdown);

  min-inline-size: 180px;
  padding: var(--sp-1);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--sh-3);

  animation: dropdown-in var(--dur-fast) var(--ease-out);
}

.dropdown__menu[hidden] {
  display: none;
}

@keyframes dropdown-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

.dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  inline-size: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-soft);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  text-align: start;
  cursor: pointer;
}

.dropdown__item:hover {
  background: var(--surface-sunken);
  color: var(--ink);
  text-decoration: none;
}

.dropdown__item.is-active {
  background: var(--brand-soft);
  color: var(--brand-ink);
}

/* Shown, greyed, and inert — a language that is built but not switched on yet.
   Rendered as a <span> rather than a disabled link, so there is no path to it
   at all: nothing to middle-click, nothing for a crawler to follow. */
.dropdown__item.is-disabled {
  color: var(--ink-muted);
  cursor: default;
}

.dropdown__item.is-disabled:hover {
  background: transparent;
}

.dropdown__soon {
  margin-inline-start: auto;
  padding: 1px var(--sp-2);
  border-radius: var(--r-full);
  background: var(--surface-sunken);
  color: var(--ink-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-normal);
  text-transform: lowercase;
}

/* The tick sits at the trailing edge and only appears on the active row, so the
   rows do not shift when the selection changes. */
.dropdown__item .dropdown__check {
  margin-inline-start: auto;
  opacity: 0;
}

.dropdown__item.is-active .dropdown__check {
  opacity: 1;
}

.dropdown__sep {
  block-size: 1px;
  margin: var(--sp-1) 0;
  background: var(--border);
}

/* -- trigger ---------------------------------------------------------------
 * Wider than a square icon button because it shows the current value. On a
 * phone the label is dropped and only the icons remain — the flag-free globe
 * plus the chevron still read as "language", and the header stays uncrowded.
 * ----------------------------------------------------------------------- */

.dropdown__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  block-size: 38px;
  padding-inline: var(--sp-2);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--ink-soft);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}

.dropdown__trigger:hover {
  background: var(--surface-sunken);
  color: var(--ink);
}

.dropdown__trigger[aria-expanded="true"] {
  background: var(--brand-soft);
  color: var(--brand-ink);
}

/* The chevron turns to point up while the panel is open. */
.dropdown__trigger .dropdown__caret {
  transition: transform var(--dur-fast) var(--ease);
}

.dropdown__trigger[aria-expanded="true"] .dropdown__caret {
  transform: rotate(180deg);
}

@media (max-width: 479px) {
  .dropdown__trigger .dropdown__label { display: none; }
}

/* --------------------------------------------------------------------------
 * The notification panel
 * --------------------------------------------------------------------------
 * A dropdown with a head, a scrolling body and a foot — wider than a menu
 * because each row is a sentence rather than a label, and capped in height so
 * fifteen of them cannot run off the bottom of a laptop screen.
 *
 * It reuses .dropdown__menu for its position, its shadow and its open/close
 * behaviour; everything below is what a panel needs and a menu does not.
 * ----------------------------------------------------------------------- */

.notif-panel {
  inline-size: min(24rem, calc(100vw - var(--sp-6)));
  padding: 0;
  overflow: hidden;
}

.notif-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-block-end: 1px solid var(--border);
}

/* "Mark all read" is a real button, not a link: it changes state and goes
   nowhere, and a link that does neither lies to the status bar. */
.notif-panel__clear {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--brand-ink);
  cursor: pointer;
}

.notif-panel__clear:hover { text-decoration: underline; }

.notif-panel__body {
  max-block-size: min(24rem, 60vh);
  overflow-y: auto;
}

.notif-panel__empty {
  padding: var(--sp-6) var(--sp-4);
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  text-align: center;
}

.notif-panel__all {
  display: block;
  padding: var(--sp-3);
  border-block-start: 1px solid var(--border);
  background: var(--surface-sunken);
  color: var(--brand-ink);
  font-size: var(--fs-sm);
  text-align: center;
  text-decoration: none;
}

.notif-panel__all:hover { background: var(--surface); }

/* -- one row --------------------------------------------------------------- */

.notif-row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  color: inherit;
  text-decoration: none;
}

.notif-row + .notif-row { border-block-start: 1px solid var(--border); }

a.notif-row:hover { background: var(--surface-sunken); }

/* The unread mark is a dot in a tinted disc rather than a coloured row: a list
   where most rows are highlighted has highlighted nothing. */
.notif-row__mark {
  flex: none;
  inline-size: 10px;
  block-size: 10px;
  margin-block-start: 6px;
  border-radius: var(--r-full);
  background: transparent;
}

.notif-row--unread .notif-row__mark { background: var(--brand); }

.notif-row__body { min-inline-size: 0; }

.notif-row__text {
  display: block;
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  color: var(--ink-soft);
  unicode-bidi: isolate;
}

.notif-row--unread .notif-row__text {
  color: var(--ink);
  font-weight: var(--fw-medium);
}

.notif-row__time {
  display: block;
  margin-block-start: 2px;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

/* On a phone the panel is the width of the window rather than a card floating
   in one corner of it. */
@media (max-width: 40rem) {
  .notif-panel {
    position: fixed;
    inset-inline: var(--sp-3);
    inline-size: auto;
  }
}
