/* Al-Hakeem Design System - CSS Custom Properties */
/* Based on DESIGN-SYSTEM.md specification */

/* ============================================================================
   FONTS
   ============================================================================ */

/* ============================================================================
   ACTIVIST — per-weight families
   ============================================================================
   The designer ships 10 OTFs (arfonts-activist_all.zip). Each weight has
   its OWN file, so each weight gets its OWN CSS family — the family NAME
   encodes the weight, no numeric font-weight declaration needed. Callers
   pick a cut by family token only:

       font-family: var(--font-activist-semibold);   /* always SemiBold */

   Italic variants live in the SAME family (one extra @font-face per
   family) and are picked via font-style: italic on the consuming rule.
*/

@font-face { font-family: "Activist-ExtraLight"; src: url("/static/fonts/activist/activist-extra-light.otf")         format("opentype"); font-style: normal; font-display: swap; }
@font-face { font-family: "Activist-ExtraLight"; src: url("/static/fonts/activist/activist-extra-light-italic.otf")  format("opentype"); font-style: italic; font-display: swap; }

@font-face { font-family: "Activist-Light";      src: url("/static/fonts/activist/activist-light.otf")               format("opentype"); font-style: normal; font-display: swap; }
@font-face { font-family: "Activist-Light";      src: url("/static/fonts/activist/activist-light-italic.otf")        format("opentype"); font-style: italic; font-display: swap; }

@font-face { font-family: "Activist-Regular";    src: url("/static/fonts/activist/activist-regular.otf")             format("opentype"); font-style: normal; font-display: swap; }
@font-face { font-family: "Activist-Regular";    src: url("/static/fonts/activist/activist-regular-italic.otf")      format("opentype"); font-style: italic; font-display: swap; }

@font-face { font-family: "Activist-SemiBold";   src: url("/static/fonts/activist/activist-semi-bold.otf")           format("opentype"); font-style: normal; font-display: swap; }
@font-face { font-family: "Activist-SemiBold";   src: url("/static/fonts/activist/activist-semi-bold-italic.otf")    format("opentype"); font-style: italic; font-display: swap; }

@font-face { font-family: "Activist-Bold";       src: url("/static/fonts/activist/activist-bold.otf")                format("opentype"); font-style: normal; font-display: swap; }
@font-face { font-family: "Activist-Bold";       src: url("/static/fonts/activist/activist-bold-italic.otf")         format("opentype"); font-style: italic; font-display: swap; }


/* ────────────────────────────────────────────────────────────────────────
   Arabic-Indic numeral visual-balance  (revised 2026-05-27)

   The earlier `size-adjust + unicode-range` trick (boost Activist digits
   in-place) didn't move the needle in practice — the Activist OTF
   likely doesn't ship glyphs for U+0660-U+0669, so the browser pulls
   the Arabic-Indic digits from the system fallback (Noto Sans Arabic /
   Arial), where our @font-face descriptor has no effect.

   New approach — two layers that work TOGETHER:

   1. `font-size-adjust` on body (below in :root rules):
        Tells the browser to scale every font in the stack so its
        x-height matches a fixed ratio. This pulls the fallback's
        x-height up to roughly match Activist's, so Arabic glyphs
        (digits included) stop reading as undersized.

   2. `.ds-num` utility class:
        For places where Arabic-Indic numerals are the WHOLE point
        of the field (dates, phone numbers, reference codes, the
        registration step counter, etc.) we wrap them with this
        class which bumps font-size one tier (+1pt visually). Keeps
        body copy unchanged so general Arabic text doesn't bloat.

   The two layers are independent — either can ship alone — so the
   panel still degrades gracefully on browsers that don't yet support
   `font-size-adjust` (Safari < 17, Chrome < 92, Firefox < 89).
   ──────────────────────────────────────────────────────────────────────── */
.ds-num {
  /* Subtle boost so Arabic-Indic digits stop reading as undersized
     next to Latin glyphs. 1.08em (~+1pt at body sizes) chosen after
     1.18em caused the whole header to look bloated. `em` keeps it
     proportional to context: at type-ar-12 → ~13px, at type-ar-14
     → ~15px — small enough that labels around it stay anchored.
     `tabular-nums` aligns columns of dates / phone numbers cleanly. */
  font-size: 1.08em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}


:root {
  /* ========================================================================
     TYPOGRAPHY
     ======================================================================== */

  /* `--font-ar-family` is the page-default font (set on <body>). It aliases
     the Regular per-weight family so unstyled text reads as Activist Regular
     — the combined weight-keyed "Activist" family was removed since each
     cut now lives in its own family, addressed via the tokens below. */
  --font-ar-family:            "Activist-Regular",    "Noto Sans Arabic", Arial, sans-serif;
  --font-activist-extra-light: "Activist-ExtraLight", "Noto Sans Arabic", Arial, sans-serif;
  --font-activist-light:       "Activist-Light",      "Noto Sans Arabic", Arial, sans-serif;
  --font-activist-regular:     "Activist-Regular",    "Noto Sans Arabic", Arial, sans-serif;
  --font-activist-semibold:    "Activist-SemiBold",   "Noto Sans Arabic", Arial, sans-serif;
  --font-activist-bold:        "Activist-Bold",       "Noto Sans Arabic", Arial, sans-serif;

  /* Type Scale */
  --type-ar-12: 0.75rem;
  --type-ar-14: 0.875rem;
  --type-ar-16: 1rem;
  --type-ar-18: 1.125rem;
  --type-ar-22: 1.375rem;
  --type-ar-24: 1.5rem;
  --type-ar-28: 1.75rem;
  --type-ar-32: 2rem;
  --type-ar-36: 2.25rem;
  --type-ar-40: 2.5rem;
  --type-ar-44: 2.75rem;
  --type-ar-48: 3rem;
  --type-ar-52: 3.25rem;
  --type-ar-57: 3.5625rem;

  --line-default: normal;
  /* Synced from login-page tokens.css. Use --line-100 when the line-box
     must equal the font-size with no extra leading (so flex `gap` is the
     true visible distance between baselines). */
  --line-0:   0;
  --line-100: 1;
  --line-120: 1.2;
  --line-130: 1.3;
  --tracking-default: 0;

  /* Text Direction */
  --direction-ar: rtl;
  --text-align-ar-start: right;
  --text-align-ar-end: left;

  /* ========================================================================
     COLOR PALETTES
     ======================================================================== */

  /* Blue (Primary Brand) */
  --color-blue-50: #eff4ff;
  --color-blue-100: #dae6ff;
  --color-blue-200: #bdd4ff;
  --color-blue-300: #90b8ff;
  --color-blue-400: #5c93fe;
  --color-blue-500: #366bfb;
  --color-blue-600: #234cf0;
  --color-blue-700: #1836dd;
  --color-blue-800: #1a2db3;
  --color-blue-900: #1b2c8d;
  --color-blue-950: #161d55;
  --color-blue-1000: #03030a;

  /* Green (Success / Positive) */
  /* Synced with login-page/src/app/tokens.css (Core.Color — Green). */
  --color-green-50: #e8fff8;
  --color-green-100: #c8ffec;
  --color-green-200: #97ffdf;
  --color-green-300: #55ffd3;
  --color-green-400: #0adfae;
  --color-green-500: #00dcab;
  --color-green-600: #00b48d;
  --color-green-700: #009075;
  --color-green-800: #00725d;
  --color-green-900: #005d4f;
  --color-green-950: #00352e;
  --color-green-1000: #000a09;

  /* Pink (Danger / Female Gender) */
  --color-pink-50: #fef1fa;
  --color-pink-100: #fde6f6;
  --color-pink-200: #feccf0;
  --color-pink-300: #fea3e2;
  --color-pink-400: #fd69cc;
  --color-pink-500: #f73db5;
  --color-pink-600: #e71b95;
  --color-pink-700: #c90d77;
  --color-pink-800: #a60e62;
  --color-pink-900: #8a1154;
  --color-pink-950: #550230;
  --color-pink-1000: #0a0006;

  /* Cerulean (Info / Locked States) */
  --color-cerulean-50: #f0faff;
  --color-cerulean-100: #e0f3fe;
  --color-cerulean-200: #b9e9fe;
  --color-cerulean-300: #7cd8fd;
  --color-cerulean-400: #36c6fa;
  --color-cerulean-500: #0ba6df;
  --color-cerulean-600: #008dc9;
  --color-cerulean-700: #0171a3;
  --color-cerulean-800: #065e86;
  --color-cerulean-900: #0b4e6f;
  --color-cerulean-950: #07324a;
  --color-cerulean-1000: #01070a;

  /* BlackHaze (Neutral Gray) */
  --color-blackHaze-50: #f6f7f9;
  --color-blackHaze-100: #eceef2;
  --color-blackHaze-200: #d5dbe2;
  --color-blackHaze-300: #b0bac9;
  --color-blackHaze-400: #8595ab;
  --color-blackHaze-500: #667991;
  --color-blackHaze-600: #516178;
  --color-blackHaze-700: #424e62;
  --color-blackHaze-800: #394353;
  --color-blackHaze-900: #333b47;
  --color-blackHaze-950: #22272f;
  --color-blackHaze-1000: #07080a;

  /* Cararra (Warm Neutral) */
  --color-cararra-50: #edf0ed;
  --color-cararra-100: #e1e6e1;
  --color-cararra-200: #c2cdc3;
  --color-cararra-300: #9cac9e;
  --color-cararra-400: #778a79;
  --color-cararra-500: #5c705f;
  --color-cararra-600: #48594a;
  --color-cararra-700: #3c493e;
  --color-cararra-800: #333c34;
  --color-cararra-900: #2d342f;
  --color-cararra-950: #171c18;
  --color-cararra-1000: #080a09;

  /* BrightSun (Warning) */
  --color-brightSun-50: #fffbeb;
  --color-brightSun-100: #fff3c6;
  --color-brightSun-200: #ffe588;
  --color-brightSun-300: #ffd24c;
  --color-brightSun-400: #ffbd20;
  --color-brightSun-500: #f99b07;
  --color-brightSun-600: #dd7302;
  --color-brightSun-700: #b75006;
  --color-brightSun-800: #943d0c;
  --color-brightSun-900: #7a330d;
  --color-brightSun-950: #461902;
  --color-brightSun-1000: #0a0400;

  /* Radical Red (Error) */
  --color-radicalRed-50: #fff0f2;
  --color-radicalRed-100: #ffe2e8;
  --color-radicalRed-200: #ffcad6;
  --color-radicalRed-300: #ff9fb4;
  --color-radicalRed-400: #ff698d;
  --color-radicalRed-500: #ff2c64;
  --color-radicalRed-600: #ed1156;
  --color-radicalRed-700: #c80849;
  --color-radicalRed-800: #a80944;
  --color-radicalRed-900: #8f0c40;
  --color-radicalRed-950: #50011e;
  --color-radicalRed-1000: #0a0004;

  /* Red (true red — added 2026-05-28 per user feedback on the doctor
     review decision bar. The existing `radicalRed-*` family is pink-
     leaning (carmine / hot pink) and reads as "playful" rather than
     "STOP / harm" when used for destructive actions like rejecting a
     doctor's application. This family is a Tailwind-style red palette
     reserved for those destructive paths. */
  --color-red-50:  #fef2f2;
  --color-red-100: #fee2e2;
  --color-red-200: #fecaca;
  --color-red-300: #fca5a5;
  --color-red-400: #f87171;
  --color-red-500: #ef4444;
  --color-red-600: #dc2626;
  --color-red-700: #b91c1c;
  --color-red-800: #991b1b;
  --color-red-900: #7f1d1d;
  --color-red-950: #450a0a;
  --color-red-1000: #1f0303;

  /* White */
  --color-white-50: #ffffff;
  --color-white-100: #efefef;
  --color-white-200: #dcdcdc;
  --color-white-300: #bdbdbd;
  --color-white-400: #989898;
  --color-white-500: #7c7c7c;
  --color-white-600: #656565;
  --color-white-700: #525252;
  --color-white-800: #464646;
  --color-white-900: #3d3d3d;
  --color-white-950: #292929;
  --color-white-1000: #0a0a0a;

  /* Divider */
  --color-divider-line: #e7eef2;
  --color-divider-text: #7c9db5;

  /* ========================================================================
     SEMANTIC TOKENS
     ======================================================================== */

  /* Background */
  --bg-page: var(--color-cararra-50);
  --bg-card: var(--color-white-50);
  --bg-input: var(--color-blackHaze-50);
  --bg-sidebar: var(--color-white-50);

  /* Text */
  --text-onPage-primary: var(--color-cararra-1000);
  --text-onPage-secondary: var(--color-cararra-800);
  --text-onCard-primary: var(--color-blue-1000);
  --text-onCard-secondary: var(--color-blue-1000);
  --text-link: var(--color-blue-600);
  --text-disabled: var(--color-blue-400);
  --text-divider: var(--color-divider-text);
  --text-label: var(--color-blackHaze-950);
  --text-input: var(--color-blackHaze-950);
  --text-placeholder: var(--color-blackHaze-500);

  /* Brand */
  --brand-primary: var(--color-blue-600);
  --brand-primaryText: var(--color-blue-50);

  /* Border */
  --border-default: var(--color-blue-600);
  --border-disabled: var(--color-blue-400);
  --border-divider: var(--color-divider-line);

  /* ========================================================================
     SPACING
     ======================================================================== */

  --space-0: 0rem;
  --space-0_5: 0.125rem;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-7: 2rem;
  --space-8: 2.5rem;
  --space-9: 3rem;
  --space-10: 3.5rem;
  --space-11: 4rem;
  --space-12: 5rem;
  --space-13: 6rem;
  --space-14: 7.5rem;
  --space-15: 10rem;

  /* Layout */
  --layout-padding-inline: var(--space-7);
  --content-padding-block: 2.5rem;
  --card-padding: var(--space-7);
  --card-gap: var(--space-6);

  /* ========================================================================
     BORDER & RADIUS
     ======================================================================== */

  --stroke-none: 0rem;
  --stroke-1: 0.0625rem;
  --stroke-1_5: 0.09375rem;
  --stroke-2: 0.125rem;
  --stroke-4: 0.25rem;

  --radius-0: 0rem;
  --radius-2: 0.125rem;
  --radius-4: 0.25rem;
  --radius-8: 0.5rem;

  /* ========================================================================
     OPACITY
     ======================================================================== */

  --opacity-0: 0;
  --opacity-20: 0.2;
  --opacity-40: 0.4;
  --opacity-60: 0.6;
  --opacity-70: 0.7;
  --opacity-80: 0.8;
  --opacity-100: 1;

  /* ========================================================================
     ICON SIZES
     ======================================================================== */

  --icon-size-12: 0.75rem;
  --icon-size-16: 1rem;
  --icon-size-20: 1.25rem;
  --icon-size-24: 1.5rem;
  --icon-size-32: 2rem;
  --icon-size-40: 2.5rem;
  --icon-size-48: 3rem;

  /* ========================================================================
     SPECIAL VALUES (string aliases for cleaner inline style)
     ======================================================================== */

  --value-none: none;
  --value-transparent: transparent;

  /* ========================================================================
     Z-INDEX
     ======================================================================== */

  --z-base: 0;
  --z-content: 10;
  --z-sticky: 20;
  --z-dropdown: 30;
  --z-overlay: 40;
  --z-modal: 50;
  --z-popover: 60;
  --z-tooltip: 70;
  --z-notification: 80;
  --z-max: 100;

  /* ========================================================================
     INTERACTIVE STATES
     ======================================================================== */

  /* Primary (Filled Blue) */
  /* Primary button — text colour is blue-50 across every interactive state
     (default / hover / pressed / focus-visible). Figma master 1595:3503.
     Only the disabled state shifts the label to blue-200. */
  --interactive-primary-default-bg: var(--color-blue-600);
  --interactive-primary-default-text: var(--color-blue-50);
  --interactive-primary-hover-bg: var(--color-blue-500);
  --interactive-primary-hover-text: var(--color-blue-50);
  --interactive-primary-active-bg: var(--color-blue-800);  /* legacy alias — kept for any callers using --active-bg directly; pressed uses -pressed-bg below */
  --interactive-primary-active-text: var(--color-blue-50);
  --interactive-primary-pressed-bg: var(--color-blue-700);
  --interactive-primary-pressed-text: var(--color-blue-50);
  --interactive-primary-disabled-bg: var(--color-blue-400);
  --interactive-primary-disabled-text: var(--color-blue-200);

  /* Secondary (Outlined Blue) */
  --interactive-secondary-default-bg: transparent;
  --interactive-secondary-default-text: var(--color-blue-600);
  --interactive-secondary-default-border: var(--color-blue-600);
  --interactive-secondary-hover-text: var(--color-blue-500);
  --interactive-secondary-hover-border: var(--color-blue-500);
  --interactive-secondary-disabled-text: var(--color-blue-400);
  --interactive-secondary-disabled-border: var(--color-blue-400);

  /* Tertiary (Ghost Blue — text-only button) */
  --interactive-tertiary-default-bg: transparent;
  --interactive-tertiary-default-text: var(--color-blue-600);
  --interactive-tertiary-default-border: transparent;
  --interactive-tertiary-hover-bg: transparent;
  --interactive-tertiary-hover-text: var(--color-blue-500);
  --interactive-tertiary-hover-border: transparent;
  --interactive-tertiary-active-bg: transparent;
  --interactive-tertiary-active-text: var(--color-blue-800);
  --interactive-tertiary-active-border: transparent;
  --interactive-tertiary-pressed-bg: transparent;
  --interactive-tertiary-pressed-text: var(--color-blue-700);
  --interactive-tertiary-pressed-border: transparent;
  --interactive-tertiary-disabled-bg: transparent;
  --interactive-tertiary-disabled-text: var(--color-blue-400);
  --interactive-tertiary-disabled-border: transparent;

  /* Danger (Filled Red — proper `red` family, NOT radicalRed)
     -----------------------------------------------------------------
     2026-05-28 re-re-color: `radicalRed-600` (#ed1156) reads as hot
     PINK to reviewers, which clashes with the universal "STOP / harm /
     rejection" semantic. Tailwind-style `red-600` (#dc2626) is the
     correct destructive-action colour and is now in the palette as
     `--color-red-*`. radicalRed remains in the palette for non-
     destructive pink accents elsewhere. */
  --interactive-danger-default-bg: var(--color-red-600);
  --interactive-danger-default-text: var(--color-red-50);
  --interactive-danger-hover-bg: var(--color-red-700);
  --interactive-danger-hover-text: var(--color-red-50);
  --interactive-danger-disabled-bg: var(--color-red-200);
  --interactive-danger-disabled-text: var(--color-red-400);

  /* ========================================================================
     FEEDBACK SYSTEM
     ========================================================================
     Each variant has:
       bg       — fill behind the alert
       border   — 1px outline
       icon     — fill colour for the leading SVG glyph
       text     — accent / dismiss icon colour
       message  — title text (max-contrast on bg)
       desc     — description text (medium contrast on bg)
     Pattern (per `foundations/color.md`):
       bg = palette-50, border|icon = palette-500, message = palette-950, desc = palette-700
  */

  --feedback-success-bg: var(--color-green-50);
  --feedback-success-border: var(--color-green-500);
  --feedback-success-icon: var(--color-green-500);
  --feedback-success-text: var(--color-green-500);
  --feedback-success-message: var(--color-green-950);
  --feedback-success-desc: var(--color-green-700);

  --feedback-error-bg: var(--color-radicalRed-50);
  --feedback-error-border: var(--color-radicalRed-500);
  --feedback-error-icon: var(--color-radicalRed-500);
  --feedback-error-text: var(--color-radicalRed-500);
  --feedback-error-message: var(--color-radicalRed-950);
  --feedback-error-desc: var(--color-radicalRed-500);

  --feedback-warning-bg: var(--color-brightSun-50);
  --feedback-warning-border: var(--color-brightSun-500);
  --feedback-warning-icon: var(--color-brightSun-500);
  --feedback-warning-text: var(--color-brightSun-500);
  --feedback-warning-message: var(--color-brightSun-950);
  --feedback-warning-desc: var(--color-brightSun-700);

  --feedback-info-bg: var(--color-cerulean-50);
  --feedback-info-border: var(--color-cerulean-500);
  --feedback-info-icon: var(--color-cerulean-500);
  --feedback-info-text: var(--color-cerulean-500);
  --feedback-info-message: var(--color-cerulean-950);
  --feedback-info-desc: var(--color-cerulean-700);

  /* Network status — uses the same shape as the four message variants. */
  --feedback-offline-bg: var(--color-blackHaze-50);
  --feedback-offline-border: var(--color-blackHaze-500);
  --feedback-offline-icon: var(--color-blackHaze-500);
  --feedback-offline-text: var(--color-blackHaze-500);
  --feedback-offline-message: var(--color-blackHaze-950);
  --feedback-offline-desc: var(--color-blackHaze-700);

  --feedback-online-bg: var(--color-green-50);
  --feedback-online-border: var(--color-green-500);
  --feedback-online-icon: var(--color-green-500);
  --feedback-online-text: var(--color-green-500);
  --feedback-online-message: var(--color-green-950);
  --feedback-online-desc: var(--color-green-950);

  /* ========================================================================
     FIELD STATE LADDER (foundations/color.md, components/fields/README.md)
     ========================================================================
     Every form field derives its visual state from the 10-state ladder:
       default → focused → focused_filled → filled
       disabled  readonly  success  error  warning  info
     Tokens follow `--field-{state}-{slot}` where slot ∈
       { bg, label, value, placeholder, border, icon }.
     Border is only painted when the state has a 1.5px outline
     (focused, focused_filled, error, warning).
  */

  /* Default */
  --field-default-bg: var(--color-blackHaze-50);
  --field-default-label: var(--color-blackHaze-1000);
  --field-default-value: var(--color-blackHaze-800);
  --field-default-placeholder: var(--color-blackHaze-800);
  --field-default-border: var(--value-transparent);
  --field-default-icon: var(--color-blackHaze-500); /* Figma briefcase SVG stroke = #667991 = blackHaze-500 */

  /* Focused (no value yet) */
  --field-focused-bg: var(--field-default-bg);
  --field-focused-label: var(--field-default-label);
  --field-focused-value: var(--field-default-value);
  --field-focused-placeholder: var(--field-default-placeholder);
  --field-focused-border: var(--color-blue-600);
  --field-focused-icon: var(--field-default-icon);
  --field-focused-cursor: var(--color-blue-600);

  /* Focused + filled (clear-affordance shown) */
  --field-focused_filled-bg: var(--field-default-bg);
  --field-focused_filled-label: var(--field-default-label);
  --field-focused_filled-value: var(--field-default-value);
  --field-focused_filled-placeholder: var(--field-default-placeholder);
  --field-focused_filled-border: var(--color-blue-600);
  --field-focused_filled-icon: var(--field-default-icon);
  --field-focused-filled-clear: var(--color-blue-300);

  /* Filled (not focused, has value) */
  --field-filled-bg: var(--field-default-bg);
  --field-filled-label: var(--field-default-label);
  --field-filled-value: var(--field-default-value);
  --field-filled-placeholder: var(--field-default-placeholder);
  --field-filled-border: var(--value-transparent);
  --field-filled-icon: var(--field-default-icon);

  /* Readonly */
  --field-readonly-bg: var(--color-blackHaze-100);
  --field-readonly-label: var(--color-blackHaze-1000);
  --field-readonly-value: var(--color-blackHaze-300); /* Figma: blackHaze-300 (was -500) */
  --field-readonly-placeholder: var(--color-blackHaze-300);
  --field-readonly-border: var(--value-transparent);
  --field-readonly-icon: var(--color-blackHaze-300);

  /* Disabled */
  --field-disabled-bg: var(--color-blackHaze-50);
  --field-disabled-label: var(--color-blackHaze-300);
  --field-disabled-value: var(--color-blackHaze-200);
  --field-disabled-placeholder: var(--color-blackHaze-200);
  --field-disabled-border: var(--value-transparent);
  --field-disabled-icon: var(--color-blackHaze-200);

  /* Success */
  --field-success-bg: var(--color-blackHaze-50);
  --field-success-label: var(--color-green-1000); /* Figma: green-1000 (was blackHaze-1000) */
  --field-success-value: var(--color-green-600);
  --field-success-placeholder: var(--field-default-placeholder);
  --field-success-border: var(--value-transparent);
  --field-success-icon: var(--field-default-icon);
  --field-success-status-icon: var(--color-green-600); /* Figma success tick = green-600 (was -500) */

  /* Error */
  --field-error-bg: var(--color-radicalRed-50);
  --field-error-label: var(--color-radicalRed-950);
  --field-error-value: var(--color-radicalRed-500);
  --field-error-placeholder: var(--field-default-placeholder);
  --field-error-border: var(--color-radicalRed-600);
  --field-error-icon: var(--color-radicalRed-500);
  --field-error-status-icon: var(--color-radicalRed-500);

  /* Warning */
  --field-warning-bg: var(--color-brightSun-50);
  --field-warning-label: var(--color-brightSun-950);
  --field-warning-value: var(--color-brightSun-500);
  --field-warning-placeholder: var(--field-default-placeholder);
  --field-warning-border: var(--color-brightSun-600);
  --field-warning-icon: var(--color-brightSun-500);

  /* Info */
  --field-info-bg: var(--color-blackHaze-50);
  --field-info-label: var(--color-blackHaze-1000);
  --field-info-value: var(--color-blackHaze-800);
  --field-info-placeholder: var(--field-default-placeholder);
  --field-info-border: var(--value-transparent);
  --field-info-icon: var(--field-default-icon);

  /* Status icon shown in `focused_filled` (the clear × glyph wrapper). */
  --field-focused_filled-status-icon: var(--color-blue-300);

  /* ========================================================================
     BUTTON SHADOWS  (Figma node 1595:3503 — Primary Button master)
     ========================================================================
     Two-layer halos tinted to the button's own fill, geometry fixed at
     0/6/6 + 0/12/12 across every state (matches the Figma drop-shadow
     stack). Alphas are 0.06 + 0.08 — DO NOT increase them on hover; the
     hover signal comes from the bg colour change, not a heavier shadow.
     Disabled fields drop the shadow entirely.

     Tint per state matches the button's own background colour:
       - default:  blue-600 (#234cf0) — 35, 76, 240
       - hover:    blue-500 (#366bfb) — 54, 107, 251
       - pressed:  blue-700 (#1836dd) — 24,  54, 221
  */

  --btn-primary-shadow-default:
    0 0.375rem 0.375rem 0 color-mix(in srgb, var(--color-blue-600) 6%, transparent),
    0 0.75rem  0.75rem  0 color-mix(in srgb, var(--color-blue-600) 8%, transparent);

  --btn-primary-shadow-hover:
    0 0.375rem 0.375rem 0 color-mix(in srgb, var(--color-blue-500) 6%, transparent),
    0 0.75rem  0.75rem  0 color-mix(in srgb, var(--color-blue-500) 8%, transparent);

  --btn-primary-shadow-pressed:
    0 0.375rem 0.375rem 0 color-mix(in srgb, var(--color-blue-700) 6%, transparent),
    0 0.75rem  0.75rem  0 color-mix(in srgb, var(--color-blue-700) 8%, transparent);

  --btn-primary-shadow-focus: var(--btn-primary-shadow-default);

  /* Back-compat alias used by older code. */
  --btn-primary-shadow: var(--btn-primary-shadow-default);

  /* Focus ring (1.5px) — Figma uses the bg colour itself (blue-600), not a
     lighter tint, so the ring reads at the same strength as the inner pill. */
  --btn-primary-focus-border: var(--color-blue-600);

  /* Soft floating-panel shadows for dropdowns / popovers. */
  --avatar-dropdown-shadow: 0 0.75rem 1.5rem 0 color-mix(in srgb, var(--color-blackHaze-1000) 6%, transparent);

  /* ========================================================================
     HEADER / TOPBAR CHROME
     ======================================================================== */

  --header-bg: var(--bg-card);
  --header-logo-text: var(--brand-primary);
  --header-lang-label: var(--text-onCard-secondary);
  --header-lang-name: var(--text-onCard-primary);
  --header-lang-border: var(--border-divider);
  --header-lang-label-opacity: var(--opacity-60);

  /* ========================================================================
     ACCOUNT MENU / AVATAR (used by topbar dropdown)
     ======================================================================== */

  --avatar-size: var(--icon-size-32);
  --avatar-icon-size: var(--icon-size-20);
  --avatar-male-bg: var(--color-cerulean-100);
  --avatar-male-icon: var(--color-cerulean-700);
  --avatar-female-bg: var(--color-pink-100);
  --avatar-female-icon: var(--color-pink-700);

  --avatar-dropdown-bg: var(--bg-card);
  --avatar-dropdown-radius: var(--radius-8);
  --avatar-dropdown-text: var(--text-onCard-primary);
  --avatar-dropdown-icon: var(--color-blackHaze-500);
  --avatar-dropdown-divider: var(--border-divider);
  --avatar-dropdown-profile-hover-bg: var(--color-blackHaze-50);
  --avatar-dropdown-logout-text: var(--color-radicalRed-600);
  --avatar-dropdown-logout-hover-bg: var(--color-radicalRed-50);

  --menu-action-default-bg: var(--value-transparent);
  --menu-action-default-text: var(--text-onCard-primary);
  --menu-action-default-icon: var(--color-blackHaze-500);
  --menu-action-hover-bg: var(--color-blackHaze-50);
  --menu-action-hover-text: var(--text-onCard-primary);
  --menu-action-hover-icon: var(--color-blue-600);
  --menu-action-disabled-bg: var(--value-transparent);
  --menu-action-disabled-text: var(--text-disabled);
  --menu-action-disabled-icon: var(--color-blackHaze-300);

  /* ========================================================================
     SIDEBAR (Panel-specific)
     ======================================================================== */

  --sidebar-width: 16rem;
  --sidebar-collapsed-width: 4rem;
  --topbar-height: 4rem;
}

/* ============================================================================
   GLOBAL STYLES
   ============================================================================ */

body {
  font-family: var(--font-ar-family);
  font-weight: 400;
  font-size: var(--type-ar-16);
  line-height: var(--line-default);
  color: var(--text-onPage-primary);
  background-color: var(--bg-page);
  /* NOTE 2026-05-27: an earlier attempt set `font-size-adjust: 0.5`
     here to normalise x-height between Activist (Arabic) and its
     Latin fallbacks. In practice it scaled the WHOLE document up
     visibly — every paragraph, every label, the sidebar nav — so we
     dropped it and now lean on the targeted `.ds-num` utility class
     for the cases that actually needed help (digit-heavy fields). */
}

/* ============================================================================
   TRANSITIONS
   ============================================================================ */

.btn-transition {
  transition: background-color 0.2s ease, box-shadow 0.2s ease,
    transform 0.15s ease, opacity 0.2s ease;
}

.btn-transition:hover:not(:disabled) {
  transform: translateY(-0.0625rem);
  box-shadow: 0 0.25rem 0.75rem 0 color-mix(in srgb, var(--color-blue-600) 18%, transparent);
}

.btn-transition:active:not(:disabled) {
  transform: translateY(0.0625rem);
  box-shadow: 0 0.0625rem 0.25rem 0 color-mix(in srgb, var(--color-blue-600) 10%, transparent);
}

.input-focus-transition {
  transition: box-shadow 0.25s ease, border-color 0.25s ease;
}

.input-focus-transition:focus-within {
  box-shadow: 0 0 0 0.1875rem color-mix(in srgb, var(--color-blue-600) 8%, transparent);
}

/* ============================================================================
   RTL DIRECTION FLIPS
   ============================================================================ */

[dir="rtl"] .flip-rtl {
  transform: scaleX(-1);
}

/* ============================================================================
   ANIMATIONS
   ============================================================================ */

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(1.25rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-1rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.anim-fade-in-up {
  animation: fadeInUp 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.anim-slide-down {
  animation: slideDown 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* ----------------------------------------------------------------------------
   AVATAR LOADING SKELETON
   Used on the doctors-list 48px circular photo (templates/doctors/list.html).
   The <span> wrapper carries the moving gradient; the <img> child sits on
   top fully transparent until its `onload` flips the `is-loaded` class on
   the wrapper, which kills the animation, drops the gradient, and fades
   the actual photo in over 200ms. RTL-agnostic — the gradient axis is
   logical (the background-position numbers are symmetric anyway).
   ---------------------------------------------------------------------------- */
@keyframes ds-avatar-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

.ds-avatar-skeleton {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  /* border-box so the ring lives INSIDE the 48×48 box — the avatar's
     outer footprint stays identical whether the row is in skeleton,
     loaded, or static state. Otherwise content-box (the default for
     inline-block) would inflate the column to 48 + 2*stroke. */
  box-sizing: border-box;
  /* Thin blackHaze ring frames every avatar — keeps the silhouette
     consistent against any row background (zebra stripe, hover blue,
     selection). Token-only: --stroke-1 (0.0625rem) for thickness,
     --color-blackHaze-200 for the line. */
  border: var(--stroke-1) solid var(--color-blackHaze-200);
  /* Two-stop blackHaze gradient — sits inside our token palette so we
     never touch raw hex. 200% width gives the highlight band room to
     traverse without the gradient ends ever showing as a hard seam. */
  background-image: linear-gradient(
    90deg,
    var(--color-blackHaze-100) 0%,
    var(--color-blackHaze-200) 50%,
    var(--color-blackHaze-100) 100%
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: ds-avatar-shimmer 1.4s ease-in-out infinite;
}

.ds-avatar-skeleton > img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 200ms ease-out;
}

.ds-avatar-skeleton.is-loaded {
  background-image: none;
  animation: none;
}

.ds-avatar-skeleton.is-loaded > img {
  opacity: 1;
}

/* The gendered default SVGs are local files that decode synchronously —
   they don't need a skeleton frame. The plain (non-wrapper) variant
   below renders them straight, no animation overhead. Same blackHaze
   ring as the loaded variant so all rows look uniform. */
.ds-avatar-static {
  display: inline-block;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: var(--stroke-1) solid var(--color-blackHaze-200);
  /* `box-sizing: border-box` keeps the OUTER footprint at 48×48 so the
     ring doesn't push the surrounding row text by 2px. Same reason for
     the explicit width/height on `.ds-avatar-skeleton` above — the
     wrapper there is already block-sized by border-box defaults inside
     the cascade. */
  box-sizing: border-box;
}

/* ----------------------------------------------------------------------------
   STACKED REVIEWERS  (used in templates/doctors/list.html, "من يراجع" column)
   Renders 24px circular avatars for every admin who has issued at least one
   verdict (Approve / Reject / Request-Changes) on the doctor's current
   review round. Multiple reviewers stack with a -0.5rem overlap, and a
   "+N" chip caps the row at 3 visible avatars before collapsing the rest.
   Token-only — no raw hex, no raw px (the small px on the avatar size is
   a rem-equivalent: 24px = 1.5rem; if you ever swap to a rem token, just
   replace width/height — the rest of the cascade keeps working).
   ---------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------------
   DOCTOR DETAIL HEADER PHOTO  (templates/doctors/detail.html)
   64×64 square with radius-4 corners. Two visual modes driven by the
   presence of an uploaded photo:
     · default (.ds-doctor-detail-photo)            → photo fills edge-to-edge
     · fallback (.ds-doctor-detail-photo--fallback) → centred gendered SVG
   The class is set server-side based on whether `doctor_photo` is
   populated. The `onerror` handler on the <img> also toggles the
   `--fallback` modifier when a previously-uploaded photo's presigned
   URL has expired and the gendered SVG takes over — keeping the
   visual treatment consistent.
   ---------------------------------------------------------------------------- */
.ds-doctor-detail-photo--fallback {
  /* Lift the gendered avatar SVG visually off the background by
     tinting the frame a touch toward cerulean — this way an
     "uploaded-soon-after" preview isn't mistaken for the placeholder. */
  background-color: var(--color-blackHaze-50, var(--color-blackHaze-100));
}

/* ----------------------------------------------------------------------------
   DOCTOR DETAIL STATUS BADGE — local size uplift  (added 2026-05-27)
   The default .ds-badge is sized for table cells (12px font, 4×8 padding)
   which reads as a tiny chip next to the 22px doctor name in the detail
   header. We bump it ONE tier up here so the status anchors visually
   against the name — but scope the change to `.ds-doctor-detail-status`
   so the list-page and other surfaces keep the compact chip. The marker
   square (the coloured dot rendered via ::before) scales up in lock-step
   so the proportions stay clean. RTL-safe — all spacings are logical.
   ---------------------------------------------------------------------------- */
.ds-doctor-detail-status > .ds-badge {
  font-size: var(--type-ar-14);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-4);
  gap: var(--space-2);
}
.ds-doctor-detail-status > .ds-badge::before {
  /* Bigger marker square to keep the visual ratio with the larger label. */
  width: 0.625rem;   /* 10px */
  height: 0.625rem;
}

.ds-reviewers-stack {
  /* `inline-flex` so the stack flows next to whatever sits beside it in
     the table cell, but still establishes its own baseline. The row-
     reverse mirror happens automatically under RTL because we rely on
     `flex-direction: row` (logical direction) — but we use a negative
     `margin-inline-start` on the children instead of `margin-left`,
     so the overlap direction also flips cleanly. */
  display: inline-flex;
  align-items: center;
  flex-direction: row;
  vertical-align: middle;
}

.ds-reviewer-avatar {
  position: relative;
  display: inline-block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  overflow: hidden;
  /* The white ring is what creates the "stacked playing cards" depth —
     each avatar's blackHaze edge sits on top of a 2px white halo that
     visually separates it from the avatar behind it. */
  box-sizing: border-box;
  border: var(--stroke-2) solid var(--color-white-50);
  background-color: var(--color-blackHaze-100);
  flex-shrink: 0;
}

/* Every child after the first slides under its predecessor by half its
   width. Using `margin-inline-start` (not `-left`) flips correctly for
   RTL: in RTL the second card slides UNDER the first from the right. */
.ds-reviewers-stack > .ds-reviewer-avatar + .ds-reviewer-avatar,
.ds-reviewers-stack > .ds-reviewer-avatar + .ds-reviewers-more,
.ds-reviewers-stack > .ds-reviewers-more + .ds-reviewer-avatar {
  margin-inline-start: -0.5rem;
}

.ds-reviewer-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Initials chip when the admin has no avatar uploaded. Cerulean tint
   keeps the colour in the same family the panel uses for "actively
   under review" (badge `cerulean-500`). */
.ds-reviewer-avatar--initials {
  background-color: var(--color-cerulean-100);
  color: var(--color-cerulean-900);
  font-size: 0.6875rem;        /* 11px — readable inside 24px circle */
  font-weight: 600;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-transform: uppercase;
  letter-spacing: 0;
}

/* "+N" chip for the overflow tail. Sized identically to an avatar so
   the stack baseline stays even. */
.ds-reviewers-more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  box-sizing: border-box;
  border: var(--stroke-2) solid var(--color-white-50);
  background-color: var(--color-blackHaze-200);
  color: var(--color-blackHaze-900);
  font-size: 0.625rem;         /* 10px — same band as the initials chip */
  font-weight: 600;
  line-height: 1;
  flex-shrink: 0;
}

/* Tooltip on the whole stack (data-tip set in the template) — reuses the
   existing `[data-tip]:hover::after` rule already defined for the verified
   badge. The `position: relative` lets the absolutely-positioned tooltip
   anchor here. */
.ds-reviewers-stack[data-tip] {
  position: relative;
}

/* When the stack is rendered as a <button> (i.e. ≥2 reviewers, where a
   popup makes sense), give it pointer affordance + transparent button
   chrome so it visually matches the read-only span variant. */
button.ds-reviewers-stack {
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
}
button.ds-reviewers-stack:focus-visible {
  outline: var(--stroke-2) solid var(--color-cerulean-500);
  outline-offset: 0.125rem;
  border-radius: var(--radius-8);
}

/* ----------------------------------------------------------------------------
   REVIEWERS POPUP  (used in templates/doctors/list.html for ≥2 reviewers)
   A single global dialog sits at the page bottom; clicks on any clickable
   stack drive it via data-attributes (see the JS at the foot of list.html).
   Token-safe: every color is a Core.Color token or a color-mix on one;
   every radius is on the {0,2,4,8} ladder.
   ---------------------------------------------------------------------------- */
.ds-reviewers-popup {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: none;                  /* JS flips this to flex on open */
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  /* Backdrop = pure token tint, no raw rgba(). 50% of blackHaze-1000
     (the darkest neutral) blended with transparent gives the same
     dim-the-page feel without violating the design-system rule. */
  background-color: color-mix(in srgb, var(--color-blackHaze-1000) 50%, transparent);
}
.ds-reviewers-popup.is-open {
  display: flex;
  animation: fadeInUp 0.22s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.ds-reviewers-popup__dialog {
  width: 100%;
  max-width: 28rem;               /* 448px */
  background-color: var(--bg-card, var(--color-white-50));
  border-radius: var(--radius-8);
  /* Card → inner sections will use radius-4 to respect the nested
     radius ladder (8 → 4 → 2). */
  box-shadow: 0 1.5rem 3rem color-mix(in srgb, var(--color-blackHaze-1000) 16%, transparent);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  max-height: min(80vh, 32rem);
}

.ds-reviewers-popup__header {
  padding: var(--space-4) var(--space-5);
  border-block-end: var(--stroke-1) solid var(--color-blackHaze-200);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.ds-reviewers-popup__title {
  margin: 0;
  font-size: var(--type-ar-16);
  font-weight: 600;
  color: var(--color-blackHaze-900);
  line-height: 1.4;
  /* min-width: 0 + ellipsis keeps a very long doctor name from pushing
     the close button off the dialog. */
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.ds-reviewers-popup__close {
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-4);
  border: 0;
  background: transparent;
  color: var(--color-blackHaze-700);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 1.25rem;
  line-height: 1;
  transition: background-color 120ms ease, color 120ms ease;
}
.ds-reviewers-popup__close:hover {
  background-color: var(--color-blackHaze-100);
  color: var(--color-blackHaze-900);
}

.ds-reviewers-popup__list {
  list-style: none;
  margin: 0;
  padding: var(--space-2) 0;
  overflow-y: auto;
}

.ds-reviewers-popup__item {
  display: flex;
  /* `flex-start` so the avatar stays anchored to the top of the row
     once decisions extend the meta column vertically. With center, a
     reviewer who decided on three steps would float their avatar to
     the middle of an awkward block. */
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  /* Separator between consecutive reviewers — easier to scan when
     multiple admins each have several decisions logged. The last
     child loses it via `&:last-child` below. */
  border-block-end: var(--stroke-1) solid var(--color-blackHaze-100);
  transition: background-color 120ms ease;
}
.ds-reviewers-popup__item:last-child {
  border-block-end: 0;
}
.ds-reviewers-popup__item:hover {
  background-color: var(--color-blackHaze-50, var(--color-blackHaze-100));
}

.ds-reviewers-popup__avatar {
  width: 2.5rem;                  /* 40px */
  height: 2.5rem;
  border-radius: 50%;
  flex-shrink: 0;
  box-sizing: border-box;
  border: var(--stroke-1) solid var(--color-blackHaze-200);
  background-color: var(--color-blackHaze-100);
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ds-reviewers-popup__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ds-reviewers-popup__avatar--initials {
  background-color: var(--color-cerulean-100);
  color: var(--color-cerulean-900);
  font-size: var(--type-ar-14);
  font-weight: 600;
  text-transform: uppercase;
}

.ds-reviewers-popup__meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: var(--space-0_5);
}
.ds-reviewers-popup__name {
  font-size: var(--type-ar-14);
  font-weight: 600;
  color: var(--color-blackHaze-900);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ds-reviewers-popup__email {
  font-size: var(--type-ar-12);
  color: var(--color-blackHaze-700);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Email is naturally LTR even inside an RTL dialog. */
  direction: ltr;
  text-align: start;
}

/* Decision list inside a reviewer item — chronological log of every
   step the admin has decided on for this doctor in the current round.
   The 0.5rem block-start margin separates it from the name/email block
   while keeping the row vertically dense. */
.ds-reviewers-popup__decisions {
  list-style: none;
  margin: var(--space-2) 0 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  /* Inset matches the avatar's left edge + gap so each decision line
     reads as a child of the admin who took it. */
  padding-inline-start: 0;
}

.ds-reviewers-popup__decision {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--space-2);
  /* radius-2 (the smallest of the {0,2,4,8} ladder) — nested inside
     the radius-4 reviewer item which itself sits inside the radius-8
     dialog. */
  border-radius: var(--radius-2);
  padding: var(--space-1) var(--space-2);
  /* Subtle resting bg so each decision is visually distinct from the
     enclosing reviewer row without competing for attention. */
  background-color: var(--color-blackHaze-50, var(--color-blackHaze-100));
}

.ds-reviewers-popup__decision__badge {
  /* 22px chip — small enough to sit next to a 14px label without
     dominating, large enough to host a 14px icon comfortably. */
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* The svg icon inside inherits `color` via stroke="currentColor", so
     setting `color` here propagates to the glyph. */
  color: var(--color-white-50);
}
.ds-reviewers-popup__decision__badge svg {
  width: 0.875rem;     /* 14px */
  height: 0.875rem;
  display: block;
}
/* Verdict-specific colors — each pair (bg + glyph contrast) lives
   exclusively in the Core.Color palette. */
.ds-reviewers-popup__decision__badge--approved {
  background-color: var(--color-green-500);
}
.ds-reviewers-popup__decision__badge--changes_requested {
  background-color: var(--color-brightSun-500);
  color: var(--color-blackHaze-1000);   /* dark on yellow for AAA */
}
.ds-reviewers-popup__decision__badge--rejected {
  background-color: var(--color-radicalRed-500);
}

.ds-reviewers-popup__decision__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 0.125rem;
}
.ds-reviewers-popup__decision__step {
  font-size: var(--type-ar-14);
  font-weight: 500;
  color: var(--color-blackHaze-900);
  line-height: 1.3;
  /* Wrap long step names rather than truncate — the dialog can grow
     vertically (max-height + scroll on the list). */
  white-space: normal;
  word-break: break-word;
}
.ds-reviewers-popup__decision__time {
  font-size: var(--type-ar-12);
  color: var(--color-blackHaze-700);
  line-height: 1.3;
  /* `font-variant-numeric: tabular-nums` keeps Arabic numerals
     vertically aligned across rows even when widths differ. */
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   REDUCED MOTION
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
  .anim-fade-in-up,
  .anim-slide-down,
  .btn-transition,
  .input-focus-transition,
  .ds-btn,
  .ds-field {
    animation: none !important;
    transition: none !important;
  }

  .ds-btn:hover:not(:disabled) {
    transform: none !important;
  }
}

/* ============================================================================
   DS COMPONENT BASE STYLES
   ============================================================================
   The structural styling for each component lives in CSS classes here so
   pages don't need to inline it. Page templates set semantic content + any
   per-instance overrides; everything visual flows from these classes.

   Patterns in use:
   - Two-layer "ring + card" shape on Buttons and Fields (see
     `foundations/radius-and-stroke.md`). Outer wrapper carries a 1.5px
     transparent border that becomes coloured on focus → zero layout shift.
   - Per-weight font-family tokens (`--font-activist-{weight}`) — declared
     at the top of this file — pick the matching font-face automatically.
*/


/* ============================================================================
   BUTTON — components/button.md
   ============================================================================
   Anatomy:
     <button class="ds-btn ds-btn--{variant} ds-btn--{size}">
       <span class="ds-btn__inner">
         [start-icon] label [end-icon]
       </span>
     </button>

   - Outer .ds-btn  : transparent 1.5px border, padding-0_5, radius-8.
                       On :focus-visible, border becomes blue-300 and the
                       outer radius drops to radius-4.
   - Inner .ds-btn__inner : the visible pill — bg, padding, radius-4,
                       transitions colour + shadow.
*/

.ds-btn {
  display: inline-flex;
  padding: var(--space-0_5);
  margin: 0;
  border-radius: var(--radius-8);
  border-width: var(--stroke-1_5);
  border-style: solid;
  border-color: var(--value-transparent);
  background: var(--value-transparent);
  cursor: pointer;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.2s ease, border-radius 0.2s ease, transform 0.15s ease;
}

.ds-btn:disabled,
.ds-btn[aria-disabled="true"] {
  cursor: not-allowed;
}

.ds-btn:hover:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(-0.0625rem);
}

.ds-btn:active:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(0.0625rem);
}

.ds-btn:focus-visible {
  outline: none;
  border-color: var(--btn-primary-focus-border);
  border-radius: var(--radius-4);
}

.ds-btn--full-width { width: 100%; }
.ds-btn--full-width .ds-btn__inner { width: 100%; }

.ds-btn__inner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: auto;
  border-radius: var(--radius-4);
  border-width: var(--stroke-none);
  border-style: solid;
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-16);
  line-height: var(--line-default);
  white-space: nowrap;
  transition:
    background-color 0.5s cubic-bezier(0.4, 0, 0.2, 1),
    box-shadow 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    border-radius 0.2s ease;
}

.ds-btn:focus-visible .ds-btn__inner {
  border-radius: var(--radius-2);
}

/* --- Sizes (per components/button.md) -------------------------------- */
.ds-btn--large  .ds-btn__inner { padding: var(--space-4) var(--space-7); font-size: var(--type-ar-16); }
.ds-btn--medium .ds-btn__inner { padding: var(--space-3) var(--space-6); font-size: var(--type-ar-14); }
.ds-btn--small  .ds-btn__inner { padding: var(--space-2) var(--space-4); font-size: var(--type-ar-14); }

/* --- Variant: primary (filled blue, with shadow halo) ---------------- */
.ds-btn--primary .ds-btn__inner {
  background-color: var(--interactive-primary-default-bg);
  color: var(--interactive-primary-default-text);
  box-shadow: var(--btn-primary-shadow-default);
}
.ds-btn--primary:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  background-color: var(--interactive-primary-hover-bg);
  box-shadow: var(--btn-primary-shadow-hover);
}
.ds-btn--primary:active:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  background-color: var(--interactive-primary-pressed-bg);
  box-shadow: var(--btn-primary-shadow-pressed);
}
.ds-btn--primary:disabled .ds-btn__inner,
.ds-btn--primary[aria-disabled="true"] .ds-btn__inner {
  background-color: var(--interactive-primary-disabled-bg);
  color: var(--interactive-primary-disabled-text);
  box-shadow: var(--value-none);
}

/* --- Variant: secondary (outlined blue) ------------------------------ */
.ds-btn--secondary .ds-btn__inner {
  background-color: var(--interactive-secondary-default-bg);
  color: var(--interactive-secondary-default-text);
  border-width: var(--stroke-1);
  border-color: var(--interactive-secondary-default-border);
}
.ds-btn--secondary:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  color: var(--interactive-secondary-hover-text);
  border-color: var(--interactive-secondary-hover-border);
}
.ds-btn--secondary:disabled .ds-btn__inner,
.ds-btn--secondary[aria-disabled="true"] .ds-btn__inner {
  color: var(--interactive-secondary-disabled-text);
  border-color: var(--interactive-secondary-disabled-border);
}

/* --- Variant: tertiary (text only, ghost) ---------------------------- */
.ds-btn--tertiary .ds-btn__inner {
  background-color: var(--interactive-tertiary-default-bg);
  color: var(--interactive-tertiary-default-text);
}
.ds-btn--tertiary:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  color: var(--interactive-tertiary-hover-text);
}
.ds-btn--tertiary:active:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  color: var(--interactive-tertiary-pressed-text);
}
.ds-btn--tertiary:disabled .ds-btn__inner,
.ds-btn--tertiary[aria-disabled="true"] .ds-btn__inner {
  color: var(--interactive-tertiary-disabled-text);
}

/* --- Variant: danger (filled red — radicalRed family) ----------------- */
.ds-btn--danger .ds-btn__inner {
  background-color: var(--interactive-danger-default-bg);
  color: var(--interactive-danger-default-text);
}
.ds-btn--danger:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  background-color: var(--interactive-danger-hover-bg);
  color: var(--interactive-danger-hover-text);
}
.ds-btn--danger:disabled .ds-btn__inner,
.ds-btn--danger[aria-disabled="true"] .ds-btn__inner {
  background-color: var(--interactive-danger-disabled-bg);
  color: var(--interactive-danger-disabled-text);
}

/* --- Variant: success (filled green — used for "Activate" etc.) ------ */
.ds-btn--success .ds-btn__inner {
  background-color: var(--color-green-600);
  color: var(--color-green-50);
}
.ds-btn--success:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  background-color: var(--color-green-500);
}

/* --- Variant: warning (filled amber — consistent with success/danger) -
   2026-05-28: was outlined (light cream bg + dark text + orange border)
   which broke visual rhythm with the filled success/danger buttons next
   to it on the doctor-review decision bar. User requested all three
   action buttons share the same treatment (filled + white icon/label),
   so the warning button now lives on brightSun-500 (amber). The icon
   inherits this white-ish text colour via `currentColor` in the
   `.ds-btn__icon` mask. */
.ds-btn--warning .ds-btn__inner {
  /* Figma decision-bar "طلب تعديل" button = BrightSun/600 (#dd7302), not
     -500. The deeper tone reads as a deliberate amber CTA next to the green
     approve, matching node 2621:976. */
  background-color: var(--color-brightSun-600);
  color: var(--color-brightSun-50);
}
.ds-btn--warning:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  background-color: var(--color-brightSun-700);
}
.ds-btn--warning:disabled .ds-btn__inner,
.ds-btn--warning[aria-disabled="true"] .ds-btn__inner {
  background-color: var(--color-brightSun-200);
  color: var(--color-brightSun-400);
}

/* --- Button icon glyph (mask-based, takes `currentColor`) ------------ */
/* 2026-05-28 — replaces inline `<img src="...svg">` inside button
   labels. `<img>` loads the SVG as a sandboxed image so `fill`/`stroke`
   colours bake in from the SVG file itself; that's why the reject /
   edit / approve icons rendered at three different colours despite
   sitting in three identically-sized buttons. The mask approach
   re-paints the SVG silhouette with the button's text colour, so an
   icon on a green Approve button is green-50 white, the icon on a red
   Reject button is red-50 white, etc. — all driven by `currentColor`.
   Size is fixed at 20px (icon-size-20 token) so the three action
   buttons line up visually. */
.ds-btn__icon {
  display: inline-block;
  width: var(--icon-size-20);
  height: var(--icon-size-20);
  background-color: currentColor;
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: contain;
  flex-shrink: 0;
  vertical-align: middle;
}


/* ============================================================================
   FIELD — components/fields/README.md
   ============================================================================
   Anatomy:
     <div class="ds-field [ds-field--error|--warning|--readonly|--disabled]">
       <label class="ds-field__label">…</label>
       <div class="ds-field__ring">                <-- transparent border ring
         <div class="ds-field__card">              <-- bg + radius (the card)
           <div class="ds-field__row">             <-- icon + input + status
             [icon] <input class="ds-field__input"> [status]
           </div>
         </div>
       </div>
       <p class="ds-field__message">…</p>
     </div>

   Default state:
     ring   — 1.5px transparent border, padding-0_5, radius-4
     card   — bg=field-default-bg, padding=space-4, radius-4

   Focus-within:
     ring   — border becomes field-focused-border (blue-600)
     card   — radius drops to radius-2 (the inner radius nests inside the
              outer radius — see foundations/radius-and-stroke.md).

   The transparent default border means the focus ring appears with **zero
   layout shift** — same width before and after.
*/

.ds-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2); /* spacing between ring and below-field message */
  width: 100%;
}

.ds-field__label {
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14);
  color: var(--field-default-label);
  /* `--line-100` (= 1) collapses leading so the label's box equals its
     font-size. With no extra leading above/below, the parent's flex `gap`
     (var(--space-4) = 1rem = 16px) IS the true visible distance between
     the label glyphs and the input row. */
  line-height: var(--line-100);
  margin: 0;
}

.ds-field__required {
  color: var(--feedback-error-message);
  margin-inline-start: var(--space-1);
}

.ds-field__ring {
  padding: var(--space-0_5);
  border-radius: var(--radius-4);
  border-width: var(--stroke-1_5);
  border-style: solid;
  border-color: var(--value-transparent);
  background: var(--value-transparent);
  transition: border-color 0.15s ease;
}

/* Card stacks the label and the input row vertically. Gap = 12px
   (--space-3 = 0.75rem) per panel spec; padding stays 16px. Label sits
   INSIDE the card so focus/error borders wrap label + row as one unit.
   `height: 5.5rem` (88px) gives every field — text, dropdown, search —
   the same vertical footprint so they line up perfectly in a row.
   Breakdown: 16 padTop + 14 label + 12 gap + 24 row + 16 padBot = 82px,
   the remaining 6px is breathing room for variance in font metrics. */
.ds-field__card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3);   /* 0.75rem = 12px */
  padding: var(--space-4);
  height: 5.5rem;        /* 88px — uniform across every field */
  box-sizing: border-box;
  border-radius: var(--radius-4);
  background-color: var(--field-default-bg);
  transition:
    background-color 0.15s ease,
    border-radius 0.15s ease;
}

.ds-field__ring:focus-within {
  border-color: var(--field-focused-border);
}
/* Inner card switches to a smaller radius whenever the outer ring shows a
   border (focus, error, warning, focused_filled). Matches the Figma
   two-layer ring+card geometry — outer radius 4, inner radius 2 once a
   1.5px border is painted on the outer. */
.ds-field__ring:focus-within .ds-field__card,
.ds-field--error .ds-field__card,
.ds-field--warning .ds-field__card,
.ds-field--focused-filled .ds-field__card,
.ds-field--focused_filled .ds-field__card {
  border-radius: var(--radius-2);
}

.ds-field__row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* Figma fixes the input row at 24px (h-[24px] on the row in
     WorkplaceTextField / SubSpecialtyDropdownField). Setting an explicit
     min-height keeps every field the same height — text inputs without
     icons, inputs with icons, and dropdowns all line up at 24px row
     height regardless of content. */
  min-height: var(--icon-size-24);
}

.ds-field__input {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  background: var(--value-transparent);
  border: var(--value-none);
  outline: var(--value-none);
  padding: 0;
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-16);
  line-height: var(--line-default);
  color: var(--field-default-value);
}
.ds-field__input::placeholder {
  color: var(--field-default-placeholder);
  opacity: var(--opacity-80); /* Figma default placeholder is 80% (was 60%) */
}
/* Disabled placeholder color is already dim — drop the opacity so it
   doesn't double-dim and disappear. Figma renders disabled placeholder
   at full opacity using blackHaze-200 directly. */
.ds-field--disabled .ds-field__input::placeholder {
  opacity: var(--opacity-100);
}

/* Native select dropdown — drop the OS chevron, render our own. */
.ds-field__input--select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("/static/icons/arrow-down-01.svg");
  background-repeat: no-repeat;
  background-position: right var(--space-1) center;
  background-size: var(--icon-size-16);
  padding-inline-end: var(--space-6);
  cursor: pointer;
}
[dir="rtl"] .ds-field__input--select {
  background-position: left var(--space-1) center;
}

/* --- Error -------------------------------------------------------------- */
.ds-field--error .ds-field__label              { color: var(--field-error-label); }
.ds-field--error .ds-field__ring               { border-color: var(--field-error-border); }
.ds-field--error .ds-field__card               { background-color: var(--field-error-bg); }
.ds-field--error .ds-field__input              { color: var(--field-error-value); }

/* --- Warning ------------------------------------------------------------ */
.ds-field--warning .ds-field__label            { color: var(--field-warning-label); }
.ds-field--warning .ds-field__ring             { border-color: var(--field-warning-border); }
.ds-field--warning .ds-field__card             { background-color: var(--field-warning-bg); }
.ds-field--warning .ds-field__input            { color: var(--field-warning-value); }

/* --- Success ------------------------------------------------------------ */
.ds-field--success .ds-field__label            { color: var(--field-success-label); }
.ds-field--success .ds-field__card             { background-color: var(--field-success-bg); }
.ds-field--success .ds-field__input            { color: var(--field-success-value); }
/* Figma success state has a wider gap (16px) between the leading tick
   status icon and the value+trailing-icon group. */
.ds-field--success .ds-field__row              { gap: var(--space-5); }
.ds-field--success .ds-field__row > :not(:first-child):not(.ds-field__status) {
  /* leave the trailing icon snug to the value */
  margin-inline-start: 0;
}

/* --- Info --------------------------------------------------------------- */
/* Previously missing entirely. Visual state with a below-field info
   message — the field itself stays neutral (blackHaze-50 bg, no border)
   but the FieldMessage below renders in cerulean. */
.ds-field--info .ds-field__label               { color: var(--field-info-label); }
.ds-field--info .ds-field__card                { background-color: var(--field-info-bg); }
.ds-field--info .ds-field__input               { color: var(--field-info-value); }

/* --- Focused + Filled --------------------------------------------------- */
/* User has typed something AND the field is still focused. Same chrome
   as `focused` (1.5px blue ring, radius-2 card) plus a clear-× affordance.
   Two class spellings supported so callers can use either dash or
   underscore (the CSS token uses underscore). */
.ds-field--focused-filled .ds-field__ring,
.ds-field--focused_filled .ds-field__ring     { border-color: var(--field-focused_filled-border); }
.ds-field--focused-filled .ds-field__card,
.ds-field--focused_filled .ds-field__card     { background-color: var(--field-focused_filled-bg); }
.ds-field--focused-filled .ds-field__input,
.ds-field--focused_filled .ds-field__input    { color: var(--field-focused_filled-value); }

/* --- Readonly ----------------------------------------------------------- */
.ds-field--readonly .ds-field__label           { color: var(--field-readonly-label); }
.ds-field--readonly .ds-field__card            { background-color: var(--field-readonly-bg); }
.ds-field--readonly .ds-field__input           { color: var(--field-readonly-value); cursor: default; }

/* --- Disabled ----------------------------------------------------------- */
/* Don't apply a global opacity — Figma dims disabled fields purely by
   token colour (blackHaze-300 label, blackHaze-200 placeholder). Adding
   opacity on top makes the field "double-dim" and harder to read. */
.ds-field--disabled .ds-field__label           { color: var(--field-disabled-label); }
.ds-field--disabled .ds-field__card            { background-color: var(--field-disabled-bg); cursor: not-allowed; }
.ds-field--disabled .ds-field__input           { color: var(--field-disabled-value); cursor: not-allowed; }


/* Inline status message under a field (FieldMessage — components/field-message.md).
   Matches the Figma WorkplaceTextField below-field message: a boxed alert
   (padding 16px + radius 4px) coloured per kind. Outer field already has
   2px breathing room from the ring padding, so the message sits flush
   against the input box visually.

   In Figma the message rendered for `--default`/`help` text has no
   background (transparent) — only error/warning/info/success show the
   coloured tint. */
.ds-field__message {
  display: flex;
  align-items: center;
  gap: var(--space-3); /* 12px between icon and text (Figma --spacing/3) */
  padding: var(--space-4); /* 16px Figma --sds-size-space-400 */
  border-radius: var(--radius-4);
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-14);
  line-height: var(--line-default);
  color: var(--text-placeholder);
  margin: 0;
  background: var(--value-transparent);
}
.ds-field__message--error {
  background-color: var(--feedback-error-bg);
  color: var(--feedback-error-message);
}
.ds-field__message--warning {
  background-color: var(--feedback-warning-bg);
  color: var(--feedback-warning-message);
}
.ds-field__message--success {
  background-color: var(--feedback-success-bg);
  color: var(--feedback-success-message);
}
.ds-field__message--info {
  background-color: var(--feedback-info-bg);
  color: var(--feedback-info-message);
}


/* ============================================================================
   DROPDOWN — custom select with search + options panel
   Figma node 2318:4017 (SubSpecialtyDropdownField)

   Re-uses the .ds-field__ring + .ds-field__card geometry, then adds:
   - .ds-dropdown__trigger  — clickable wrapper around the ring (cursor:
                               pointer + opens the panel on click via JS)
   - .ds-dropdown__row      — overrides .ds-field__row to use
                               justify-content: space-between so the
                               chevron sits on one edge and the
                               value+icon group on the other.
   - .ds-dropdown__panel    — floating white card below the trigger
                               (absolute positioning, z-index dropdown).
   - .ds-dropdown__option   — each row in the options list (h-48,
                               clickable, hover/selected states).
   ============================================================================ */

.ds-dropdown {
  position: relative; /* anchor for the floating panel */
}

/* Hidden input that carries the form value — visually gone. */
.ds-dropdown > input[type="hidden"] {
  display: none;
}

/* Trigger wraps the ring. Makes the whole card clickable + focusable. */
.ds-dropdown__trigger {
  cursor: pointer;
  user-select: none;
}
.ds-dropdown__trigger:focus-visible {
  border-color: var(--field-focused-border);
}
.ds-dropdown__trigger[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: var(--opacity-60);
}

/* Row layout: chevron on one edge, value+icon on the other. Figma uses
   `justify-content: space-between` so the row stretches to the card width
   regardless of value text length. */
.ds-dropdown__row {
  justify-content: space-between;
  width: 100%;
}

/* Chevron — 24x24. Rotates 180° when the panel is open so the V flips up. */
.ds-dropdown__chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size-24);
  height: var(--icon-size-24);
  flex-shrink: 0;
  transition: transform 0.18s ease;
}
.ds-dropdown.is-open .ds-dropdown__chevron {
  transform: rotate(180deg);
}

/* Value + trailing-icon group on the leading edge (RIGHT in RTL). */
.ds-dropdown__value-group {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 8px between value text and icon (Figma --spacing/3) */
}
.ds-dropdown__value {
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-16);
  color: var(--field-default-value);
  line-height: var(--line-default);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ds-dropdown__value--placeholder {
  opacity: var(--opacity-80); /* match input::placeholder opacity */
}
.ds-dropdown__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size-24);
  height: var(--icon-size-24);
  flex-shrink: 0;
}

/* ---------------------- Floating panel ----------------------------------- */

.ds-dropdown__panel {
  position: absolute;
  top: calc(100% + var(--space-2)); /* 8px below trigger (matches Figma gap) */
  inset-inline: 0;
  z-index: var(--z-dropdown);
  background-color: var(--bg-card);
  border-radius: var(--radius-4);
  padding: var(--space-4); /* 16px */
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 12px between search, divider, options (Figma --sds-size-space-300) */
  /* Figma uses two layered drop-shadows for depth — first soft, then
     deeper for elevation. */
  box-shadow:
    0 6px 6px color-mix(in srgb, var(--color-blackHaze-1000) 6%, transparent),
    0 12px 12px color-mix(in srgb, var(--color-blackHaze-1000) 12%, transparent);
}
.ds-dropdown__panel[hidden] {
  display: none;
}

/* ---------------------- Search input inside panel ------------------------ */

/* Outer ring (1.5px blue border) — same focus-style chrome the input
   itself shows in the field. The search field is "always focused" in the
   Figma open state. */
.ds-dropdown__search-ring {
  border: var(--stroke-1_5) solid var(--field-focused-border);
  border-radius: var(--radius-2);
  padding: var(--space-0_5); /* 2px outer ring padding */
}
.ds-dropdown__search-row {
  display: flex;
  align-items: center;
  /* No space-between: we want search-icon + input adjacent on the
     leading edge (RIGHT in RTL), × pushed to the trailing edge. */
  height: 2.5rem; /* 40px — Figma h-[40px] */
  padding: 0 var(--space-4); /* 16px horizontal */
  background-color: var(--field-default-bg);
  gap: var(--space-2);
}
.ds-dropdown__search-clear {
  /* Hidden by default. Sibling-selector below reveals it as soon as
     the user has typed something into the input
     (`:not(:placeholder-shown)` matches an input whose own placeholder
     is no longer visible — i.e. it carries a value). */
  display: none;
  width: var(--icon-size-20);
  height: var(--icon-size-20);
  cursor: pointer;
  flex-shrink: 0;
  /* Push the × to the far end (LEFT in RTL) regardless of how wide
     the typed text becomes. */
  margin-inline-start: auto;
}
.ds-dropdown__search-input:not(:placeholder-shown) ~ .ds-dropdown__search-clear {
  display: inline-flex;
}
.ds-dropdown__search-input {
  /* Size to content (not flex-grow) so the placeholder/text sits
     directly adjacent to the leading search icon. The whole row is
     still click-target via the surrounding ring (input itself is
     small but the input expands as the user types via auto-grow on
     `min-width: 0`). */
  flex: 0 1 auto;
  min-width: 0;
  background: var(--value-transparent);
  border: var(--value-none);
  outline: var(--value-none);
  padding: 0;
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-16);
  color: var(--field-default-value);
  text-align: start; /* RIGHT in RTL — adjacent to the leading icon */
}
.ds-dropdown__search-input::placeholder {
  color: var(--field-default-placeholder);
  opacity: var(--opacity-80);
}
.ds-dropdown__search-icon {
  display: inline-flex;
  width: var(--icon-size-20);
  height: var(--icon-size-20);
  flex-shrink: 0;
}

/* Divider line between search and options. Figma uses blue-800 at 8% alpha. */
.ds-dropdown__divider {
  height: 1px;
  background-color: var(--color-blue-800);
  opacity: 0.08;
  border-radius: var(--radius-4); /* token-only: system uses 8/4/2/0 */
  margin: 0 var(--space-4); /* 16px horizontal indent like Figma */
}

/* ---------------------- Options list ------------------------------------- */

.ds-dropdown__options {
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 12px between options (Figma --spacing/4) */
}

.ds-dropdown__option {
  /* Reset button styles — keep keyboard accessibility. */
  appearance: none;
  background: var(--value-transparent);
  border: var(--value-none);
  cursor: pointer;
  font: inherit;
  text-align: inherit;
  width: 100%;

  display: flex;
  align-items: center;
  /* `flex-start` packs items at the START of the main axis. In RTL
     that's the RIGHT edge — so the badge (first DOM child) sits at
     far right and the text follows directly to its left, separated
     only by `gap`. NOT `space-between` (which would push them to
     opposite edges with empty space in the middle). */
  justify-content: flex-start;
  gap: var(--space-3);
  height: 3rem; /* 48px — Figma h-[48px] */
  padding: var(--space-2) var(--space-4); /* 8px vertical, 16px horizontal */
  border-radius: var(--radius-2);
  color: var(--color-blue-900); /* Figma uses blue-900 for option text */
  transition: background-color 0.12s ease;
}
.ds-dropdown__option:hover,
.ds-dropdown__option:focus-visible {
  background-color: var(--color-blue-50);
  outline: var(--value-none);
}

/* Selected (active) row — Figma node 2321:5189. Uniform blue chrome
   regardless of the per-status palette: the row swaps to blue-50
   background and the label becomes Semi-Bold blue-600. `!important`
   is required to beat the inline `style="color: …"` that carries the
   per-status text colour in the unselected state (Figma node 2321:5198). */
.ds-dropdown__option--selected {
  background-color: var(--color-blue-50);
}
.ds-dropdown__option--selected .ds-dropdown__option-text {
  font-family: var(--font-activist-semibold) !important;
  color: var(--color-blue-600) !important;
}

.ds-dropdown__option-text {
  /* Size to content (don't grow) so the text sits directly adjacent
     to the badge instead of being pushed to the far edge. */
  flex: 0 1 auto;
  min-width: 0;
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-16);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Icon badge: blue-50 square with the icon inside. Each option in the
   Figma design carries its own small "tag" — gives the list visual
   rhythm and matches the field's leading-icon style. */
.ds-dropdown__option-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem; /* 28px — 20px icon + 4px padding each side */
  height: 1.75rem;
  border-radius: var(--radius-2);
  background-color: var(--color-blue-50);
  flex-shrink: 0;
}

/* ---------------------- Status swatch ----------------------------------
   When the caller provides `swatch="<css color>"` on an option (or
   "all" for the multi-colour aggregate), we render a solid coloured
   square INSTEAD of the icon badge. Used by the doctors-list status
   filter where each status carries the same colour as its
   `ds_doctor_status_badge` (success=green, error=red, …) and the
   "All" option pies all five colours together.
*/
/* Both option-swatch and trigger swatch are 24x24 per the user spec.
   Colours come from the Core.Color palette tokens (blue/green/pink/
   cerulean/brightSun/blackHaze/radicalRed) defined at the top of this
   file — so the swatch palette stays in lock-step with the rest of the
   design-system tokens. `inline-flex` so a centred ::after pseudo can
   host the "selected" tick glyph (see selected-state overrides below). */
.ds-dropdown__option-swatch,
.ds-dropdown__icon--swatch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size-24);   /* 24px */
  height: var(--icon-size-24);  /* 24px */
  border-radius: var(--radius-2);
  flex-shrink: 0;
  /* Inset 1px border in body colour for a subtle outline that reads
     against both the white panel and the blue-50 hover background. */
  box-shadow: inset 0 0 0 var(--stroke-1) var(--border-divider);
}

/* Selected option — the marker (swatch OR icon-badge) flips to a
   saturated blue-600 fill with its glyph rendered in blue-50. Mirrors
   Figma node 2321:5189: the active row's leading badge inverts colour.
   `background` shorthand wins over the inline `background-color` AND
   clears the conic-gradient that the `--all` variant ships with.
   For the badge case we ALSO override the inline `background-color`
   that `ds_icon`'s mask span sets, hence `!important` on the inner rule. */

/* --- 1) Swatch variant (used by status dropdown; solid colour squares) --- */
.ds-dropdown__option--selected .ds-dropdown__option-swatch {
  background: var(--color-blue-600) !important;
  box-shadow: var(--value-none);
}
.ds-dropdown__option--selected .ds-dropdown__option-swatch::after {
  content: "";
  display: block;
  width: var(--icon-size-16);
  height: var(--icon-size-16);
  background-color: var(--color-blue-50);
  -webkit-mask: url("/static/icons/tick-02.svg") center / contain no-repeat;
          mask: url("/static/icons/tick-02.svg") center / contain no-repeat;
}

/* --- 2) Icon-badge variant (used by date dropdown — clock icon inside
   blue-50 square). Selected → badge becomes blue-600, icon recolours
   to blue-50 by overriding the mask-span's inline background-color. --- */
.ds-dropdown__option--selected .ds-dropdown__option-badge {
  background-color: var(--color-blue-600);
}
.ds-dropdown__option--selected .ds-dropdown__option-badge .ds-icon-mask {
  background-color: var(--color-blue-50) !important;
}

/* "All" — split the square into five wedges, one per status. Conic
   gradient gives a tight pie-chart look. Colours map 1:1 to the
   solid swatch each individual status uses (Core.Color -500 level). */
.ds-dropdown__option-swatch--all,
.ds-dropdown__icon--swatch--all {
  background: conic-gradient(
    var(--color-blackHaze-400)    0deg  72deg,   /* pending      */
    var(--color-cerulean-500)     72deg 144deg,  /* under_review */
    var(--color-green-500)       144deg 216deg,  /* approved     */
    var(--color-radicalRed-500)  216deg 288deg,  /* rejected     */
    var(--color-brightSun-500)   288deg 360deg   /* needs_edit   */
  );
}

.ds-dropdown__no-match {
  text-align: center;
  color: var(--text-onCard-secondary);
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-14);
  padding: var(--space-4) 0;
  margin: 0;
}
.ds-dropdown__no-match[hidden] { display: none; }


/* ============================================================================
   CARD — surface for forms, lists, summaries
   ============================================================================
*/
.ds-card {
  background-color: var(--bg-card);
  border-radius: var(--radius-8);
  padding: var(--card-padding);
  box-shadow: 0 0.0625rem 0.125rem 0 color-mix(in srgb, var(--color-blackHaze-1000) 2%, transparent);
}

.ds-card__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-18);
  color: var(--text-onCard-primary);
  margin: 0 0 var(--space-4);
}


/* ============================================================================
   ALERT — components/alert.md
   ============================================================================
*/
.ds-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-4);
  border-width: var(--stroke-1);
  border-style: solid;
}
.ds-alert__icon { flex-shrink: 0; line-height: 0; }
.ds-alert__body { flex: 1 1 auto; min-width: 0; }
.ds-alert__title {
  margin: 0;
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14);
  line-height: var(--line-default);
}
.ds-alert__desc {
  margin: var(--space-1) 0 0;
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-12);
  line-height: var(--line-default);
}
.ds-alert__dismiss {
  flex-shrink: 0;
  background: var(--value-transparent);
  border: var(--value-none);
  padding: 0;
  cursor: pointer;
  line-height: 0;
  opacity: var(--opacity-80);
  transition: opacity 0.15s ease;
}
.ds-alert__dismiss:hover { opacity: var(--opacity-100); }


/* ============================================================================
   BADGE — status pill
   ============================================================================
*/
.ds-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  /* Nested-radius rule: container card uses --radius-8, so two levels
     inside (table row → status pill) drops to --radius-2. Keeps the
     8 → 4 → 2 → 0 inward cadence consistent across the panel. */
  border-radius: var(--radius-2);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  line-height: 1;
  white-space: nowrap;
}


/* ============================================================================
   GLOBAL — keep the page from ever scrolling horizontally on small screens.
   Specific containers (.ds-table-wrap, etc.) own their own horizontal
   scroll; the page itself shouldn't shift sideways when one element
   overflows.
   ============================================================================
*/
html,
body {
  max-width: 100%;
  overflow-x: hidden;
}
/* Flex parents in `templates/base.html` (`#main-content` is `flex flex-col`,
   `<main>` is `flex-1`) default to `min-width: auto` on the cross axis,
   meaning they grow to fit the widest child. A wide table inside main
   would then drag the whole page wider than the viewport. Setting
   `min-width: 0` lets these containers stay viewport-bound and forces
   any overflow handling onto the table wrapper itself. */
#main-content,
#main-content > main {
  min-width: 0;
}

/* ============================================================================
   TABLE — wrapper for the panel's lists
   ============================================================================
*/
.ds-table-wrap {
  background-color: var(--bg-card);
  border-radius: var(--radius-8);
  /* Horizontal scroll when the table overflows the viewport (mobile).
     Vertical hidden keeps the rounded corners clipping the top/bottom
     edges of the table content. iOS gets momentum scrolling.
     `width: 100%` + `max-width: 100%` pin the wrapper to its parent
     so the inner <table>'s `min-width: 36rem` (mobile) overflows
     INSIDE the wrapper instead of pushing the wrapper itself wider
     than the viewport. Without these, flex parents (`<main class="flex-1">`)
     would grow to fit the table and the whole page would scroll
     horizontally — leaving the wrapper's `overflow-x: auto` dormant. */
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  box-shadow: 0 0.0625rem 0.125rem 0 color-mix(in srgb, var(--color-blackHaze-1000) 2%, transparent);
}
.ds-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-14);
}
/* Below the desktop sidebar breakpoint, force a comfortable minimum so
   tables don't squash into illegible columns on narrow phones — the
   wrapper above scrolls instead. 36rem ≈ 576px covers every panel
   list (4–7 columns); anything wider just scrolls farther. */
@media (max-width: 767px) {
  .ds-table {
    min-width: 36rem;
  }
}

/* Doctor detail page — two-column issues + preview layout. Below
   ~60rem (≈ 960px) the preview pane is too narrow to be useful, so
   we stack: issues on top, preview underneath. */
@media (max-width: 959px) {
  .ds-doctor-detail-grid {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}
.ds-table thead th {
  padding: var(--space-3) var(--space-4);
  text-align: start;
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  color: var(--text-label);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-block-end: var(--stroke-1) solid var(--border-divider);
  background-color: var(--bg-card);
}
.ds-table tbody td {
  padding: var(--space-3) var(--space-4);
  color: var(--text-onCard-primary);
  border-block-end: var(--stroke-1) solid var(--border-divider);
  vertical-align: middle;
}
.ds-table tbody tr:last-child td {
  border-block-end: var(--value-none);
}
.ds-table tbody tr:hover {
  background-color: var(--color-blackHaze-50);
}
.ds-table__cell--secondary { color: var(--text-onCard-secondary); }
.ds-table__cell--primary   { color: var(--text-onCard-primary); font-family: var(--font-activist-semibold); }
.ds-table__empty {
  padding: var(--space-8) var(--space-4);
  text-align: center;
  color: var(--text-placeholder);
}


/* ============================================================================
   PAGE HEADER
   ============================================================================
*/
.ds-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}
.ds-page-header__title-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.ds-page-header__title {
  margin: 0;
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-28);
  color: var(--text-onPage-primary);
  line-height: var(--line-default);
}
.ds-page-header__crumbs {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-12);
  color: var(--text-placeholder);
  flex-wrap: wrap;
}
.ds-page-header__crumb-link {
  color: var(--text-link);
  font-family: var(--font-activist-semibold);
  text-decoration: none;
}
.ds-page-header__crumb-current {
  color: var(--text-onPage-primary);
  font-family: var(--font-activist-semibold);
}
.ds-page-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}


/* ============================================================================
   CHECKBOX
   ============================================================================
*/
.ds-checkbox {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
}
.ds-checkbox__input {
  width: 1rem;
  height: 1rem;
  margin-top: 0.125rem;
  accent-color: var(--brand-primary);
  flex-shrink: 0;
  cursor: inherit;
}
.ds-checkbox__label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-14);
  color: var(--text-onCard-primary);
}
.ds-checkbox__label-text {
  font-family: var(--font-activist-semibold);
}
.ds-checkbox__help {
  font-size: var(--type-ar-12);
  color: var(--text-placeholder);
}
.ds-checkbox--disabled { cursor: not-allowed; opacity: var(--opacity-60); }


/* ============================================================================
   SHELL LAYOUT — Sidebar + Topbar  (panel-redesign 2026-05-12)
   ============================================================================
   These styles refine the admin panel chrome to mirror the Activist-family
   visual rhythm of the doctor-facing FE (login-page project). The structural
   IDs `#sidebar`, `#sidebar-overlay`, `#sidebar-toggle` and the class hook
   `sidebar-open` are PRESERVED — they back panel.js's mobile-toggle logic.
   The dimension tokens `--sidebar-width`, `--topbar-height` are PRESERVED —
   base.html's main-content offset reads them.
*/

/* --- Sidebar shell ----------------------------------------------------- */
.ds-sidebar {
  /* layout + chrome — `position: fixed` + dimensions are still applied
     by base.html / sidebar.html inline so the transform animation keeps
     working in tandem with the mobile-toggle class swap. */
  display: flex;
  flex-direction: column;
  background-color: var(--bg-sidebar);
  border-inline-end: var(--stroke-1) solid var(--border-divider);
}

.ds-sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-inline: var(--space-5);
  height: var(--topbar-height);
  border-block-end: var(--stroke-1) solid var(--border-divider);
}
.ds-sidebar__brand-logo {
  width: 1.75rem;
  height: 2.4rem;
  flex-shrink: 0;
  display: block;
}
.ds-sidebar__brand-text {
  display: flex;
  flex-direction: column;
  gap: 0.075rem;
  min-width: 0;
  line-height: 1;
}
.ds-sidebar__brand-name {
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-18);
  color: var(--brand-primary);
  line-height: 1;
}
.ds-sidebar__brand-sub {
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-12);
  color: var(--text-placeholder);
  line-height: 1;
}

.ds-sidebar__nav {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--space-4) var(--space-3);
  scrollbar-width: thin;
  scrollbar-color: var(--color-blackHaze-200) var(--value-transparent);
}
.ds-sidebar__nav::-webkit-scrollbar { width: 0.375rem; }
.ds-sidebar__nav::-webkit-scrollbar-thumb {
  background: var(--color-blackHaze-200);
  border-radius: var(--radius-4);
}

.ds-sidebar__nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.ds-sidebar__section-heading {
  margin-block-start: var(--space-5);
  margin-block-end: var(--space-1);
  padding-inline: var(--space-3);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  color: var(--text-placeholder);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1.2;
}
/* First section heading shouldn't push down — overrides the top margin. */
.ds-sidebar__section-heading:first-child {
  margin-block-start: 0;
}

.ds-sidebar__footer {
  border-block-start: var(--stroke-1) solid var(--border-divider);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-0_5);
}

/* --- Side link (every sidebar row, nav + footer) ----------------------- */
.ds-side-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0.625rem var(--space-3);
  border-radius: var(--radius-8);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14);
  color: var(--menu-action-default-text);  /* blue-900 — DS AccountMenu token */
  text-decoration: none;
  line-height: 1;
  transition:
    background-color 0.18s ease,
    color 0.18s ease,
    transform 0.18s ease;
  position: relative;
}
.ds-side-link__icon {
  flex-shrink: 0;
  width: var(--icon-size-20);
  height: var(--icon-size-20);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--menu-action-default-icon);   /* blue-600 */
}
.ds-side-link__icon svg { width: 100%; height: 100%; }
.ds-side-link__label { min-width: 0; flex: 1 1 auto; }

.ds-side-link:hover:not(.ds-side-link--active):not(.ds-side-link--danger) {
  background-color: var(--menu-action-hover-bg);   /* blue-50 */
}
.ds-side-link:active:not(.ds-side-link--active):not(.ds-side-link--danger) {
  background-color: var(--menu-action-pressed-bg); /* blue-100 */
}
.ds-side-link:focus-visible {
  outline: none;
  background-color: var(--menu-action-focus-bg);
  box-shadow: inset 0 0 0 var(--stroke-1_5) var(--menu-action-focus-border);
}

.ds-side-link--active {
  background-color: var(--menu-action-selected-bg);  /* blue-100 */
  color: var(--menu-action-selected-text);           /* blue-800 */
}
.ds-side-link--active .ds-side-link__icon { color: var(--brand-primary); }

.ds-side-link--danger {
  color: var(--menu-logout-default-text);            /* radicalRed-500 */
}
.ds-side-link--danger .ds-side-link__icon {
  color: var(--menu-logout-default-icon);
}
.ds-side-link--danger:hover {
  background-color: var(--menu-logout-hover-bg);     /* radicalRed-50 */
}
.ds-side-link--danger:active {
  background-color: var(--menu-logout-pressed-bg);   /* radicalRed-100 */
}

/* --- Topbar shell ------------------------------------------------------ */
.ds-topbar {
  background-color: var(--bg-card);
  border-block-end: var(--stroke-1) solid var(--border-divider);
}
.ds-topbar__title-block {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}
.ds-topbar__title {
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-16);
  color: var(--text-onCard-primary);
  line-height: 1.2;
  margin: 0;
}
.ds-topbar__subtitle {
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-12);
  color: var(--text-placeholder);
  line-height: 1.2;
}

.ds-topbar__icon-btn {
  width: 2.5rem;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-color: var(--value-transparent);
  border: var(--value-none);
  border-radius: var(--radius-4);
  color: var(--text-onCard-primary);
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.ds-topbar__icon-btn:hover { background-color: var(--color-blackHaze-50); }

/* Region badge — same blue-50 chip pattern as DS Header.lang-pill */
.ds-topbar__region {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.25rem var(--space-2);
  background-color: var(--color-blue-50);
  color: var(--brand-primary);
  border-radius: var(--radius-4);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  line-height: 1;
}

/* Locale switch — outlined chip */
.ds-topbar__lang {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.375rem var(--space-3);
  background-color: var(--value-transparent);
  color: var(--header-lang-label);
  border: var(--stroke-1) solid var(--border-divider);
  border-radius: var(--radius-4);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  line-height: 1;
  text-decoration: none;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.ds-topbar__lang:hover {
  border-color: var(--header-lang-border);
  background-color: var(--color-blue-50);
}

/* --- User avatar + dropdown (zero-JS, via <details>) ------------------- */
.ds-user-menu {
  position: relative;
}
.ds-user-menu__trigger {
  list-style: none;          /* Firefox */
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.25rem;
  padding-inline-end: var(--space-2);
  border-radius: var(--radius-8);
  border: var(--stroke-1) solid var(--value-transparent);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.ds-user-menu__trigger::-webkit-details-marker { display: none; }
.ds-user-menu__trigger::marker { display: none; }
.ds-user-menu[open] > .ds-user-menu__trigger,
.ds-user-menu__trigger:hover {
  background-color: var(--color-blue-50);
  border-color: var(--border-divider);
}
.ds-user-menu__avatar {
  width: var(--avatar-size, 2.25rem);
  height: var(--avatar-size, 2.25rem);
  border-radius: 999px;
  background-color: var(--avatar-male-bg);
  color: var(--avatar-male-icon);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-14);
  line-height: 1;
  flex-shrink: 0;
}
.ds-user-menu__name {
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14);
  color: var(--text-onCard-primary);
  line-height: 1.2;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ds-user-menu__chevron {
  width: var(--icon-size-16);
  height: var(--icon-size-16);
  color: var(--avatar-arrow-color);
  transition: transform 0.2s ease;
}
.ds-user-menu[open] .ds-user-menu__chevron { transform: rotate(180deg); }

.ds-user-menu__panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  inset-inline-end: 0;
  min-width: 14rem;
  background-color: var(--avatar-dropdown-bg);
  border-radius: var(--avatar-dropdown-radius);
  box-shadow: var(--avatar-dropdown-shadow);
  padding: var(--space-2);
  z-index: var(--z-dropdown);
  display: flex;
  flex-direction: column;
  gap: var(--space-0_5);
  animation: dsUserMenuIn 0.18s ease-out both;
}
@keyframes dsUserMenuIn {
  from { opacity: 0; transform: translateY(-0.25rem); }
  to   { opacity: 1; transform: translateY(0); }
}
.ds-user-menu__header {
  padding: var(--space-2) var(--space-3) var(--space-3);
  border-block-end: var(--stroke-1) solid var(--avatar-dropdown-divider);
  margin-block-end: var(--space-2);
}
.ds-user-menu__header-name {
  display: block;
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14);
  color: var(--text-onCard-primary);
  line-height: 1.2;
}
.ds-user-menu__header-email {
  display: block;
  margin-block-start: 0.125rem;
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-12);
  color: var(--text-placeholder);
  line-height: 1.2;
  word-break: break-all;
}

/* --- Page section header (smaller than ds-page-header — for inline use)  */
.ds-section-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-18);
  color: var(--text-onCard-primary);
  line-height: 1.2;
}
.ds-section-title__icon {
  width: var(--icon-size-20);
  height: var(--icon-size-20);
  color: var(--brand-primary);
  display: inline-flex;
}

/* --- Stat card (used by dashboard tiles) ------------------------------- */
.ds-stat-card {
  background-color: var(--bg-card);
  border-radius: var(--radius-8);
  padding: var(--space-5);
  box-shadow: 0 0.0625rem 0.125rem 0 color-mix(in srgb, var(--color-blackHaze-1000) 2%, transparent);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.ds-stat-card:hover {
  transform: translateY(-0.125rem);
  box-shadow:
    0 0.5rem 1rem 0 color-mix(in srgb, var(--color-blue-600) 4%, transparent),
    0 0.125rem 0.25rem 0 color-mix(in srgb, var(--color-blackHaze-1000) 3%, transparent);
}
.ds-stat-card__label {
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  color: var(--text-placeholder);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0;
  line-height: 1.2;
}
.ds-stat-card__value {
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-32);
  color: var(--text-onCard-primary);
  line-height: 1;
  margin: 0;
}
.ds-stat-card__accent {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-8);
  background-color: var(--color-blue-50);
  color: var(--brand-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.ds-stat-card__accent svg { width: 1.25rem; height: 1.25rem; }

/* Variants — re-tint accent tile by feedback tone */
.ds-stat-card--warning .ds-stat-card__accent {
  background-color: var(--feedback-warning-bg);
  color: var(--feedback-warning-icon);
}
.ds-stat-card--info .ds-stat-card__accent {
  background-color: var(--feedback-info-bg);
  color: var(--feedback-info-icon);
}
.ds-stat-card--success .ds-stat-card__accent {
  background-color: var(--feedback-success-bg);
  color: var(--feedback-success-icon);
}
.ds-stat-card--error .ds-stat-card__accent {
  background-color: var(--feedback-error-bg);
  color: var(--feedback-error-icon);
}

/* --- Mobile sidebar overlay tint --------------------------------------- */
#sidebar-overlay {
  /* The base.html supplies the layout (`fixed inset-0`, z-index from
     var(--z-overlay)). Just refine the visual to match the FE's dim. */
  background-color: color-mix(in srgb, var(--color-blackHaze-1000) 40%, transparent);  /* color-blackHaze-1000 @ 40% */
  backdrop-filter: blur(2px);
  transition: opacity 0.18s ease;
}

/* ============================================================================
   TOOLTIP — `[data-tip="…"]` utility
   ============================================================================
   Add `data-tip="text"` to any non-replaced element (span/button/a/div) and
   a styled bubble appears above it on hover/focus. CSS-only, zero JS, GPU
   transitions. Works in RTL and LTR — the bubble is horizontally centred
   on the host so writing-direction doesn't matter.

   - Host MUST be a non-replaced element (img can't host ::after — wrap it
     in a <span data-tip="…">).
   - Bubble = `::after` (text), arrow = `::before` (tiny rotated square).
   - Both are hidden by default and faded in via opacity transition.
   - z-index sits above table/card chrome but below modals.
*/
[data-tip] {
  position: relative;
}
[data-tip]::after,
[data-tip]::before {
  position: absolute;
  bottom: calc(100% + var(--space-2)); /* 8px gap above the host */
  left: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: var(--z-dropdown, 50);
}
[data-tip]::after {
  content: attr(data-tip);
  transform: translateX(-50%) translateY(0.25rem);
  background-color: var(--color-blackHaze-900);
  color: var(--color-white-50);
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-12);
  line-height: 1.4;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-4);
  white-space: nowrap;
  box-shadow: 0 0.25rem 0.75rem 0 color-mix(in srgb, var(--color-blackHaze-1000) 12%, transparent);
}
[data-tip]::before {
  content: "";
  width: var(--space-2);
  height: var(--space-2);
  bottom: calc(100% + var(--space-1));
  transform: translateX(-50%) rotate(45deg);
  background-color: var(--color-blackHaze-900);
}
[data-tip]:hover::after,
[data-tip]:hover::before,
[data-tip]:focus-visible::after,
[data-tip]:focus-visible::before {
  opacity: 1;
}
[data-tip]:hover::after,
[data-tip]:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  [data-tip]::after,
  [data-tip]::before {
    transition: none;
  }
}

/* Verified-doctor wrapper — small inline-flex host so the badge stays
   inline with the name AND can carry the data-tip tooltip above. */
.ds-verified-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: help;
}

/* ============================================================================
   STEP ACCORDION — per-step review card (Figma node 2621:922 "مراجعة الخطوات")
   Used by `templates/doctors/detail.html` for the per-step review cards.

   Rebuilt 2026-05-30 to match the Figma "Step review" spec across its five
   states (pending → in-review → approved → needs-changes → rejected). All
   measurements map Figma pixel values onto the project token scale BY VALUE
   (note: Figma's Spacing/N is offset one step from --space-N, e.g. Figma
   Spacing/5 = 16px = --space-4). Colours come straight from the palette /
   feedback tokens, never raw hex.

   Header anatomy (RTL: reads right → left):
       [num/state chip] [title] ...flex gap... [status pill] [toggle box]
   Chip + title sit at the start edge (right); the status pill and the +/−
   toggle box sit at the end edge (left). The native <details> marker is
   hidden; the collapsed/open glyph swap is pure CSS via [open].
   ============================================================================ */

/* ── Shell: the real selection-ring border (NOT outline/absolute) ──────────
   Figma wraps every step in an outer frame that, WHEN OPEN, paints a 2px
   blue-600 ring at radius-8 with an 8px inset gap (p-2) before the white
   card (node 2621:951). We model that with a real `border` on a wrapper so
   the ring participates in layout (occupies the 8px), exactly per the design
   — no `outline`, no `position:absolute`. Collapsed steps carry a transparent
   2px border of the same width so the card never shifts when toggled. */
.ds-step-shell {
  border-radius: var(--radius-8);
  padding: 0;
  /* The collapsed shell carries NO border so the gap between step cards equals
     the list's 16px flex gap exactly (a real transparent border used to add
     2px×2 = 4px, pushing the visible gap to 20px). The open-state selection
     ring is a box-shadow — it paints but doesn't occupy layout, so neighbours
     stay a clean 16px apart. */
  transition: box-shadow 200ms ease, padding 200ms ease;
}
.ds-step-shell:has(> details[open]) {
  padding: var(--space-2);  /* 8px gap between the ring and the inner card */
  box-shadow: 0 0 0 var(--stroke-2) var(--color-blue-600);
}

/* The card itself: .ds-card supplies bg; here we pin radius + shadow to the
   Figma step-card spec. CLOSED card = radius-8 (node 2621:938); OPEN inner
   card = radius-4 (node 2621:952) nested inside the radius-8 ring. Both carry
   the two-layer cararra-950 drop shadow (0/6/6 @6% + 0/12/12 @12%). Padding is
   zeroed inline so the summary + body own their own insets. */
.ds-step-accordion {
  border-radius: var(--radius-8);
  box-shadow:
    0 0.375rem 0.375rem color-mix(in srgb, var(--color-cararra-950) 6%, transparent),
    0 0.75rem 0.75rem  color-mix(in srgb, var(--color-cararra-950) 12%, transparent);
  /* `interpolate-size` lets the open/close height tween below animate to/from
     the `auto` keyword (Chromium 129+). Inherited down to ::details-content. */
  interpolate-size: allow-keywords;
  transition: border-radius 200ms ease, box-shadow 200ms ease;
}
.ds-step-accordion[open] {
  border-radius: var(--radius-4);
}

/* ── Smooth open / close disclosure ────────────────────────────────────
   Native <details> snaps open instantly. We animate the reveal by tweening
   the ::details-content box from block-size:0 → auto (needs the
   `interpolate-size: allow-keywords` set on the host above) with a synced
   opacity fade and a small upward settle. `content-visibility … allow-discrete`
   keeps the body painted through the collapse so the CLOSE direction animates
   too — not just open. Engines without ::details-content (Firefox / Safari
   today) simply open instantly: no layout breakage, just no tween. The whole
   block is gated behind prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  .ds-step-accordion::details-content {
    block-size: 0;
    opacity: 0;
    overflow: clip;
    transition:
      block-size 280ms cubic-bezier(0.25, 0.1, 0.25, 1),
      opacity 200ms ease,
      content-visibility 280ms allow-discrete;
  }
  .ds-step-accordion[open]::details-content {
    block-size: auto;
    opacity: 1;
  }
}

.ds-step-accordion__summary {
  list-style: none;
  /* Figma: header sits at a 20px inset (Frame 371 @ x/y 20). */
  padding: var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  cursor: pointer;
}
.ds-step-accordion__summary::-webkit-details-marker {
  display: none;
}

/* Start cluster (right in RTL): state chip + step title. */
.ds-step-accordion__lead {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
}
.ds-step-accordion__title {
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-22);
  line-height: 1.3;
  color: var(--text-onCard-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* End cluster (left in RTL): status pill + optional issue counts + toggle. */
.ds-step-accordion__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* State chip — 32px square, holds the step number (pending/in-review) or a
   verdict glyph (approved/changes/rejected). Figma node 2621:949 = radius-4. */
.ds-step-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size-32);
  height: var(--icon-size-32);
  border-radius: var(--radius-4);
  flex-shrink: 0;
  font-family: var(--font-activist-regular);
  font-size: 1.25rem; /* Figma chip numeral = 20px (no 20px type token) */
  line-height: 1;
  transition: border-radius 200ms ease;
}
/* When the step is OPEN, the number chip + toggle box tighten to radius-2
   (Figma open frame 2621:963 = radius-2; the toggle is squared to match per
   the 2026-05-30 request). `[open]` is on the inner <details>; chip + toggle
   are descendants, so this reaches them. */
.ds-step-accordion[open] .ds-step-chip,
.ds-step-accordion[open] .ds-step-accordion__toggle {
  border-radius: var(--radius-2);
}

/* Header divider — the 1px rule under the summary in an OPEN step. Figma node
   2621:967: blue-800 (#1a2db3) @ 8% opacity, inset 20px from each side (it
   spans the inner content width, not the full card). Implemented as a styled
   <div> inside the body so it lives in normal flow. */
.ds-step-divider {
  height: var(--stroke-1);
  margin-inline: var(--space-5);
  background-color: color-mix(in srgb, var(--color-blue-800) 8%, transparent);
}
.ds-step-chip__icon {
  width: var(--icon-size-24);
  height: var(--icon-size-24);
  background-color: currentColor;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-size: contain;
}

/* Status pill — bg + dot + label, all coloured per verdict family.
   Figma: padding 8/16, radius-4, 12px SemiBold label, 12px square dot. */
.ds-step-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-4);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  line-height: 1;
  white-space: nowrap;
  flex-shrink: 0;
}
.ds-step-pill__dot {
  width: 0.75rem;  /* 12px */
  height: 0.75rem;
  border-radius: var(--radius-2);
  flex-shrink: 0;
}
/* Collapsed pending pill shows "awaiting"; the open one shows "under
   review". Both labels ship in the markup; CSS picks one via [open]. */
.ds-step-accordion[open] .ds-step-pill__label--idle { display: none; }
.ds-step-accordion:not([open]) .ds-step-pill__label--active { display: none; }

/* Toggle box — 32px blue-50 square, radius-4, centred +/− glyph (blue-600).
   The glyph is the ACTUAL Figma icon (plus-sign / remove-01) rendered as a
   24px currentColor mask, not a text character — so it matches the design's
   stroke weight + cap exactly. MUST be the last child of
   .ds-step-accordion__meta so it lands at the outermost (visual-left) edge. */
.ds-step-accordion__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size-32);
  height: var(--icon-size-32);
  background-color: var(--color-blue-50);
  border-radius: var(--radius-4);
  color: var(--color-blue-600);
  flex-shrink: 0;
  user-select: none;
  transition: background-color 160ms ease, border-radius 200ms ease;
}
.ds-step-accordion__toggle::before {
  content: "";
  width: var(--icon-size-24);
  height: var(--icon-size-24);
  background-color: currentColor;
  -webkit-mask: url(/static/icons/fig-plus-sign.svg) center / contain no-repeat;
  mask: url(/static/icons/fig-plus-sign.svg) center / contain no-repeat;
}
.ds-step-accordion[open]
  > .ds-step-accordion__summary
  .ds-step-accordion__toggle::before {
  -webkit-mask-image: url(/static/icons/fig-remove-01.svg);
  mask-image: url(/static/icons/fig-remove-01.svg);
}

/* ── Per-state colour map (verdict family) ─────────────────────────────
   pending  → blue   (collapsed)  /  cerulean (open = "under review")
   approved → green   ·  changes → brightSun  ·  rejected → radicalRed */
.ds-step--pending  .ds-step-pill      { background: var(--color-blue-50);  color: var(--color-blue-950); }
.ds-step--pending  .ds-step-pill__dot { background: var(--color-blue-500); }
/* Open pending step → "under review" cerulean. `[open]` lives on the inner
   <details>, while the state class is on the shell, so we reach through it. */
.ds-step--pending:has(> details[open]) .ds-step-pill      { background: var(--color-cerulean-50);  color: var(--color-cerulean-950); }
.ds-step--pending:has(> details[open]) .ds-step-pill__dot { background: var(--color-cerulean-500); }

.ds-step--approved .ds-step-pill      { background: var(--color-green-50);  color: var(--color-green-950); }
.ds-step--approved .ds-step-pill__dot { background: var(--color-green-500); }

.ds-step--changes  .ds-step-pill      { background: var(--color-brightSun-50);  color: var(--color-brightSun-950); }
.ds-step--changes  .ds-step-pill__dot { background: var(--color-brightSun-500); }

.ds-step--rejected .ds-step-pill      { background: var(--color-radicalRed-50);  color: var(--color-radicalRed-950); }
.ds-step--rejected .ds-step-pill__dot { background: var(--color-radicalRed-500); }

/* Chip fill + glyph colour. Figma binds the -500 family tone to every state
   chip (Pink/500, Green/500, BrightSun/500); glyph is the near-white -50. */
.ds-step--pending  .ds-step-chip { background: var(--color-pink-500);       color: var(--color-pink-50); }
/* Optical centering of the step NUMBER inside the pink chip. The Activist font
   reserves ~5px descent that digits don't use (their ink sits entirely above
   the baseline), so pure flex-centering floats the numeral high and the tight
   line box looks clipped. `text-box-trim` (the same mechanism Figma uses) trims
   the line box to the cap/baseline edges, so the digit's own box is what gets
   centred — exact, no clipping. Scoped to the pending chip only (it holds the
   number); the verdict chips hold a symmetric 24px icon and stay untouched. */
.ds-step--pending  .ds-step-chip {
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}
.ds-step--approved .ds-step-chip { background: var(--color-green-500);      color: var(--color-green-50); }
.ds-step--changes  .ds-step-chip { background: var(--color-brightSun-500);  color: var(--color-brightSun-50); }
.ds-step--rejected .ds-step-chip { background: var(--color-radicalRed-500); color: var(--color-radicalRed-50); }

/* Title takes a subtle verdict tint once a step is decided (Figma: the
   approved/needs-edit titles read green-/orange-tinted near-black). */
.ds-step--approved .ds-step-accordion__title { color: var(--color-green-950); }
.ds-step--changes  .ds-step-accordion__title { color: var(--color-brightSun-950); }
.ds-step--rejected .ds-step-accordion__title { color: var(--color-radicalRed-950); }

/* ── Submitted-data field cells (Figma open card: 3-up grid of blackHaze-50
   tiles, label over value, right-aligned in RTL). ──────────────────────── */
.ds-step-fields {
  display: grid;
  /* Figma node 2623:4516: a fixed 3-up grid (3 × ~316px cells, 16px gaps).
     `minmax(0,1fr)` lets long values ellipsize instead of blowing the track
     out. Collapses to 2-up / 1-up on tablet / phone below. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin: 0;
}
@media (max-width: 900px) {
  .ds-step-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .ds-step-fields { grid-template-columns: 1fr; }
}
.ds-step-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background-color: var(--color-blackHaze-50);
  border-radius: var(--radius-2);
  min-width: 0;
}
.ds-step-field__label {
  margin: 0;
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14);
  line-height: 1;
  color: var(--color-blackHaze-950);
  opacity: var(--opacity-70);
}
.ds-step-field__value {
  margin: 0;
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-16);
  line-height: 1.3;
  color: var(--color-blackHaze-1000);
  word-break: break-word;
}
.ds-step-field__value--empty {
  /* Figma node 2623:4500 ("لم يدخل"): Regular weight (via the font family —
     no numeric font-weight), blackHaze-1000 @ 40% opacity — NOT italic. */
  font-family: var(--font-activist-regular);
  color: var(--color-blackHaze-1000);
  opacity: var(--opacity-40);
}

/* ── Field states: note / approved ─────────────────────────────────────
   Figma nodes 2641:5216 (note) + 2633:5046 (approved). The cell keeps the
   blackHaze-50 bg + radius-2, but a 20px status icon joins at the far LEFT
   and the value text recolours to the verdict family. Layout becomes
   row + space-between so the label/value stack stays at the start (right
   in RTL) and the icon pins to the end (left). */
.ds-step-field--note,
.ds-step-field--approved {
  /* row-reverse so the status icon pins to the LEFT and the label/value stack
     sits on the RIGHT (flush against the cell's right edge) — matching Figma
     nodes 2641:5216 / 2633:5046. Plain `row` on an RTL page put the icon on
     the right and the text on the left, which was backwards. */
  flex-direction: row-reverse;
  align-items: flex-start;
  justify-content: space-between;
}
/* The label/value stack regains its column flow inside the row. The status
   icon is a direct child (mask-driven, currentColor). */
.ds-step-field--note > .ds-step-field__body,
.ds-step-field--approved > .ds-step-field__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  /* RTL: flex-start = right edge; text-align start = right. Both pin the
     label/value to the right so the Arabic text reads flush-right. */
  align-items: flex-start;
  text-align: start;
}
.ds-step-field__status {
  width: var(--icon-size-20);
  height: var(--icon-size-20);
  flex-shrink: 0;
  background-color: currentColor;
  -webkit-mask: center / contain no-repeat;
  mask: center / contain no-repeat;
}
.ds-step-field--note   .ds-step-field__status {
  color: var(--color-brightSun-600);
  -webkit-mask-image: url(/static/icons/fig-alert-circle.svg);
  mask-image: url(/static/icons/fig-alert-circle.svg);
}
.ds-step-field--approved .ds-step-field__status {
  color: var(--color-green-600);
  -webkit-mask-image: url(/static/icons/fig-check.svg);
  mask-image: url(/static/icons/fig-check.svg);
}
/* Value recolour per state (Figma: note → brightSun-950, approved → green-950). */
.ds-step-field--note   .ds-step-field__value { color: var(--color-brightSun-950); }
.ds-step-field--approved .ds-step-field__value { color: var(--color-green-950); }

/* ── Needs-edit (changes_requested) step: de-emphasise every field that is NOT
   flagged for editing, so the orange "needs changes" cells read as the focus
   (Figma node 2641:5141). Non-flagged labels drop to 40% and their values to
   20%; the settled green check stays full-colour but grows to 24px. The
   flagged `.ds-step-field--note` cells keep full prominence. ── */
.ds-step--changes .ds-step-field:not(.ds-step-field--note) .ds-step-field__label {
  opacity: var(--opacity-40);
}
.ds-step--changes .ds-step-field--approved .ds-step-field__value {
  opacity: var(--opacity-20);
}
.ds-step--changes .ds-step-field__value--empty {
  opacity: var(--opacity-20);
}
.ds-step--changes .ds-step-field--approved .ds-step-field__status {
  width: var(--icon-size-24);
  height: var(--icon-size-24);
}

/* ── Decision-bar action buttons (Figma node 2621:969) ─────────────────────
   panel-shell.css gives every .ds-btn a "premium" treatment — gradient fill,
   inset white highlight, layered shadows, 9/18 padding, 8px inner radius — all
   with !important. The Figma decision-bar buttons are the opposite: a FLAT
   fill, 12/24 padding, 4px radius, and a single two-layer drop-shadow tinted
   to the fill family. So these overrides are scoped to `.ds-step-actions` (the
   doctor-review action row only) and carry !important to win over panel-shell.

   The canvas tints the shadow with the raw fill (#00b48d / #dd7302); per the
   "shades from the design system, not raw hex" decision we mix from the token
   of the same family. Blur/offset map 1:1: 0/6/6 @ 6% + 0/12/12 @ 8%
   (0.375rem = 6px, 0.75rem = 12px). Warning sits on brightSun-600 to match the
   design (panel-shell had it on -500). */
.ds-step-actions .ds-btn--success .ds-btn__inner,
.ds-step-actions .ds-btn--warning .ds-btn__inner {
  padding: var(--space-3) var(--space-6) !important;   /* 12 / 24 */
  min-height: 0 !important;
  border-radius: var(--radius-4) !important;
}
.ds-step-actions .ds-btn--success .ds-btn__inner {
  background: var(--color-green-600) !important;
  color: var(--color-green-50) !important;
  box-shadow:
    0 0.375rem 0.375rem color-mix(in srgb, var(--color-green-600) 6%, transparent),
    0 0.75rem  0.75rem  color-mix(in srgb, var(--color-green-600) 8%, transparent) !important;
}
.ds-step-actions .ds-btn--success:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  background: var(--color-green-500) !important;
  box-shadow:
    0 0.375rem 0.375rem color-mix(in srgb, var(--color-green-600) 8%, transparent),
    0 0.75rem  0.75rem  color-mix(in srgb, var(--color-green-600) 12%, transparent) !important;
}
.ds-step-actions .ds-btn--success:disabled .ds-btn__inner,
.ds-step-actions .ds-btn--success[aria-disabled="true"] .ds-btn__inner {
  background: var(--color-green-600) !important;
  box-shadow: none !important;
  opacity: var(--opacity-40);
}
.ds-step-actions .ds-btn--warning .ds-btn__inner {
  background: var(--color-brightSun-600) !important;
  color: var(--color-brightSun-50) !important;
  box-shadow:
    0 0.375rem 0.375rem color-mix(in srgb, var(--color-brightSun-600) 6%, transparent),
    0 0.75rem  0.75rem  color-mix(in srgb, var(--color-brightSun-600) 8%, transparent) !important;
}
.ds-step-actions .ds-btn--warning:hover:not(:disabled):not([aria-disabled="true"]) .ds-btn__inner {
  background: var(--color-brightSun-700) !important;
  box-shadow:
    0 0.375rem 0.375rem color-mix(in srgb, var(--color-brightSun-600) 8%, transparent),
    0 0.75rem  0.75rem  color-mix(in srgb, var(--color-brightSun-600) 12%, transparent) !important;
}

/* ── "Add note" button — Figma node 2648:5395 ──────────────────────────────
   A soft gold outlined pill that sits at the START edge (right in RTL) of the
   decision-bar action row, opposite the approve / request-changes cluster.
   Three nested boxes mirror the design's three frames exactly:
     · .ds-note-btn        → 2px transparent pad (focus-ring spacer, like .ds-btn)
     · .ds-note-btn__ring  → 1px gold-600 border, radius-4, 2px inner pad
     · .ds-note-btn__inner → gold-50 fill, radius-2, 8/16 padding,
                              12px SemiBold gold-950 label + 16px note-add icon
   The gold/* family isn't in the generated Tailwind palette, so the three
   tones are declared here (values straight from the Figma variables). */
:root {
  --color-gold-50:  #ffffe7;
  --color-gold-600: #d19d00;
  --color-gold-950: #442504;
}
.ds-note-btn {
  display: inline-flex;
  padding: var(--space-0_5);
  margin: 0;
  border: none;
  background: transparent;
  border-radius: var(--radius-4);
  cursor: pointer;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.15s ease;
}
.ds-note-btn:hover  { transform: translateY(-0.0625rem); }
.ds-note-btn:active { transform: translateY(0.0625rem); }
.ds-note-btn:focus-visible { outline: none; }
.ds-note-btn__ring {
  display: inline-flex;
  padding: var(--space-0_5);
  /* 1px gold border via INSET shadow, not `border`: Figma draws the stroke
     inside the 36px ring frame (inside-stroke), so a real border — which grows
     an auto-height box by 2px — would push the pill to 42px instead of 40px. */
  box-shadow: inset 0 0 0 var(--stroke-1) var(--color-gold-600);
  border-radius: var(--radius-4);
  transition: box-shadow 0.2s ease;
}
.ds-note-btn:focus-visible .ds-note-btn__ring { box-shadow: inset 0 0 0 var(--stroke-1) var(--color-gold-950); }
.ds-note-btn__inner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--color-gold-50);
  border-radius: var(--radius-2);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  line-height: 1;
  color: var(--color-gold-950);
  white-space: nowrap;
  transition: background-color 0.2s ease;
}
.ds-note-btn:hover .ds-note-btn__inner {
  background: color-mix(in srgb, var(--color-gold-600) 10%, var(--color-gold-50));
}
.ds-note-btn__icon {
  width: var(--icon-size-16);
  height: var(--icon-size-16);
  flex-shrink: 0;
  /* Figma node 2648:5388: the note-add glyph is gold-600 (#d19d00) — a brighter
     tone than the gold-950 label, so it's NOT currentColor. */
  background-color: var(--color-gold-600);
  -webkit-mask: url(/static/icons/fig-note-add.svg) center / contain no-repeat;
  mask: url(/static/icons/fig-note-add.svg) center / contain no-repeat;
}

/* ============================================================================
   FILE-ACTIONS SECTION — Figma node 2654:5517 ("إجراءات الملف")
   A titled white card holding a right-aligned row of pill buttons: three blue
   (primary-outline) + one gold. The pill shares the "add note" button shape.
   ============================================================================ */
.ds-file-actions__title {
  margin: 0 0 var(--space-5);     /* 20px gap to the card (Figma section gap-20) */
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-18);   /* 18px */
  line-height: 1.2;
  color: var(--text-onPage-primary);
  text-align: start;              /* right in RTL */
}
.ds-file-actions__card {
  background: var(--bg-card);
  border-radius: var(--radius-8);
  padding: var(--space-5);        /* 20px */
  box-shadow:
    0 0.375rem 0.375rem color-mix(in srgb, var(--color-cararra-950) 6%, transparent),
    0 0.75rem  0.75rem  color-mix(in srgb, var(--color-cararra-950) 12%, transparent);
}
.ds-file-actions__row {
  display: flex;
  /* Same proven recipe as the header stat row: row-reverse + flex-end keeps the
     buttons clustered on the RIGHT (start) with the mock's left-to-right order
     (audit … note) preserved on this RTL page. */
  flex-direction: row-reverse;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-3);            /* 12px */
  flex-wrap: wrap;
}

/* ── Pill button (shared shape) ──────────────────────────────────────────────
   Colour comes from the --pill-* custom props the variant sets; the icon mask
   is set per-instance inline. Same anatomy as `.ds-note-btn`. */
.ds-pill {
  display: inline-flex;
  padding: var(--space-0_5);      /* 2px */
  margin: 0;
  border: none;
  background: transparent;
  border-radius: var(--radius-4);
  cursor: pointer;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.15s ease;
}
.ds-pill:hover  { transform: translateY(-0.0625rem); }
.ds-pill:active { transform: translateY(0.0625rem); }
.ds-pill:focus-visible { outline: none; }
.ds-pill__ring {
  display: inline-flex;
  padding: var(--space-0_5);      /* 2px */
  box-shadow: inset 0 0 0 var(--stroke-1) var(--pill-border);
  border-radius: var(--radius-4);
}
.ds-pill__inner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);            /* 8px */
  padding: var(--space-2) var(--space-4);  /* 8 / 16 */
  background: var(--pill-bg);
  border-radius: var(--radius-2);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);   /* 12px */
  line-height: 1;
  color: var(--pill-text);
  white-space: nowrap;
  transition: background-color 0.2s ease;
}
.ds-pill:hover .ds-pill__inner {
  background: color-mix(in srgb, var(--pill-border) 10%, var(--pill-bg));
}
.ds-pill__icon {
  width: var(--icon-size-16);     /* 16px */
  height: var(--icon-size-16);
  flex-shrink: 0;
  background-color: var(--pill-icon);
  -webkit-mask: center / contain no-repeat;
  mask: center / contain no-repeat;
}
.ds-pill--blue {
  --pill-border: var(--color-blue-600);
  --pill-bg:     var(--color-blue-50);
  --pill-text:   var(--color-blue-600);
  --pill-icon:   var(--color-blue-600);
}
.ds-pill--gold {
  --pill-border: var(--color-gold-600);
  --pill-bg:     var(--color-gold-50);
  --pill-text:   var(--color-gold-950);
  --pill-icon:   var(--color-gold-600);
}

/* ============================================================================
   DOCTOR HEADER CARD — Figma node 2621:923
   Top-of-page identity card. Two rows separated by a hairline:
     row 1  [status pill][note badge] ……… [file# / name / email][photo]
     row 2  ……………………………… [gender][phone][nationality][submitted]
   RTL: the badges + stat tiles read from the right. Card shadow + radius match
   the open-step card (cararra-950 6%/12%, radius-8). All measurements map the
   Figma pixel values onto the token scale by value.
   ============================================================================ */
.ds-doc-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);          /* 20px */
  padding: var(--space-5);      /* 20px */
  background: var(--bg-card);
  border-radius: var(--radius-8);
  box-shadow:
    0 0.375rem 0.375rem color-mix(in srgb, var(--color-cararra-950) 6%, transparent),
    0 0.75rem  0.75rem  color-mix(in srgb, var(--color-cararra-950) 12%, transparent);
}
.ds-doc-header__top {
  display: flex;
  /* The Figma frame is authored LTR (badges at canvas-left, identity at
     canvas-right). On this RTL page the faithful reproduction needs the row
     reversed so identity + photo land on the RIGHT (matching both the mock and
     the previous header) and the status / note badges on the LEFT. */
  flex-direction: row-reverse;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.ds-doc-header__badges {
  display: flex;
  align-items: center;
  gap: var(--space-4);          /* 16px */
  flex-wrap: wrap;
}

/* Status pill (doctor.status) — bg-50 / text-950 / 16px dot-500 per family. */
.ds-doc-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);          /* 8px */
  padding: var(--space-2) var(--space-4);  /* 8 / 16 */
  border-radius: var(--radius-4);
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14); /* 14px */
  line-height: 1;
  white-space: nowrap;
}
.ds-doc-pill__dot {
  width: var(--icon-size-16);   /* 16px */
  height: var(--icon-size-16);
  border-radius: var(--radius-2);
  flex-shrink: 0;
}
.ds-doc-pill--blue      { background: var(--color-blue-50);       color: var(--color-blue-950); }
.ds-doc-pill--blue      .ds-doc-pill__dot { background: var(--color-blue-500); }
.ds-doc-pill--green     { background: var(--color-green-50);      color: var(--color-green-950); }
.ds-doc-pill--green     .ds-doc-pill__dot { background: var(--color-green-500); }
.ds-doc-pill--red       { background: var(--color-radicalRed-50); color: var(--color-radicalRed-950); }
.ds-doc-pill--red       .ds-doc-pill__dot { background: var(--color-radicalRed-500); }
.ds-doc-pill--cerulean  { background: var(--color-cerulean-50);   color: var(--color-cerulean-950); }
.ds-doc-pill--cerulean  .ds-doc-pill__dot { background: var(--color-cerulean-500); }
.ds-doc-pill--brightSun { background: var(--color-brightSun-50);  color: var(--color-brightSun-950); }
.ds-doc-pill--brightSun .ds-doc-pill__dot { background: var(--color-brightSun-500); }
.ds-doc-pill--neutral   { background: var(--color-blackHaze-50);  color: var(--color-blackHaze-950); }
.ds-doc-pill--neutral   .ds-doc-pill__dot { background: var(--color-blackHaze-500); }

/* (The header "Has note" badge was removed 2026-05-31 — the doctor-note
   indicator now lives only in the File-actions section's gold pill.) */

/* Edit-deadline countdown chip (kept from the old header — not in the Figma
   mock, but dropping the edit deadline is a real UX loss; it lives quietly in
   the badge cluster, only while the doctor is in needs_edit). */
.ds-doc-header__badges .ds-countdown { flex-shrink: 0; }

/* Identity cluster (end edge / left in RTL): file# + name/email, then photo. */
.ds-doc-header__identity {
  display: flex;
  flex-direction: row-reverse;  /* photo on the right, id text to its left */
  align-items: flex-start;
  justify-content: flex-end;
  gap: var(--space-5);          /* 20px */
  min-width: 0;
}
.ds-doc-header__idtext {
  display: flex;
  flex-direction: column;
  /* RTL: in a flex COLUMN the cross axis is the inline axis, so flex-START is
     the RIGHT edge. The identity stack (file# / name / email) hugs the right,
     flush against the photo — matching the mock. (flex-end would push it left.) */
  align-items: flex-start;
  gap: var(--space-4);          /* 16px */
  min-width: 0;
}
.ds-doc-fileno {
  display: flex;
  flex-direction: column;
  align-items: flex-start;      /* RTL → right edge */
  gap: var(--space-3);          /* 12px */
  padding: var(--space-2) var(--space-3);  /* 8 / 12 */
  background: var(--color-blackHaze-50);
  border-radius: var(--radius-4);
}
.ds-doc-fileno__label {
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12);
  line-height: 1;
  color: var(--color-blackHaze-950);
  opacity: var(--opacity-70);
}
.ds-doc-fileno__value {
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-12);
  line-height: 1;
  color: var(--color-blackHaze-500);
}
.ds-doc-nameblock {
  display: flex;
  flex-direction: column;
  align-items: flex-start;      /* RTL → right edge */
  gap: var(--space-3);          /* 12px */
  min-width: 0;
}
/* Name + email use text-box-trim (like the Figma text layers) so the 12px
   flex gap on .ds-doc-nameblock is the gap between the actual glyphs — without
   it, line-height padding inflated the visible gap to ~20px. */
.ds-doc-name {
  margin: 0;
  font-family: var(--font-activist-bold);
  font-size: var(--type-ar-24); /* 24px */
  line-height: 1.2;
  color: var(--text-onCard-primary);
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}
.ds-doc-email {
  margin: 0;
  font-family: var(--font-activist-regular);
  font-size: var(--type-ar-16); /* 16px */
  line-height: 1.2;
  color: var(--text-onCard-secondary);
  opacity: var(--opacity-70);
  direction: ltr;
  text-align: end;
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}
.ds-doc-photo {
  width: 90px;
  height: 90px;
  border-radius: var(--radius-4);  /* Figma 4.286px ≈ 4px */
  overflow: hidden;
  flex-shrink: 0;
  background: var(--color-blue-500);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ds-doc-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* No real photo → neutral frame + gendered avatar SVG (the blue-500 frame from
   the mock only reads well behind an actual cover photo). */
.ds-doc-photo--fallback { background: var(--color-blackHaze-100); }
.ds-doc-photo--fallback img { width: 65%; height: 65%; object-fit: contain; }

/* Hairline divider — blue-800 @ 8%, full content width. */
.ds-doc-header__divider {
  height: var(--stroke-1);
  width: 100%;
  background: color-mix(in srgb, var(--color-blue-800) 8%, transparent);
  border-radius: var(--radius-4);
}

/* Stat tiles row. */
.ds-doc-header__stats {
  display: flex;
  /* Reversed for the same reason as the top row: matches the Figma tile order
     (gender → … → submitted, left to right). */
  flex-direction: row-reverse;
  align-items: stretch;
  justify-content: flex-end;
  gap: var(--space-5);          /* 20px */
  flex-wrap: wrap;
}
.ds-doc-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;      /* RTL → right edge (label + value right-aligned) */
  gap: var(--space-2);          /* 8px */
  padding: var(--space-2) var(--space-4);  /* 8 / 16 */
  background: var(--color-blackHaze-50);
  border-radius: var(--radius-4);
}
/* Nationality tile: value stack + flag on a single centred row. row-reverse
   puts the flag to the RIGHT of the label/value stack, matching the mock
   (flag at canvas-x 55, text at 16) and the previous header. */
.ds-doc-stat--nat {
  flex-direction: row-reverse;
  align-items: center;
  gap: var(--space-3);          /* 8px (Figma spacing/3) */
}
.ds-doc-stat__label {
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-12); /* 12px */
  line-height: 1;
  color: var(--color-blackHaze-950);
  opacity: var(--opacity-70);
}
.ds-doc-stat__value {
  font-family: var(--font-activist-semibold);
  font-size: var(--type-ar-14); /* 14px */
  line-height: 1;
  color: var(--color-blackHaze-1000);
}
.ds-doc-stat__flag {
  width: var(--icon-size-20);   /* 20px */
  height: var(--icon-size-20);
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--color-blackHaze-100);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ds-doc-stat__flag img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* ============================================================================
   DECISION DIALOGS — approve / request-changes / reject modals
   Used by `templates/doctors/detail.html`. Native HTML5 <dialog> opened via
   `dialog.showModal()` from panel.js. A coloured top accent stripe encodes
   the action family (Core.Color tokens):
       approve          → green-600
       request_changes  → brightSun-500
       reject           → red-600
   RTL: the dialog inherits page direction; logical properties + flexbox keep
   the title at the start (right in RTL) and the action buttons at the end
   (left in RTL).
   ============================================================================ */
.ds-decision-dialog {
  width: min(92vw, 560px);
  max-height: 86vh;
  padding: 0;
  border: var(--stroke-1) solid var(--border-divider);
  border-radius: var(--radius-8, 12px);
  background: var(--bg-card, #fff);
  color: var(--text-onCard-primary);
  box-shadow: 0 24px 64px rgba(16, 24, 40, 0.24);
  overflow: hidden;
}
.ds-decision-dialog::backdrop {
  background: rgba(16, 24, 40, 0.55);
  backdrop-filter: blur(2px);
}
/* Lightweight enter animation (respects reduced motion below). */
.ds-decision-dialog[open] {
  animation: ds-decision-pop 140ms ease-out;
}
@keyframes ds-decision-pop {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.ds-decision-dialog__inner {
  display: flex;
  flex-direction: column;
  max-height: 86vh;
  /* Top accent stripe — overridden per variant below. */
  border-block-start: 3px solid var(--color-blue-600);
}
.ds-decision-dialog--approve .ds-decision-dialog__inner {
  border-block-start-color: var(--color-green-600);
}
.ds-decision-dialog--edit .ds-decision-dialog__inner {
  border-block-start-color: var(--color-brightSun-500);
}
.ds-decision-dialog--reject .ds-decision-dialog__inner {
  border-block-start-color: var(--color-red-600);
}

.ds-decision-dialog__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-block-end: var(--stroke-1) solid var(--border-divider);
}
.ds-decision-dialog__title {
  margin: 0;
  font-size: var(--type-ar-16, 1rem);
  font-weight: 700;
  color: var(--text-onCard-primary);
  text-align: start;
}
.ds-decision-dialog__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  padding: 0;
  border: none;
  border-radius: var(--radius-4);
  background: transparent;
  color: var(--text-placeholder);
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}
.ds-decision-dialog__close:hover {
  background: var(--bg-input);
  color: var(--text-onCard-primary);
}

.ds-decision-dialog__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  overflow-y: auto;
}
.ds-decision-dialog__lead {
  margin: 0;
  font-size: var(--type-ar-13);
  line-height: 1.55;
  color: var(--text-onCard-secondary);
}
.ds-decision-dialog__empty {
  margin: 0;
  padding: var(--space-3);
  font-size: var(--type-ar-13);
  color: var(--text-placeholder);
  background: var(--bg-input);
  border-radius: var(--radius-4);
  text-align: center;
}

/* Firm-action banner (reject) — red. */
.ds-decision-dialog__danger-banner {
  padding: var(--space-2) var(--space-3);
  font-size: var(--type-ar-13);
  font-weight: 600;
  line-height: 1.5;
  color: var(--color-red-700);
  background: var(--color-red-50);
  border: var(--stroke-1) solid var(--color-red-200);
  border-radius: var(--radius-4);
}
/* Override warning — brightSun (a prior verdict exists). */
.ds-decision-dialog__override-warn {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  font-size: var(--type-ar-12);
  line-height: 1.5;
  color: var(--color-brightSun-950);
  background: var(--color-brightSun-50);
  border: var(--stroke-1) solid var(--color-brightSun-200);
  border-radius: var(--radius-4);
}

/* Reason group (a fieldset per field in edit / single group in reject). */
.ds-reason-group {
  margin: 0;
  padding: var(--space-2) var(--space-3) var(--space-1);
  border: var(--stroke-1) solid var(--border-divider);
  border-radius: var(--radius-4);
}
.ds-reason-group__legend {
  padding: 0 var(--space-1);
  font-size: var(--type-ar-12);
  font-weight: 700;
  color: var(--text-placeholder);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Selectable reason row. */
.ds-reason-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2);
  border-radius: var(--radius-4);
  cursor: pointer;
  transition: background-color 120ms ease;
}
.ds-reason-row:hover {
  background: var(--bg-input);
}
.ds-reason-row__check {
  margin-block-start: 0.15rem;
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
  accent-color: var(--color-blue-600);
  cursor: pointer;
}
.ds-reason-row__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.ds-reason-row__title {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--type-ar-14);
  font-weight: 600;
  color: var(--text-onCard-primary);
}
.ds-reason-row__msg {
  font-size: var(--type-ar-13);
  line-height: 1.5;
  color: var(--text-onCard-secondary);
  white-space: pre-wrap;
}
.ds-reason-row__fix {
  font-size: var(--type-ar-12);
  line-height: 1.45;
  color: var(--text-placeholder);
}

.ds-decision-dialog__custom {
  padding-block-start: var(--space-1);
}
.ds-decision-dialog__note-label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--type-ar-13);
  font-weight: 600;
  color: var(--text-onCard-primary);
}
.ds-decision-dialog__note-label textarea {
  width: 100%;
  resize: vertical;
  font-family: inherit;
  font-weight: 400;
}

.ds-decision-dialog__footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: flex-end;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-block-start: var(--stroke-1) solid var(--border-divider);
  background: var(--bg-subtle, var(--bg-input));
}

@media (prefers-reduced-motion: reduce) {
  .ds-decision-dialog[open] { animation: none; }
}

