/*
 * CommonLynk — Canonical Design Tokens
 * Always reference via var(--cl-*). Never hardcode hex values in new code.
 *
 * Token roles:
 *   --cl-ink      primary text, headings, navbar            (was old navy hex)
 *   --cl-paper    page and card background                  (was old cream hex)
 *   --cl-accent   CTAs, active states, highlights           (was old gold hex)
 *   --cl-teal     secondary actions, success states         (tokenised teal)
 *   --cl-danger   destructive actions, delete buttons, error states
 *                 (replaces the retired burgundy where it was used for danger)
 *   --cl-muted    muted body text, hints, secondary labels
 *   --cl-sidebar  sidebar background — defaults to --cl-ink; tenant base.html
 *                 may override per OrgProfile.nav_color
 *   --cl-border   subtle 1px border / divider — derived from --cl-ink
 *
 * Per-template :root blocks in templates/base.html and templates/landing/base.html
 * still declare local aliases (--navy, --teal, --gold, --burgundy etc.). The
 * legacy hex literals they used to hold have been swept to var(--cl-*) refs.
 */

/* Global scrollbar — gold thumb on neutral track. Overridden in
   templates/base.html for the .sidebar (translucent white on the navy
   sidebar background reads cleaner than gold). */
::-webkit-scrollbar{width:4px;height:4px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:#C4A875;border-radius:999px}
::-webkit-scrollbar-thumb:hover{background:#0B1F3A}
*{scrollbar-width:thin;scrollbar-color:#C4A875 transparent}

:root{
  /* Core palette */
  --cl-ink:    #0B1F3A;  /* Dark navy — primary text, headings, navbar */
  --cl-paper:  #F5F2EC;  /* Off-white — page & card backgrounds */
  --cl-accent: #C4A875;  /* Warm gold — CTAs, active states, highlights */
  --cl-teal:   #3FA68D;  /* Teal — secondary actions, success states */
  --cl-teal-dark: #0F6E56;  /* Dark teal — done/complete text on teal-tinted fills */
  --cl-danger: #C0392B;  /* Destructive actions, delete buttons, error states */
  --cl-muted:  #6B7280;  /* Muted body text, hints, secondary labels */

  /* Extended status palette */
  --cl-info:    #1565C0;             /* Informational accents, info banners, links */
  --cl-warning: #B45309;             /* Warning/attention text & badges (amber) */
  --cl-purple:  #7C3AED;             /* Category/tag accents */
  --cl-white:   #FFFFFF;             /* True white card surfaces & inverse text */
  --cl-page:    #FDFCF9;             /* Marketing ground — a lighter paper. The
                                        PRODUCT (tenant + Platform Admin) stays
                                        on --cl-paper; this is the landing site's
                                        airier surface, deliberately a separate
                                        token so restyling marketing can never
                                        move the workspace ground. */
  --cl-warm:    #F5F1E9;             /* Marketing rhythm band — a warm fill one
                                        step darker than --cl-page, used to
                                        separate marketing sections without
                                        introducing a second ground colour.
                                        The PRODUCT does not use it. */
  --cl-accent-deep: #A6884F;         /* Deep gold — accent hover/pressed and gold
                                        text that must clear contrast on a light
                                        ground (--cl-accent alone does not). */
  --cl-shadow:  rgba(11, 31, 58, 0.15); /* Ink-tinted drop shadow */

  /* Comma-separated RGB triplets of the core colors, for translucency.
     rgba() cannot take a hex custom property as its color argument, so
     rgba(var(--cl-accent), .1) silently fails — use rgba(var(--cl-accent-rgb), .1).
     Keep each triplet in sync with the hex above it. */
  --cl-ink-rgb:    11, 31, 58;
  --cl-paper-rgb:  245, 242, 236;
  --cl-accent-rgb: 196, 168, 117;
  --cl-danger-rgb: 192, 57, 43;
  --cl-white-rgb:  255, 255, 255;

  /* Light tint backgrounds — paired with their status colors */
  --cl-teal-bg:    #EAF6F2;   /* success/teal state backgrounds */
  --cl-danger-bg:  #FDECEA;   /* error/danger state backgrounds */
  --cl-info-bg:    #EEF4FB;   /* info state backgrounds */
  --cl-warning-bg: #FEF3E2;   /* warning state backgrounds */

  /* ── Attention banners (the amber "act on your subscription" family) ──
     A SEPARATE ramp from --cl-warning / --cl-warning-bg above, which is the
     inline warning TEXT + badge pair. These three are the filled banner
     treatment: a tinted card with its own hairline and high-contrast body
     copy. Keeping them apart is deliberate — folding the banner into
     --cl-warning would restyle every warning badge on the platform.

     Two severities, because the tenant app shell renders two different
     messages: --cl-warn-* is the workspace-is-read-only grace banner (and the
     .cl-badge-gold pair, which was a verbatim second copy of it), while
     --cl-warn-soft-* is the dismissible "renews in N days" heads-up. */
  --cl-warn-bg:          #FEF3C7;   /* grace banner + gold badge fill */
  --cl-warn-text:        #92400E;   /* grace banner + gold badge copy */
  --cl-warn-border:      #FDE68A;   /* grace banner hairline */
  --cl-warn-soft-bg:     #FEF9C3;   /* expiry-soon banner fill */
  --cl-warn-soft-text:   #854D0E;   /* expiry-soon banner copy */
  --cl-warn-soft-border: #FEF08A;   /* expiry-soon banner hairline */

  /* Derived semantic tokens */
  --cl-text:        var(--cl-ink);
  --cl-bg:          var(--cl-paper);
  --cl-sidebar:     var(--cl-ink);   /* Sidebar background — overridden per-tenant in base.html */
  --cl-surface:     #0B1F3A;         /* Dark navy surface (buttons, badges, popovers) — pinned, never follows tenant text color */
  /* D1 (2026-08-27) — the PRIMARY button is NAVY, not gold.
     Gold is now the ACCENT role plus the on-navy inversion only. These two
     tokens had ZERO consumers when the decision landed (`.cl-btn-primary` in
     commonlynk.components.css already hardcoded var(--cl-ink)), so flipping
     them changed no pixel — it makes the token layer AGREE with the component
     layer, which is what stops the next author reading `--cl-btn-primary` and
     building a gold button that no longer matches anything. */
  --cl-btn-primary: var(--cl-ink);
  --cl-btn-text:    var(--cl-white);
  --cl-success:     var(--cl-teal);
  --cl-border:      #E8E8E5;   /* Subtle 1px border / divider */

  /* Focus / selection halo — the ring drawn behind a focused control, as
     `box-shadow: 0 0 0 3px var(--cl-focus-ring)`. A COLOUR rather than a whole
     shadow, because that is the shape every caller already uses.
     It was REFERENCED here and defined nowhere: an undefined custom property
     makes the whole declaration invalid, so any template that did not alias it
     locally rendered no focus ring at all. Keyboard operators have to be able to
     see which field they are in, and some of those fields hold credentials. */
  --cl-focus-ring:  rgba(var(--cl-accent-rgb), 0.35);

  /* Typography */
  --cl-font-sans:"Inter Tight","Helvetica Neue",Helvetica,Arial,sans-serif;
  --cl-font-mono:"JetBrains Mono",ui-monospace,Menlo,Monaco,Consolas,monospace;
  --cl-fs-display:56px;
  --cl-fs-h1:36px;
  --cl-fs-h2:22px;
  --cl-fs-h3:15px;
  --cl-fs-body:14px;
  --cl-fs-small:12px;
  --cl-fs-label:10px;
  --cl-fw-light:300;
  --cl-fw-regular:400;
  --cl-fw-medium:500;
  --cl-fw-semibold:600;
  --cl-fw-bold:700;
  --cl-track-display:-0.03em;
  --cl-track-heading:-0.02em;
  --cl-track-label:0.18em;

  /* === Component Tokens === */

  /* Buttons */
  --cl-btn-padding-y: 0.5rem;
  --cl-btn-padding-x: 1.1rem;
  --cl-btn-padding-y-sm: 0.3rem;
  --cl-btn-padding-x-sm: 0.75rem;
  --cl-btn-padding-y-lg: 0.65rem;
  --cl-btn-padding-x-lg: 1.5rem;
  --cl-btn-font-size: 0.875rem;
  --cl-btn-font-size-sm: 0.8rem;
  --cl-btn-font-weight: 600;
  --cl-btn-radius: 6px;
  --cl-btn-transition: background 150ms ease, opacity 150ms ease, box-shadow 150ms ease;

  /* Surfaces */
  --cl-radius-sm: 4px;
  --cl-radius-md: 8px;
  --cl-radius-lg: 12px;
  --cl-radius-card: 10px;
  --cl-radius-modal: 14px;
  --cl-radius-badge: 999px;

  /* Elevation */
  --cl-shadow-sm: 0 1px 3px var(--cl-shadow);
  --cl-shadow-md: 0 4px 12px var(--cl-shadow);
  --cl-shadow-lg: 0 8px 24px var(--cl-shadow);
  /* Named ROLE, not a fourth size: the lift a Hub card takes on hover
     (design system 9.3). Aliased so the card never names a raw shadow. */
  --cl-shadow-lift: var(--cl-shadow-md);

  /* Transitions */
  --cl-transition-fast: 120ms ease;
  --cl-transition: 200ms ease;
  --cl-transition-slow: 350ms ease;
}

/* ── Phone input widget (templates/components/phone_input.html) ───────────
   The tenant portal does not load Bootstrap, so the widget can't rely on
   .input-group / .form-select. These rules render the country-code select
   and the number field as one cohesive input group: [🇪🇬 +20][ number … ]. */
/* NB: `overflow: hidden` here used to clip the country-code dropdown. The
   dropdown is position:absolute inside .phone-picker (position:relative), and
   that containing block is a DESCENDANT of this box, so the clip applied
   (CSS 2.1 §11.1.1). Worse, this box then became a scroll container, so the
   picker's search.focus() scrolled the clipped dropdown into view — dragging a
   search box into the pill where the number input had been. The rounded corners
   it was there for are now done with logical radii on the end children. */
.phone-input-group {
  display: flex;
  border: 1px solid var(--cl-border);
  border-radius: 6px;
  overflow: visible;
  background: #fff;
}
/* Logical, so the pill stays correct when the row flips under [dir=rtl].
   `.phone-picker` covers the current core/_phone_field.html markup (which does
   not use the --embedded modifier); only the left-corner radii are ported —
   not min-width — so the +20 button stays content-width. */
.phone-input-group > .phone-picker--embedded,
.phone-input-group > .phone-picker {
  border-start-start-radius: 6px;
  border-end-start-radius: 6px;
}
.phone-input-group > .phone-status {
  border-start-end-radius: 6px;
  border-end-end-radius: 6px;
}
.phone-input-group:focus-within {
  border-color: var(--cl-accent);
  box-shadow: 0 0 0 3px rgba(196, 168, 117, 0.15);
}
.phone-code-select {
  border: none;
  border-inline-end: 1px solid var(--cl-border);
  background: var(--cl-paper);
  padding: 0.5rem 0.625rem;
  font-size: 0.875rem;
  min-width: 84px;
  max-width: 120px;
  cursor: pointer;
  outline: none;
  appearance: auto;          /* keep the native dropdown arrow */
  color: var(--cl-ink);
}
.phone-number-input {
  border: none;
  flex: 1;
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  outline: none;
  background: transparent;
  color: var(--cl-ink);
  min-width: 0;              /* let the field shrink inside the flex group */
}
.phone-number-input::placeholder { color: var(--cl-muted); }
/* Live E.164 validation badge appended by static/js/localization.js. It
   toggles the d-none / text-* classes the script already emits. */
.phone-status {
  display: flex;
  align-items: center;
  padding: 0 0.625rem;
  font-size: 0.85rem;
  background: var(--cl-paper);
  border-inline-start: 1px solid var(--cl-border);
}
.phone-status.d-none      { display: none; }
.phone-status.text-success { color: var(--cl-teal); }
.phone-status.text-danger  { color: var(--cl-danger); }
.phone-status.text-muted   { color: var(--cl-muted); }

/* ── Flag-button country-code picker (P04, 2026-05-26) ─────────────────────
   Used standalone (templates/core/_phone_picker.html) and as the country-code
   half of templates/components/phone_input.html. Drop-in replacement for the
   prior native <select>; same data attributes so localization.js wires up. */
.phone-picker { position: relative; display: inline-block; min-width: 0; }
.phone-picker--embedded {
  /* When embedded inside .phone-input-group flex row */
  border-inline-end: 1px solid var(--cl-border);
  background: var(--cl-paper);
}
.phone-picker-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0.5rem 0.625rem;
  background: transparent;
  border: 1px solid var(--cl-border);
  border-radius: 6px;
  font-size: 0.875rem; color: var(--cl-ink);
  cursor: pointer; white-space: nowrap;
}
.phone-picker--embedded .phone-picker-btn {
  border: none; border-radius: 0;
  min-width: 84px;
}
.phone-picker-btn:hover { background: var(--cl-paper); }
.phone-picker--embedded .phone-picker-btn:hover { background: color-mix(in srgb, var(--cl-paper) 60%, white); }
.phone-picker-flag { font-size: 1.05rem; line-height: 1; }
.phone-picker-code { font-variant-numeric: tabular-nums; }
.phone-picker-caret { font-size: 0.7rem; opacity: 0.55; margin-inline-start: 2px; }
.phone-picker-dropdown {
  position: absolute; top: calc(100% + 4px); inset-inline-start: 0; z-index: 200;
  background: #fff;
  border: 1px solid var(--cl-border); border-radius: 8px;
  min-width: 280px; max-width: 380px;
  padding: 8px;
  box-shadow: 0 8px 28px rgba(11,31,58,0.14);
}
.phone-picker-search {
  width: 100%; box-sizing: border-box;
  padding: 7px 10px; font-size: 13px;
  border: 1px solid var(--cl-border); border-radius: 6px;
  color: var(--cl-ink); background: #fff; margin-bottom: 6px;
}
.phone-picker-search:focus { outline: none; border-color: var(--cl-accent); }
.phone-picker-list { max-height: 280px; overflow-y: auto; }
.phone-picker-option {
  display: grid; grid-template-columns: 22px 1fr auto;
  align-items: center; gap: 8px;
  width: 100%;
  padding: 7px 10px;
  background: transparent; border: none; border-radius: 5px;
  text-align: start; font-size: 13px; color: var(--cl-ink);
  cursor: pointer;
}
.phone-picker-option:hover,
.phone-picker-option.is-active { background: var(--cl-paper); }
.phone-picker-option.is-selected { background: color-mix(in srgb, var(--cl-accent) 14%, transparent); }
.phone-picker-option-flag { font-size: 1.05rem; line-height: 1; }
.phone-picker-option-name { color: var(--cl-ink); }
.phone-picker-option-dial { color: var(--cl-muted); font-variant-numeric: tabular-nums; }
.phone-picker-option.is-hidden { display: none; }

/* ── Indeterminate "preparing" progress overlay (2026-06-10) ──────────────
   A fixed bottom-centre card with a spinner + animated bar, for multi-second
   operations that have NO measurable byte/percentage progress — e.g. a
   server-side file build (the Translation Manager all-languages .xlsx export
   is the first user). The bar animates on its own; show/hide by toggling the
   .is-visible class. Self-contained (own spinner + keyframes) so it can be
   dropped into any page that loads this file.
   Markup:
     <div class="cl-prep-overlay" role="status" aria-live="polite">
       <div class="cl-prep-overlay__row">
         <span class="cl-prep-overlay__spinner"></span>
         <span class="js-label">Preparing…</span>
       </div>
       <div class="cl-prep-bar"><span></span></div>
     </div>
   JS: el.classList.add('is-visible') / .remove('is-visible'). */
@keyframes cl-prep-indeterminate { 0% { left: -45%; } 100% { left: 100%; } }
@keyframes cl-prep-spin { to { transform: rotate(360deg); } }
.cl-prep-overlay {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  z-index: 10000; min-width: 300px; max-width: 90vw;
  background: var(--cl-ink); color: var(--cl-white);
  padding: 0.85rem 1.25rem; border-radius: var(--cl-radius-card);
  box-shadow: var(--cl-shadow-lg); display: none;
}
.cl-prep-overlay.is-visible { display: block; }
.cl-prep-overlay__row {
  display: flex; align-items: center; gap: 0.6rem;
  font-size: 0.875rem; margin-bottom: 0.6rem;
}
.cl-prep-overlay__spinner {
  display: inline-block; width: 12px; height: 12px; flex: none;
  border: 2px solid rgba(255, 255, 255, 0.25); border-top-color: var(--cl-accent);
  border-radius: 50%; animation: cl-prep-spin 0.8s linear infinite;
}
.cl-prep-bar {
  position: relative; height: 4px; border-radius: 2px; overflow: hidden;
  background: rgba(255, 255, 255, 0.18);
}
.cl-prep-bar > span {
  position: absolute; top: 0; height: 100%; width: 45%; border-radius: 2px;
  background: var(--cl-accent); animation: cl-prep-indeterminate 1.1s ease-in-out infinite;
}

/* ── Row actions dropdown (registration lists) ─────────────────── */
/* The cell the row menu sits in. It was a class SIX templates asked for and no
   stylesheet defined, so each one hand-added `style="text-align:center"` — or
   forgot to, which is why the beneficiaries lists sat left of the programme and
   activity lists. Defining it is what makes the menu column line up across the
   platform without every list restating how. */
.cl-row-actions-cell{width:1%;white-space:nowrap;text-align:center;}
.cl-row-actions{position:relative;display:inline-block;}
.cl-actions-btn{background:none;border:none;cursor:pointer;font-size:1.25rem;color:var(--cl-ink);padding:4px 8px;border-radius:4px;line-height:1;}
.cl-actions-btn:hover{background:var(--cl-paper);}
/* Positioned FIXED, not absolute, and placed by cl_kebab.js against the
   trigger's viewport rect. Every kebab in the platform renders inside a
   `.table-wrap` (overflow-x:auto), and an absolutely-positioned menu is
   CLIPPED by that scroller — it appeared as a tiny scrollable box pinned to
   the table's edge instead of a menu under the button. `fixed` escapes the
   scroller; no ancestor of a kebab declares transform/filter/contain, which
   are the only things that would re-trap it. top/left are placeholders: the
   menu is `hidden` until the script unhides it, and the script always sets
   both first, so there is no state in which these values are shown.
   z-index clears the two shells' sticky headers and mobile drawer (1000/1001);
   a drawer click is an outside click, so a menu can never be open beneath it. */
.cl-actions-dropdown{position:fixed;top:0;left:0;right:auto;width:max-content;max-width:min(20rem,calc(100vw - 1rem));background:var(--cl-paper);border:1px solid var(--cl-border);border-radius:6px;box-shadow:0 4px 12px rgba(var(--cl-ink-rgb),.08);min-width:140px;z-index:1200;padding:4px 0;}
.cl-actions-dropdown a,.cl-actions-dropdown button{display:block;width:100%;padding:8px 16px;text-align:start;background:none;border:none;color:var(--cl-ink);text-decoration:none;cursor:pointer;font-size:.875rem;box-sizing:border-box;}
.cl-actions-dropdown a:hover,.cl-actions-dropdown button:hover{background:var(--cl-paper);}
.cl-actions-delete{color:var(--cl-danger);}
tr[data-href]{cursor:pointer;}

/* ── Directional glyphs ───────────────────────────────────────────────────
   `←` `→` `↩` in a back link, a pagination control, a wizard nav or a
   forward CTA carry DIRECTION, not decoration. Flex rows and logical
   properties already swap sides under `dir=rtl`, but the arrowhead keeps
   pointing the way it was drawn — so on an Arabic tenant "next" reads as
   pointing backwards. Mirroring the glyph is the whole fix.

   This lives HERE rather than in commonlynk.components.css because it has to
   reach every shell: `external_base.html` — the anonymous public form-fill
   page, and so the single most likely place for an Arabic reader to meet a
   wizard arrow — loads the tokens sheet and NOT the components sheet.

   `.arrow` is a marker class carried only by these glyph spans; it is
   deliberately unscoped so one rule serves every surface. An arrow that is
   genuinely NOT directional (a `from → to` transition, a breadcrumb
   separator, an arrow baked into a msgid) must not carry it. */
[dir="rtl"] .arrow { display: inline-block; transform: scaleX(-1); }
