/*
 * Darssly Design System
 * ---------------------
 * Source of truth: Figma "Darssly" — frame "Design System" (node 39:938).
 *
 * Loaded AFTER assets/css/styles.css in layouts/app.blade.php, so the :root
 * block below re-points the Bootstrap RTL theme's existing custom properties
 * at the new palette. Most of the theme is already var()-driven and rethemes
 * for free; the component sections further down fix the things tokens can't
 * express (radii, paddings, weights, new components).
 *
 * Sections
 *   1. Design tokens
 *   2. Theme token remap
 *   3. Base & typography
 *   4. Buttons
 *   5. Forms
 *   6. Cards
 *   7. Badges & chips
 *   8. Icon tiles
 *   9. Section headings
 *  10. Auth pages
 *  11. Multi-step form (register wizard)
 *  12. Modals
 *  13. Floating help menu
 *  14. Footer
 *  15. Site navbar
 *  16. Mobile bottom navigation
 *  17. Mobile drawer
 *  18. Search panel
 *  19. Notification panel
 *  20. Dashboard placeholder
 *  21. Dashboard (shell, sidebar, stats, panels, course cards, rows, profile)
 *  22. Account forms (panes on /account, help video cards)
 *  23. Dashboard-page remap (theme markup inside .ds-dash-page__content)
 *  24. Native page vocabulary (tabs, toolbars, tables, cards)
 *  25. Dashboard app shell (fixed topbar + side rail / mobile drawer)
 *  26. Homepage
 *  27. Shorts viewer
 *  28. Educational profile dialog
 *  29. Cookie consent
 */

@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+Arabic:wght@400;500;600;700;800&display=swap");

/* ==========================================================================
   1. Design tokens
   ========================================================================== */

:root {
    /* --- Brand palette ---------------------------------------------------- */
    --ds-emerald: #10b981; /* اللون الأساسي / التحفيز */
    --ds-navy: #131b2e; /* اللون المؤسسي / الثقة */
    --ds-amber: #f59e0b; /* التنبيهات / التقييمات */
    --ds-slate: #1e293b; /* النصوص الأساسية */
    --ds-cloud: #f7f9fb; /* خلفية التطبيق */

    /* Emerald ramp — derived for states/surfaces */
    --ds-emerald-deep: #005136; /* headings, high-contrast on light */
    --ds-emerald-hover: #0ea371;
    --ds-emerald-active: #0b8a5f;
    --ds-emerald-on-dark: #81d8ad; /* labels on navy panels */
    --ds-emerald-soft: rgba(16, 185, 129, 0.1); /* secondary button fill */
    --ds-emerald-soft-hover: rgba(16, 185, 129, 0.18);

    /* --- Text ------------------------------------------------------------- */
    --ds-text-heading: #191c1e;
    --ds-text-body: #3f4943;
    --ds-text-muted: #64748b; /* secondary copy — footer, captions */
    --ds-text-placeholder: #6b7280;
    --ds-text-on-dark: #ffffff;

    /* --- Surfaces --------------------------------------------------------- */
    --ds-surface: #ffffff;
    --ds-surface-sunken: #f7f9fb;
    --ds-surface-avatar: #e6e8ea;

    /* --- Borders ---------------------------------------------------------- */
    --ds-border: #bec9c0; /* inputs — solid */
    --ds-border-hairline: #e2e8f0; /* page-level rules (footer) */
    --ds-border-subtle: rgba(190, 201, 192, 0.3); /* cards */
    --ds-border-divider: rgba(190, 201, 192, 0.2); /* rules inside cards */
    --ds-border-on-dark: rgba(255, 255, 255, 0.3);

    /* --- Status ----------------------------------------------------------- */
    --ds-danger: #ba1a1a;
    --ds-warning: #f59e0b;
    --ds-success: #10b981;

    /* --- Chip (subject tag on course card) -------------------------------- */
    --ds-chip-bg: rgba(215, 223, 249, 0.3);
    --ds-chip-text: #3e465b;

    /* --- Icon tile sizes ---------------------------------------------------
     Two sizes only. Every round/square icon holder in the app picks one of
     these — before this there were 34px, 36px and 44px holders sitting next
     to each other and the rows never lined up. */
    --ds-tile-sm: 36px; /* list rows, social/action lists */
    --ds-tile-md: 44px; /* stat cards, course cards */

    /* --- Radii ------------------------------------------------------------ */
    --ds-radius-sm: 8px;
    --ds-radius-md: 12px; /* buttons, inputs */
    --ds-radius-lg: 16px; /* tiles, grouped panels */
    --ds-radius-xl: 24px; /* cards, feature panels */
    --ds-radius-pill: 9999px;

    /* --- Shadows ---------------------------------------------------------- */
    --ds-shadow-card: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
    --ds-shadow-button:
        0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
    --ds-shadow-raised:
        0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);

    /* --- Typography ------------------------------------------------------- */
    --ds-font: "Noto Sans Arabic", sans-serif;

    --ds-headline-lg: 40px;
    --ds-headline-lg-lh: 48px;
    --ds-headline-lg-ls: -0.8px;

    --ds-headline-md: 26px;
    --ds-headline-md-lh: 33.8px;

    --ds-headline-sm: 18px;
    --ds-headline-sm-lh: 25.2px;

    --ds-body: 16px;
    --ds-body-lh: 26px;

    --ds-label: 12px;
    --ds-label-lh: 12px;
    --ds-label-ls: 0.6px;

    --ds-weight-regular: 400;
    --ds-weight-medium: 500;
    --ds-weight-semibold: 600;
    --ds-weight-bold: 700;
}

/* ==========================================================================
   2. Theme token remap
   Re-points the existing theme variables so the ~39k lines of styles.css
   inherit the new palette without being edited.
   ========================================================================== */

:root {
    --color-primary: var(--ds-emerald);
    --color-primary-100: var(--ds-emerald-deep);
    --color-primary-alt: var(--ds-emerald-soft);
    --color-primary-light: #f0fdf8;
    --color-primary-lighter: #e7f9f1;

    /* The theme uses --color-secondary as its accent; the new system's second
     brand colour is the navy used for inverted panels. */
    --color-secondary: var(--ds-navy);
    --color-secondary-alt: #eef1f6;

    --color-heading: var(--ds-text-heading);
    --color-body: var(--ds-text-body);

    --color-darker: var(--ds-navy);
    --color-darkest: var(--ds-navy);
    --color-dark: var(--ds-slate);
    --color-bodyest: var(--ds-slate);

    --color-success: var(--ds-success);
    --color-danger: var(--ds-danger);
    --color-warning: var(--ds-warning);

    --color-border: var(--ds-border);
    --color-border-2: var(--ds-border-subtle);
    --bs-border-color: var(--ds-border-subtle);

    --color-light: var(--ds-cloud);
    --color-lighter: var(--ds-cloud);
    --color-extra: var(--ds-cloud);
    --color-extra2: var(--ds-cloud);
    --color-grey2: var(--ds-cloud);
    --color-gray-light: var(--ds-cloud);

    --primary-opacity: var(--ds-emerald-soft);
    --secondary-opacity: rgba(19, 27, 46, 0.1);
    --success-opacity: rgba(16, 185, 129, 0.1);
    --warning-opacity: rgba(245, 158, 11, 0.1);
    --danger-opacity: rgba(186, 26, 26, 0.1);

    /* The new system is flat — no gradients. Collapse the theme's gradient
     tokens to solid emerald so .btn-gradient (used ~166x) stays on-brand. */
    --gradient-dark: linear-gradient(
        90deg,
        var(--ds-emerald) 0%,
        var(--ds-emerald) 100%
    );
    --gradient-dark-2: linear-gradient(
        90deg,
        var(--ds-emerald) 0%,
        var(--ds-emerald) 100%
    );

    --radius: var(--ds-radius-md);
    --radius-small: var(--ds-radius-sm);
    --radius-10: var(--ds-radius-md);
    --radius-big: var(--ds-radius-xl);

    --shadow-1: var(--ds-shadow-card);
    --shadow-primary: var(--ds-shadow-button);
    --shadow-light: var(--ds-shadow-card);

    --font-primary: var(--ds-font);
    --font-secondary: var(--ds-font);
}

/* ==========================================================================
   3. Base & typography
   ========================================================================== */

body {
    font-family: var(--ds-font);
    font-size: var(--ds-body);
    line-height: var(--ds-body-lh);
    color: var(--ds-text-body);
    background-color: var(--ds-cloud);
}

h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
    font-family: var(--ds-font);
    color: var(--ds-text-heading);
}

h1,
.h1 {
    font-size: var(--ds-headline-lg);
    line-height: var(--ds-headline-lg-lh);
    letter-spacing: var(--ds-headline-lg-ls);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald-deep);
}

h2,
.h2 {
    font-size: var(--ds-headline-md);
    line-height: var(--ds-headline-md-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-navy);
}

h3,
.h3,
h4,
.h4 {
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-semibold);
}

p {
    font-size: var(--ds-body);
    line-height: var(--ds-body-lh);
    color: var(--ds-text-body);
}

/* Small uppercase-ish caption used above every spec block in the design */
.ds-label,
.rbt-title-style-2 .subtitle {
    font-size: var(--ds-label);
    line-height: var(--ds-label-lh);
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-body);
}

a {
    color: var(--ds-emerald);
}

a:hover {
    color: var(--ds-emerald-hover);
}

/* ==========================================================================
   4. Buttons
   Figma: 16px/24px regular text, 16px 48px padding, 12px radius.
   ========================================================================== */

.rbt-btn,
.ds-btn {
    font-family: var(--ds-font);
    font-size: var(--ds-body);
    font-weight: var(--ds-weight-regular);
    letter-spacing: normal;
    line-height: 24px;
    height: auto;
    padding: 16px 48px;
    border-radius: var(--ds-radius-md);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    box-shadow: var(--ds-shadow-button);
    text-align: center;
    transition:
        background-color 0.25s ease-in-out,
        color 0.25s ease-in-out,
        border-color 0.25s ease-in-out;
}

.rbt-btn:hover,
.ds-btn:hover {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
}

.rbt-btn:active,
.ds-btn:active {
    background: var(--ds-emerald-active);
}

@media only screen and (max-width: 575px) {
    .rbt-btn,
    .ds-btn {
        padding: 14px 28px;
        height: auto;
        line-height: 24px;
    }
}

/* Only .ds-btn — `.rbt-btn` is used ~166x by the theme and must keep its own
   display and border, so this cannot be folded into the shared base above.

   The reset matters: Bootstrap's reboot sets `-webkit-appearance: button` on
   `button` and `[type=submit]` and nothing clears the UA border, so a
   `<button class="ds-btn">` painted a native 2px outset frame around the fill.
   It went unnoticed while .ds-btn was only ever used on <a> elements — the
   account forms were the first to put it on a real <button>.

   This sits ABOVE the modifiers on purpose: `border: 0` here still loses to
   `.ds-btn--outline`'s own border, which is declared further down. */
.ds-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 0;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}

.ds-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Size variants kept in step with the theme's existing modifiers */
.rbt-btn.btn-sm,
.ds-btn--sm {
    padding: 10px 24px;
    font-size: 14px;
    line-height: 20px;
}

.rbt-btn.btn-xs,
.ds-btn--xs {
    padding: 8px 18px;
    font-size: 12px;
    line-height: 18px;
}

.rbt-btn.btn-md,
.ds-btn--md {
    padding: 13px 36px;
}

/* Secondary — soft emerald tint, no shadow */
.rbt-btn.btn-secondary,
.ds-btn--secondary {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    box-shadow: none;
}

.rbt-btn.btn-secondary:hover,
.ds-btn--secondary:hover {
    background: var(--ds-emerald-soft-hover);
    color: var(--ds-emerald);
}

/* Outline — emerald hairline, used on the tutor card */
.rbt-btn.btn-border,
.ds-btn--outline {
    background: transparent;
    border: 1px solid var(--ds-emerald);
    color: var(--ds-emerald);
    line-height: 24px;
    box-shadow: none;
}

.rbt-btn.btn-border:hover,
.ds-btn--outline:hover {
    background: var(--ds-emerald);
    border-color: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

/* Ghost — text only, optional trailing icon */
.ds-btn--ghost {
    background: transparent;
    color: var(--ds-text-body);
    box-shadow: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.ds-btn--ghost:hover {
    background: rgba(63, 73, 67, 0.06);
    color: var(--ds-text-heading);
}

.ds-btn--ghost-danger {
    background: transparent;
    color: var(--ds-danger);
    box-shadow: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.ds-btn--ghost-danger:hover {
    background: rgba(186, 26, 26, 0.08);
    color: var(--ds-danger);
}

/* Inverted — for use inside navy panels */
.rbt-btn.btn-white,
.ds-btn--inverted {
    background: var(--ds-surface);
    color: var(--ds-navy);
    box-shadow: none;
}

.rbt-btn.btn-white:hover,
.ds-btn--inverted:hover {
    background: var(--ds-cloud);
    color: var(--ds-navy);
}

.ds-btn--inverted-outline {
    background: transparent;
    border: 1px solid var(--ds-border-on-dark);
    color: var(--ds-text-on-dark);
    box-shadow: none;
}

.ds-btn--inverted-outline:hover {
    background: rgba(255, 255, 255, 0.1);
    color: var(--ds-text-on-dark);
}

/* The theme's gradient button is flattened to the solid brand colour */
.rbt-btn.btn-gradient,
.rbt-btn.btn-gradient.btn-gradient-2,
.rbt-btn.btn-gradient.btn-gradient-3 {
    background-image: none;
    background-color: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.rbt-btn.btn-gradient:hover {
    background-color: var(--ds-emerald-hover);
    background-position: 0 0;
}

/* Dark surface wrapper — matches the "Dark/Inverted" panel in the design */
.ds-panel--dark {
    background: var(--ds-navy);
    border-radius: var(--ds-radius-lg);
    padding: 32px;
    color: var(--ds-text-on-dark);
}

.ds-panel--dark .ds-label {
    color: var(--ds-emerald-on-dark);
}

/* ==========================================================================
   5. Forms
   ========================================================================== */

.form-control,
.rbt-default-form .form-control,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="number"],
input[type="search"],
input[type="url"],
input[type="date"],
textarea,
select {
    font-family: var(--ds-font);
    font-size: var(--ds-body);
    line-height: 24px;
    color: var(--ds-text-heading);
    background-color: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    padding: 12px 21px;
    height: auto;
    box-shadow: none;
    transition:
        border-color 0.2s ease-in-out,
        box-shadow 0.2s ease-in-out;
}

.form-control::placeholder,
textarea::placeholder {
    color: var(--ds-text-placeholder);
    opacity: 1;
}

.form-control:focus,
.rbt-default-form .form-control:focus,
input:focus,
textarea:focus,
select:focus {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
    outline: none;
}

.form-control.is-invalid,
.form-control.error {
    border-color: var(--ds-danger);
}

/* Labels sit above the field, 16px, heading colour */
label,
.form-label,
.rbt-default-form label {
    font-family: var(--ds-font);
    font-size: var(--ds-body);
    line-height: 24px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-heading);
    margin-bottom: 8px;
}

/* Checkbox / radio.
   The theme (styles.css) hides the native control and paints a box on the
   FOLLOWING SIBLING label's ::before, filling it with var(--color-primary) when
   checked — which the token remap already points at emerald. So only the
   resting box needs adjusting here; do NOT try to size the input itself, it is
   opacity:0 and absolutely positioned. */
input[type="checkbox"] ~ label::before,
input[type="radio"] ~ label::before {
    border-width: 1px;
    border-color: var(--ds-border);
    border-radius: 4px;
}

input[type="radio"] ~ label::before {
    border-radius: var(--ds-radius-pill);
}

input[type="checkbox"]:focus-visible ~ label::before,
input[type="radio"]:focus-visible ~ label::before {
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
}

/* Escape hatch: a checkbox with no sibling label to paint on would otherwise be
   invisible. Opt in with .ds-check to get a real, self-drawn control. */
.ds-check {
    appearance: none;
    -webkit-appearance: none;
    opacity: 1;
    position: static;
    width: 20px;
    height: 20px;
    margin: 0;
    flex-shrink: 0;
    display: inline-grid;
    place-content: center;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: 4px;
    cursor: pointer;
}

.ds-check[type="radio"] {
    border-radius: var(--ds-radius-pill);
}

.ds-check::after {
    content: "";
    width: 10px;
    height: 5px;
    border-bottom: 2px solid var(--ds-text-on-dark);
    border-left: 2px solid var(--ds-text-on-dark);
    transform: rotate(-45deg) translate(1px, -1px) scale(0);
    transition: transform 0.15s ease-in-out;
}

.ds-check:checked {
    background: var(--ds-emerald);
    border-color: var(--ds-emerald);
}

.ds-check:checked::after {
    transform: rotate(-45deg) translate(1px, -1px) scale(1);
}

.form-check-label {
    font-size: var(--ds-body);
    line-height: 24px;
    color: var(--ds-text-heading);
}

/* ==========================================================================
   6. Cards
   ========================================================================== */

.rbt-card,
.ds-card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-card);
    overflow: hidden;
}

.rbt-card .rbt-card-body,
.ds-card__body {
    padding: 24px;
}

.rbt-card-title,
.ds-card__title {
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.rbt-card-text,
.ds-card__text {
    font-size: var(--ds-body);
    line-height: 24px;
    color: var(--ds-text-body);
}

/* Course card — media 192px, meta row, divided footer */
.ds-course-card__media {
    position: relative;
    height: 192px;
    overflow: hidden;
}

.ds-course-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ds-course-card__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.ds-course-card__rating {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--ds-amber);
    font-size: var(--ds-body);
    line-height: 24px;
}

.ds-course-card__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-top: 1px solid var(--ds-border-divider);
    padding-top: 17px;
}

.ds-course-card__price {
    color: var(--ds-emerald);
    font-size: var(--ds-body);
    line-height: 24px;
}

.ds-course-card__author {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--ds-text-heading);
    font-size: var(--ds-body);
}

.ds-course-card__author img {
    width: 32px;
    height: 32px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-avatar);
    object-fit: cover;
}

/* Tutor card — centred, ringed avatar */
.ds-tutor-card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-card);
    padding: 32px;
    text-align: center;
}

.ds-tutor-card__avatar {
    width: 96px;
    height: 96px;
    border: 4px solid var(--ds-emerald);
    border-radius: var(--ds-radius-pill);
    padding: 8px;
    margin: 0 auto 24px;
    overflow: hidden;
}

.ds-tutor-card__avatar img {
    width: 100%;
    height: 100%;
    border-radius: var(--ds-radius-pill);
    object-fit: cover;
}

.ds-tutor-card__name {
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-tutor-card__role {
    font-size: var(--ds-body);
    line-height: 24px;
    color: var(--ds-text-body);
    margin-bottom: 16px;
}

/* ==========================================================================
   7. Badges & chips
   ========================================================================== */

.rbt-badge,
.ds-badge {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    border-radius: var(--ds-radius-pill);
    padding: 4px 12px;
    font-size: var(--ds-body);
    line-height: 24px;
    font-weight: var(--ds-weight-regular);
    display: inline-block;
}

.ds-badge--amber {
    background: var(--ds-amber);
}

.ds-badge--navy {
    background: var(--ds-navy);
}

/* Subject chip on the course card */
.ds-chip {
    background: var(--ds-chip-bg);
    color: var(--ds-chip-text);
    border-radius: var(--ds-radius-sm);
    padding: 4px 12px;
    font-size: var(--ds-body);
    line-height: 24px;
    display: inline-block;
}

/* ==========================================================================
   8. Icon tiles
   ========================================================================== */

.ds-icon-tile {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 18px 1px;
}

.ds-icon-tile__label {
    font-size: var(--ds-label);
    line-height: var(--ds-label-lh);
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-heading);
    opacity: 0.6;
}

/* ==========================================================================
   9. Section headings
   RTL: the accent rule sits on the right edge, per the design.
   ========================================================================== */

.ds-section-heading {
    border-right: 4px solid var(--ds-emerald);
    padding-right: 20px;
    font-size: var(--ds-headline-md);
    line-height: var(--ds-headline-md-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald-deep);
    text-align: right;
}

[dir="ltr"] .ds-section-heading {
    border-right: 0;
    border-left: 4px solid var(--ds-emerald);
    padding-right: 0;
    padding-left: 20px;
    text-align: left;
}

/* ==========================================================================
   10. Auth pages
   Figma: "sign in" (44:66). Shared shell — sign up / forgot / reset / OTP
   reuse these classes.
   ========================================================================== */

.ds-auth {
    background: var(--ds-cloud);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 24px 64px;
}

@media only screen and (max-width: 767px) {
    .ds-auth {
        padding: 24px 20px;
    }
}

/* --- Brand block above the card --- */
.ds-auth__brand {
    text-align: center;
    padding-bottom: 24px;
}

.ds-auth__brand-title {
    font-size: 40px;
    line-height: 48px;
    letter-spacing: -1px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
    margin: 0 0 7px;
}

.ds-auth__brand-tagline {
    font-size: 14px;
    line-height: 22.4px;
    color: var(--ds-text-body);
    margin: 0;
}

/* --- Card --- */
.ds-auth__card {
    width: 100%;
    max-width: 480px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    padding: 41px;
    box-shadow:
        0 4px 20px 0 rgba(16, 185, 129, 0.05),
        0 1px 3px 0 rgba(0, 0, 0, 0.01);
}

@media only screen and (max-width: 575px) {
    .ds-auth__card {
        padding: 28px 20px;
    }
}

.ds-auth__header {
    margin-bottom: 32px;
    text-align: right;
}

.ds-auth__title {
    font-size: var(--ds-headline-md);
    line-height: var(--ds-headline-md-lh);
    font-weight: var(--ds-weight-bold);
    color: #0f172a;
    margin: 0 0 7px;
}

.ds-auth__subtitle {
    font-size: 14px;
    line-height: 22.4px;
    color: var(--ds-text-body);
    margin: 0;
}

/* --- Fields — label sits above the input --- */
.ds-auth__field {
    margin-bottom: 10px;
    position: relative;
}

.ds-auth__field label {
    display: block;
    position: static;
    transform: none;
    font-size: var(--ds-label);
    line-height: var(--ds-label-lh);
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-medium);
    color: #0f172a;
    text-align: right;
    padding: 0 4px;
    margin-bottom: 8px;
}

/* "(اختياري)" next to a field label. Sits inside the <label> so clicking it
   still focuses the input; only the weight and colour are dialled back. */
.ds-auth__optional {
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-muted);
}

.ds-auth__field input:not([type="checkbox"]):not([type="radio"]),
.ds-auth__field select,
.ds-auth__field textarea {
    width: 100%;
    background: var(--ds-surface);
    border: 1px solid rgba(190, 201, 192, 0.5);
    border-radius: var(--ds-radius-sm);
    padding: 11px 17px;
    font-size: 14px;
    line-height: normal;
    color: var(--ds-text-heading);
    text-align: right;
    height: auto;
    box-shadow: none;
}

.ds-auth__field textarea {
    resize: vertical;
    min-height: 96px;
    line-height: 24px;
}

.ds-auth__field input::placeholder,
.ds-auth__field textarea::placeholder {
    color: var(--ds-text-placeholder);
    opacity: 1;
}

.ds-auth__field input:focus,
.ds-auth__field select:focus,
.ds-auth__field textarea:focus {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
    outline: none;
}

/* Numeric fields (phone) read LTR — keep the caret and text on the left.
   Selector must out-specify the :not():not() base rule above. */
.ds-auth__field input[dir="ltr"]:not([type="checkbox"]):not([type="radio"]) {
    text-align: left;
}

.ds-auth__field input.is-invalid,
.ds-auth__field select.is-invalid,
.ds-auth__field textarea.is-invalid {
    border-color: var(--ds-danger);
    box-shadow: 0 0 0 3px rgba(186, 26, 26, 0.1);
}

/* The theme's floating-label helper has no role here */
.ds-auth__field .focus-border {
    display: none;
}

/* --- Password reveal toggle — sits inside the field, left edge in RTL --- */
.ds-auth__field .password-toggle-wrapper {
    position: relative;
}

.ds-auth__field .password-toggle-btn {
    position: absolute;
    top: 50%;
    left: 14px;
    right: auto;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: none;
    border: 0;
    color: var(--ds-text-placeholder);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    z-index: 2;
    transition: color 0.2s ease-in-out;
}

.ds-auth__field .password-toggle-btn:hover {
    color: var(--ds-emerald);
}

/* --- Identity chip — "you are acting on this account" (reset password) --- */
.ds-auth__identity {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 16px;
    margin-bottom: 20px;
    background: var(--ds-surface-sunken);
    border: 1px solid var(--ds-border-divider);
    border-radius: var(--ds-radius-md);
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
}

.ds-auth__identity i {
    flex-shrink: 0;
    color: var(--ds-emerald);
    font-size: 16px;
}

.ds-auth__identity strong {
    direction: ltr;
    unicode-bidi: isolate;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Meta row: forgot-password link + remember me --- */
.ds-auth__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

.ds-auth__link {
    font-size: var(--ds-label);
    line-height: var(--ds-label-lh);
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-medium);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-auth__link:hover {
    color: var(--ds-emerald-hover);
    text-decoration: underline;
}

.ds-auth__remember {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: var(--ds-label);
    letter-spacing: var(--ds-label-ls);
    color: var(--ds-text-body);
    margin: 0;
}

/* The theme hides native checkboxes (opacity:0 / position:absolute) and draws a
   fake box on a SIBLING label. Here the input is nested inside its label, so no
   sibling exists — draw the box on the input itself instead. */
.ds-auth__remember input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    opacity: 1;
    position: static;
    width: 18px;
    height: 18px;
    margin: 0;
    flex-shrink: 0;
    display: inline-grid;
    place-content: center;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: 4px;
    cursor: pointer;
    transition:
        background-color 0.15s ease-in-out,
        border-color 0.15s ease-in-out;
}

.ds-auth__remember input[type="checkbox"]::after {
    content: "";
    width: 10px;
    height: 5px;
    border-bottom: 2px solid var(--ds-text-on-dark);
    border-left: 2px solid var(--ds-text-on-dark);
    transform: rotate(-45deg) translate(1px, -1px) scale(0);
    transition: transform 0.15s ease-in-out;
}

.ds-auth__remember input[type="checkbox"]:checked {
    background: var(--ds-emerald);
    border-color: var(--ds-emerald);
}

.ds-auth__remember input[type="checkbox"]:checked::after {
    transform: rotate(-45deg) translate(1px, -1px) scale(1);
}

.ds-auth__remember input[type="checkbox"]:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
}

/* The theme also adds a ::after tick to any label following a checkbox — it has
   no box to sit on here, so suppress it. */
.ds-auth__remember::before,
.ds-auth__remember::after {
    display: none;
}

/* --- Primary submit --- */
.ds-auth__submit {
    width: 100%;
    display: block;
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    border: 0;
    border-radius: var(--ds-radius-md);
    padding: 16px;
    font-size: var(--ds-body);
    line-height: 24px;
    font-weight: var(--ds-weight-regular);
    text-align: center;
    box-shadow:
        0 10px 15px -3px rgba(0, 81, 54, 0.2),
        0 4px 6px -4px rgba(0, 81, 54, 0.2);
    transition: background-color 0.25s ease-in-out;
}

.ds-auth__submit:hover {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
}

.ds-auth__submit:disabled {
    opacity: 0.65;
    cursor: not-allowed;
}

/* --- "أو" separator --- */
.ds-auth__separator {
    display: flex;
    align-items: center;
    padding: 16px 0;
}

.ds-auth__separator::before,
.ds-auth__separator::after {
    content: "";
    flex: 1 0 0;
    height: 1px;
    background: var(--ds-border-subtle);
}

.ds-auth__separator span {
    padding: 0 16px;
    font-size: var(--ds-label);
    line-height: var(--ds-label-lh);
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-body);
}

/* --- Social buttons --- */
.ds-auth__social {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 56px;
    padding: 14px 18px;
    background: var(--ds-surface);
    border: 1px solid rgba(190, 201, 192, 0.5);
    border-radius: var(--ds-radius-md);
    color: var(--ds-text-body);
    font-size: var(--ds-body);
    line-height: 25.6px;
    text-decoration: none;
    transition: background-color 0.2s ease-in-out;
}

.ds-auth__social:hover {
    background: var(--ds-cloud);
    color: var(--ds-text-heading);
}

.ds-auth__social + .ds-auth__social {
    margin-top: 12px;
}

.ds-auth__social svg,
.ds-auth__social i {
    width: 20px;
    height: 20px;
    font-size: 20px;
    flex-shrink: 0;
}

/* --- Below-card links --- */
.ds-auth__alt {
    padding-top: 39px;
    text-align: center;
    font-size: 14px;
    line-height: 22.4px;
    color: var(--ds-text-body);
}

.ds-auth__alt a {
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-auth__alt a:hover {
    text-decoration: underline;
}

/* --- Legal footer --- */
.ds-auth__footer {
    padding-top: 24px;
    text-align: center;
}

.ds-auth__footer-links {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 24px;
    margin-bottom: 16px;
}

.ds-auth__footer-links a {
    font-size: var(--ds-label);
    line-height: var(--ds-label-lh);
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-medium);
    color: rgba(63, 73, 67, 0.6);
    text-decoration: none;
}

.ds-auth__footer-links a:hover {
    color: var(--ds-text-body);
}

.ds-auth__copyright {
    font-size: var(--ds-label);
    line-height: 16px;
    color: #64748b;
    margin: 0;
}

.ds-auth__copyright a {
    color: inherit;
    text-decoration: underline;
}

/* ==========================================================================
   11. Multi-step form (register wizard)
   Figma: "sign up" (43:2) — frame 43:9 "Signup Card". Step 1 is the only
   designed step; steps 2 and 3 reuse the same shell.
   ========================================================================== */

/* --- Numerical stepper --------------------------------------------------
   RTL: step 1 renders on the right, so the progress rule fills from the
   right edge. Bullets sit above the rule via z-index. */
.ds-steps {
    position: relative;
    width: 100%;
    max-width: 280px;
    margin: 0 auto 47px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.ds-steps__track,
.ds-steps__progress {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    height: 2px;
    pointer-events: none;
}

.ds-steps__track {
    left: 0;
    right: 0;
    background: #eceef0;
}

.ds-steps__progress {
    right: 0;
    width: 0;
    background: var(--ds-emerald);
    transition: width 0.35s ease-in-out;
}

[dir="ltr"] .ds-steps__progress {
    right: auto;
    left: 0;
}

.ds-step {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.ds-step__bullet {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-avatar);
    color: var(--ds-text-body);
    font-size: var(--ds-body);
    line-height: 24px;
    font-weight: var(--ds-weight-bold);
    box-shadow: 0 0 0 4px var(--ds-surface);
    transition:
        background-color 0.25s ease-in-out,
        color 0.25s ease-in-out;
}

.ds-step__bullet i {
    font-size: 18px;
}

.ds-step.is-done .ds-step__bullet {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.ds-step.is-active .ds-step__bullet {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    box-shadow:
        0 0 0 4px var(--ds-surface),
        var(--ds-shadow-button);
}

.ds-step__caption {
    margin: 8px 0 0;
    font-size: 11px;
    line-height: 16px;
    color: var(--ds-text-placeholder);
    white-space: nowrap;
    transition: color 0.25s ease-in-out;
}

.ds-step.is-active .ds-step__caption {
    color: var(--ds-emerald);
    font-weight: var(--ds-weight-semibold);
}

/* --- Panes --- */
.ds-step-pane {
    display: none;
}

.ds-step-pane.is-current {
    display: block;
    animation: ds-step-in 0.25s ease-in-out;
}

@keyframes ds-step-in {
    from {
        opacity: 0;
        transform: translateY(6px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.ds-step-pane__title {
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
    text-align: right;
    margin: 0 0 24px;
}

/* Two fields side by side (الاسم الأول / الاسم الثاني) */
.ds-field-row {
    display: flex;
    gap: 16px;
}

.ds-field-row > * {
    flex: 1 0 0;
    min-width: 0;
}

@media only screen and (max-width: 479px) {
    .ds-field-row {
        display: block;
    }
}

/* --- Step actions --- */
.ds-step-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-top: 16px;
}

.ds-step-actions .ds-auth__submit {
    flex: 1 0 0;
}

.ds-auth__back {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 16px 22px;
    background: var(--ds-surface);
    border: 1px solid rgba(190, 201, 192, 0.5);
    border-radius: var(--ds-radius-md);
    color: var(--ds-text-body);
    font-size: var(--ds-body);
    line-height: 24px;
    transition: background-color 0.2s ease-in-out;
}

.ds-auth__back:hover {
    background: var(--ds-cloud);
    color: var(--ds-text-heading);
}

/* --- Choice boxes (account type) ---------------------------------------
   The input is NESTED in its label, so the theme's `input ~ label::before`
   painter never fires — the box below is drawn on the sibling span. */
.ds-choice-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}

@media only screen and (max-width: 400px) {
    .ds-choice-grid {
        grid-template-columns: 1fr;
    }
}

.ds-choice {
    display: block;
    position: relative;
    margin: 0;
    cursor: pointer;
}

.ds-choice::before,
.ds-choice::after {
    display: none;
}

.ds-choice input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    pointer-events: none;
}

.ds-choice__box {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    height: 100%;
    padding: 18px 8px;
    background: var(--ds-surface);
    border: 1px solid rgba(190, 201, 192, 0.5);
    border-radius: var(--ds-radius-md);
    text-align: center;
    transition:
        border-color 0.2s ease-in-out,
        background-color 0.2s ease-in-out,
        box-shadow 0.2s ease-in-out;
}

.ds-choice:hover .ds-choice__box {
    border-color: var(--ds-emerald);
}

.ds-choice__icon {
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ds-radius-md);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 20px;
    transition:
        background-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

.ds-choice__label {
    display: block;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-choice input[type="radio"]:checked ~ .ds-choice__box {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
}

.ds-choice input[type="radio"]:checked ~ .ds-choice__box .ds-choice__icon {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.ds-choice input[type="radio"]:focus-visible ~ .ds-choice__box {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
}

/* ==========================================================================
   12. Modals (.ds-modal*)
   Applied on top of Bootstrap's `.modal` markup. The auth page deliberately
   deletes `.modal-backdrop` from the DOM (see the cleanup JS in
   auth/login.blade.php), so the dimming overlay is painted on the `.modal`
   element itself — it survives that cleanup and needs no extra node.
   ========================================================================== */

.ds-modal {
    background: rgba(19, 27, 46, 0); /* navy, transparent until .show */
    transition:
        background-color 0.3s ease-in-out,
        backdrop-filter 0.3s ease-in-out;
}

.ds-modal.show {
    background: rgba(19, 27, 46, 0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.ds-modal .modal-dialog {
    max-width: 460px;
    padding: 16px;
}

.ds-modal.fade .modal-dialog {
    transform: translateY(16px) scale(0.98);
    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.3, 1);
}

.ds-modal.show .modal-dialog {
    transform: none;
}

/* --- Shell --- */
.ds-modal__content {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    padding: 32px 28px;
    box-shadow:
        0 24px 48px -12px rgba(19, 27, 46, 0.22),
        0 4px 20px 0 rgba(16, 185, 129, 0.05);
}

@media only screen and (max-width: 575px) {
    .ds-modal__content {
        padding: 26px 18px;
    }
}

/* --- Header --- */
.ds-modal__header {
    position: relative;
    text-align: center;
    margin-bottom: 24px;
}

.ds-modal__icon {
    width: 56px;
    height: 56px;
    margin: 0 auto 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 24px;
}

.ds-modal__icon--danger {
    background: rgba(186, 26, 26, 0.1);
    color: var(--ds-danger);
}

.ds-modal__icon--whatsapp {
    background: rgba(37, 211, 102, 0.12);
    color: #25d366;
}

.ds-modal__title {
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-bold);
    color: #0f172a;
    margin: 0 0 7px;
}

.ds-modal__subtitle {
    font-size: 14px;
    line-height: 22.4px;
    color: var(--ds-text-body);
    margin: 0;
}

/* Close — sits in the top-left corner of an RTL card */
.ds-modal__close {
    position: absolute;
    top: -8px;
    left: -6px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: var(--ds-radius-pill);
    color: var(--ds-text-placeholder);
    font-size: 16px;
    line-height: 1;
    transition:
        background-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

.ds-modal__close:hover {
    background: var(--ds-surface-sunken);
    color: var(--ds-text-heading);
}

/* --- Body ---
   Spacing is set on the pieces rather than on `* + *`: most children here are
   toggled with display:none, and a sibling selector would leave their gap
   behind. Margins on a display:none element collapse away for free. */
.ds-modal__actions {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Side-by-side (cancel + confirm); stacks on narrow screens */
.ds-modal__actions--row {
    flex-direction: row;
    align-items: stretch;
}

.ds-modal__actions--row .ds-auth__submit {
    flex: 1 0 0;
}

@media only screen and (max-width: 419px) {
    .ds-modal__actions--row {
        flex-direction: column;
    }
}

.ds-modal__body .ds-choice-grid {
    margin-bottom: 20px;
}

/* Alerts inside a modal stay flat and quiet */
.ds-modal .alert,
.ds-dialog .alert {
    border: 0;
    border-radius: var(--ds-radius-sm);
    padding: 12px 16px;
    font-size: 14px;
    line-height: 22px;
    margin: 0 0 16px;
}

.ds-modal .alert-success,
.ds-dialog .alert-success {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
}

.ds-modal .alert-info,
.ds-dialog .alert-info {
    background: var(--ds-surface-sunken);
    color: var(--ds-text-body);
}

.ds-modal .alert-danger,
.ds-dialog .alert-danger {
    background: rgba(186, 26, 26, 0.08);
    color: var(--ds-danger);
}

/* --- Hand-rolled dialog (no Bootstrap) ---------------------------------
   The help overlays in layouts/app.blade.php are plain divs toggled with a
   `.show` class. They borrow every inner piece from .ds-modal__*; only the
   overlay behaviour differs. */
.ds-dialog {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 10001; /* above the theme's back-to-top (10000) */
    padding: 20px;
    overflow-y: auto;
    background: rgba(19, 27, 46, 0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    animation: ds-dialog-fade 0.25s ease-in-out;
}

.ds-dialog.show {
    display: flex;
    align-items: center;
    justify-content: center;
}

.ds-dialog .ds-modal__content {
    width: 100%;
    max-width: 460px;
    margin: auto;
    animation: ds-dialog-rise 0.3s cubic-bezier(0.2, 0.8, 0.3, 1);
}

@keyframes ds-dialog-fade {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes ds-dialog-rise {
    from {
        opacity: 0;
        transform: translateY(16px) scale(0.98);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* --- Channel picker row (email / WhatsApp) --- */
.ds-modal__channel {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 14px 16px;
    background: var(--ds-surface);
    border: 1px solid rgba(190, 201, 192, 0.5);
    border-radius: var(--ds-radius-md);
    text-align: right;
    transition:
        border-color 0.2s ease-in-out,
        background-color 0.2s ease-in-out,
        box-shadow 0.2s ease-in-out;
}

.ds-modal__channel:hover:not(:disabled) {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
}

.ds-modal__channel:disabled {
    opacity: 0.6;
}

.ds-modal__channel-icon {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ds-radius-md);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 20px;
    transition:
        background-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

.ds-modal__channel:hover:not(:disabled) .ds-modal__channel-icon {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.ds-modal__channel-text {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-modal__channel-label {
    display: block;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-modal__channel-value {
    display: block;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-placeholder);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ds-modal__channel-arrow {
    flex: 0 0 auto;
    color: var(--ds-text-placeholder);
    font-size: 18px;
}

/* --- OTP code field --- */
.ds-otp-field {
    text-align: center;
}

.ds-otp-input {
    width: 100%;
    background: var(--ds-surface);
    border: 1px solid rgba(190, 201, 192, 0.5);
    border-radius: var(--ds-radius-md);
    padding: 16px 12px;
    font-size: 28px;
    line-height: 36px;
    font-weight: var(--ds-weight-semibold);
    letter-spacing: 12px;
    text-indent: 12px; /* balance the trailing letter-space so digits sit centred */
    text-align: center;
    color: var(--ds-text-heading);
    direction: ltr;
    box-shadow: none;
    height: auto;
}

.ds-otp-input::placeholder {
    color: var(--ds-text-placeholder);
    opacity: 1;
    font-weight: var(--ds-weight-regular);
}

.ds-otp-input:focus {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
    outline: none;
    background: var(--ds-surface);
}

.ds-otp-input.is-invalid {
    border-color: var(--ds-danger);
    box-shadow: 0 0 0 3px rgba(186, 26, 26, 0.1);
}

.ds-otp-error {
    display: none;
    margin-top: 8px;
    font-size: 12px;
    color: var(--ds-danger);
}

/* --- Inline destination (email / phone) — always LTR inside RTL copy --- */
.ds-modal__inline-ltr {
    display: inline-block;
    direction: ltr;
    unicode-bidi: isolate;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

/* --- Quiet text link (resend) --- */
.ds-modal__foot-note {
    text-align: center;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
}

.ds-modal__link-btn {
    padding: 0;
    margin-inline-start: 4px;
    background: none;
    border: 0;
    color: var(--ds-emerald);
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
}

.ds-modal__link-btn::before,
.ds-modal__link-btn::after {
    display: none;
    content: none;
}

.ds-modal__link-btn:hover {
    color: var(--ds-emerald-hover);
    text-decoration: underline;
}

.ds-modal__link-btn:disabled {
    opacity: 0.6;
    text-decoration: none;
}

/* --- Dark mode --- */
.active-dark-mode .ds-modal__content {
    background: var(--color-darker);
    border-color: var(--dark-color-border, rgba(255, 255, 255, 0.1));
}

.active-dark-mode .ds-modal__title,
.active-dark-mode .ds-modal__channel-label,
.active-dark-mode .ds-modal__inline-ltr,
.active-dark-mode .ds-modal .ds-choice__label {
    color: var(--color-white);
}

.active-dark-mode .ds-modal__subtitle,
.active-dark-mode .ds-modal__channel-value,
.active-dark-mode .ds-modal__foot-note {
    color: var(--color-white-off);
}

.active-dark-mode .ds-modal__channel,
.active-dark-mode .ds-modal .ds-choice__box,
.active-dark-mode .ds-modal .ds-auth__social,
.active-dark-mode .ds-otp-input {
    background: var(--color-bodyest);
    border-color: var(--dark-color-border);
    color: var(--color-white);
}

.active-dark-mode .ds-modal .alert-info {
    background: var(--color-bodyest);
    color: var(--color-white-off);
}

/* ==========================================================================
   13. Floating help menu (.ds-fab*)
   One emerald toggle at the bottom-right that fans out the support actions.
   RTL note: the theme's back-to-top sits bottom-LEFT (rtl-style.css), so this
   corner is free.
   ========================================================================== */

/* Cross-axis note: in a column flexbox the cross axis follows `direction`, so
   `flex-start` is the RIGHT edge under dir="rtl" and the LEFT edge under ltr —
   i.e. always the edge this menu is anchored to. Never use flex-end here. */
.ds-fab {
    position: fixed;
    left: 24px;
    bottom: 24px;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
}

[dir="ltr"] .ds-fab {
    right: auto;
    left: 24px;
}

.ds-fab__items {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    /* centres the 48px action circles under the 56px toggle */
    margin-inline-start: 4px;
    visibility: hidden;
    transition: visibility 0.25s;
}

.ds-fab.is-open .ds-fab__items {
    visibility: visible;
}

/* The theme sets `appearance: button` on every <button>, which paints native
   chrome (white fill + border). Two of these items are buttons and one is an
   anchor — reset hard so all three are just a circle plus a label. */
.ds-fab__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0;
    margin: 0;
    border: 0;
    background: none;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    box-shadow: none;
    color: inherit;
    text-align: start;
    text-decoration: none;
    cursor: pointer;
    opacity: 0;
    transform: translateY(10px) scale(0.85);
    transition:
        opacity 0.2s ease-in-out,
        transform 0.25s cubic-bezier(0.2, 0.8, 0.3, 1);
}

.ds-fab__item:hover,
.ds-fab__item:focus {
    background: none;
    outline: none;
}

.ds-fab.is-open .ds-fab__item {
    opacity: 1;
    transform: none;
}

/* Fan out bottom-up: the item nearest the toggle moves first */
.ds-fab.is-open .ds-fab__item:nth-last-child(1) {
    transition-delay: 0.02s;
}
.ds-fab.is-open .ds-fab__item:nth-last-child(2) {
    transition-delay: 0.06s;
}
.ds-fab.is-open .ds-fab__item:nth-last-child(3) {
    transition-delay: 0.1s;
}

.ds-fab__label {
    padding: 6px 12px;
    background: var(--ds-navy);
    color: var(--ds-text-on-dark);
    border-radius: var(--ds-radius-pill);
    font-size: 12px;
    line-height: 18px;
    font-weight: var(--ds-weight-medium);
    white-space: nowrap;
    box-shadow: var(--ds-shadow-card);
}

.ds-fab__btn {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-pill);
    color: var(--ds-text-on-dark);
    font-size: 20px;
    cursor: pointer;
    box-shadow: var(--ds-shadow-raised);
    transition: background-color 0.2s ease-in-out;
}

.ds-fab__btn:hover {
    color: var(--ds-text-on-dark);
}

.ds-fab__btn--support {
    background: var(--ds-navy);
}

.ds-fab__btn--support:hover {
    background: var(--ds-slate);
}

.ds-fab__btn--bug {
    background: var(--ds-danger);
}

.ds-fab__btn--bug:hover {
    background: #9f1616;
}

.ds-fab__btn--whatsapp {
    background: #25d366;
}

.ds-fab__btn--whatsapp:hover {
    background: #128c7e;
}

.ds-fab__toggle {
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 24px;
    cursor: pointer;
    box-shadow:
        0 10px 15px -3px rgba(0, 81, 54, 0.3),
        0 4px 6px -4px rgba(0, 81, 54, 0.3);
    transition: background-color 0.2s ease-in-out;
}

.ds-fab__toggle:hover {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
}

.ds-fab.is-open .ds-fab__toggle {
    background: var(--ds-slate);
}

.ds-fab.is-open .ds-fab__toggle:hover {
    background: var(--ds-navy);
}

/* Icon swap: help mark collapsed, close mark expanded */
.ds-fab__toggle .ds-fab__icon-close,
.ds-fab.is-open .ds-fab__toggle .ds-fab__icon-open {
    display: none;
}

.ds-fab.is-open .ds-fab__toggle .ds-fab__icon-close {
    display: block;
}

@media only screen and (max-width: 767px) {
    .ds-fab {
        left: 16px;
        bottom: 16px;
        gap: 10px;
    }

    [dir="ltr"] .ds-fab {
        left: 16px;
    }

    .ds-fab__items {
        gap: 10px;
    }

    .ds-fab__btn {
        width: 44px;
        height: 44px;
        font-size: 18px;
    }

    .ds-fab__toggle {
        width: 52px;
        height: 52px;
        font-size: 22px;
    }
}

/* ==========================================================================
   14. Footer (.ds-footer*)
   Figma: "Footer" (1:229). A hairline top border, then three columns —
   brand / quick links / contact + social — over a centred copyright line.
   Replaces the theme's `.rbt-footer` + `.copyright-area` markup entirely, so
   none of the `footer-style-1` rules in styles.css apply here.
   ========================================================================== */

/* Horizontal rhythm comes from the theme's Bootstrap `.container` in the
   markup (1320px / 12px gutter), so the footer lines up with every other
   section on the page. Only vertical padding is set here. */
.ds-footer {
    background: var(--ds-surface);
    border-top: 1px solid var(--ds-border-hairline);
    padding: 80px 0;
}

.ds-footer__grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 48px;
}

/* RTL note: the grid flows with `direction`, so the first column in the DOM
   is the right-most one on the page. No explicit ordering needed. */
.ds-footer__col--brand {
    grid-column: span 5;
}

.ds-footer__col--links {
    grid-column: span 3;
}

.ds-footer__col--contact {
    grid-column: span 4;
}

/* --- Brand column ------------------------------------------------------- */
/* The footer brand is a text wordmark, not the logo image (per the frame). */
.ds-footer__brand {
    display: inline-block;
    margin-bottom: 24px;
    color: var(--ds-emerald);
    font-size: 30px;
    font-weight: var(--ds-weight-bold);
    line-height: 36px;
    text-decoration: none;
    transition: color 0.2s ease-in-out;
}

.ds-footer__brand:hover,
.ds-footer__brand:focus-visible {
    color: var(--ds-emerald-hover);
}

.ds-footer__about {
    max-width: 384px;
    margin: 0;
    color: var(--ds-text-muted);
    font-size: 16px;
    line-height: 32px;
}

/* --- Link columns ------------------------------------------------------- */
.ds-footer__title {
    margin: 0 0 24px;
    color: var(--ds-navy);
    font-size: 16px;
    font-weight: var(--ds-weight-bold);
    line-height: 24px;
}

.ds-footer__list {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-footer__list li {
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-footer__list a {
    color: var(--ds-text-muted);
    font-size: 14px;
    font-weight: var(--ds-weight-regular);
    line-height: 20px;
    text-decoration: none;
    transition: color 0.2s ease-in-out;
}

.ds-footer__list a:hover,
.ds-footer__list a:focus-visible {
    color: var(--ds-emerald);
}

/* --- Social icons ------------------------------------------------------- */
.ds-footer__social {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-footer__social li {
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-footer__social-link {
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--ds-border-hairline);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-slate);
    font-size: 16px;
    line-height: 1;
    transition:
        background-color 0.2s ease-in-out,
        border-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

.ds-footer__social-link i {
    display: block;
}

.ds-footer__social-link:hover,
.ds-footer__social-link:focus-visible {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

/* --- Copyright bar ------------------------------------------------------ */
.ds-footer__bottom {
    margin-top: 48px;
    padding-top: 48px;
    border-top: 1px solid var(--ds-border-hairline);
    text-align: center;
}

.ds-footer__copyright {
    margin: 0;
    color: var(--ds-text-muted);
    font-size: 12px;
    line-height: 16px;
}

.ds-footer__copyright a {
    color: var(--ds-text-muted);
    text-decoration: underline;
    transition: color 0.2s ease-in-out;
}

.ds-footer__copyright a:hover,
.ds-footer__copyright a:focus-visible {
    color: var(--ds-emerald);
}

@media only screen and (max-width: 991px) {
    .ds-footer {
        padding: 64px 0;
    }

    .ds-footer__grid {
        gap: 40px;
    }

    .ds-footer__col--brand {
        grid-column: span 12;
    }

    .ds-footer__col--links,
    .ds-footer__col--contact {
        grid-column: span 6;
    }

    .ds-footer__bottom {
        margin-top: 40px;
        padding-top: 32px;
    }
}

@media only screen and (max-width: 575px) {
    .ds-footer {
        padding: 48px 0;
    }

    .ds-footer__grid {
        gap: 32px;
    }

    .ds-footer__col--links,
    .ds-footer__col--contact {
        grid-column: span 12;
    }

    .ds-footer__about {
        font-size: 15px;
        line-height: 28px;
    }
}

/* ==========================================================================
   15. Site navbar (.ds-nav*)

   Two frames, one shell: `Header - Navigation` (1:268) at >=992px and
   `Header - Top Navigation Bar` (11:240) below it. Lives entirely in
   partials/navbar.blade.php and REPLACES the theme's `.rbt-header` /
   `.rbt-header-middle` / `.rbt-header-wrapper` markup — none of the
   `rbt-header-3` rules in styles.css apply any more.

   Three things to know before touching it:

   - Two theme JS hooks must stay on their elements. `.search-trigger-active`
     is what main.js binds to open `.rbt-search-dropdown` (it also adds `.open`
     to the trigger, which is where the search button's active state comes
     from), and `.hamberger-button` is what opens `.popup-mobile-menu`. Both are
     bound by delegation, so any element type works.
   - The theme's sticky machinery is gone. `.rbt-sticky-placeholder` and
     `.rbt-header-wrapper` are no longer rendered; `position: sticky` does the
     job and main.js's headerSticky() no-ops on the empty selectors.
   - The bar is the containing block for `.rbt-search-dropdown`, which the theme
     positions `absolute; top: 100%; left/right: 0`. `position: sticky` is a
     positioned element, so that works — but the dropdown must stay INSIDE
     `.ds-nav`.

   Horizontal rhythm comes from the theme's Bootstrap `.container` in the
   markup, not from this file — same reason as the footer: the bar has to line
   up with every other section on the page.
   ========================================================================== */

.ds-nav {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: rgba(255, 255, 255, 0.9);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border-bottom: 1px solid var(--ds-border-hairline);
}

/* Paired with `.container` in the markup. The grid flows with `direction`, so
   DOM order = right-to-left: brand first (rightmost), actions last. */
.ds-nav__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding-top: 16px;
    padding-bottom: 16px;
}

/* Text wordmark, not the logo image — the frame specifies text, and the
   `site_name` setting holds the Latin "Darssly". Same call as .ds-footer__brand. */
.ds-nav__brand {
    flex-shrink: 0;
    font-family: var(--ds-font);
    font-size: 24px;
    line-height: 32px;
    font-weight: var(--ds-weight-bold);
    letter-spacing: -0.6px;
    color: var(--ds-emerald);
    text-decoration: none;
    white-space: nowrap;
}

.ds-nav__brand:hover,
.ds-nav__brand:focus {
    color: var(--ds-emerald-hover);
    text-decoration: none;
}

/* --- Links ---------------------------------------------------------------- */

.ds-nav__links {
    display: flex;
    align-items: center;
    gap: 32px;
}

.ds-nav__link {
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-muted);
    white-space: nowrap;
    text-decoration: none;
    transition: color 0.2s ease;
}

.ds-nav__link:hover,
.ds-nav__link:focus {
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-nav__link.is-active {
    color: var(--ds-emerald);
    font-weight: var(--ds-weight-semibold);
}

/* --- Actions -------------------------------------------------------------- */

.ds-nav__actions {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-shrink: 0;
}

/* The theme sets `appearance: button` on every <button>, which paints native
   white chrome — reset it here so the search icon and the burger match the
   anchor-based bell. Same trap as .ds-fab__item. */
.ds-nav__icon-btn {
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: transparent;
    color: var(--ds-slate);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-nav__icon-btn:hover,
.ds-nav__icon-btn:focus,
.ds-nav__icon-btn.open {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-nav__icon-btn i {
    font-size: 18px;
    line-height: 1;
}

.ds-nav__login {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 24px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    white-space: nowrap;
    text-decoration: none;
    transition: background-color 0.2s ease;
}

.ds-nav__login:hover,
.ds-nav__login:focus {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

/* --- Avatar + account menu ------------------------------------------------ */

.ds-nav__user {
    position: relative;
}

.ds-nav__avatar {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    overflow: hidden;
    background: var(--ds-surface-avatar);
    cursor: pointer;
    box-shadow: 0 0 0 2px transparent;
    transition: box-shadow 0.2s ease;
}

.ds-nav__avatar img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ds-nav__user:hover .ds-nav__avatar,
.ds-nav__user.is-open .ds-nav__avatar,
.ds-nav__avatar:focus-visible {
    box-shadow: 0 0 0 2px var(--ds-emerald);
}

.ds-nav__menu {
    position: absolute;
    top: calc(100% + 12px);
    inset-inline-end: 0;
    min-width: 248px;
    padding: 8px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-raised);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition:
        opacity 0.18s ease,
        transform 0.18s ease,
        visibility 0.18s;
}

/* Bridges the 12px gap under the avatar so the pointer can travel from the
   trigger into the menu without it closing mid-way. */
.ds-nav__menu::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    top: -12px;
    height: 12px;
}

.ds-nav__user:hover .ds-nav__menu,
.ds-nav__user.is-open .ds-nav__menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.ds-nav__menu-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px 14px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--ds-border-divider);
}

.ds-nav__menu-head img {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--ds-surface-avatar);
}

.ds-nav__menu-name {
    display: block;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-nav__menu-role {
    display: block;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

.ds-nav__menu-item {
    -webkit-appearance: none;
    appearance: none;
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 12px;
    border: 0;
    border-radius: var(--ds-radius-md);
    background: transparent;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-body);
    text-align: start;
    text-decoration: none;
    cursor: pointer;
    transition:
        background-color 0.15s ease,
        color 0.15s ease;
}

.ds-nav__menu-item:hover,
.ds-nav__menu-item:focus {
    background: var(--ds-surface-sunken);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-nav__menu-item i {
    width: 18px;
    font-size: 16px;
    text-align: center;
}

.ds-nav__menu-item--danger:hover,
.ds-nav__menu-item--danger:focus {
    background: rgba(186, 26, 26, 0.08);
    color: var(--ds-danger);
}

/* --- Breakpoint ----------------------------------------------------------- */

@media (min-width: 992px) {
    .ds-nav__burger {
        display: none;
    }
}

/* Below 992px the bar collapses to the `Header - Top Navigation Bar` frame:
   wordmark on the right, burger on the left, nothing else. Search, account and
   dashboard all move to the bottom bar (section 16) and the drawer. */
@media (max-width: 991.98px) {
    .ds-nav {
        background: rgba(247, 249, 251, 0.8);
        border-bottom-color: var(--ds-border-subtle);
    }

    .ds-nav__inner {
        padding-inline: 20px;
    }

    .ds-nav__brand {
        font-size: var(--ds-headline-md);
        line-height: var(--ds-headline-md-lh);
        letter-spacing: normal;
    }

    /* .ds-nav__notif deliberately stays visible — the bell is the one thing added
     to the frame's burger-only top bar, because notifications were otherwise
     unreachable on a phone. It renders left of the wordmark, beside the burger,
     and opens as a bottom sheet (section 19). */
    .ds-nav__links,
    .ds-nav__search,
    .ds-nav__login,
    .ds-nav__user {
        display: none;
    }

    .ds-nav__actions {
        gap: 4px;
    }
}

/* ==========================================================================
   16. Mobile bottom navigation (.ds-bottomnav*)

   Built from the `Bottom Navigation (Mobile Global Shell)` frame (11:251) and
   living in partials/bottom-nav.blade.php, which layouts/app.blade.php renders
   once per page (skipped on auth screens along with the help menu).

   DOM order is right-to-left like every other flex row here, so the markup
   reads الرئيسية → بحث → لوحة التحكم → حسابي and paints in that order from the
   right edge.

   The بحث item carries `.search-trigger-active`, so it opens the same search
   panel as the desktop icon and picks up the theme's `.open` class for free.
   ========================================================================== */

:root {
    /* Bar height (13 + 18 + 4 + 15 + 12). The spacer, the help menu and the
     back-to-top button all offset by this, so change it in one place. */
    --ds-bottomnav-h: 62px;
}

/* Both the bar and its spacer live in the same partial and are hidden together
   at >=992px — so the body never reserves room for a bar that isn't there, and
   auth pages (which skip the partial entirely) need no special case. */
.ds-bottomnav,
.ds-bottomnav-spacer {
    display: none;
}

@media (max-width: 991.98px) {
    .ds-bottomnav-spacer {
        display: block;
        height: calc(var(--ds-bottomnav-h) + env(safe-area-inset-bottom, 0px));
    }

    .ds-bottomnav {
        position: fixed;
        inset-inline: 0;
        bottom: 0;
        z-index: 1035;
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: 4px;
        padding: 13px 24px calc(12px + env(safe-area-inset-bottom, 0px));
        background: rgba(255, 255, 255, 0.9);
        -webkit-backdrop-filter: blur(8px);
        backdrop-filter: blur(8px);
        border-top: 1px solid var(--ds-border-subtle);
    }

    /* Same `appearance: button` reset as .ds-nav__icon-btn — بحث is a <button>
     and the other three are anchors, so without it only one item gets chrome. */
    .ds-bottomnav__item {
        -webkit-appearance: none;
        appearance: none;
        flex: 1 1 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 4px;
        padding: 0;
        border: 0;
        background: transparent;
        color: #3c4a42;
        text-decoration: none;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
        transition: color 0.15s ease;
    }

    .ds-bottomnav__item i {
        font-size: 18px;
        line-height: 1;
    }

    /* حسابي shows the signed-in user's own photo instead of a glyph. Sized to the
     same 18px optical box as the icons so all four labels stay on one baseline. */
    .ds-bottomnav__avatar {
        display: block;
        width: 20px;
        height: 20px;
        margin-top: -1px;
        border-radius: 50%;
        overflow: hidden;
        background: var(--ds-surface-avatar);
        box-shadow: 0 0 0 1.5px transparent;
        transition: box-shadow 0.15s ease;
    }

    .ds-bottomnav__avatar img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .ds-bottomnav__item.is-active .ds-bottomnav__avatar {
        box-shadow: 0 0 0 1.5px var(--ds-emerald);
    }

    .ds-bottomnav__label {
        font-size: 10px;
        line-height: 15px;
        font-weight: var(--ds-weight-medium);
        text-align: center;
        white-space: nowrap;
    }

    .ds-bottomnav__item:hover,
    .ds-bottomnav__item:focus {
        color: var(--ds-emerald);
        text-decoration: none;
    }

    .ds-bottomnav__item.is-active,
    .ds-bottomnav__item.open {
        color: var(--ds-emerald);
    }

    .ds-bottomnav__item.is-active .ds-bottomnav__label,
    .ds-bottomnav__item.open .ds-bottomnav__label {
        font-weight: var(--ds-weight-bold);
    }

    /* Lift the two bottom-anchored floats clear of the bar. The help menu sits
     bottom-right (section 13) and rtl-style.css moves the theme's back-to-top
     to bottom-left, so both would otherwise sit on top of it. */
    .ds-fab {
        bottom: calc(
            24px + var(--ds-bottomnav-h) + env(safe-area-inset-bottom, 0px)
        );
    }

    .rbt-progress-parent {
        bottom: calc(
            30px + var(--ds-bottomnav-h) + env(safe-area-inset-bottom, 0px)
        );
    }
}

/* ==========================================================================
   17. Mobile drawer (.ds-drawer*)

   Lives in partials/mobile-menu.blade.php and mirrors the desktop bar: the same
   five links plus a single logout/login button. It **replaces** the theme's
   `.popup-mobile-menu .inner-wrapper` visual treatment — the `.mainmenu`
   accordion markup is gone, so all the `popup-mobile-menu .mainmenu` rules in
   styles.css are dormant.

   `.popup-mobile-menu` and `.close-button` are kept purely as main.js hooks:
   the burger adds `.active` to the overlay, `.close-button` removes it, and a
   third handler closes when the click target IS the overlay — which is why the
   panel must be a child element and not the overlay itself.
   ========================================================================== */

.ds-drawer.popup-mobile-menu {
    background: rgba(19, 27, 46, 0.55);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}

.ds-drawer__panel {
    display: flex;
    flex-direction: column;
    width: min(320px, 86vw);
    height: 100%;
    padding: 0;
    background: var(--ds-surface);
    border: 0;
    box-shadow: var(--ds-shadow-raised);
}

.ds-drawer__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 24px;
    border-bottom: 1px solid var(--ds-border-hairline);
}

.ds-drawer__brand {
    font-size: var(--ds-headline-md);
    line-height: var(--ds-headline-md-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-drawer__brand:hover,
.ds-drawer__brand:focus {
    color: var(--ds-emerald-hover);
    text-decoration: none;
}

/* Same `appearance: button` reset as everywhere else in this file. */
.ds-drawer__close {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-body);
    font-size: 18px;
    cursor: pointer;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-drawer__close:hover,
.ds-drawer__close:focus {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

.ds-drawer__nav {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 16px 16px 24px;
}

.ds-drawer__link {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 14px;
    border-radius: var(--ds-radius-md);
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-body);
    text-decoration: none;
    transition:
        background-color 0.15s ease,
        color 0.15s ease;
}

.ds-drawer__link + .ds-drawer__link {
    margin-top: 2px;
}

.ds-drawer__link i {
    width: 20px;
    font-size: 18px;
    text-align: center;
    color: var(--ds-text-muted);
    transition: color 0.15s ease;
}

.ds-drawer__link:hover,
.ds-drawer__link:focus {
    background: var(--ds-surface-sunken);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-drawer__link:hover i,
.ds-drawer__link:focus i {
    color: var(--ds-emerald);
}

.ds-drawer__link.is-active {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-weight: var(--ds-weight-semibold);
}

.ds-drawer__link.is-active i {
    color: var(--ds-emerald);
}

.ds-drawer__foot {
    flex-shrink: 0;
    padding: 20px 24px calc(24px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--ds-border-hairline);
}

/* The drawer's only account affordance is the way out — everything else lives
   in the bottom bar and the desktop avatar menu. */
.ds-drawer__logout,
.ds-drawer__login {
    -webkit-appearance: none;
    appearance: none;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 12px 20px;
    border: 0;
    border-radius: var(--ds-radius-pill);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    cursor: pointer;
    text-decoration: none;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-drawer__logout {
    background: rgba(186, 26, 26, 0.08);
    color: var(--ds-danger);
}

.ds-drawer__logout:hover,
.ds-drawer__logout:focus {
    background: rgba(186, 26, 26, 0.14);
    color: var(--ds-danger);
}

.ds-drawer__login {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.ds-drawer__login:hover,
.ds-drawer__login:focus {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

.ds-drawer__social {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 20px;
}

.ds-drawer__social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 35px;
    height: 35px;
    border-radius: 50%;
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
    font-size: 16px;
    text-decoration: none;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-drawer__social-link:hover,
.ds-drawer__social-link:focus {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

/* ==========================================================================
   18. Search panel (.ds-search*)

   The form inside the theme's `.rbt-search-dropdown` (which still provides the
   slide-down panel and its open/close JS — see section 15). Rebuilt from the
   theme's four-across `.rbt-search-with-category` row into: a دورات/مدرسين
   segmented control, one large input, and the المرحلة/المادة selects folded
   behind a "تصفية متقدمة" disclosure.

   The selects carry `data-no-picker`, which main.js's selectPicker() now honours
   — without it the theme swaps them for bootstrap-select widgets and none of the
   styling below applies.

   The segmented control is real radios. styles.css hides bare inputs and paints
   on the *following sibling* label, which is exactly this markup's shape, so
   `.ds-search__seg-label` is the painted surface — don't nest the input inside
   the label here or the theme's `input ~ label` selectors stop matching.
   ========================================================================== */

.ds-search {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 28px 0 32px;
}

/* Sunken track, so the raised active pill has something to sit against.
   --ds-surface-sunken is too close to white to read as a track here. */
.ds-search__seg {
    /* Also the containing block for the absolutely-positioned radios below. */
    position: relative;
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    background: #eaeff3;
    border-radius: var(--ds-radius-pill);
}

/* Pin these to a 1px box — the size matters, not just the hiding.
   styles.css has a blanket `input, select, textarea { width: 100% }`. These
   radios are position:absolute with no width of their own, so that 100%
   resolved against the containing block (the full-width search dropdown) and
   made each one 1440px wide. They are invisible, but layout still counts them:
   the pair added ~600px of phantom horizontal scroll to every page on the site,
   which in RTL showed up as a blank strip down the left of the viewport.
   Never hide an input with position/opacity alone here. */
.ds-search__seg input[type="radio"] {
    position: absolute;
    top: 0;
    inset-inline-start: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    opacity: 0;
    pointer-events: none;
}

/* IMPORTANT — every declaration the theme also sets must be qualified with the
   sibling combinator. `input[type=radio] ~ label` in styles.css is specificity
   (0,1,2) and would otherwise beat a plain `.ds-search__seg-label` (0,1,0),
   forcing padding-left:20px / font-size:15px / weight:400 onto these labels and
   making the two segments different widths. The selector below is (0,3,2). */
.ds-search__seg input[type="radio"] ~ .ds-search__seg-label {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* Equal-width segments — otherwise "دورات" and "مدرسين" size to their text
     and the pill jumps width as you switch between them. */
    min-width: 116px;
    margin: 0;
    /* !important is load-bearing, not laziness: rtl-style.css (which loads AFTER
     this file) sets `input[type=radio] ~ label { padding-left: 0 !important;
     padding-right: 30px !important }` to make room for the fake radio it paints.
     An !important declaration beats any specificity, so without matching it the
     labels come out padded 0/30 and the text sits off-centre in its segment.
     This selector is (0,3,1) vs that rule's (0,1,2), so important-vs-important
     resolves our way. */
    padding: 9px 18px !important;
    border-radius: var(--ds-radius-pill);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-muted);
    cursor: pointer;
    transition:
        background-color 0.18s ease,
        color 0.18s ease;
}

/* The theme paints a fake radio on label::before/::after for any hidden input —
   suppress it, this control is the swatch itself. */
.ds-search__seg-label::before,
.ds-search__seg-label::after {
    content: none !important;
}

.ds-search__seg-label i {
    font-size: 15px;
    line-height: 1;
}

.ds-search__seg input[type="radio"] ~ .ds-search__seg-label:hover {
    color: var(--ds-emerald);
}

.ds-search__seg input[type="radio"]:checked + .ds-search__seg-label {
    background: var(--ds-surface);
    color: var(--ds-emerald);
    font-weight: var(--ds-weight-semibold);
    box-shadow: var(--ds-shadow-card);
}

.ds-search__seg input[type="radio"]:focus-visible + .ds-search__seg-label {
    outline: 2px solid var(--ds-emerald);
    outline-offset: 2px;
}

.ds-search__field {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    max-width: 640px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-pill);
    transition:
        border-color 0.18s ease,
        box-shadow 0.18s ease;
}

.ds-search__field:focus-within {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 4px var(--ds-emerald-soft);
}

.ds-search__field-icon {
    flex-shrink: 0;
    margin-inline-start: 20px;
    font-size: 18px;
    color: var(--ds-text-muted);
}

.ds-search__field input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
    height: 56px;
    padding: 0 12px;
    border: 0 !important;
    background: transparent !important;
    font-size: 15px;
    color: var(--ds-text-heading);
    box-shadow: none !important;
}

.ds-search__field input[type="text"]:focus {
    border: 0 !important;
    box-shadow: none !important;
}

.ds-search__field input::placeholder {
    color: var(--ds-text-placeholder);
}

.ds-search__submit {
    -webkit-appearance: none;
    appearance: none;
    flex-shrink: 0;
    margin: 6px;
    padding: 0 28px;
    height: 44px;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.ds-search__submit:hover,
.ds-search__submit:focus {
    background: var(--ds-emerald-hover);
}

.ds-search__disclosure {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: transparent;
    font-size: 13px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-muted);
    cursor: pointer;
    transition:
        color 0.15s ease,
        background-color 0.15s ease;
}

.ds-search__disclosure:hover,
.ds-search__disclosure:focus {
    background: var(--ds-surface-sunken);
    color: var(--ds-emerald);
}

.ds-search__disclosure i {
    font-size: 15px;
    transition: transform 0.2s ease;
}

.ds-search__disclosure.is-open i {
    transform: rotate(180deg);
}

.ds-search__advanced {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    width: 100%;
}

.ds-search__advanced-panel {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 16px;
    width: 100%;
    max-width: 640px;
}

.ds-search__advanced-panel[hidden] {
    display: none;
}

.ds-search__select {
    flex: 1 1 220px;
    min-width: 0;
}

.ds-search__select label {
    display: block;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-muted);
}

.ds-search__select select {
    width: 100%;
    height: 46px;
    padding: 0 14px;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    font-size: 14px;
    color: var(--ds-text-heading);
}

.ds-search__select select:focus {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
    outline: none;
}

@media (max-width: 991.98px) {
    .ds-search {
        padding: 20px 0 24px;
        gap: 14px;
    }
    .ds-search__seg {
        gap: 2px;
        padding: 2px;
        margin-bottom: 10px;
    }
    .ds-search__field input[type="text"] {
        height: 50px;
    }

    .ds-search__submit {
        padding: 0 18px;
        height: 38px;
    }

    .ds-search__advanced {
        margin-top: 10px;
    }

    .ds-search__advanced-panel {
        flex-direction: column;
        gap: 12px;
    }
}

/* ==========================================================================
   19. Notification panel (.ds-notif*)

   One component, two shapes, no markup swap:
     - >= 992px it is a dropdown anchored under the bell.
     - <  992px the same node becomes a full-viewport backdrop and its
       `.ds-notif__sheet` child slides up from the bottom edge.

   Everything visual lives here. The panel's JS
   (partials/navbar-notifications.blade.php) only toggles inline
   `display: block/none` on `.ds-notif__panel` and renders `.ds-notif__item`
   rows into `#notifications-list`.

   You cannot transition out of `display: none`, so the sheet animates on an
   `is-open` class added a frame later by the small enhancement script in that
   partial, rather than on the display change itself.
   ========================================================================== */

/* --- Bell + unread badge -------------------------------------------------- */

.ds-notif {
    position: relative;
}

/* The bell is at the inline END of the bar, so the badge sits on its outward
   (inline-end) corner — the LEFT one under dir="rtl". The ring is the surface
   colour, so the badge reads as detached from the glyph behind it. */
.ds-notif__badge {
    position: absolute;
    top: -1px;
    inset-inline-end: -1px;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
    box-shadow: 0 0 0 2px var(--ds-surface);
    color: var(--ds-text-on-dark);
    font-family: var(--ds-font);
    font-size: 10px;
    font-weight: var(--ds-weight-bold);
    line-height: 1;
}

/* --- Panel ---------------------------------------------------------------- */

/* The bell sits at the inline-END of the bar — the LEFT edge under dir="rtl" —
   so the panel must open toward the middle of the screen. The theme's original
   `right: 0` pinned its right edge to the bell and grew it 400px further left,
   straight off the viewport. Anchoring the inline-end edge instead makes it
   grow inward, which is also what .ds-nav__menu (the avatar dropdown, same
   corner) already does. */
.ds-notif__panel {
    position: absolute;
    top: calc(100% + 10px);
    inset-inline-end: 0;
    inset-inline-start: auto;
    z-index: 1000;
    width: 380px;
    max-width: calc(100vw - 32px);
    overflow: hidden;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-raised);
    direction: rtl;
    text-align: right;
}

/* Grab handle — only visible below 992px, where the panel is a bottom sheet. */
.ds-notif__grab {
    display: none;
}

/* --- Head ----------------------------------------------------------------- */

.ds-notif__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--ds-border-divider);
}

.ds-notif__heading {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-notif__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 11px;
    font-weight: var(--ds-weight-bold);
    line-height: 1;
}

/* A <button> — needs the appearance/border reset or the browser paints native
   chrome around it (the trap documented on .ds-btn). */
.ds-notif__mark {
    -webkit-appearance: none;
    appearance: none;
    flex-shrink: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ds-emerald);
    font-family: inherit;
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    line-height: 20px;
    cursor: pointer;
    text-decoration: none;
    transition: color 0.2s ease;
}

.ds-notif__mark:hover,
.ds-notif__mark:focus {
    color: var(--ds-emerald-active);
    text-decoration: underline;
}

/* --- List ----------------------------------------------------------------- */

.ds-notif__list {
    max-height: 380px;
    overflow-y: auto;
    padding: 8px;
    scrollbar-width: thin;
    scrollbar-color: var(--ds-border) transparent;
}

.ds-notif__list::-webkit-scrollbar {
    width: 6px;
}

.ds-notif__list::-webkit-scrollbar-track {
    background: transparent;
}

.ds-notif__list::-webkit-scrollbar-thumb {
    background: var(--ds-border);
    border-radius: var(--ds-radius-pill);
}

/* Same appearance/border reset again — the rows are real <button>s so they are
   keyboard reachable and announce as actionable. */
.ds-notif__item {
    -webkit-appearance: none;
    appearance: none;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    width: 100%;
    padding: 12px;
    border: 0;
    border-radius: var(--ds-radius-md);
    background: transparent;
    font-family: inherit;
    text-align: start;
    cursor: pointer;
    transition: background-color 0.18s ease;
}

.ds-notif__item + .ds-notif__item {
    margin-top: 2px;
}

.ds-notif__item:hover,
.ds-notif__item:focus-visible {
    background: var(--ds-surface-sunken);
}

.ds-notif__item.is-unread {
    background: rgba(16, 185, 129, 0.07);
}

.ds-notif__item.is-unread:hover,
.ds-notif__item.is-unread:focus-visible {
    background: var(--ds-emerald-soft);
}

.ds-notif__item-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
    font-size: 16px;
}

.ds-notif__item.is-unread .ds-notif__item-icon {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

.ds-notif__item-body {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-notif__item-title {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 14px;
    line-height: 22px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-notif__item-text {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 2px;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-notif__item-time {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 6px;
    font-size: 11px;
    line-height: 16px;
    color: var(--ds-text-placeholder);
}

.ds-notif__item-time i {
    font-size: 12px;
}

.ds-notif__item-time span {
    unicode-bidi: embed;
}

.ds-notif__item-dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    margin-top: 14px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
}

/* --- Empty & loading ------------------------------------------------------ */

.ds-notif__empty {
    padding: 34px 22px;
    text-align: center;
}

.ds-notif__empty-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    margin: 0 auto 12px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-placeholder);
    font-size: 20px;
}

.ds-notif__empty-title {
    margin: 0;
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-notif__empty-text {
    margin: 4px 0 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-notif__loading {
    padding: 8px;
}

.ds-notif__skel {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    animation: ds-notif-pulse 1.4s ease-in-out infinite;
}

.ds-notif__skel-icon {
    flex: 0 0 auto;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
}

.ds-notif__skel-lines {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ds-notif__skel-lines span {
    display: block;
    height: 10px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
}

.ds-notif__skel-lines span:first-child {
    width: 55%;
}

@keyframes ds-notif-pulse {
    0%,
    100% {
        opacity: 1;
    }
    50% {
        opacity: 0.45;
    }
}

/* --- Foot ----------------------------------------------------------------- */

.ds-notif__foot {
    border-top: 1px solid var(--ds-border-divider);
}

.ds-notif__foot-link {
    display: block;
    padding: 12px;
    text-align: center;
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
    text-decoration: none;
    transition: background-color 0.18s ease;
}

.ds-notif__foot-link:hover {
    background: var(--ds-surface-sunken);
    color: var(--ds-emerald-active);
    text-decoration: none;
}

/* --- Full-message modal ----------------------------------------------------
   Built on the section 12 shell. Bootstrap opens it with `backdrop: false`, so
   no `.modal-backdrop` node exists at all — the dim is painted by
   `.ds-modal.show` itself. That is what makes the old z-index war (a
   MutationObserver plus a 50ms interval restacking dialog/content/backdrop)
   unnecessary. The one thing still needed is a z-index above the mobile sheet
   (1060) and the header lifted behind it (1070). */

.ds-notif-modal {
    z-index: 1090;
}

.ds-notif-modal .modal-dialog {
    max-width: 520px;
}

.ds-notif-modal__message {
    max-height: 50vh;
    overflow-y: auto;
    padding: 16px;
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
    font-size: 15px;
    line-height: 1.9;
    color: var(--ds-text-body);
    white-space: pre-wrap;
    word-wrap: break-word;
}

.ds-notif-modal__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--ds-border-divider);
    font-size: 12px;
    color: var(--ds-text-placeholder);
}

.ds-notif-modal__meta span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.ds-notif-modal__meta span[dir="ltr"] {
    unicode-bidi: embed;
}

/* --- Mobile: the panel becomes a bottom sheet ----------------------------- */

@media (max-width: 991.98px) {
    /* Two properties on .ds-nav break a fixed-position sheet nested inside it,
     and both have to go for the sheet to fill the viewport:

     1. `backdrop-filter` makes an element the CONTAINING BLOCK for its
        position:fixed descendants (same as `transform` or `filter`). With it
        on, `inset: 0` below resolves against the ~66px header, so the sheet
        renders squashed inside the navbar. Dropping the blur costs nothing —
        the bar is repainted opaque here, so there is nothing behind to blur.
     2. `position: sticky` + `z-index` makes .ds-nav a STACKING CONTEXT, which
        caps every descendant's z-index at the header's own. The sheet would
        paint under the bottom bar (1035) no matter how high its z-index. Lift
        the whole header, but only while the sheet is open, so normal paint
        order is untouched the rest of the time. */
    .ds-nav {
        background: var(--ds-cloud);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    body.ds-notif-open .ds-nav {
        z-index: 1070;
    }

    .ds-notif__panel {
        position: fixed;
        inset: 0;
        z-index: 1060;
        width: auto;
        max-width: none;
        overflow: visible;
        border: 0;
        border-radius: 0;
        background: rgba(19, 27, 46, 0.55);
        -webkit-backdrop-filter: blur(4px);
        backdrop-filter: blur(4px);
        box-shadow: none;
        opacity: 0;
        /* Belt and braces: `.is-open` is added a frame after the panel's own JS
       flips display, so between those two moments — and in any world where the
       enhancement script didn't run — this is a full-viewport, fully
       transparent element. Without pointer-events:none it would silently
       swallow every tap on the page. */
        pointer-events: none;
        transition: opacity 0.22s ease;
    }

    .ds-notif__panel.is-open {
        opacity: 1;
        pointer-events: auto;
    }

    .ds-notif__sheet {
        position: absolute;
        inset-inline: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        max-height: 80vh;
        overflow: hidden;
        padding-bottom: env(safe-area-inset-bottom, 0px);
        background: var(--ds-surface);
        border-radius: var(--ds-radius-xl) var(--ds-radius-xl) 0 0;
        box-shadow: var(--ds-shadow-raised);
        transform: translateY(100%);
        transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
    }

    .ds-notif__panel.is-open .ds-notif__sheet {
        transform: translateY(0);
    }

    .ds-notif__grab {
        display: block;
        width: 44px;
        height: 4px;
        margin: 10px auto 2px;
        border-radius: var(--ds-radius-pill);
        background: var(--ds-border);
    }

    .ds-notif__head {
        padding: 12px 20px;
    }

    .ds-notif__heading {
        font-size: 17px;
    }

    /* The sheet is the scroller on mobile, so the list runs full length inside
       it — but keep it scrollable itself so a short list doesn't stretch. */
    .ds-notif__list {
        flex: 1 1 auto;
        max-height: none;
        padding: 8px 12px;
        -webkit-overflow-scrolling: touch;
    }

    .ds-notif__item {
        padding: 14px 12px;
    }

    /* Page must not scroll behind the sheet. */
    body.ds-notif-open {
        overflow: hidden;
    }

    /* The help menu is z-index 9999 — an order of magnitude above the sheet — so
     it floats on top of it. Raising the sheet past it would also put it over
     the drawer; hiding the FAB for the duration is the smaller change. */
    body.ds-notif-open .ds-fab {
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
    }
}

/* ==========================================================================
   20. Dashboard placeholder (.ds-dashboard-placeholder*)
   Empty state for the new /dashboard page while it is being built out.
   ========================================================================== */

.ds-dashboard-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 16px;
    max-width: 520px;
    margin: 0 auto;
    padding: 40px 0;
}

.ds-dashboard-placeholder__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 88px;
    height: 88px;
    border-radius: var(--ds-radius-xl);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 36px;
}

.ds-dashboard-placeholder__title {
    margin: 0;
    font-size: var(--ds-headline-lg);
    line-height: var(--ds-headline-lg-lh);
    letter-spacing: var(--ds-headline-lg-ls);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-dashboard-placeholder__text {
    margin: 0 0 8px;
    font-size: var(--ds-body);
    line-height: var(--ds-body-lh);
    color: var(--ds-text-muted);
}

/* ==========================================================================
   21. Dashboard (.ds-dash*)
   Figma: "Student Dashboard" (48:33), "Aside - Sidebar (Right)" (48:138),
   "Student Dashboard (My Courses)" (49:300), "Student Dashboard (Table)" (49:430).

   Used by resources/views/dashboard.blade.php (the role-aware hub) and
   resources/views/profile/dashboard.blade.php (the profile overview at /account).
   Both extend layouts/app.blade.php rather than a shell of their own, so the
   navbar, the mobile bottom bar and the help FAB all keep working — the bottom
   bar in particular has to stay reachable on phones.

   The shell is a two-column grid. Grid columns flow with `direction`, so the
   FIRST column is the RIGHT one under dir="rtl" — the sidebar is first in the
   markup and lands on the right, matching frame 48:138. Same for .ds-dash-grid:
   the main column is first and sits right, the activity column left.

   MOTION RULE — nothing in the dashboard moves on hover. No `transform`, no
   `scale`, no lift, no shadow change. Hover may only change `background-color`,
   `border-color` and `color`. Cards that grow or jump under the pointer make a
   dense page feel unstable, and a lifted card also shifts the text under it.
   (The lift was removed from .ds-fab and .ds-footer__social-link for the same
   reason. `transform` elsewhere in this file is entrance animation — modals,
   the drawer, the notification sheet — which is fine and should stay.)

   SIZING RULE — icon holders in this section use --ds-tile-sm / --ds-tile-md,
   never a raw px value, and cards that sit side by side carry a `min-height` so
   a one-line and a two-line label still line up. (Sections 10-19 keep their own
   sizes on purpose — the auth and modal chrome is not part of this family, and
   pulling it onto the same tokens would couple screens that have no reason to
   resize together.)
   ========================================================================== */

.ds-dash-page {
    background: var(--ds-cloud);
    padding-top: 32px;
    padding-bottom: 64px;
}

.ds-dash {
    display: grid;
    grid-template-columns: 256px minmax(0, 1fr);
    gap: 32px;
    align-items: start;
}

/* Sits below the sticky navbar (73px tall + 16px breathing room). */
.ds-dash__aside {
    position: sticky;
    top: 89px;
}

.ds-dash__main {
    min-width: 0;
}

/* --- Sidebar / pill nav (.ds-dashnav) ------------------------------------- */

.ds-dashnav {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-card);
    padding: 24px 16px;
}

/* Drawer header — hidden by default, shown only inside .ds-shell__aside below
   992px (section 25), where the drawer covers the topbar and therefore covers
   the burger that opened it. It lives in the two nav partials rather than in the
   aside markup because that markup is duplicated across four shell files. */
.ds-dashnav__head {
    display: none;
}

.ds-dashnav__head-title {
    font-size: 20px;
    line-height: 1;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald);
}

/* A real <button>, so it needs the appearance/border reset (see .ds-btn). */
.ds-dashnav__close {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-body);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-dashnav__close:hover,
.ds-dashnav__close:focus-visible {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

.ds-dashnav__brand {
    display: block;
    text-align: center;
    margin-bottom: 24px;
}

.ds-dashnav__brand-name {
    display: block;
    font-size: var(--ds-headline-md);
    line-height: var(--ds-headline-md-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald);
}

.ds-dashnav__brand-sub {
    display: block;
    margin-top: 2px;
    font-size: 13px;
    color: var(--ds-text-muted);
}

.ds-dashnav__scroll {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ds-dashnav__group {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ds-dashnav__group + .ds-dashnav__group {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--ds-border-divider);
}

.ds-dashnav__group-title {
    padding: 0 12px 6px;
    font-size: var(--ds-label);
    line-height: 16px;
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
}

/* The theme paints native chrome on every <button> (`appearance: button`), and
   logout is a button — reset it here or that one item gets a white box. */
.ds-dashnav__link {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 10px 12px;
    border: 0;
    border-radius: var(--ds-radius-md);
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    color: var(--ds-text-body);
    font-family: var(--ds-font);
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-medium);
    text-align: start;
    text-decoration: none;
    cursor: pointer;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-dashnav__link:hover,
.ds-dashnav__link:focus-visible {
    background: var(--ds-surface-sunken);
    color: var(--ds-text-heading);
    text-decoration: none;
}

.ds-dashnav__link.is-active {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-weight: var(--ds-weight-bold);
}

.ds-dashnav__link--danger {
    color: var(--ds-danger);
}

.ds-dashnav__link--danger:hover {
    background: var(--danger-opacity);
    color: var(--ds-danger);
}

.ds-dashnav__icon {
    flex-shrink: 0;
    font-size: 18px;
}

.ds-dashnav__label {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-dashnav__lock {
    flex-shrink: 0;
    font-size: 12px;
    color: var(--ds-warning);
}

.ds-dashnav__link.is-locked {
    color: var(--ds-text-muted);
}

.ds-dashnav__logout-form {
    margin: 0;
}

/* --- Greeting header (Figma 48:35) ---------------------------------------- */

.ds-dash-head {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 24px;
}

.ds-dash-head__avatar {
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--ds-surface-avatar);
}

.ds-dash-head__text {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-dash-head__title {
    margin: 0;
    font-size: var(--ds-headline-md);
    line-height: var(--ds-headline-md-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-dash-head__sub {
    margin: 2px 0 0;
    font-size: var(--ds-body);
    line-height: 24px;
    color: var(--ds-text-muted);
}

/* The shared layout (layouts/dashboard.blade.php) has no avatar in its header,
   so it needs no left gutter and sits tighter to the content. */
.ds-dash-head--compact {
    margin-bottom: 20px;
}

.ds-dash-head__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    flex-shrink: 0;
}

/* Wrapper the shared layout drops each page's old theme markup into. The theme's
   own `.rbt-*` blocks bring their own spacing, so this only supplies the panel. */
.ds-dash-page__content > .section-title:first-child,
.ds-dash-page__content > .row:first-child {
    margin-top: 0;
}

.ds-dash-head__action {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    padding: 11px 22px;
    border: 0;
    border-radius: var(--ds-radius-md);
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
    white-space: nowrap;
}

.ds-dash-head__action:hover {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

/* --- Notices -------------------------------------------------------------- */

.ds-notice {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 24px;
    padding: 16px 20px;
    border: 1px solid transparent;
    border-radius: var(--ds-radius-lg);
    font-size: 14px;
    line-height: 22px;
}

.ds-notice > i {
    flex-shrink: 0;
    font-size: 20px;
}

.ds-notice > div {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ds-notice form {
    margin: 0;
}

.ds-notice--success {
    background: var(--ds-emerald-soft);
    border-color: rgba(16, 185, 129, 0.3);
    color: #047857;
}

.ds-notice--warning {
    background: rgba(245, 158, 11, 0.12);
    border-color: rgba(245, 158, 11, 0.35);
    color: #92400e;
}

.ds-notice--danger {
    background: var(--danger-opacity);
    border-color: rgba(186, 26, 26, 0.25);
    color: var(--ds-danger);
}

.ds-notice__action {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    padding: 8px 16px;
    border: 1px solid currentColor;
    border-radius: var(--ds-radius-md);
    -webkit-appearance: none;
    appearance: none;
    background: var(--ds-surface);
    color: inherit;
    font-family: var(--ds-font);
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.ds-notice__action:hover {
    background: transparent;
    color: inherit;
    text-decoration: none;
}

/* --- Stat tiles ----------------------------------------------------------- */

.ds-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

/* No lift and no scale on hover — see the motion rule at the top of this
   section. `min-height` keeps a one-line and a two-line label level, and
   `margin-top: auto` on the label pins the text to the bottom either way. */
.ds-stat {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-height: 152px;
    padding: 20px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-card);
    text-decoration: none;
    transition: border-color 0.2s ease;
}

.ds-stat:hover {
    border-color: var(--ds-emerald);
    text-decoration: none;
}

.ds-stat__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ds-tile-md);
    height: var(--ds-tile-md);
    margin-bottom: auto;
    border-radius: var(--ds-radius-md);
    font-size: 20px;
}

.ds-stat__value {
    font-size: 28px;
    line-height: 34px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-stat__label {
    font-size: 14px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-stat--emerald .ds-stat__icon {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

.ds-stat--navy .ds-stat__icon {
    background: rgba(19, 27, 46, 0.08);
    color: var(--ds-navy);
}

.ds-stat--amber .ds-stat__icon {
    background: rgba(245, 158, 11, 0.14);
    color: #b45309;
}

.ds-stat--slate .ds-stat__icon {
    background: rgba(30, 41, 59, 0.08);
    color: var(--ds-slate);
}

/* Compact secondary counters (admin) */
.ds-ministats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
    margin-bottom: 24px;
}

.ds-ministat {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    font-size: 13px;
    color: var(--ds-text-muted);
    text-decoration: none;
}

.ds-ministat:hover {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
    text-decoration: none;
}

.ds-ministat > i {
    color: var(--ds-emerald);
    font-size: 16px;
}

.ds-ministat__value {
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-ministat__label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Content grid & panels ------------------------------------------------ */

.ds-dash-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 24px;
    align-items: start;
}

.ds-dash-grid__main,
.ds-dash-grid__side {
    min-width: 0;
}

.ds-panel {
    padding: 24px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-card);
}

.ds-panel + .ds-panel {
    margin-top: 24px;
}

.ds-panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 20px;
}

.ds-panel__title {
    margin: 0;
    font-size: 20px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-panel__link {
    flex-shrink: 0;
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-panel__link:hover {
    color: var(--ds-emerald-hover);
    text-decoration: underline;
}

/* --- Status tag ------------------------------------------------------------
   Deliberately NOT .ds-badge: that one (section 7) is the solid 16px hero badge.
   This is the small soft pill used for statuses inside dashboard panels. */

.ds-tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: var(--ds-radius-pill);
    font-size: 12px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
    white-space: nowrap;
}

.ds-tag--emerald {
    background: var(--ds-emerald-soft);
    color: #047857;
}

.ds-tag--amber {
    background: rgba(245, 158, 11, 0.14);
    color: #b45309;
}

.ds-tag--danger {
    background: var(--danger-opacity);
    color: var(--ds-danger);
}

.ds-tag--navy {
    background: rgba(19, 27, 46, 0.08);
    color: var(--ds-navy);
}

.ds-tag--slate {
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
}

/* --- Course card (Figma 49:300) ------------------------------------------- */

.ds-course-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

.ds-course-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    height: 100%;
    min-height: 232px;
    padding: 20px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-card);
}

/* A bare .ds-tag is a flex child here and would stretch the full width. */
.ds-course-card > .ds-tag {
    align-self: flex-start;
}

.ds-course-card__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.ds-course-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: var(--ds-tile-md);
    height: var(--ds-tile-md);
    border-radius: var(--ds-radius-md);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 20px;
}

.ds-course-card__chip {
    padding: 4px 12px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-chip-bg);
    color: var(--ds-chip-text);
    font-size: 12px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ds-course-card__title {
    margin: 0;
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-bold);
}

.ds-course-card__title a {
    color: var(--ds-text-heading);
    text-decoration: none;
}

.ds-course-card__title a:hover {
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-course-card__meta {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 14px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-course-card__progress-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}

.ds-course-card__progress-label {
    font-size: 13px;
    color: var(--ds-text-muted);
}

.ds-course-card__progress-value {
    font-size: 13px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald);
}

.ds-course-card__bar {
    height: 8px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    overflow: hidden;
}

.ds-course-card__bar-fill {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--ds-emerald);
}

/* margin-top:auto here rather than on the progress block, so cards without a
   progress bar still line their buttons up across the row. */
.ds-course-card__cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-top: auto;
    padding: 12px 16px;
    border-radius: var(--ds-radius-md);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
}

.ds-course-card__cta:hover {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

/* --- List rows (Figma 49:430) --------------------------------------------- */

.ds-rows {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ds-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--ds-border-divider);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    transition: background-color 0.2s ease;
}

.ds-row:hover {
    background: var(--ds-surface-sunken);
}

.ds-row.is-highlight {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
}

/* In an RTL flex column the cross axis follows `direction`, so flex-start is
   the right edge — the anchored one. Never use flex-end here. */
.ds-row__stat {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    flex-shrink: 0;
    min-width: 48px;
}

.ds-row__stat-value {
    font-size: 15px;
    line-height: 20px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-row__stat-sub {
    font-size: 11px;
    line-height: 16px;
    color: var(--ds-text-muted);
}

.ds-row__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border-radius: var(--ds-radius-sm);
    font-size: 16px;
}

.ds-row__icon--emerald {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

.ds-row__icon--amber {
    background: rgba(245, 158, 11, 0.14);
    color: #b45309;
}

.ds-row__icon--danger {
    background: var(--danger-opacity);
    color: var(--ds-danger);
}

.ds-row__icon--slate {
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
}

.ds-row__avatar {
    flex-shrink: 0;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border-radius: 50%;
    object-fit: cover;
    background: var(--ds-surface-avatar);
}

.ds-row__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}

.ds-row__title {
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ds-row__title a {
    color: inherit;
    text-decoration: none;
}

.ds-row__title a:hover {
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-row__meta {
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ds-row__end {
    flex-shrink: 0;
}

.ds-row__action {
    display: inline-flex;
    align-items: center;
    padding: 6px 14px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
    white-space: nowrap;
}

.ds-row__action:hover {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

/* Laravel's paginator markup, boxed under a panel's rows. */
.ds-pagination {
    display: flex;
    justify-content: center;
    margin-top: 24px;
}

.ds-pagination .pagination {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-pagination .page-link,
.ds-pagination .pagination li > span,
.ds-pagination .pagination li > a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 10px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    color: var(--ds-text-body);
    font-size: 14px;
    text-decoration: none;
}

.ds-pagination .pagination li > a:hover {
    border-color: var(--ds-emerald);
    color: var(--ds-emerald);
}

.ds-pagination .pagination .active > span,
.ds-pagination .pagination li.active > a {
    border-color: transparent;
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.ds-pagination .pagination .disabled > span {
    opacity: 0.45;
}

/* --- Empty states --------------------------------------------------------- */

.ds-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 32px 16px;
    text-align: center;
}

.ds-empty--sm {
    gap: 8px;
    padding: 24px 12px;
}

.ds-empty__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
    font-size: 24px;
}

.ds-empty--sm .ds-empty__icon {
    width: 44px;
    height: 44px;
    font-size: 20px;
}

.ds-empty__text {
    max-width: 42ch;
    margin: 0;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-muted);
}

.ds-empty__action {
    display: inline-flex;
    align-items: center;
    padding: 9px 20px;
    border: 0;
    border-radius: var(--ds-radius-md);
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
}

.ds-empty__action:hover {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

/* --- Profile overview (/account) ------------------------------------------ */

.ds-profile-hero {
    margin-bottom: 24px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-card);
    overflow: hidden;
}

.ds-profile-hero__cover {
    height: 160px;
    background-color: var(--ds-surface-sunken);
    background-size: cover;
    background-position: center;
}

.ds-profile-hero__body {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    padding: 0 24px 24px;
}

.ds-profile-hero__avatar {
    flex-shrink: 0;
    width: 104px;
    height: 104px;
    margin-top: -52px;
    border: 4px solid var(--ds-surface);
    border-radius: 50%;
    object-fit: cover;
    background: var(--ds-surface-avatar);
}

.ds-profile-hero__text {
    flex: 1 1 auto;
    min-width: 0;
    padding-top: 16px;
}

.ds-profile-hero__name {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
    font-size: 24px;
    line-height: 32px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-profile-hero__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
    margin: 8px 0 0;
    padding: 0;
    list-style: none;
    font-size: 14px;
    color: var(--ds-text-muted);
}

.ds-profile-hero__meta li {
    display: flex;
    align-items: center;
    gap: 6px;
}

.ds-profile-hero__bio {
    max-width: 60ch;
    margin: 12px 0 0;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
}

.ds-profile-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    flex-shrink: 0;
    padding-top: 16px;
}

.ds-profile-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px;
    align-items: start;
}

/* Definition list — the theme gives dl/dd their own margins, so reset. */
.ds-info {
    margin: 0;
}

.ds-info__row {
    display: flex;
    /* align-items: baseline; */
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--ds-border-divider);
}

.ds-info__row:first-child {
    padding-top: 0;
}

.ds-info__row:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.ds-info__key {
    flex: 0 0 38%;
    max-width: 170px;
    margin: 0;
    font-size: 13px;
    line-height: 20px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-muted);
}

.ds-info__value {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 14px;
    line-height: 22px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-heading);
    overflow-wrap: anywhere;
}

.ds-info__blank {
    color: var(--ds-text-placeholder);
    font-weight: var(--ds-weight-regular);
    font-style: italic;
}

.ds-info__hint {
    font-size: 12px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-muted);
}

.ds-sociallist,
.ds-actionlist {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ds-sociallist__item,
.ds-actionlist__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--ds-border-divider);
    border-radius: var(--ds-radius-md);
    color: var(--ds-text-body);
    text-decoration: none;
    transition:
        border-color 0.2s ease,
        background-color 0.2s ease;
}

.ds-sociallist__item:hover,
.ds-actionlist__item:hover {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
    text-decoration: none;
}

.ds-sociallist__icon,
.ds-actionlist__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border-radius: 50%;
    background: var(--ds-surface-sunken);
    color: var(--ds-text-body);
    font-size: 15px;
}

.ds-sociallist__label {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-sociallist__go,
.ds-actionlist__go {
    flex-shrink: 0;
    font-size: 15px;
    color: var(--ds-text-muted);
}

.ds-actionlist__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}

.ds-actionlist__title {
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-actionlist__meta {
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

.ds-actionlist__item--danger .ds-actionlist__icon {
    background: var(--danger-opacity);
    color: var(--ds-danger);
}

.ds-actionlist__item--danger:hover {
    border-color: var(--ds-danger);
    background: var(--danger-opacity);
}

/* --- Responsive ----------------------------------------------------------- */

@media (max-width: 1199.98px) {
    .ds-dash-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .ds-ministats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* The side column now sits under the main one, so its panels need the gap
       the grid used to provide. */
    .ds-dash-grid__side > .ds-panel:first-child {
        margin-top: 24px;
    }
}

@media (max-width: 991.98px) {
    .ds-dash {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }

    /* The sidebar becomes a horizontally scrollable pill row above the content.
       The bottom bar stays exactly as it is — nothing here touches it. */
    .ds-dash__aside {
        position: static;
    }

    .ds-dashnav {
        padding: 8px;
        border-radius: var(--ds-radius-lg);
    }

    .ds-dashnav__brand {
        display: none;
    }

    .ds-dashnav__scroll {
        flex-direction: row;
        flex-wrap: nowrap;
        gap: 8px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .ds-dashnav__scroll::-webkit-scrollbar {
        display: none;
    }

    /* display:contents dissolves the groups so every link becomes a direct flex
       item of the scroller — that is what makes one continuous row out of the
       grouped desktop markup. Same trick for the logout <form>. */
    .ds-dashnav__group,
    .ds-dashnav__logout-form {
        display: contents;
    }

    .ds-dashnav__group-title {
        display: none;
    }

    .ds-dashnav__link {
        flex: 0 0 auto;
        width: auto;
        padding: 8px 14px;
        border: 1px solid var(--ds-border-subtle);
        border-radius: var(--ds-radius-pill);
        background: var(--ds-surface);
        font-size: 14px;
        white-space: nowrap;
    }

    .ds-dashnav__link.is-active {
        border-color: transparent;
        background: var(--ds-emerald-soft);
    }

    .ds-dashnav__label {
        flex: 0 0 auto;
    }

    .ds-profile-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .ds-profile-hero__body {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    .ds-profile-hero__text,
    .ds-profile-hero__actions {
        padding-top: 0;
    }
}

@media (max-width: 767.98px) {
    .ds-dash-page {
        padding-top: 20px;
        padding-bottom: 40px;
    }

    .ds-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .ds-course-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .ds-panel {
        padding: 18px;
        border-radius: var(--ds-radius-lg);
    }

    .ds-dash-head__title {
        font-size: 20px;
        line-height: 28px;
    }

    .ds-dash-head__sub {
        font-size: 14px;
        line-height: 20px;
    }

    .ds-dash-head__action {
        width: 100%;
        justify-content: center;
    }

    .ds-dash-head {
        flex-wrap: wrap;
    }

    .ds-notice {
        flex-wrap: wrap;
    }

    .ds-info__row {
        flex-direction: column;
        gap: 4px;
    }

    .ds-info__key {
        flex: 0 0 auto;
        max-width: none;
    }
}

@media (max-width: 575.98px) {
    .ds-stat {
        padding: 16px;
    }

    .ds-stat__value {
        font-size: 24px;
        line-height: 30px;
    }

    .ds-ministats {
        grid-template-columns: minmax(0, 1fr);
    }

    .ds-profile-hero__cover {
        height: 120px;
    }

    .ds-profile-hero__avatar {
        width: 84px;
        height: 84px;
        margin-top: -42px;
    }
}

/* ==========================================================================
   22. Account forms (.ds-form*, .ds-cover*, .ds-danger*)
   The panes on /account. Inputs, selects, textareas and labels are already
   themed by section 5 — this section is layout, grouping and the few bespoke
   blocks (cover/avatar editor, the links repeater, the delete-account box).

   Same motion rule as section 21: no hover transforms anywhere.
   ========================================================================== */

.ds-pane-head {
    margin-bottom: 24px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--ds-border-divider);
}

.ds-pane-head__title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 20px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-pane-head__text {
    margin: 6px 0 0;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-muted);
}

.ds-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px 24px;
}

.ds-form__full {
    grid-column: 1 / -1;
}

.ds-field {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.ds-field > label {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-field > label i {
    color: var(--ds-text-muted);
    font-size: 15px;
}

.ds-field input,
.ds-field select,
.ds-field textarea {
    width: 100%;
    padding: 11px 16px;
    font-size: 15px;
}

.ds-field textarea {
    min-height: 120px;
    resize: vertical;
}

/* A value that is shown but not editable (the email address). */
.ds-field__static {
    padding: 11px 16px;
    border: 1px solid var(--ds-border-divider);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-body);
    font-size: 15px;
}

.ds-field__hint {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

.ds-field__error {
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-danger);
}

.ds-form__actions {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 4px;
    padding-top: 20px;
    border-top: 1px solid var(--ds-border-divider);
}

/* main.js turns every select into a bootstrap-select widget, and the address
   pane's country -> state AJAX drives it through that API — so the widget stays
   and gets dressed to match .ds-field inputs instead of being opted out. */
.ds-field .bootstrap-select > .dropdown-toggle,
.ds-field .filter-select .dropdown-toggle {
    width: 100%;
    padding: 11px 16px;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    color: var(--ds-text-heading);
    font-family: var(--ds-font);
    font-size: 15px;
    line-height: 24px;
    box-shadow: none;
}

.ds-field .bootstrap-select > .dropdown-toggle:focus,
.ds-field .bootstrap-select.show > .dropdown-toggle {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
    outline: none !important;
}

.ds-field .bootstrap-select .dropdown-menu {
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    box-shadow: var(--ds-shadow-raised);
}

/* --- Cover + avatar editor ------------------------------------------------ */

.ds-cover {
    position: relative;
    margin-bottom: 32px;
    border-radius: var(--ds-radius-lg);
    overflow: hidden;
}

.ds-cover__img {
    height: 200px;
    background-color: var(--ds-surface-sunken);
    background-size: cover;
    background-position: center;
}

.ds-cover__actions {
    position: absolute;
    inset-block-start: 16px;
    inset-inline-end: 16px;
}

/* Both triggers are <label for="...file input">, so they need the button reset
   and an explicit cursor. */
.ds-cover__btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 8px 16px;
    border-radius: var(--ds-radius-md);
    background: rgba(255, 255, 255, 0.92);
    color: var(--ds-text-heading);
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    cursor: pointer;
}

.ds-cover__btn:hover {
    background: #fff;
}

.ds-cover__avatar {
    position: absolute;
    inset-block-end: 16px;
    inset-inline-start: 24px;
    width: 96px;
    height: 96px;
}

.ds-cover__avatar img {
    width: 100%;
    height: 100%;
    border: 4px solid var(--ds-surface);
    border-radius: 50%;
    object-fit: cover;
    background: var(--ds-surface-avatar);
}

.ds-cover__avatar-btn {
    position: absolute;
    inset-block-end: 2px;
    inset-inline-end: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin: 0;
    border: 2px solid var(--ds-surface);
    border-radius: 50%;
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 13px;
    cursor: pointer;
}

.ds-cover__avatar-btn:hover {
    background: var(--ds-emerald-hover);
}

/* --- Repeater (instructor reels) ------------------------------------------ */

.ds-repeater {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.ds-repeater__item {
    display: flex;
    align-items: center;
    gap: 10px;
}

.ds-repeater__item input {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-repeater__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    -webkit-appearance: none;
    appearance: none;
    background: var(--ds-surface);
    color: var(--ds-danger);
    cursor: pointer;
}

.ds-repeater__remove:hover {
    border-color: var(--ds-danger);
    background: var(--danger-opacity);
}

/* --- Danger zone ---------------------------------------------------------- */

.ds-danger {
    padding: 20px;
    border: 1px solid rgba(186, 26, 26, 0.25);
    border-radius: var(--ds-radius-lg);
    background: var(--danger-opacity);
    color: var(--ds-danger);
}

.ds-danger--warning {
    border-color: rgba(245, 158, 11, 0.35);
    background: rgba(245, 158, 11, 0.12);
    color: #92400e;
}

.ds-danger__title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    font-size: 16px;
    font-weight: var(--ds-weight-bold);
    color: inherit;
}

.ds-danger__text {
    margin: 0 0 8px;
    font-size: 14px;
    line-height: 22px;
    color: inherit;
}

.ds-danger__list {
    margin: 0 0 8px;
    padding-inline-start: 20px;
    font-size: 14px;
    line-height: 22px;
    color: inherit;
}

.ds-danger__text:last-child,
.ds-danger__list:last-child {
    margin-bottom: 0;
}

.ds-btn--danger {
    background: var(--ds-danger);
    color: var(--ds-text-on-dark);
    box-shadow: none;
}

.ds-btn--danger:hover {
    background: #9a1616;
    color: var(--ds-text-on-dark);
}

/* --- Help video cards (/account/help) ------------------------------------- */

.ds-video-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
}

.ds-video-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface);
    box-shadow: var(--ds-shadow-card);
    overflow: hidden;
}

/* The thumbnail is a magnific-popup trigger (.popup-video), not an embed. */
.ds-video-card__thumb {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    background: var(--ds-surface-sunken);
    overflow: hidden;
}

.ds-video-card__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ds-video-card__play {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    /* RTL: inset-inline-start + a positive X translate centres it */
    transform: translate(50%, -50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    color: var(--ds-emerald);
    font-size: 20px;
}

.ds-video-card__thumb:hover .ds-video-card__play {
    background: #fff;
}

.ds-video-card__body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 16px;
}

.ds-video-card__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 2px;
}

.ds-video-card__admin {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--ds-border-divider);
}

.ds-video-card__admin form {
    margin: 0;
}

.ds-video-card__title {
    margin: 0;
    font-size: 16px;
    line-height: 24px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-video-card__text {
    margin: 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

/* --- Responsive ----------------------------------------------------------- */

@media (max-width: 767.98px) {
    .ds-form {
        grid-template-columns: minmax(0, 1fr);
        gap: 16px;
    }

    .ds-cover__img {
        height: 150px;
    }

    .ds-cover__avatar {
        width: 76px;
        height: 76px;
        inset-inline-start: 16px;
    }

    .ds-form__actions .ds-btn {
        width: 100%;
    }
}

/* Utility surfaces */
.ds-surface {
    background: var(--ds-surface);
}

.ds-surface--sunken {
    background: var(--ds-surface-sunken);
}

.ds-surface--navy {
    background: var(--ds-navy);
    color: var(--ds-text-on-dark);
}

.bg-color-primary,
.ds-bg-primary {
    background-color: var(--ds-emerald) !important;
}

.color-primary,
.ds-text-primary {
    color: var(--ds-emerald) !important;
}

/* ==========================================================================
   23. Dashboard page content (.ds-dash-page__content)
   Everything inside the .ds-panel that layouts/dashboard.blade.php drops each
   page into — i.e. every view that @extends('layouts.dashboard').

   WHY THIS IS A SCOPED REMAP AND NOT 60-ODD REWRITTEN BLADE FILES
   ------------------------------------------------------------------------
   Those pages are ~26k lines of the vendor theme's `rbt-*` / Bootstrap markup
   and they share a small, repetitive vocabulary: .section-title, .rbt-table,
   .rbt-badge-5, .alert, .course-field, .rbt-modern-select, .rbt-btn,
   .tab-button-style-2, .rbt-accordion-style, .rbt-card. Restyling that
   vocabulary once — scoped so it cannot leak onto the public site — puts every
   dashboard page on the design system in one place, exactly the way section 2
   rethemes the 39k-line vendor stylesheet without editing it.

   Pages still get converted to native .ds-* markup one at a time. This section
   is what the ones that haven't been converted yet look like, and it is also
   the safety net for any page that keeps theme markup on purpose.

   SPECIFICITY — the theme's rules are mostly (0,2,2) and rtl-style.css loads
   AFTER this file. Every override here leads with `.ds-dash-page__content`,
   which buys a class and puts these at (0,3,x). Where rtl-style.css uses
   !important (it does for RTL padding on radios/labels) the override must be
   !important too. Check both files before assuming a rule "doesn't apply".

   MOTION — section 21's rule holds here: nothing in the dashboard moves on
   hover. Hover may change background-color, border-color and color only. The
   theme's .hover-icon-reverse sliding-arrow button is therefore neutralised
   below rather than restyled.
   ========================================================================== */

/* --- The panel itself ----------------------------------------------------- */

.ds-dash-page__content {
    min-width: 0;
}

/* Pages converted to native .ds-* markup bring their own .ds-panel blocks, so
   the shared one would nest a card inside a card. They opt out with
   @section('content-modifier', 'ds-dash-page__content--bare') — the class
   itself has to stay, because everything below hangs off it. */
.ds-dash-page__content--bare {
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

/* The theme's blocks bring their own top/bottom margins; strip them at the
   edges so the panel's own 24px padding is the only gutter. */
.ds-dash-page__content > *:first-child,
.ds-dash-page__content > form > *:first-child {
    margin-top: 0;
}

.ds-dash-page__content > *:last-child,
.ds-dash-page__content > form > *:last-child {
    margin-bottom: 0;
}

/* Card-in-card. Many pages wrap their whole body in the theme's shadow-box
   card, which is now sitting inside our .ds-panel — two borders, two radii,
   48px of doubled padding. Flatten the inner one. `.rbt-hover` is excluded:
   that modifier marks the real course cards further down, which stay cards. */
.ds-dash-page__content .rbt-card.rbt-shadow-box,
.ds-dash-page__content .rbt-card.rbt-gradient-border,
.ds-dash-page__content .rbt-shadow-box:not(.rbt-card) {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
}

.ds-dash-page__content .rbt-card.rbt-shadow-box > .rbt-card-body,
.ds-dash-page__content .rbt-card.rbt-gradient-border > .rbt-card-body,
.ds-dash-page__content .rbt-card.rbt-shadow-box .rbt-pd-20,
.ds-dash-page__content .rbt-card.rbt-gradient-border .rbt-pd-20 {
    padding: 0;
}

/* --- Headings (.section-title / .rbt-title-style-3) ----------------------- */

.ds-dash-page__content .section-title {
    margin-bottom: 24px;
}

.ds-dash-page__content .section-title h1,
.ds-dash-page__content .section-title h2,
.ds-dash-page__content .section-title h3,
.ds-dash-page__content .section-title h4,
.ds-dash-page__content .rbt-title-style-3 {
    margin: 0;
    font-family: var(--ds-font);
    font-size: 20px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-dash-page__content .section-title p {
    margin: 6px 0 0;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-muted);
}

.ds-dash-page__content .section-title p strong {
    color: var(--ds-text-heading);
    font-weight: var(--ds-weight-semibold);
}

/* Bare headings the pages scatter as field-group labels */
.ds-dash-page__content h4:not([class]),
.ds-dash-page__content h5:not([class]) {
    font-size: 17px;
    line-height: 26px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-dash-page__content h6:not([class]) {
    font-size: 15px;
    line-height: 24px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
    margin-bottom: 8px;
}

/* --- Tabs (.tab-button-style-2) ------------------------------------------
   The theme paints these as a full-width underlined bar. The design system has
   no underline tabs — this becomes the same sunken segmented control the
   search panel (section 18) uses.

   `.tab-button-style-2 li a` is (0,2,1) and sets padding/border/box-shadow, and
   `li a .title` is (0,3,1) and sets font-size — so the title rule below has to
   carry the same shape to win. */

.ds-dash-page__content .advance-tab-button {
    margin-bottom: 24px;
}

.ds-dash-page__content .nav-tabs.tab-button-style-2,
.ds-dash-page__content ul.tab-button-style-2 {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    max-width: 100%;
    margin: 0;
    padding: 4px;
    border: 0;
    border-bottom: 0;
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
    justify-content: flex-start;
}

.ds-dash-page__content .tab-button-style-2 li a,
.ds-dash-page__content .tab-button-style-2 li .tab-button {
    padding: 9px 20px;
    border: 0;
    border-radius: var(--ds-radius-sm);
    background: transparent;
    color: var(--ds-text-muted);
    box-shadow: none;
    text-decoration: none;
    transition:
        background-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

/* Kill the theme's sliding 2px underline — motion rule. */
.ds-dash-page__content .tab-button-style-2 li a::after,
.ds-dash-page__content .tab-button-style-2 li a::before {
    display: none;
}

.ds-dash-page__content .tab-button-style-2 li a:hover {
    background: rgba(19, 27, 46, 0.05);
    color: var(--ds-text-heading);
}

.ds-dash-page__content .tab-button-style-2 li a.active {
    background: var(--ds-surface);
    color: var(--ds-emerald);
    box-shadow: var(--ds-shadow-card);
}

.ds-dash-page__content .tab-button-style-2 li a .title {
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: inherit;
    margin-bottom: 0;
}

/* --- Filter / toolbar row ------------------------------------------------- */

.ds-dash-page__content .rbt-dashboard-filter-wrapper {
    padding: 16px;
    margin-bottom: 24px;
    background: var(--ds-surface-sunken);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
}

.ds-dash-page__content .rbt-dashboard-filter-wrapper .filter-select label,
.ds-dash-page__content .filter-select .select-label {
    display: block;
    margin-bottom: 6px;
    font-size: var(--ds-label);
    line-height: 16px;
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
}

/* --- Tables (.rbt-dashboard-table / .rbt-table) ---------------------------
   The theme zebra-stripes with --color-grey and paints the head with
   --primary-opacity, which the token remap turned into a wash of emerald
   across the whole header row. Replaced with one hairline-ruled table on a
   sunken header — the shape in Figma "Student Dashboard (Table)" (49:430). */

.ds-dash-page__content .rbt-dashboard-table {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    overflow-x: auto;
}

.ds-dash-page__content .rbt-dashboard-table .rbt-table,
.ds-dash-page__content .rbt-table,
.ds-dash-page__content table.table {
    margin: 0;
    border: 0;
    border-collapse: collapse;
    width: 100%;
}

.ds-dash-page__content .rbt-table tr th,
.ds-dash-page__content .rbt-table tr td,
.ds-dash-page__content table.table tr th,
.ds-dash-page__content table.table tr td {
    padding: 14px 16px;
    border: 0;
    vertical-align: middle;
}

.ds-dash-page__content .rbt-table thead tr th,
.ds-dash-page__content .rbt-table thead tr td,
.ds-dash-page__content table.table thead tr th {
    background: var(--ds-surface-sunken);
    border-bottom: 1px solid var(--ds-border-subtle);
    font-size: 13px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
    white-space: nowrap;
}

.ds-dash-page__content .rbt-table tbody tr th,
.ds-dash-page__content .rbt-table tbody tr td,
.ds-dash-page__content table.table tbody tr td,
.ds-dash-page__content table.table tbody tr th {
    font-size: 14px;
    line-height: 22px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-body);
    background: transparent;
}

/* (0,3,2) — has to beat the theme's :nth-child(even) zebra at (0,2,2). */
.ds-dash-page__content .rbt-table tbody tr:nth-child(even) th,
.ds-dash-page__content .rbt-table tbody tr:nth-child(even) td {
    background: transparent;
}

.ds-dash-page__content .rbt-table tbody tr + tr th,
.ds-dash-page__content .rbt-table tbody tr + tr td,
.ds-dash-page__content table.table tbody tr + tr td,
.ds-dash-page__content table.table tbody tr + tr th {
    border-top: 1px solid var(--ds-border-divider);
}

.ds-dash-page__content .rbt-table tbody tr:hover th,
.ds-dash-page__content .rbt-table tbody tr:hover td {
    background: var(--ds-surface-sunken);
}

/* Row-leading <th> — most of these tables use it for the id/name cell. */
.ds-dash-page__content .rbt-table tbody tr th {
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-dash-page__content .rbt-table tfoot tr th,
.ds-dash-page__content .rbt-table tfoot tr td {
    background: var(--ds-surface-sunken);
    border-top: 1px solid var(--ds-border-subtle);
    font-size: 14px;
    color: var(--ds-text-heading);
}

.ds-dash-page__content .rbt-table a {
    color: var(--ds-text-heading);
    font-weight: var(--ds-weight-medium);
    text-decoration: none;
}

.ds-dash-page__content .rbt-table a:hover {
    color: var(--ds-emerald);
}

/* An empty-state row spans the table — give it room so the notice inside it
   reads as the panel's own empty state. */
.ds-dash-page__content .rbt-table tbody tr td[colspan] {
    padding: 32px 16px;
}

/* --- Status badges (.rbt-badge-5 + the theme's bg-color-*-opacity pairs) ---
   The theme's colour pairs are applied as two utility classes on the same
   element, so each tone is matched on the utility rather than a modifier. */

.ds-dash-page__content .rbt-badge-5,
.ds-dash-page__content .badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: max-content;
    height: auto;
    padding: 4px 12px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
    font-size: 12px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
    white-space: nowrap;
}

.ds-dash-page__content .rbt-badge-5.color-success,
.ds-dash-page__content .badge.bg-success,
.ds-dash-page__content .rbt-badge-5.bg-primary-opacity {
    background: var(--ds-emerald-soft);
    color: #047857;
}

.ds-dash-page__content .rbt-badge-5.color-warning,
.ds-dash-page__content .badge.bg-warning {
    background: rgba(245, 158, 11, 0.14);
    color: #b45309;
}

.ds-dash-page__content .rbt-badge-5.color-danger,
.ds-dash-page__content .badge.bg-danger {
    background: rgba(186, 26, 26, 0.1);
    color: var(--ds-danger);
}

.ds-dash-page__content .rbt-badge-5.color-secondary,
.ds-dash-page__content .badge.bg-secondary {
    background: rgba(19, 27, 46, 0.08);
    color: var(--ds-navy);
}

/* --- Alerts --------------------------------------------------------------
   Bootstrap alerts do three different jobs across these pages: validation
   errors (alert-danger, usually via <x-input-error>), inline notes
   (alert-info/warning) and centred empty states (alert-info inside a colspan
   cell or a .col-12). All three get the .ds-notice treatment. */

.ds-dash-page__content .alert {
    padding: 14px 18px;
    margin-bottom: 16px;
    border: 1px solid transparent;
    border-radius: var(--ds-radius-md);
    font-size: 14px;
    line-height: 22px;
}

.ds-dash-page__content .alert p:last-child,
.ds-dash-page__content .alert ul:last-child {
    margin-bottom: 0;
}

.ds-dash-page__content .alert ul {
    padding-inline-start: 18px;
}

.ds-dash-page__content .alert-danger {
    background: rgba(186, 26, 26, 0.07);
    border-color: rgba(186, 26, 26, 0.2);
    color: var(--ds-danger);
}

.ds-dash-page__content .alert-warning {
    background: rgba(245, 158, 11, 0.1);
    border-color: rgba(245, 158, 11, 0.25);
    color: #b45309;
}

.ds-dash-page__content .alert-success {
    background: var(--ds-emerald-soft);
    border-color: rgba(16, 185, 129, 0.25);
    color: #047857;
}

.ds-dash-page__content .alert-info,
.ds-dash-page__content .alert-secondary {
    background: var(--ds-surface-sunken);
    border-color: var(--ds-border-subtle);
    color: var(--ds-text-muted);
}

/* <x-input-error> renders `alert alert-danger mt-2` under a field — it should
   read as field help, not as a page-level banner. */
.ds-dash-page__content .course-field .alert-danger,
.ds-dash-page__content .form-group + .alert-danger,
.ds-dash-page__content [class*="col-"] > .alert-danger:last-child {
    padding: 0;
    margin-top: 6px;
    margin-bottom: 0;
    background: transparent;
    border: 0;
    font-size: 13px;
    line-height: 20px;
}

/* --- Forms ---------------------------------------------------------------
   Sections 5 and 22 already theme the controls themselves. What is left is the
   theme's field wrappers, which these pages use instead of .ds-field. */

.ds-dash-page__content .rbt-course-field-wrapper > .course-field:last-child,
.ds-dash-page__content .course-field:last-child {
    margin-bottom: 0;
}

.ds-dash-page__content .course-field > label,
.ds-dash-page__content .rbt-default-form label {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

/* Grey inset group inside a form (course settings, pricing) */
.ds-dash-page__content .course-field.edu-bg-gray {
    padding: 20px;
    background: var(--ds-surface-sunken);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
}

/* Field hints — `small.d-block` with a feather-info glyph */
.ds-dash-page__content .course-field small,
.ds-dash-page__content .form-group small {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-dash-page__content .course-field small i {
    margin-inline-end: 4px;
    color: var(--ds-text-placeholder);
}

.ds-dash-page__content .course-field small a {
    color: var(--ds-emerald);
}

/* The theme's floating-label group (`.form-group > input + label + .focus-border`).
   The label is absolutely positioned over the field and animates on focus; the
   design system puts labels above fields, and every page using this group
   already prints a heading above it, so the floating copy is redundant chrome
   that overlaps the value. Hide it rather than re-teach the animation. */
.ds-dash-page__content .form-group {
    margin-bottom: 0;
    position: relative;
}

.ds-dash-page__content .form-group > label {
    display: none;
}

.ds-dash-page__content .form-group .focus-border {
    display: none;
}

.ds-dash-page__content .form-group > input,
.ds-dash-page__content .form-group > textarea {
    width: 100%;
}

/* bootstrap-select widget — dressed to match .ds-field, the same call section 22
   makes for the address pane (that widget cannot be opted out of with
   data-no-picker because JS drives it through selectpicker('val')). */
.ds-dash-page__content .rbt-modern-select .dropdown-toggle,
.ds-dash-page__content .rbt-modern-select .btn.dropdown-toggle {
    padding: 12px 21px;
    height: auto;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    box-shadow: none;
    font-family: var(--ds-font);
    font-size: var(--ds-body);
    line-height: 24px;
    color: var(--ds-text-heading);
}

.ds-dash-page__content .rbt-modern-select .dropdown-toggle:focus,
.ds-dash-page__content .rbt-modern-select.show .dropdown-toggle {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
    outline: none;
}

.ds-dash-page__content .rbt-modern-select .dropdown-menu {
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    box-shadow: var(--ds-shadow-raised);
    padding: 6px;
}

.ds-dash-page__content .rbt-modern-select .dropdown-menu li a {
    border-radius: var(--ds-radius-sm);
    padding: 8px 12px;
    font-size: 14px;
    color: var(--ds-text-body);
}

.ds-dash-page__content .rbt-modern-select .dropdown-menu li a.selected,
.ds-dash-page__content .rbt-modern-select .dropdown-menu li a:hover {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

/* .height-45 hard-codes a 45px control; the design system's is taller. */
.ds-dash-page__content .rbt-modern-select.height-45 .dropdown-toggle,
.ds-dash-page__content .rbt-modern-select.height-45 select {
    height: auto;
}

.ds-dash-page__content .form-check {
    padding-inline-start: 0;
    margin-bottom: 8px;
}

.ds-dash-page__content .form-check-label {
    font-size: 14px;
    line-height: 22px;
}

/* --- Buttons -------------------------------------------------------------
   Section 4's .rbt-btn is the marketing button: 16px text, 16px/48px padding.
   Far too large for a dense table toolbar, so it is scaled down here and only
   here — the public site keeps the big one. */

.ds-dash-page__content .rbt-btn {
    padding: 11px 24px;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    box-shadow: none;
}

.ds-dash-page__content .rbt-btn.btn-sm {
    padding: 9px 18px;
    font-size: 13px;
    line-height: 18px;
}

.ds-dash-page__content .rbt-btn.btn-xs {
    padding: 6px 14px;
    font-size: 12px;
    line-height: 18px;
}

/* Motion rule: neutralise the theme's sliding-arrow button. The second
   .btn-icon is a duplicate that slides in from the other side on hover, and
   .btn-text carries a -23px offset to make room for the swap. Both go. */
.ds-dash-page__content .rbt-btn.hover-icon-reverse .btn-text {
    margin-inline-start: 0;
    transform: none;
}

.ds-dash-page__content .rbt-btn.hover-icon-reverse .icon-reverse-wrapper {
    gap: 8px;
}

.ds-dash-page__content .rbt-btn.hover-icon-reverse .btn-icon {
    transform: none;
    opacity: 1;
    transition: none;
}

.ds-dash-page__content .rbt-btn.hover-icon-reverse .btn-icon + .btn-icon {
    display: none;
}

/* Round icon buttons in table action cells */
.ds-dash-page__content .rbt-round-btn {
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    line-height: var(--ds-tile-sm);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface);
    color: var(--ds-text-muted);
    box-shadow: none;
}

.ds-dash-page__content .rbt-round-btn:hover {
    background: var(--ds-emerald-soft);
    border-color: var(--ds-emerald);
    color: var(--ds-emerald);
}

/* --- Accordion (.rbt-accordion-style) ------------------------------------
   Used by the course create/edit forms to group field sets. Becomes a plain
   bordered group with a sunken header. */

.ds-dash-page__content .rbt-accordion-style .card,
.ds-dash-page__content .rbt-accordion-style .accordion-item {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    box-shadow: none;
    overflow: hidden;
}

.ds-dash-page__content .rbt-accordion-style .card + .card,
.ds-dash-page__content .rbt-accordion-style .accordion-item + .accordion-item {
    margin-top: 16px;
}

.ds-dash-page__content .rbt-accordion-style .card .card-header {
    padding: 0;
    background: var(--ds-surface-sunken);
    border: 0;
}

.ds-dash-page__content .rbt-accordion-style .card .card-header button {
    padding: 16px 20px;
    background: transparent;
    border: 0;
    box-shadow: none;
    font-size: 15px;
    line-height: 24px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-dash-page__content
    .rbt-accordion-style
    .card
    .card-header
    button[aria-expanded="true"] {
    color: var(--ds-emerald);
}

.ds-dash-page__content .rbt-accordion-style .card .card-body {
    padding: 20px;
}

/* --- Course cards (.rbt-card.variation-01.rbt-hover) ----------------------
   The list card on /dashboard/courses and the wishlist. Section 6 already
   gives .rbt-card the surface; this is the dashboard's denser trim. */

.ds-dash-page__content .rbt-card.variation-01 .rbt-card-img img {
    width: 100%;
    height: 168px;
    object-fit: cover;
}

.ds-dash-page__content .rbt-card.variation-01 .rbt-card-body {
    padding: 20px;
}

.ds-dash-page__content .rbt-card .rbt-card-title {
    font-size: 16px;
    line-height: 24px;
    font-weight: var(--ds-weight-semibold);
    margin-bottom: 12px;
}

.ds-dash-page__content .rbt-card .rbt-card-title a {
    color: var(--ds-text-heading);
}

.ds-dash-page__content .rbt-card .rbt-card-title a:hover {
    color: var(--ds-emerald);
}

.ds-dash-page__content .rbt-card .rbt-meta {
    gap: 6px 14px;
    margin-bottom: 12px;
}

.ds-dash-page__content .rbt-card .rbt-meta li {
    margin: 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-dash-page__content .rbt-card .rbt-meta li i {
    margin-inline-end: 5px;
    color: var(--ds-text-placeholder);
}

.ds-dash-page__content .rbt-card .rbt-card-bottom:empty {
    display: none;
}

/* Motion rule — the theme's .rbt-hover lifts the card on hover. */
.ds-dash-page__content .rbt-card.rbt-hover:hover {
    transform: none;
    box-shadow: var(--ds-shadow-card);
    border-color: var(--ds-emerald);
}

/* --- Progress bars -------------------------------------------------------- */

.ds-dash-page__content .rbt-progress-style-1 .progress {
    height: 8px;
    background: var(--ds-surface-sunken);
    border-radius: var(--ds-radius-pill);
    overflow: visible;
}

.ds-dash-page__content .rbt-progress-style-1 .progress-bar {
    border-radius: var(--ds-radius-pill);
    background-color: var(--ds-emerald) !important;
}

.ds-dash-page__content .rbt-progress-style-1 h6 {
    font-size: 13px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
}

.ds-dash-page__content .rbt-progress-style-1 .progress-number {
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
}

/* --- Pagination ----------------------------------------------------------
   Same treatment as .ds-pagination in section 21, applied to the bare
   Bootstrap pagination Laravel's paginator renders. */

.ds-dash-page__content .pagination {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
    margin: 24px 0 0;
    padding: 0;
    list-style: none;
}

.ds-dash-page__content .pagination .page-link,
.ds-dash-page__content .pagination li > a,
.ds-dash-page__content .pagination li > span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    padding: 0 10px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-sm);
    background: var(--ds-surface);
    color: var(--ds-text-body);
    font-size: 14px;
    text-decoration: none;
}

.ds-dash-page__content .pagination li > a:hover {
    border-color: var(--ds-emerald);
    color: var(--ds-emerald);
}

.ds-dash-page__content .pagination .active > span,
.ds-dash-page__content .pagination li.active > a,
.ds-dash-page__content .pagination .page-item.active .page-link {
    background: var(--ds-emerald);
    border-color: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.ds-dash-page__content .pagination .disabled > span,
.ds-dash-page__content .pagination .page-item.disabled .page-link {
    opacity: 0.5;
}

/* --- Modals raised from a dashboard page ---------------------------------
   These are plain Bootstrap modals declared inside @section('dashboard-content'),
   so they are descendants of the panel and can be scoped from here. They are
   NOT .ds-modal (section 12) — that shell has its own markup — but they get the
   same card treatment so the two read as one family.

   The overlay differs on purpose: the login page's cleanupModalBackdrops()
   only runs on auth screens, so .modal-backdrop is intact here and does the
   dimming, where .ds-modal has to paint it on the .modal element itself. */

.ds-dash-page__content .modal-content {
    border: 0;
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-raised);
}

.ds-dash-page__content .modal-header {
    padding: 20px 24px;
    border-bottom: 1px solid var(--ds-border-divider);
}

.ds-dash-page__content .modal-title {
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-dash-page__content .modal-body {
    padding: 24px;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
}

.ds-dash-page__content .modal-footer {
    padding: 16px 24px;
    gap: 10px;
    border-top: 1px solid var(--ds-border-divider);
}

.ds-dash-page__content .modal-footer > * {
    margin: 0;
}

/* --- Misc ----------------------------------------------------------------- */

.ds-dash-page__content .text-muted {
    color: var(--ds-text-muted) !important;
}

.ds-dash-page__content hr {
    border-color: var(--ds-border-divider);
    opacity: 1;
}

/* Bootstrap's .row is negative-margined; when a page uses it as its outermost
   block that pulls content out past the panel's 24px padding. */
.ds-dash-page__content > .row,
.ds-dash-page__content > form > .row {
    margin-inline: 0;
}

.ds-dash-page__content > .row > [class*="col-"],
.ds-dash-page__content > form > .row > [class*="col-"] {
    padding-inline: 0;
}

/* --- Responsive ----------------------------------------------------------- */

@media only screen and (max-width: 767px) {
    .ds-dash-page__content .section-title h4,
    .ds-dash-page__content .rbt-title-style-3 {
        font-size: 18px;
        line-height: 26px;
    }

    .ds-dash-page__content .nav-tabs.tab-button-style-2,
    .ds-dash-page__content ul.tab-button-style-2 {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }

    .ds-dash-page__content .nav-tabs.tab-button-style-2::-webkit-scrollbar,
    .ds-dash-page__content ul.tab-button-style-2::-webkit-scrollbar {
        display: none;
    }

    .ds-dash-page__content .tab-button-style-2 li a,
    .ds-dash-page__content .tab-button-style-2 li .tab-button {
        white-space: nowrap;
        padding: 8px 14px;
    }

    .ds-dash-page__content .rbt-table tr th,
    .ds-dash-page__content .rbt-table tr td {
        padding: 12px;
    }
}

/* ==========================================================================
   24. Dashboard page components (.ds-tabs, .ds-toolbar, .ds-table, .ds-mediacard)
   The native vocabulary a /dashboard page is written in once it is converted
   off the theme markup that section 23 remaps.

   Section 21 covers the hub (stats, panels, .ds-course-card, .ds-row); this
   covers what a *list* page needs on top of that: a tab strip, a filter bar, a
   data table and an image-led card. They are page-level components, so unlike
   section 23 they are NOT scoped to .ds-dash-page__content — /account pages use
   them too.

   Same motion rule as sections 21-23: nothing moves on hover.
   ========================================================================== */

/* --- Tabs (.ds-tabs) -----------------------------------------------------
   BOOTSTRAP TRAP, the same one the account panes hit (see CLAUDE.md): the
   bundled Bootstrap is 5.0.2, whose Tab resolves its parent with
   closest('.nav, .list-group') — [role="tablist"] was only accepted from 5.2.
   So a .ds-tabs list driven by data-bs-toggle="tab" MUST also carry `nav`, or
   Bootstrap throws inside SelectorEngine.children(null, '.active') and clicking
   a tab does nothing at all. Write it as `class="nav ds-tabs"`. */

.ds-tabs {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    max-width: 100%;
    margin: 0 0 24px;
    padding: 4px;
    list-style: none;
    border: 0;
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
}

.ds-tabs > li {
    margin: 0;
    padding: 0;
}

.ds-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 20px;
    border: 0;
    border-radius: var(--ds-radius-sm);
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    background: transparent;
    color: var(--ds-text-muted);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
    white-space: nowrap;
    transition:
        background-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

.ds-tab:hover {
    background: rgba(19, 27, 46, 0.05);
    color: var(--ds-text-heading);
    text-decoration: none;
}

.ds-tab.active,
.ds-tab[aria-selected="true"] {
    background: var(--ds-surface);
    color: var(--ds-emerald);
    box-shadow: var(--ds-shadow-card);
}

/* Count pill inside a tab */
.ds-tab__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    padding: 0 6px;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.08);
    color: inherit;
    font-size: 11px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
}

.ds-tab.active .ds-tab__count {
    background: var(--ds-emerald-soft);
}

/* --- Toolbar (.ds-toolbar) — search + filters above a list ---------------- */

.ds-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    padding: 16px;
    margin-bottom: 20px;
    background: var(--ds-surface-sunken);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
}

.ds-toolbar__field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    flex: 1 1 220px;
}

.ds-toolbar__label {
    font-size: var(--ds-label);
    line-height: 16px;
    letter-spacing: var(--ds-label-ls);
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
}

/* The magnifier is absolutely positioned on the inline-start edge, so the
   input needs matching padding on that side — logical properties only, this
   flips with `direction`. */
.ds-toolbar__search {
    position: relative;
}

.ds-toolbar__search > i {
    position: absolute;
    inset-inline-start: 16px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ds-text-placeholder);
    font-size: 16px;
    pointer-events: none;
}

.ds-toolbar__search input {
    width: 100%;
    padding-inline-start: 42px;
}

.ds-toolbar__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    flex-shrink: 0;
}

/* Selects in a toolbar come in two flavours and both have to end up the same
   height, or the row's `align-items: flex-end` lines them up on ragged bottoms:

     - data-no-picker  -> a native <select>, already themed by section 5;
     - no attribute    -> main.js swaps it for a bootstrap-select widget, whose
                          real control is a <button class="dropdown-toggle">
                          inside an injected .bootstrap-select wrapper.

   The widget's wrapper replaces the select in the DOM, so it must be styled on
   .bootstrap-select — .ds-toolbar__field > select never matches it. Same call
   section 22 makes for the address pane. */
.ds-toolbar__field > select,
.ds-toolbar__field .bootstrap-select {
    width: 100%;
}

.ds-toolbar__field .bootstrap-select > .dropdown-toggle {
    width: 100%;
    padding: 11px 16px;
    height: auto;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    color: var(--ds-text-heading);
    font-family: var(--ds-font);
    font-size: 15px;
    line-height: 24px;
    box-shadow: none;
}

.ds-toolbar__field .bootstrap-select > .dropdown-toggle:focus,
.ds-toolbar__field .bootstrap-select.show > .dropdown-toggle {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 3px var(--ds-emerald-soft);
    outline: none !important;
}

.ds-toolbar__field .bootstrap-select .dropdown-menu {
    padding: 6px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    box-shadow: var(--ds-shadow-raised);
}

.ds-toolbar__field .bootstrap-select .dropdown-menu li a {
    padding: 8px 12px;
    border-radius: var(--ds-radius-sm);
    font-size: 14px;
    color: var(--ds-text-body);
}

.ds-toolbar__field .bootstrap-select .dropdown-menu li a.selected,
.ds-toolbar__field .bootstrap-select .dropdown-menu li a:hover {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

/* Escape hatch for a select that DOES carry data-no-picker and stays native:
   a `multiple` one renders as a tall list box and would break the row's
   alignment. Prefer leaving the widget on in a toolbar. */
.ds-toolbar__field > select[multiple] {
    height: 50px;
    overflow-y: auto;
}

/* --- Table (.ds-table) — Figma "Student Dashboard (Table)" (49:430) -------
   A table fills its panel edge to edge, so the panel drops its padding and the
   table wrapper drops the border/radius the panel already provides. `overflow:
   hidden` on the panel is what clips the table's square corners back to the
   panel's radius — without it the header's sunken fill pokes out of them. */

.ds-panel--flush {
    padding: 0;
    overflow: hidden;
}

.ds-panel--flush > .ds-table-wrap {
    border: 0;
    border-radius: 0;
}

.ds-table-wrap {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    overflow-x: auto;
}

.ds-table {
    width: 100%;
    margin: 0;
    border: 0;
    border-collapse: collapse;
}

.ds-table thead th {
    padding: 14px 16px;
    background: var(--ds-surface-sunken);
    border: 0;
    border-bottom: 1px solid var(--ds-border-subtle);
    font-size: 13px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
    white-space: nowrap;
    text-align: start;
}

.ds-table tbody td,
.ds-table tbody th {
    padding: 14px 16px;
    border: 0;
    vertical-align: middle;
    font-size: 14px;
    line-height: 22px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-body);
    text-align: start;
}

.ds-table tbody tr + tr td,
.ds-table tbody tr + tr th {
    border-top: 1px solid var(--ds-border-divider);
}

.ds-table tbody tr:hover td,
.ds-table tbody tr:hover th {
    background: var(--ds-surface-sunken);
}

.ds-table tbody th {
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-table a {
    color: var(--ds-text-heading);
    font-weight: var(--ds-weight-medium);
    text-decoration: none;
}

.ds-table a:hover {
    color: var(--ds-emerald);
}

/* Dates, ids, money — anything that must not be reordered by the RTL bidi
   algorithm. Use on the <td>, not on a wrapping span. */
.ds-table__ltr {
    direction: ltr;
    text-align: start;
    unicode-bidi: isolate;
}

.ds-table__actions {
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: flex-start;
}

/* Small round action button in a table cell. Resets `appearance` because these
   are often real <button>s inside a delete form — see the note in section 21. */
.ds-iconbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    flex-shrink: 0;
    padding: 0;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    background: var(--ds-surface);
    color: var(--ds-text-muted);
    font-size: 15px;
    text-decoration: none;
    transition:
        background-color 0.2s ease-in-out,
        border-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

.ds-iconbtn:hover {
    background: var(--ds-emerald-soft);
    border-color: var(--ds-emerald);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-iconbtn--danger:hover {
    background: rgba(186, 26, 26, 0.08);
    border-color: var(--ds-danger);
    color: var(--ds-danger);
}

/* Person cell: avatar + name/sub, used in most admin and instructor tables. */
.ds-cell-user {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.ds-cell-user__avatar {
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    flex-shrink: 0;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-avatar);
    object-fit: cover;
}

/* Fallback when the person has no photo — same circle, first letter inside.
   Kept separate from .ds-row__icon, which is a square tile for glyphs. */
.ds-cell-user__initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    flex-shrink: 0;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    line-height: 1;
}

.ds-cell-user__body {
    min-width: 0;
}

.ds-cell-user__name {
    display: block;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-cell-user__sub {
    display: block;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

/* --- Media card (.ds-mediacard) ------------------------------------------
   The image-led course card the list pages use. .ds-course-card (section 21)
   is the hub's compact icon card and has no image — these are siblings, not
   variants, because the hub card has to stay short enough for the side column. */

.ds-cardgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 20px;
}

.ds-mediacard {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    box-shadow: var(--ds-shadow-card);
    overflow: hidden;
    transition: border-color 0.2s ease-in-out;
}

.ds-mediacard:hover {
    border-color: var(--ds-emerald);
}

.ds-mediacard__media {
    position: relative;
    display: block;
    height: 160px;
    background: var(--ds-surface-sunken);
    overflow: hidden;
}

.ds-mediacard__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Badge floated over the image. inset-inline-start flips with `direction`. */
.ds-mediacard__flag {
    position: absolute;
    top: 12px;
    inset-inline-start: 12px;
}

.ds-mediacard__body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1 1 auto;
    padding: 16px;
}

.ds-mediacard__title {
    margin: 0;
    font-size: 16px;
    line-height: 24px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
    /* Two lines, so a long and a short title still leave the cards aligned. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.ds-mediacard__title a {
    color: inherit;
    text-decoration: none;
}

.ds-mediacard__title a:hover {
    color: var(--ds-emerald);
}

.ds-mediacard__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-mediacard__meta li {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-mediacard__meta li i {
    color: var(--ds-text-placeholder);
}

/* A labelled row of .ds-tag chips ("المراحل: ثانوي ← الأول  الثاني  +3").
   Overflow is trimmed by the caller with ->take(n) plus a __more counter, so
   the row never wraps past two lines and the cards stay the same height. */
.ds-chiprow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.ds-chiprow__label {
    font-size: 12px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
}

.ds-chiprow__more {
    font-size: 12px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-muted);
}

.ds-chiprow__none {
    font-size: 13px;
    color: var(--ds-text-placeholder);
}

/* Pushes the footer to the bottom so cards in a row line their CTAs up. */
.ds-mediacard__spacer {
    flex: 1 1 auto;
}

.ds-mediacard__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--ds-border-divider);
}

.ds-mediacard__cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
    text-decoration: none;
}

.ds-mediacard__cta:hover {
    color: var(--ds-emerald-hover);
    text-decoration: none;
}

/* --- Question review (.ds-question) --------------------------------------
   A quiz question with its options marked correct / picked, shown read-only in
   an attempt-detail modal. Deliberately not built on .form-check: the theme
   hides the native control and paints a box on the FOLLOWING SIBLING label (see
   the checkbox note in section 5), which needs a real input per option and
   fights every attempt to colour a *disabled* correct/incorrect state. These
   are plain <li>s with a feather glyph instead. */

.ds-question {
    padding: 16px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
}

.ds-question + .ds-question {
    margin-top: 12px;
}

.ds-question__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.ds-question__title {
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-question__options {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-question__option {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 8px 12px;
    border-radius: var(--ds-radius-sm);
    background: var(--ds-surface-sunken);
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
}

.ds-question__option > i {
    flex-shrink: 0;
    color: var(--ds-text-placeholder);
}

.ds-question__option > span:first-of-type {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-question__option.is-correct {
    background: var(--ds-emerald-soft);
    color: #047857;
}

.ds-question__option.is-correct > i {
    color: var(--ds-emerald);
}

/* Picked but wrong — correct-and-picked keeps the emerald above, because
   .is-correct is declared first and this only repaints the non-correct case. */
.ds-question__option.is-picked:not(.is-correct) {
    background: rgba(186, 26, 26, 0.07);
    color: var(--ds-danger);
}

.ds-question__option.is-picked:not(.is-correct) > i {
    color: var(--ds-danger);
}

/* --- Feed (.ds-feed) — notifications, activity logs ----------------------
   A vertical list of read/unread items inside a .ds-panel. Unread is a tint
   plus an emerald rail on the inline-start edge, not a bold weight — the weight
   change made rows jump height as they were marked read. */

.ds-feed {
    display: flex;
    flex-direction: column;
    margin: -24px;
}

.ds-feed__item {
    display: block;
    width: 100%;
    padding: 18px 24px;
    border: 0;
    border-inline-start: 3px solid transparent;
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    text-align: start;
    cursor: pointer;
    transition: background-color 0.2s ease-in-out;
}

.ds-feed__item + .ds-feed__item {
    border-top: 1px solid var(--ds-border-divider);
}

.ds-feed__item:hover {
    background: var(--ds-surface-sunken);
}

.ds-feed__item.is-unread {
    background: var(--ds-emerald-soft);
    border-inline-start-color: var(--ds-emerald);
}

.ds-feed__head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}

.ds-feed__title {
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-feed__text {
    margin: 0 0 8px;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
}

.ds-feed__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 16px;
}

.ds-feed__meta span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

/* --- Inline progress (.ds-progress) --------------------------------------- */

.ds-progress__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}

.ds-progress__label {
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-progress__value {
    font-size: 13px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
}

.ds-progress__bar {
    height: 8px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    overflow: hidden;
}

.ds-progress__fill {
    display: block;
    height: 100%;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
}

/* --- Responsive ----------------------------------------------------------- */

@media only screen and (max-width: 767px) {
    .ds-tabs {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }

    .ds-tabs::-webkit-scrollbar {
        display: none;
    }

    .ds-tab {
        padding: 8px 14px;
    }

    .ds-toolbar {
        padding: 12px;
    }

    .ds-toolbar__field {
        flex: 1 1 100%;
    }

    .ds-cardgrid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* The wrapper scrolls; without a floor the columns crush instead. */
    .ds-table {
        min-width: 560px;
    }

    .ds-table--wide {
        min-width: 750px;
    }

    .ds-table thead th,
    .ds-table tbody td,
    .ds-table tbody th {
        padding: 12px;
    }

    .ds-feed {
        margin: -20px;
    }

    .ds-feed__item {
        padding: 16px 20px;
    }
}

/* ==========================================================================
   25. Dashboard app shell (.ds-shell*)

   /dashboard, /admin and /account are an application, not pages on the
   marketing site, so they get their own chrome: a slim fixed topbar and a fixed
   full-height side menu. The site navbar (.ds-nav, section 15), its drawer and
   the footer are NOT rendered on these pages at all — see
   layouts/dashboard.blade.php.

   The topbar carries only the wordmark (a link back to the public homepage),
   the notification bell and the avatar menu. The bell and the avatar reuse the
   navbar's own markup and classes so their CSS (sections 15 and 19) and their
   ~600 lines of JS keep working unchanged.

   DIRECTION — the side menu is at the inline START, which under dir="rtl" is
   the RIGHT edge, matching Figma "Aside - Sidebar (Right)" (48:138). Content is
   pushed with margin-inline-start. Everything here uses logical properties, so
   an LTR build would mirror correctly with one exception noted at the drawer
   transform below.

   LAYERS — topbar 1040, aside 1030, its mobile overlay 1025. The bottom bar is
   1035, which is why the mobile aside stops above it rather than overlapping.
   ========================================================================== */

:root {
    --ds-topbar-h: 64px;
    --ds-sidebar-w: 264px;
}

/* --- Topbar --------------------------------------------------------------- */

/* NEVER give this backdrop-filter. It would become the containing block for its
   position:fixed descendants (same trap section 19 documents for .ds-nav), and
   the notification bottom sheet — which is nested inside the bell — would
   render squashed inside the 64px bar instead of filling the viewport. */
.ds-shell__topbar {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: 1040;
    display: flex;
    align-items: center;
    gap: 12px;
    height: var(--ds-topbar-h);
    padding-inline: 24px;
    background: var(--ds-surface);
    border-bottom: 1px solid var(--ds-border-hairline);
}

/* position:fixed + z-index makes the topbar a STACKING CONTEXT, so the sheet's
   own z-index is capped at 1040 — under nothing today, but the moment anything
   sits higher it would paint over the sheet. Lift the whole bar while the sheet
   is open, exactly as section 19 does for .ds-nav. */
body.ds-notif-open .ds-shell__topbar {
    z-index: 1070;
}

/* Wordmark — the one way back to the public site, per the product decision that
   the dashboard shows "only the logo" from the old navbar. */
.ds-shell__brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    color: var(--ds-emerald);
    font-size: 22px;
    font-weight: var(--ds-weight-bold);
    line-height: 1;
    text-decoration: none;
}

.ds-shell__brand:hover {
    color: var(--ds-emerald-hover);
    text-decoration: none;
}

.ds-shell__brand-back {
    font-size: 15px;
    color: var(--ds-text-muted);
}

.ds-shell__brand:hover .ds-shell__brand-back {
    color: var(--ds-emerald-hover);
}

/* Only meaningful on wide screens — it explains what the wordmark does. */
.ds-shell__brand-hint {
    font-size: 13px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-muted);
}

.ds-shell__spacer {
    flex: 1 1 auto;
}

.ds-shell__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* Section 15 hides the avatar menu below 992px, because on the marketing site it
   moves into the bottom bar. Re-show it here — at >=992px the topbar is the only
   route to /account and logout, since the bottom bar is hidden at that width.
   Below 992px it is hidden again (see the mobile block): the bar is back on
   shell pages now and carries حسابي, so two account entry points 40px apart in
   the same corner was just duplication. Logout is in the drawer. */
.ds-shell__topbar .ds-nav__user {
    display: block;
}

/* Burger — mobile only, opens the off-canvas side menu. Deliberately NOT
   .hamberger-button: that class is bound by the theme's main.js to the site
   drawer (.popup-mobile-menu), which is not rendered on these pages. */
.ds-shell__burger {
    display: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    padding: 0;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    background: var(--ds-surface);
    color: var(--ds-text-heading);
    font-size: 18px;
}

.ds-shell__burger:hover {
    background: var(--ds-surface-sunken);
}

/* --- Side menu ------------------------------------------------------------ */

.ds-shell__aside {
    position: fixed;
    inset-block-start: var(--ds-topbar-h);
    inset-block-end: 0;
    inset-inline-start: 0;
    z-index: 1030;
    width: var(--ds-sidebar-w);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--ds-surface);
    border-inline-end: 1px solid var(--ds-border-hairline);
}

/* .ds-dashnav is a standalone card on the hub's old grid layout. Inside the
   fixed rail it has to be flush — no border, radius or shadow of its own. */
.ds-shell__aside .ds-dashnav {
    min-height: 100%;
    padding: 20px 12px;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

.ds-shell__overlay {
    display: none;
}

/* --- Content -------------------------------------------------------------- */

.ds-shell__main {
    margin-block-start: var(--ds-topbar-h);
    margin-inline-start: var(--ds-sidebar-w);
    min-height: calc(100vh - var(--ds-topbar-h));
    background: var(--ds-cloud);
}

.ds-shell__content {
    max-width: 1320px;
    margin-inline: auto;
    padding: 32px 24px 64px;
}

/* --- Mobile: the rail becomes an off-canvas drawer ------------------------ */

@media (max-width: 991.98px) {
    .ds-shell__topbar {
        gap: 10px;
        padding-inline: 16px;
    }

    .ds-shell__burger {
        display: inline-flex;
    }

    .ds-shell__brand-hint {
        display: none;
    }

    /* Stops above the bottom bar (1035) rather than under it — the drawer is
       1030, so overlapping would put the bar on top of the menu's last items.

       Whether there IS a bottom bar depends on the page: layouts/app.blade.php
       skips it (and the help FAB) on every route in its $isAuthPage list, which
       now includes dashboard.* and admin.* — so /dashboard has no bar and
       /account does. Reserving the gap is the default because it is the safe
       failure: a 62px gap looks slightly loose, an overlap eats تسجيل الخروج.
       The :has() rule below reclaims it where there is genuinely no bar; a
       browser without :has() support simply keeps the harmless gap. */
    /* The drawer is a TRUE full-height off-canvas: it starts at the top of the
       viewport, not under the topbar, and its overlay covers the topbar and the
       bottom bar too. The earlier version sandwiched the panel between the two
       fixed bars (aside 1030 < topbar 1040), which read as a stacking bug and
       left the topbar lit and tappable behind the dim — you could open the
       notification sheet on top of an open drawer. Stack, low to high:
       bottom bar 1035 → overlay 1045 → drawer 1050. */
    .ds-shell__aside {
        inset-block-start: 0;
        inset-block-end: 0;
        z-index: 1050;
        width: min(300px, 84vw);
        box-shadow: var(--ds-shadow-raised);
        /* `transform` has no logical variant, so this one value is direction-
           bound: +100% parks the panel off the RIGHT edge, which is the
           inline-start edge under dir="rtl". An LTR build needs -100%. */
        transform: translateX(100%);
        visibility: hidden;
        transition:
            transform 0.28s cubic-bezier(0.22, 1, 0.36, 1),
            visibility 0.28s;
    }

    .ds-shell__aside.is-open {
        transform: translateX(0);
        visibility: visible;
    }

    /* Covering the topbar means the burger that opened the drawer is no longer
       visible, so the drawer brings its own header and close button. Hidden at
       >=992px, where this is a static rail and there is nothing to close. */
    .ds-shell__aside .ds-dashnav__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        margin-bottom: 12px;
        padding-bottom: 12px;
        border-bottom: 1px solid var(--ds-border-hairline);
    }

    .ds-shell__overlay {
        display: block;
        position: fixed;
        inset-block-start: 0;
        inset-block-end: 0;
        inset-inline: 0;
        z-index: 1045;
        background: rgba(19, 27, 46, 0.55);
        -webkit-backdrop-filter: blur(4px);
        backdrop-filter: blur(4px);
        opacity: 0;
        /* Transparent full-viewport element until it opens — without this it
           would swallow every tap on the page. Same reasoning as section 19. */
        pointer-events: none;
        transition: opacity 0.22s ease;
    }

    .ds-shell__overlay.is-open {
        opacity: 1;
        pointer-events: auto;
    }

    body.ds-shell-drawer-open {
        overflow: hidden;
    }

    .ds-shell__main {
        margin-inline-start: 0;
    }

    /* The bar's spacer is a real element appended after the content, so without
       this every shell page would be exactly one bar taller than the viewport
       and scroll ~62px with nothing to show. Subtracting it here keeps an empty
       page at exactly 100vh. Browsers without :has() just get the extra scroll,
       which is the harmless direction to fail in. */
    body:has(.ds-bottomnav) .ds-shell__main {
        min-height: calc(
            100vh - var(--ds-topbar-h) - var(--ds-bottomnav-h) -
                env(safe-area-inset-bottom, 0px)
        );
    }

    /* The avatar menu is a duplicate down here — حسابي is in the bottom bar and
       logout is in the drawer. See the .ds-shell__topbar .ds-nav__user rule. */
    .ds-shell__topbar .ds-nav__user {
        display: none;
    }

    .ds-shell__content {
        padding: 20px 16px 40px;
    }

    /* Section 21 turns .ds-dashnav into a horizontally scrolling pill row below
       992px — that was for the old sticky-column layout. In the drawer it must
       stay a vertical list, so every one of those rules is undone here. Each
       selector leads with .ds-shell__aside to win on specificity (0,2,0 vs
       section 21's 0,1,0). */
    .ds-shell__aside .ds-dashnav {
        /* Full-height drawer, so the last link would otherwise sit on the very
           bottom edge — under the home indicator on a notched phone. */
        padding: 16px 12px calc(16px + env(safe-area-inset-bottom, 0px));
        border-radius: 0;
    }

    .ds-shell__aside .ds-dashnav__scroll {
        flex-direction: column;
        flex-wrap: nowrap;
        gap: 2px;
        overflow-x: visible;
    }

    .ds-shell__aside .ds-dashnav__group,
    .ds-shell__aside .ds-dashnav__logout-form {
        display: flex;
        flex-direction: column;
        gap: 2px;
    }

    .ds-shell__aside .ds-dashnav__group-title {
        display: block;
    }

    .ds-shell__aside .ds-dashnav__link {
        flex: 0 0 auto;
        width: 100%;
        padding: 10px 12px;
        border: 0;
        border-radius: var(--ds-radius-md);
        background: transparent;
        font-size: 15px;
        white-space: normal;
    }

    .ds-shell__aside .ds-dashnav__link.is-active {
        background: var(--ds-emerald-soft);
    }
}

/* --- Pages inside the shell ----------------------------------------------- */

/* .ds-dash-page painted its own cloud background and vertical padding for the
   old full-width layout; inside the shell .ds-shell__content owns both. */
.ds-shell .ds-dash-page {
    padding: 0;
    background: transparent;
}

/* The hub's two-column content grid (main + activity) still applies, but its
   outer .ds-dash sidebar grid does not — the rail replaced it. */
.ds-shell .ds-dash {
    display: block;
}

.ds-shell .ds-dash__aside {
    display: none;
}

/* ==========================================================================
   26. Homepage (.ds-home*)

   Built from the Figma "Main" frame (1:4) — five sections, in DOM order:
   hero, value props, أبرز المدرسين, أحدث الكورسات, دروس سريعة (dark).
   Everything above and below them (navbar, footer) is untouched.

   It REPLACES the theme's homepage markup wholesale: .rbt-banner-area,
   .rbt-rbt-course-area, .rbt-service-area and the rest are no longer rendered
   by home.blade.php, so none of their rules in styles.css apply here.

   Two notes on the spec:
   - The Figma frame is set in Readex Pro; the site is Noto Sans Arabic (design
     system frame 39:938) and stays that way — the navbar and footer sit on
     this same page, so a second typeface would clash inside one screen. Sizes,
     weights and colours are taken from the frame as-is.
   - The frame's #0f172a headings are darker than --ds-text-heading (#191c1e).
     A local --ds-home-ink token holds it rather than bending the global one.
   ========================================================================== */

:root {
    /* The frame's slate-900 heading ink and the 100px rhythm between sections. */
    --ds-home-ink: #0f172a;
    --ds-home-gap: 100px;
    /* 0 4px 20px -2px rgba(15,23,42,.05) — every card on this page uses it. */
    --ds-home-shadow: 0 4px 20px -2px rgba(15, 23, 42, 0.05);
}

/* Vertical rhythm. The hero opens the page under the navbar; every later
   section is spaced by one --ds-home-gap, so changing the number moves the
   whole page at once. */
.ds-home-hero {
    padding-block-start: 64px;
}

.ds-home-section {
    padding-block-start: var(--ds-home-gap);
}

/* The tail. `.ds-home-section` is padding-block-START only, which worked while
   the dark shorts strip — which brings its own vertical padding — was the last
   thing on the page. The FAQ band now sits below it, so it needs the closing
   space or it lands on the footer's hairline.

   Unlike section 30's `.ds-page`, this is a modifier on the section rather than
   a wrapper: the FAQ partial renders NOTHING when there are no questions, so a
   wrapper would leave 100px of empty page behind on a database with none. */
.ds-home-section--tail {
    padding-block-end: var(--ds-home-gap);
}

/* --- Shared section heading ----------------------------------------------- */

/* A two-column grid rather than a flex row, because the aside («مشاهدة الكل»,
   plus the shorts arrows) has to sit against DIFFERENT rows at different
   widths: beside the subtitle on desktop, beside the title on a phone. Flex
   could only stack it underneath, which left it reading as a third line of the
   subtitle instead of a control.

   Columns flow with `direction`, so column 1 is the RIGHT one under dir="rtl" —
   title and subtitle land right, the aside left. Don't add `order`. */
.ds-home-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    column-gap: 24px;
    margin-block-end: 48px;
}

.ds-home-head__title {
    grid-area: 1 / 1;
}

.ds-home-head__sub {
    grid-area: 2 / 1;
}

/* Spans both rows and sits on the last one's baseline. `1 / -1` also does the
   right thing in the title-only case, where there is no second row. */
.ds-home-head__aside {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: end;
    display: flex;
    align-items: center;
    gap: 12px;
}

.ds-home-head--center {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
}

.ds-home-head__title {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0;
    font-size: 30px;
    line-height: 36px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-home-head__title i {
    color: var(--ds-emerald);
    font-size: 26px;
    line-height: 1;
}

.ds-home-head__sub {
    margin: 8px 0 0;
    font-size: 16px;
    line-height: 24px;
    color: var(--ds-text-muted);
}

.ds-home-head__link {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.2s ease;
}

.ds-home-head__link:hover {
    color: var(--ds-emerald-active);
    text-decoration: none;
}

/* --- 1. Hero -------------------------------------------------------------- */

/* Two equal columns with a 64px gutter (frame 1:5). Grid flows with
   `direction`: the copy is first in the markup and sits on the RIGHT, the
   media on the left — matching the frame, where the tablet is on the left. */
.ds-home-hero__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 64px;
}

.ds-home-hero__title {
    margin: 0;
    font-size: 48px;
    line-height: 58px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-home-hero__text {
    max-width: 576px;
    margin: 32px 0 0;
    font-size: 18px;
    line-height: 28px;
    color: var(--ds-text-muted);
}

.ds-home-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-block-start: 48px;
}

/* The frame's buttons are their own size (17px/40px pill), larger than
   .ds-btn — kept local rather than bending the shared component. */
.ds-home-btn {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 17px 40px;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-family: inherit;
    font-size: 16px;
    line-height: 24px;
    font-weight: var(--ds-weight-bold);
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.ds-home-btn:hover,
.ds-home-btn:focus {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

.ds-home-btn i {
    font-size: 18px;
    line-height: 1;
}

.ds-home-btn--ghost {
    background: transparent;
    border: 1px solid var(--ds-border-hairline);
    color: var(--ds-home-ink);
}

.ds-home-btn--ghost:hover,
.ds-home-btn--ghost:focus {
    background: var(--ds-surface-sunken);
    border-color: var(--ds-border);
    color: var(--ds-home-ink);
}

/* Media: a 9px white mat inside a 40px frame, holding a 32px rounded image
   (frame 1:6 → 1:8).

   The frame's dark scrim and 64px play button are deliberately NOT built. The
   scrim only existed to make the play button readable, and with no video behind
   it a play button is a promise the page can't keep — so both went, and the
   screenshot shows at full brightness. */
.ds-home-hero__media {
    position: relative;
    display: block;
    padding: 9px;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.5);
    border-radius: 40px;
    box-shadow: var(--ds-home-shadow);
    overflow: hidden;
}

.ds-home-hero__media img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 32px;
}

/* --- 2. Value props ------------------------------------------------------- */

.ds-home-values {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
}

.ds-home-value {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 41px;
    text-align: center;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.3);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

.ds-home-value__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: var(--ds-radius-lg);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 24px;
}

.ds-home-value__title {
    margin: 0;
    font-size: 18px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-home-value__text {
    margin: 0;
    font-size: 14px;
    line-height: 23px;
    color: var(--ds-text-muted);
}

/* --- 3. Featured tutors --------------------------------------------------- */

.ds-home-tutors {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

.ds-home-tutor {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 33px;
    text-align: center;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.3);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

/* 96px ring holding a 92px photo — the 2px gap is the frame's (1:68 → 1:69). */
.ds-home-tutor__avatar {
    width: 96px;
    height: 96px;
    padding: 2px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    box-shadow: inset 0 0 0 2px var(--ds-emerald);
}

.ds-home-tutor__avatar img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: var(--ds-radius-pill);
    object-fit: cover;
}

.ds-home-tutor__name {
    margin: 20px 0 0;
    font-size: 18px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-home-tutor__role {
    margin: 4px 0 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

/* One optional line under the profession — the visible course count on
   /instructors, which is what that page is sorted by. The homepage and /about
   pass nothing and the line is not rendered, so the Figma card is unchanged. */
.ds-home-tutor__meta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 10px 0 0;
    padding: 4px 12px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
    font-size: 12px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
}

.ds-home-tutor__meta i {
    font-size: 13px;
    line-height: 1;
}

/* Pushes the button to the card's bottom edge so a one-line and a two-line
   name still line their buttons up across the row. */
.ds-home-tutor__cta {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-block-start: auto;
    padding: 11px 16px;
    border: 1px solid var(--ds-border-hairline);
    border-radius: var(--ds-radius-md);
    background: transparent;
    color: var(--ds-home-ink);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
    transition:
        background-color 0.2s ease,
        border-color 0.2s ease,
        color 0.2s ease;
}

.ds-home-tutor__name + .ds-home-tutor__cta,
.ds-home-tutor__role + .ds-home-tutor__cta,
.ds-home-tutor__meta + .ds-home-tutor__cta {
    margin-block-start: 24px;
}

.ds-home-tutor__cta:hover,
.ds-home-tutor__cta:focus {
    background: var(--ds-emerald-soft);
    border-color: var(--ds-emerald);
    color: var(--ds-emerald);
    text-decoration: none;
}

/* --- 4. Latest courses ---------------------------------------------------- */

.ds-home-courses {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
}

.ds-home-course {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.3);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

.ds-home-course__media {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--ds-surface-sunken);
}

.ds-home-course__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ds-home-course__flag {
    position: absolute;
    top: 16px;
    inset-inline-end: 16px;
    padding: 4px 12px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 12px;
    line-height: 16px;
    font-weight: var(--ds-weight-semibold);
}

.ds-home-course__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding: 32px;
}

.ds-home-course__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.ds-home-course__rating {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 13px;
    line-height: 16px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-home-ink);
}

.ds-home-course__rating i {
    color: var(--ds-amber);
    font-size: 13px;
}

.ds-home-course__chip {
    padding: 4px 16px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 12px;
    line-height: 15px;
    font-weight: var(--ds-weight-semibold);
    white-space: nowrap;
}

.ds-home-course__title {
    margin: 24px 0 0;
    font-size: 18px;
    line-height: 23px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-home-course__title a {
    color: inherit;
    text-decoration: none;
}

.ds-home-course__title a:hover {
    color: var(--ds-emerald);
    text-decoration: none;
}

/* `margin-block-start: auto` is what makes every card in the row end at the
   same height whatever its title wraps to. */
.ds-home-course__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-block-start: auto;
    padding-block-start: 24px;
    border-block-start: 1px solid var(--ds-border-divider);
}

.ds-home-course__price {
    font-size: 18px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-home-course__price small {
    font-size: 13px;
    font-weight: var(--ds-weight-regular);
    color: var(--ds-text-muted);
}

.ds-home-course__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 24px;
    border-radius: var(--ds-radius-md);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    white-space: nowrap;
    text-decoration: none;
    transition: background-color 0.2s ease;
}

.ds-home-course__cta:hover,
.ds-home-course__cta:focus {
    background: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

.ds-home-courses__more {
    display: flex;
    justify-content: center;
    margin-block-start: 48px;
}

/* --- 5. Shorts (dark) ----------------------------------------------------- */

/* Full-bleed navy band. It is the last thing before the footer, so it carries
   its own bottom padding rather than a trailing --ds-home-gap. */
.ds-home-shorts {
    margin-block-start: var(--ds-home-gap);
    padding-block: 96px;
    background: var(--ds-navy);
}

.ds-home-shorts .ds-home-head__title {
    color: var(--ds-text-on-dark);
}

.ds-home-shorts .ds-home-head__sub {
    color: rgba(255, 255, 255, 0.65);
}

.ds-home-shorts .ds-home-head__link {
    color: var(--ds-emerald-on-dark);
}

.ds-home-shorts .ds-home-head__link:hover {
    color: var(--ds-text-on-dark);
}

/* The head has no aside on this section any more — «عرض الكل» and the
   prev/next arrows went with the horizontal track, since the fullscreen viewer
   pages through everything by itself. --plain drops the empty second column so
   the title and subtitle are not squeezed by a track that holds nothing. */
.ds-home-head--plain {
    grid-template-columns: 1fr;
}

/* A carousel of POSTERS, not players: the old row embedded up to twelve
   third-party iframes below the fold. Cards are 9:16 stills that open the
   fullscreen viewer (section 27), so the whole section costs one <img> each.

   Native scroll-snap rather than a carousel library: it swipes on touch, keeps
   working with JS off, and needs no markup the theme's swiper would demand.
   Scrolling follows `direction`, so it starts at the right. The wheel is the
   one thing native scrolling does not cover on a horizontal row — a small
   script in partials/home/shorts.blade.php adds it.

   The five cards the controller sends overflow the container slightly at
   288px, which is deliberate: a half-visible card is what tells a reader the
   row scrolls at all now that the arrows are gone. */
.ds-home-shorts__track {
    display: flex;
    gap: 24px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Keeps a swipe past the last card from turning into a browser back
       gesture or a scroll of the page behind it. */
    overscroll-behavior-x: contain;
    /* Room for the card shadow, and a little bleed so a half-visible next card
       reads as "there is more". */
    padding-block-end: 4px;
}

.ds-home-shorts__track::-webkit-scrollbar {
    display: none;
}

/* A real <button>, so it carries the appearance/border reset every .ds-* class
   on a <button> needs — see "Native button chrome" in CLAUDE.md. */
.ds-home-short {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    position: relative;
    flex: 0 0 288px;
    scroll-snap-align: start;
    padding: 0;
    aspect-ratio: 9 / 16;
    overflow: hidden;
    border-radius: var(--ds-radius-lg);
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: #000;
    cursor: pointer;
    text-align: start;
}

.ds-home-short:focus-visible {
    outline: 2px solid var(--ds-emerald);
    outline-offset: 2px;
}

.ds-home-short iframe,
.ds-home-short img {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
    /* YouTube's hqdefault is 4:3 with a vertical video pillarboxed in the
       middle; cover on a 9:16 card crops the bars off and leaves the video. */
    object-fit: cover;
    transition: opacity 0.2s ease;
}

/* Sits UNDER the Facebook embed, on providers that have no thumbnail endpoint.
   It is what the card looks like while the plugin loads, and behind a video
   that does not reach the card's edges. */
.ds-home-short__placeholder {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(120% 90% at 50% 0%, rgba(16, 185, 129, 0.18) 0%, rgba(16, 185, 129, 0) 60%),
        var(--ds-slate);
}

/* The Facebook still. Same crop and cover-scale as the viewer (design-system
   §27 explains the three numbers), so the plugin's header and its control bar
   fall outside the card and only the video is left. pointer-events:none is what
   keeps the click — and the hover that would wake the plugin's controls — on
   the card itself. */
.ds-home-short .ds-home-short__frame {
    position: absolute;
    inset-block-start: calc(var(--ds-fb-header) * -1);
    /* Physical `left` — centring has no direction, and pairing the logical
       property with translateX under RTL pushes the element off-frame. */
    left: 50%;
    transform: translateX(-50%);
    width: 140%;
    height: calc(100% + var(--ds-fb-header) + var(--ds-fb-bar));
    pointer-events: none;
}

.ds-home-short:hover img {
    opacity: 0.85;
}

/* Motion rule (section 21): the card must not move or grow under the pointer.
   The play badge changes colour instead. */
.ds-home-short__play {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    transform: translate(50%, -50%); /* RTL: inline-start is the right edge */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.35);
    color: var(--ds-text-on-dark);
    font-size: 18px;
    line-height: 1;
    pointer-events: none;
    transition: background-color 0.2s ease;
}

.ds-home-short:hover .ds-home-short__play {
    background: var(--ds-emerald);
    border-color: var(--ds-emerald);
}

/* Sits over the video, so it must not eat the click that opens the viewer. */
.ds-home-short__caption {
    display: block;
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    padding: 48px 16px 16px;
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.85) 0%,
        rgba(0, 0, 0, 0.55) 45%,
        rgba(0, 0, 0, 0) 100%
    );
    pointer-events: none;
}

.ds-home-short__title {
    margin: 0;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-on-dark);
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}

.ds-home-short__by {
    margin: 4px 0 0;
    font-size: 12px;
    line-height: 15px;
    color: rgba(255, 255, 255, 0.7);
}

/* --- Responsive ----------------------------------------------------------- */

@media (max-width: 1199.98px) {
    .ds-home-tutors {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 991.98px) {
    :root {
        --ds-home-gap: 72px;
    }

    .ds-home-hero {
        padding-block-start: 40px;
    }

    /* Copy above the media on a phone: the headline is the first thing that
       should land, and a 16:9 tablet shot eats most of a small viewport. */
    .ds-home-hero__grid {
        grid-template-columns: 1fr;
        gap: 40px;
    }

    .ds-home-hero__title {
        font-size: 34px;
        line-height: 46px;
    }

    .ds-home-hero__text {
        margin-block-start: 20px;
        font-size: 16px;
        line-height: 26px;
    }

    .ds-home-hero__actions {
        margin-block-start: 28px;
    }

    .ds-home-hero__media {
        padding: 6px;
        border-radius: 28px;
    }

    .ds-home-hero__media img {
        border-radius: 22px;
    }

    .ds-home-head {
        margin-block-end: 32px;
    }

    .ds-home-head__title {
        font-size: 24px;
        line-height: 32px;
    }

    .ds-home-head__title i {
        font-size: 22px;
    }

    .ds-home-head__sub {
        font-size: 14px;
        line-height: 22px;
    }

    .ds-home-values,
    .ds-home-courses {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    .ds-home-value {
        padding: 28px 24px;
    }

    .ds-home-course__body {
        padding: 24px;
    }

    .ds-home-tutors {
        gap: 16px;
    }

    .ds-home-tutor {
        padding: 24px 16px;
    }

    .ds-home-shorts {
        padding-block: 56px;
    }

    .ds-home-shorts__track {
        gap: 16px;
    }

    .ds-home-short {
        flex-basis: 240px;
    }
}

@media (max-width: 575.98px) {
    .ds-home-hero__title {
        font-size: 28px;
        line-height: 40px;
    }

    /* Full-width stacked buttons — two pills side by side wrap awkwardly at
       this width and leave one orphaned on its own line. */
    .ds-home-hero__actions {
        flex-direction: column;
        align-items: stretch;
    }

    .ds-home-btn {
        width: 100%;
        padding: 15px 24px;
    }

    /* Phone: the aside moves up beside the TITLE instead of the subtitle. The
       subtitle then runs the full width under both, which is the only way this
       fits — «أبرز المدرسين» + «مشاهدة الكل» sit on one line comfortably at
       360px, but the subtitle next to either does not. */
    .ds-home-head {
        column-gap: 12px;
    }

    .ds-home-head__aside {
        grid-row: 1;
        align-self: center;
    }

    .ds-home-tutor__avatar {
        width: 72px;
        height: 72px;
    }

    .ds-home-tutor__name {
        margin-block-start: 14px;
        font-size: 16px;
    }

    .ds-home-course__foot {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    .ds-home-course__cta {
        width: 100%;
    }

    /* Just under three-quarters of the viewport, so the next card always peeks
       in and the row reads as swipeable. */
    .ds-home-short {
        flex-basis: min(260px, 72vw);
    }

    .ds-home-short__play {
        width: 40px;
        height: 40px;
        font-size: 16px;
    }

    .ds-home-short__caption {
        padding: 36px 12px 12px;
    }
}

/* ==========================================================================
   27. Shorts viewer (.ds-reels*)

   The fullscreen, YouTube-Shorts-style player opened by a card in the homepage
   «دروس سريعة» band (section 26). Shell markup is
   partials/home/shorts-viewer.blade.php; every slide is built by
   assets/js/darssly-reels.js.

   Shape: one full-viewport overlay holding a vertical scroll-snap feed, one
   reel per screen. Below 992px the 9:16 frame fills the viewport edge to edge;
   above it the frame is centred and the dark surround acts as a lightbox
   (clicking it closes, which is why .ds-reel itself stays clickable).

   Four things here are load-bearing:

   - `scroll-behavior` stays AUTO on the feed. Opening a reel jumps to it by
     assigning scrollTop, and CSS smooth scrolling would turn that jump into a
     visible scroll through every reel above it. The nav buttons pass
     `behavior: 'smooth'` per call instead.
   - `.ds-reels[hidden]` needs its own display:none. The base rule sets
     `display: block`, which otherwise beats the [hidden] UA style and leaves
     the overlay permanently on top of the page.
   - The controls row is forced `direction: ltr`. A media timeline reads
     left-to-right in every locale — elapsed, bar, duration — and the knob's
     inset-inline-start (set from JS as a percentage) depends on it.
   - The video is a third-party IFRAME, so it cannot be object-fit. The frame
     carries the 9:16 box and the embed letterboxes inside it; that is also why
     the poster (a real <img>) is what covers the box until playback starts.
   ========================================================================== */

.ds-reels {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 10000; /* above .ds-fab (9999), which is hidden anyway while open */
    background: #000;
    animation: ds-reels-in 0.2s ease;
}

/* See the header note — without this the overlay never goes away. */
.ds-reels[hidden] {
    display: none;
}

@keyframes ds-reels-in {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

/* Scroll lock, plus the two floating layers that would otherwise sit on top of
   a video: the help menu and the mobile bottom bar. Same move section 19 makes
   for the notification sheet. */
body.ds-reels-open {
    overflow: hidden;
}

body.ds-reels-open .ds-fab,
body.ds-reels-open .ds-bottomnav,
body.ds-reels-open .rbt-progress-parent {
    display: none;
}

.ds-reels__feed {
    position: relative; /* slide.offsetTop is measured against this */
    height: 100%;
    overflow-y: auto;
    scroll-snap-type: y mandatory;
    scroll-behavior: auto; /* see the header note */
    overscroll-behavior: contain;
    scrollbar-width: none;
    outline: none;
}

.ds-reels__feed::-webkit-scrollbar {
    display: none;
}

.ds-reel {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    scroll-snap-align: start;
    scroll-snap-stop: always; /* a fast flick lands on the next reel, not four down */
}

.ds-reel__frame {
    position: relative;
    height: 100%;
    max-height: 100%;
    aspect-ratio: 9 / 16;
    max-width: 100%;
    overflow: hidden;
    background: #000;
}

/* The YouTube API REPLACES the mount element with its own iframe and does not
   carry the class across, so the iframe has to be reachable by tag too.

   THE OVERSIZE IS HOW YOUTUBE'S CHROME IS REMOVED. `controls: 0` hides the
   bottom control bar but nothing in the embed API hides the title bar (channel
   name, share, watch-later) at the top of the player or the YouTube wordmark at
   the bottom. Both are drawn at the edges of the PLAYER BOX, not of the video,
   so making the iframe --ds-reel-crop taller at each end and letting the
   frame's overflow clip it takes them out of view for good.

   It costs nothing. A 9:16 video in a 9:16 frame is width-limited, so growing
   the box vertically by 2×crop letterboxes the video by exactly crop at each
   end — precisely what gets clipped. The visible video is identical either way.
   (Same on a phone, where the frame is the whole viewport and the letterbox is
   larger still.) Only a video TALLER than 9:16 loses anything, and YouTube
   Shorts are 9:16.

   The prev/next buttons YouTube draws over the MIDDLE of a player cannot be
   cropped — they are avoided by not putting the player in playlist mode. See
   the note in assets/js/darssly-reels.js. */
.ds-reels {
    --ds-reel-crop: 76px;
}

.ds-reel__frame iframe,
.ds-reel__player {
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: calc(var(--ds-reel-crop) * -1);
    width: 100%;
    height: calc(100% + (var(--ds-reel-crop) * 2));
    border: 0;
}

/* --- Facebook -------------------------------------------------------------

   The plugin CONTAINS the video inside (its width, its height − header): it
   never fills a box taller than the video's own aspect, so simply growing the
   iframe leaves a dead band under the video — that band was the "video doesn't
   fill the player" bug. Three numbers fix it, and all three were measured
   against a real reel rather than guessed:

   --ds-fb-header  the plugin's title row (page name, avatar, «مشاركة»), a fixed
                   62px at every width we render at. Cropped off the top.
   --ds-fb-bar     the plugin's own control bar, which it draws over the BOTTOM
                   of the video whenever it is paused. Cropped off the bottom,
                   so ours is the only bar on screen.
   1.4×width       asking the plugin for a much wider box makes it height-limit
                   the video instead of width-limiting it, so the video covers
                   our 9:16 frame. Overscaling costs nothing — the plugin
                   centres the video and the surplus is transparent — while too
                   little would put the dead band back.

   The SDK writes inline width/height on the elements it injects, so the
   overrides have to be !important. */
/* On :root, not on .ds-reels — the homepage card (section 26) crops a Facebook
   embed with the same two numbers. */
:root {
    --ds-fb-header: 62px;
    --ds-fb-bar: 44px;
}

/* `left`, not inset-inline-start: this is centring, which has no direction, and
   the logical property plus a physical translateX(-50%) cancel out wrongly
   under dir="rtl" — inset-inline-start:50% anchors the RIGHT edge to the middle
   and the translate then drags the element another half-width further left,
   which is how it ended up off-frame entirely. */
.ds-reel__fb {
    position: absolute;
    inset-block-start: calc(var(--ds-fb-header) * -1);
    left: 50%;
    transform: translateX(-50%);
    width: 140%;
    height: calc(100% + var(--ds-fb-header) + var(--ds-fb-bar));
}

/* The SDK injects .fb-video > span > iframe and writes a px width AND height on
   each from the data-width it was given. Every level has to be overridden — a
   rule that stops at the iframe just resolves 100% against the span's inline
   height and nothing moves. */
.ds-reel__fb .fb-video,
.ds-reel__fb .fb-video > span,
.ds-reel__fb iframe {
    display: block !important;
    width: 100% !important;
    height: 100% !important;
    border: 0;
}

/* The SDK-blocked fallback (facebookFallback): the bare plugin iframe with its
   own controls, header cropped the way it always was. */
.ds-reel__frame .ds-reel__static {
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: calc(var(--ds-fb-header) * -1);
    width: 100%;
    height: calc(100% + var(--ds-fb-header));
    border: 0;
}

.ds-reel__poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 2;
    transition: opacity 0.25s ease;
}

/* Once the embed is painting frames the poster is just a stale copy of them. */
.ds-reel.is-playing .ds-reel__poster {
    opacity: 0;
    pointer-events: none;
}

/* Tap target for play/pause. It covers the frame, so everything that must stay
   clickable (the controls, the instructor link) sits above it. */
.ds-reel__surface {
    -webkit-appearance: none;
    appearance: none;
    position: absolute;
    inset: 0;
    z-index: 3;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}

.ds-reel__state {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    transform: translate(50%, -50%); /* RTL: inline-start is the right edge */
    z-index: 4;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.55);
    color: var(--ds-text-on-dark);
    font-size: 28px;
    line-height: 1;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

/* Visible only while paused — an always-on badge over a playing video reads as
   a broken player. */
.ds-reel.is-paused .ds-reel__state {
    opacity: 1;
}

/* --- Tap to unmute --------------------------------------------------------

   EVERY REEL STARTS MUTED, and this badge is what makes that a design rather
   than a defect. Audible autoplay inside a cross-origin embed is refused by
   every current browser without a user gesture behind it, and a player refused
   an audible start either mutes itself silently or fails to start at all — the
   two bugs this viewer shipped twice. Starting muted removes both; the badge
   buys the sound back for one tap, which then persists (localStorage) across
   reels and across visits.

   Three things keep it honest:
   - It is driven by the SAME state the mute icon is, so the two can never
     disagree: syncMuteUi() paints `is-muted` (can I hear this?) and
     `is-sound-blocked` (is the silence something nobody asked for?), and only
     the second one may show this.
   - `.is-playing` gates it as well. An invitation to turn on sound, sitting
     over a poster that has not started, reads as an error message.
   - It fades ITSELF out after a few seconds, with an animation rather than a JS
     timer — the animation re-runs per reel because `.is-active` moves with the
     feed. The control bar's speaker button is the permanent affordance; this is
     only the thing that points at it.

   Sits below the close button, and `pointer-events: none` so the tap lands on
   .ds-reel__surface underneath — the whole frame is the target, which is what
   makes a small badge workable on a phone. */
.ds-reel__hint {
    position: absolute;
    inset-block-start: 72px;
    inset-inline-start: 50%;
    /* Positive X: under dir="rtl" inline-start is the RIGHT edge. Same idiom as
       .ds-reel__state above — never translate(-50%, …) here. */
    transform: translateX(50%);
    z-index: 4;
    display: none;
    align-items: center;
    gap: 8px;
    max-width: calc(100% - 32px);
    padding: 8px 14px;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.72);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--ds-text-on-dark);
    font-size: 13px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    white-space: nowrap;
    pointer-events: none;
}

/* `:not(.is-static)` because this rule is more specific than the .is-static
   hide list below and would otherwise win on a Facebook fallback slide. */
.ds-reels.is-sound-blocked .ds-reel.is-active.is-playing:not(.is-static) .ds-reel__hint {
    display: inline-flex;
    animation: ds-reel-hint 4.5s ease forwards;
}

.ds-reel__hint i {
    font-size: 16px;
    line-height: 1;
}

@keyframes ds-reel-hint {
    0% { opacity: 0; transform: translateX(50%) translateY(-6px); }
    8% { opacity: 1; transform: translateX(50%); }
    80% { opacity: 1; transform: translateX(50%); }
    100% { opacity: 0; transform: translateX(50%); }
}

@media (prefers-reduced-motion: reduce) {
    .ds-reels.is-sound-blocked .ds-reel.is-active.is-playing:not(.is-static) .ds-reel__hint {
        animation: none;
    }
}

/* The buffering indicator: a soft dark disc carrying a thin emerald arc, the
   same weight as the rest of the viewer's chrome rather than the bare grey ring
   this used to be.

   Two details do most of the work:
   - It FADES IN AFTER A DELAY. Most buffers resolve in a few hundred
     milliseconds, and a spinner that flashes on every scroll reads as a page
     struggling. The delay is on the .is-buffering rule only, so it still
     disappears instantly when playback resumes.
   - The disc is steady and only the arc turns. Spinning a filled circle makes
     the whole thing look like it is wobbling. */
.ds-reel__spinner {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    transform: translate(50%, -50%);
    z-index: 4;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease; /* out: immediate */
}

.ds-reel__spinner::before {
    content: "";
    width: 24px;
    height: 24px;
    border-radius: var(--ds-radius-pill);
    border: 2px solid rgba(255, 255, 255, 0.2);
    border-block-start-color: var(--ds-emerald-on-dark);
    animation: ds-reel-spin 0.7s linear infinite;
}

.ds-reel.is-buffering .ds-reel__spinner {
    opacity: 1;
    transition: opacity 0.2s ease 0.4s; /* in: only if it lasts */
}

/* The infinite-scroll pill at the bottom of the feed uses the same arc, small. */
.ds-reels__spinner {
    display: inline-block;
    width: 15px;
    height: 15px;
    border-radius: var(--ds-radius-pill);
    border: 2px solid rgba(255, 255, 255, 0.2);
    border-block-start-color: var(--ds-emerald-on-dark);
    animation: ds-reel-spin 0.7s linear infinite;
}

@keyframes ds-reel-spin {
    to {
        transform: rotate(360deg);
    }
}

/* --- Instructor line ------------------------------------------------------ */

.ds-reel__meta {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 68px; /* clears the controls row */
    z-index: 4;
    padding: 40px 16px 12px;
    background: transparent; 
    pointer-events: none; /* the link inside re-enables it */
}

.ds-reel__author {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    pointer-events: auto;
    color: var(--ds-text-on-dark);
    text-decoration: none;
}

.ds-reel__author:hover {
    color: var(--ds-emerald-on-dark);
}

.ds-reel__avatar {
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border-radius: var(--ds-radius-pill);
    object-fit: cover;
    border: 1px solid rgba(255, 255, 255, 0.4);
    background: var(--ds-surface-avatar);
}

.ds-reel__name {
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-semibold);
}

/* --- Controls ------------------------------------------------------------- */

.ds-reel__controls {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 5;
    direction: ltr; /* a timeline reads LTR in every locale — see header note */
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px 14px;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%);
}

/* Facebook exposes no player API, so those slides keep the plugin's own
   chrome — a bar that cannot control anything is worse than no bar. */
.ds-reel.is-static .ds-reel__controls,
.ds-reel.is-static .ds-reel__state,
.ds-reel.is-static .ds-reel__hint,
.ds-reel.is-static .ds-reel__surface {
    display: none;
}

.ds-reel.is-static .ds-reel__meta {
    inset-block-end: 0;
}

.ds-reel__ctrl {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: transparent;
    color: var(--ds-text-on-dark);
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.ds-reel__ctrl:hover {
    background: rgba(255, 255, 255, 0.16);
}

.ds-reel__time {
    flex: 0 0 auto;
    min-width: 34px;
    font-size: 12px;
    line-height: 16px;
    font-variant-numeric: tabular-nums; /* the row must not twitch as it counts */
    color: rgba(255, 255, 255, 0.85);
    text-align: center;
}

/* The rail is drawn by ::before so the element itself can be a comfortable
   16px pointer target over a 4px line. */
.ds-reel__progress {
    position: relative;
    flex: 1 1 auto;
    height: 16px;
    cursor: pointer;
    touch-action: none; /* or a drag scrolls the feed instead of seeking */
}

.ds-reel__progress::before {
    content: "";
    position: absolute;
    inset-block-start: 50%;
    left: 0;
    width: 100%;
    height: 4px;
    transform: translateY(-50%);
    border-radius: var(--ds-radius-pill);
    background: rgba(255, 255, 255, 0.3);
}

.ds-reel__fill {
    position: absolute;
    inset-block-start: 50%;
    left: 0;
    width: 0;
    height: 4px;
    transform: translateY(-50%);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
}

/* inset-inline-start, not left: the JS sets that same logical property from the
   playback ratio, and mixing the two here would leave the cascade deciding
   between a physical rule and an inline logical one. */
.ds-reel__knob {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 0;
    width: 12px;
    height: 12px;
    transform: translate(-50%, -50%);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-text-on-dark);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);
}

.ds-reel__progress:focus-visible {
    outline: 2px solid var(--ds-emerald);
    outline-offset: 2px;
    border-radius: var(--ds-radius-pill);
}

/* --- Overlay chrome ------------------------------------------------------- */

/* Top-left in RTL, matching .ds-modal__close (section 12). */
.ds-reels__close {
    -webkit-appearance: none;
    appearance: none;
    position: absolute;
    inset-block-start: 16px;
    inset-inline-end: 16px;
    z-index: 6;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ds-tile-md);
    height: var(--ds-tile-md);
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.55);
    color: var(--ds-text-on-dark);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.ds-reels__close:hover {
    background: rgba(19, 27, 46, 0.85);
}

/* Desktop only: a mouse cannot swipe, and the wheel alone is easy to miss.
   Sits on the inline-end side (the left in RTL), clear of the close button. */
.ds-reels__nav {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: 16px;
    transform: translateY(-50%);
    z-index: 6;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.ds-reels__navbtn {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ds-tile-md);
    height: var(--ds-tile-md);
    padding: 0;
    border: 0;
    border-radius: var(--ds-radius-pill);
    background: rgba(255, 255, 255, 0.12);
    color: var(--ds-text-on-dark);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.ds-reels__navbtn:hover {
    background: var(--ds-emerald);
}

.ds-reels__loader {
    position: absolute;
    inset-block-end: 24px;
    inset-inline-start: 50%;
    transform: translateX(50%); /* RTL: inline-start is the right edge */
    z-index: 6;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.75);
    color: var(--ds-text-on-dark);
    font-size: 13px;
    line-height: 18px;
}

.ds-reels__loader[hidden] {
    display: none;
}

/* --- Responsive ----------------------------------------------------------- */

@media (min-width: 992px) {
    /* A lightbox on a wide screen: the frame is centred and the surround is
       click-to-close (handled in JS, on .ds-reel itself). */
    .ds-reels {
        background: rgba(9, 13, 22, 0.94);
    }

    .ds-reel {
        padding-block: 24px;
    }

    .ds-reel__frame {
        border-radius: var(--ds-radius-xl);
        box-shadow: 0 24px 60px -12px rgba(0, 0, 0, 0.7);
    }
}

@media (max-width: 991.98px) {
    /* Touch swipes the feed, so the arrows are dead weight down here. */
    .ds-reels__nav {
        display: none;
    }

    /* Edge to edge, and deliberately NOT 9:16 down here: setting width as well
       as height overrides the aspect-ratio, so the frame becomes the whole
       viewport. The embed letterboxes the video inside it and the meta line and
       controls pin to the bottom edge of the screen — which is where a thumb
       expects them, and what every native shorts feed does. */
    .ds-reel__frame {
        width: 100%;
        border-radius: 0;
    }

    .ds-reel__controls {
        padding-block-end: calc(14px + env(safe-area-inset-bottom));
    }

    .ds-reels__close {
        inset-block-start: calc(12px + env(safe-area-inset-top));
    }

    /* Edge to edge down here, so the badge has to clear the notch too — it
       sits under the close button, not beside it. */
    .ds-reel__hint {
        inset-block-start: calc(64px + env(safe-area-inset-top));
    }
}

/* ==========================================================================
   28. Educational profile dialog (.ds-eduprofile*)
   Figma frame 35:36 ("Dialog Container"); markup in
   partials/education-profile-dialog.blade.php; behaviour in
   assets/js/darssly-education-profile.js; rules in docs/class_choose_plan.md.

   A STEPPED dialog with no progress bar: one question per screen
   (المرحلة → الصف → المسار|التشعيب → المادة → نظام الدراسة), «السابق» /
   «التالي» in the footer, and steps that do not apply to the chosen grade
   skipped outright. The frame draws a single scrolling body; the steps are the
   product's later refinement of it, so the card, header, footer and option
   surfaces still come from the frame — only the one-at-a-time paging is new.

   Built on the section-12 `.ds-dialog` shell (a plain div toggled with `.show`,
   not a Bootstrap modal) — it has to open by itself on page load, and a
   hand-rolled overlay has no Bootstrap instance to keep in sync.

   The card is header / scrolling body / footer, which is why it zeroes
   `.ds-modal__content`'s padding: each of the three bands carries its own, and
   only the middle one scrolls.
   ========================================================================== */

:root {
    /* The frame's own values, kept local rather than promoted to brand tokens.

       --ds-edu-selected is #006c49, NOT --ds-emerald: a selected box carries
       white text and #10b981 only reaches ~2.4:1 against white, while this
       reaches ~7:1. The bright emerald stays on the confirm button, where
       nothing has to be read on top of it. */
    --ds-edu-selected: #006c49;
    --ds-edu-tile-bg: #eceef0; /* idle icon disc */
    --ds-edu-wash: #f0fdf4; /* selected card wash */
}

.ds-eduprofile .ds-modal__content {
    max-width: 748px; /* the frame's own width */
}

.ds-eduprofile__card {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 40px); /* .ds-dialog's own 20px padding, both ends */
    padding: 0;
    overflow: hidden;
}

/* --- Header --- */
.ds-eduprofile__head {
    position: relative;
    flex: 0 0 auto;
    padding: 32px 32px 25px;
    /* Room for the close button, which floats over this band. In RTL
       inline-end is the LEFT edge, which is the corner it sits in. */
    padding-inline-end: 60px;
    border-block-end: 1px solid var(--ds-border-subtle);
    text-align: start;
}

.ds-eduprofile__title {
    margin: 0;
    font-size: var(--ds-headline-md);
    line-height: var(--ds-headline-md-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-slate);
}

/* Rewritten per step by the JS, so it is the dialog's only orientation cue —
   there is no stepper and no progress bar by product decision. */
.ds-eduprofile__subtitle {
    margin: 7px 0 0;
    font-size: 14px;
    line-height: 22.4px;
    color: var(--ds-text-muted);
}

/* .ds-modal__close anchors itself against the card's own padding; here the
   header carries the padding, so it is re-anchored inside it.

   It goes in the top-LEFT corner (Figma 35:81), which under dir="rtl" is
   inline-**END** — not inline-start. Getting that backwards puts it on the
   right, on top of the title, which is exactly what the first version did.
   inline-end also resolves to `left`, so it overrides section 12's `left: -6px`
   without needing a physical reset. */
.ds-eduprofile__close {
    inset-block-start: 26px;
    inset-inline-end: 24px;
    inset-inline-start: auto;
}

/* --- Body: the only band that scrolls --- */
.ds-eduprofile__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 31px 32px 40px;
}

.ds-eduprofile__alert {
    /* `.ds-modal .alert` already paints this; only the rhythm is local. */
    margin-block-end: 24px;
}

/* --- Steps ---
   Exactly one is visible at a time; the rest carry `hidden`. With JavaScript
   off nothing sets that attribute, so every step renders stacked above a single
   «تأكيد» — which is the right no-JS behaviour, and why the base rule below is
   a plain block rather than anything positioned. */
.ds-eduprofile__step + .ds-eduprofile__step {
    margin-block-start: 31px;
}

/* A hidden step must take no space at all. The UA `[hidden]` rule loses to any
   explicit `display`, the trap section 27 documents for `.ds-reels[hidden]` —
   so anything here that declares one has to opt back out by name. */
.ds-eduprofile__step[hidden],
.ds-eduprofile__opts[hidden],
.ds-eduprofile__nav[hidden] {
    display: none;
}

.ds-eduprofile__legend {
    margin: 0 0 20px;
    font-size: var(--ds-headline-sm);
    line-height: var(--ds-headline-sm-lh);
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-eduprofile__hint {
    margin: 12px 0 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

/* --- Option boxes ---
   One component for every step. Column count comes from the markup as
   `--ds-edu-cols`, because the right answer depends on how many boxes there
   are: three reads well for 3 and 6, four wants 2×2 rather than a row of three
   and an orphan, and a binary choice wants two wide boxes. Grid tracks flow
   with `direction`, so the first box lands on the RIGHT — no `order` needed. */
.ds-eduprofile__opts {
    display: grid;
    grid-template-columns: repeat(var(--ds-edu-cols, 3), minmax(0, 1fr));
    gap: 14px;
}

.ds-eduprofile__opt {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    min-height: 132px;
    margin: 0;
    padding: 20px 14px;
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    cursor: pointer;
    text-align: center;
    transition:
        background-color 0.2s ease-in-out,
        border-color 0.2s ease-in-out,
        box-shadow 0.2s ease-in-out;
}

.ds-eduprofile__opt:hover {
    border-color: var(--ds-emerald);
}

.ds-eduprofile__opt-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 48px;
    height: 48px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-edu-tile-bg);
    color: var(--ds-text-body);
    font-size: 20px;
    transition:
        background-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

/* Grades get their level as a numeral instead of a glyph: no icon says
   «الصف الرابع», and the number does. */
.ds-eduprofile__opt-icon--num {
    font-size: 20px;
    font-weight: var(--ds-weight-bold);
    line-height: 1;
}

.ds-eduprofile__opt-label {
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-heading);
    /* Long track names («الهندسة وعلوم الحاسب») must wrap inside the box
       rather than widen the grid track. */
    overflow-wrap: anywhere;
}

/* The tick that marks the chosen box. Top-LEFT of an RTL card, i.e. the inline
   END — same axis note as the close button above. */
.ds-eduprofile__opt-check {
    position: absolute;
    inset-block-start: 10px;
    inset-inline-end: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-edu-selected);
    color: var(--ds-text-on-dark);
    font-size: 11px;
    opacity: 0;
    transform: scale(0.7);
    transition:
        opacity 0.15s ease-in-out,
        transform 0.15s ease-in-out;
}

/* --- The hidden radio ---
   Nested inside its label, so styles.css's `input[type=radio] ~ label` fake
   control never matches it (the same trick .ds-choice uses). It also needs a
   real 1px box: the theme's blanket `input { width: 100% }` otherwise resolves
   against the containing block and an absolutely-positioned radio comes out
   viewport-wide, adding phantom horizontal scroll to the page — section 18
   already paid for that one. */
.ds-eduprofile__input {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    opacity: 0;
    pointer-events: none;
}

/* The control is invisible, so the focus ring has to land on the surface.
   `:has()` is unavailable for this on purpose — a sibling selector is enough
   and works everywhere. */
.ds-eduprofile__input:focus-visible ~ .ds-eduprofile__opt-icon {
    outline: 2px solid var(--ds-emerald);
    outline-offset: 3px;
}

/* Selected state, sibling half: works in every browser. */
.ds-eduprofile__input:checked ~ .ds-eduprofile__opt-icon {
    background: var(--ds-edu-selected);
    color: var(--ds-text-on-dark);
}

.ds-eduprofile__input:checked ~ .ds-eduprofile__opt-label {
    font-weight: var(--ds-weight-bold);
    color: var(--ds-edu-selected);
}

.ds-eduprofile__input:checked ~ .ds-eduprofile__opt-check {
    opacity: 1;
    transform: none;
}

/* Selected state, `:has()` half — the box surface itself, which can only be
   reached from the checked input it WRAPS. Where `:has()` is missing the disc,
   the tick and the bolder label above still mark the choice, so it degrades
   quiet rather than invisible. */
.ds-eduprofile__opt:has(.ds-eduprofile__input:checked) {
    background: var(--ds-edu-wash);
    border-color: var(--ds-edu-selected);
    box-shadow: 0 4px 10px rgba(16, 185, 129, 0.1);
}

/* --- Footer ---
   Two groups pinned to opposite edges. Under dir="rtl" the first child group
   lands on the RIGHT, so «السابق» sits right and «التالي» left: going forward
   is a leftward move, the direction the page reads. */
.ds-eduprofile__foot {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 24px 32px;
    border-block-start: 1px solid var(--ds-border-subtle);
    background: var(--ds-surface);
}

.ds-eduprofile__foot-side {
    display: flex;
    align-items: center;
    gap: 12px;
}

.ds-eduprofile__nav {
    font-size: 16px;
    line-height: 24px;
    font-weight: var(--ds-weight-semibold);
    padding: 13px 32px;
}

.ds-eduprofile__nav .feather-chevron-left,
.ds-eduprofile__nav .feather-chevron-right {
    font-size: 15px;
}

/* `.ds-btn:disabled` already dims it; make it unclickable too, since «التالي»
   spends most of its life waiting for the current step to be answered. */
.ds-eduprofile__nav:disabled {
    pointer-events: none;
}

/* The overlay scrolls its own body; locking the page behind it stops the two
   from fighting on iOS. */
body.ds-eduprofile-open {
    overflow: hidden;
}

@media only screen and (max-width: 767px) {
    .ds-eduprofile__head {
        padding: 24px 20px 20px;
        padding-inline-end: 52px;
    }

    .ds-eduprofile__close {
        inset-block-start: 18px;
        inset-inline-end: 14px;
    }

    .ds-eduprofile__title {
        font-size: 22px;
        line-height: 30px;
    }

    .ds-eduprofile__body {
        padding: 24px 20px 28px;
    }

    /* Three boxes across is ~90px each on a phone. Two keeps the 48px disc and
       a wrapped label readable, whatever the markup asked for. */
    .ds-eduprofile__opts {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .ds-eduprofile__opt {
        min-height: 118px;
        padding: 16px 10px;
    }

    .ds-eduprofile__foot {
        padding: 16px 20px;
        gap: 10px;
    }

    /* Each group takes half the bar so the two buttons match, rather than
       «التالي» being twice the width of «السابق». */
    .ds-eduprofile__foot-side {
        flex: 1 1 0;
    }

    .ds-eduprofile__foot-side:last-child {
        justify-content: flex-end;
    }

    .ds-eduprofile__nav {
        flex: 1 1 auto;
        justify-content: center;
        padding-inline: 12px;
        font-size: 15px;
    }
}

/* ==========================================================================
   29. Cookie consent (.ds-cookie*)
   The blocking consent gate in partials/cookie-consent.blade.php. It is the
   section-12 `.ds-dialog` shell with three differences, all of them
   deliberate:

     - It sits at z-index 10050, ABOVE the education dialog (10001) and the
       theme's back-to-top (10000), because it has to be answered before
       anything else on the page. Don't raise the education dialog past it.
     - It has no close button and no backdrop-click handler — consent is
       mandatory, so the only way out is the accept button.
     - Its card is a little wider than the 460px modal default, because the
       consent copy is a paragraph rather than a form.

   Everything inside is `.ds-modal__*` from section 12; only the pieces below
   have no equivalent there.
   ========================================================================== */

.ds-cookie {
    z-index: 10050;
}

.ds-cookie .ds-modal__content {
    max-width: 520px;
    text-align: center;
}

.ds-cookie__text {
    margin: 0;
    font-size: 14px;
    line-height: 24px;
    color: var(--ds-text-body);
}

/* The category list — what the essential cookies are actually for. Sunken so
   it reads as supporting detail rather than a second paragraph. */
.ds-cookie__list {
    list-style: none;
    margin: 18px 0 0;
    padding: 14px 16px;
    background: var(--ds-surface-sunken);
    border-radius: var(--ds-radius-md);
    text-align: start;
}

.ds-cookie__list li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 13px;
    line-height: 21px;
    color: var(--ds-text-body);
}

.ds-cookie__list li + li {
    margin-top: 10px;
}

.ds-cookie__list i {
    flex: 0 0 auto;
    margin-top: 3px;
    font-size: 14px;
    color: var(--ds-emerald);
}

/* Policy links — a quiet row under the actions, not buttons. */
.ds-cookie__links {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin-top: 16px;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-cookie__links a {
    color: var(--ds-emerald);
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
}

.ds-cookie__links a:hover {
    color: var(--ds-emerald-hover);
    text-decoration: underline;
}

.ds-cookie__links span {
    color: var(--ds-border);
}

/* Scroll lock while the gate is up. The gate is the whole interaction, and
   the page behind it must not be readable by scrolling past the card. */
body.ds-cookie-open {
    overflow: hidden;
}

/* ==========================================================================
   30. Static marketing pages (.ds-page*)

   /about and /contact. Both used to be raw purchased-theme markup
   (.rbt-banner-area, .rbt-about-area, .rbt-service-area, .rbt-team-area,
   .rbt-conatct-area, .rbt-accordion-area) with the theme's gradients, its
   typewriter headline, its floating-label form and four different card shapes
   on one page. None of that markup is rendered any more, so none of those
   rules in styles.css apply here.

   THIS SECTION IS DELIBERATELY SMALL, because most of these pages are built
   from vocabulary that already exists:

   - `.ds-home-section` / `.ds-home-head*` / `.ds-home-btn` (section 26) — the
     section rhythm, the section heading and the pill buttons. They are named
     for the homepage but carry no homepage-specific styling, and using them
     here is what makes /about and /contact read as the same product as `/`.
     Do NOT clone them under a `.ds-page-` name.
   - `.ds-home-tutor*` (section 26) — the instructor card, reused verbatim by
     the «مدرسونا» band on /about.
   - `.ds-form` / `.ds-field*` (section 22) plus the section-5 input theming —
     the contact form.
   - `.ds-notice--success` / `--danger` (section 21) — the form's results.

   What is left, and only what is left, lives below.
   ========================================================================== */

/* --- Page hero -------------------------------------------------------------
   The compact header both pages open with: an optional soft pill, a headline,
   a lead paragraph and (on /about) two CTAs. It is NOT the homepage hero —
   there is no media column and no 48px headline. A static page opens with a
   statement of what the page is, not with a pitch. */
.ds-page-hero {
    padding-block: 56px 0;
    text-align: center;
}

.ds-page-hero__inner {
    max-width: 760px;
    margin-inline: auto;
}

.ds-page-hero__badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 18px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
}

.ds-page-hero__badge i {
    font-size: 16px;
    line-height: 1;
}

.ds-page-hero__title {
    margin: 24px 0 0;
    font-size: 40px;
    line-height: 52px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

/* The part of the headline the page is actually about — «رسالتنا، رؤيتنا،
   خطتنا» on /about. It replaces the theme's typewriter headline, which cycled
   those three words through a JS ticker: three settings the admin can edit,
   two of which were only ever readable for a second and a half. */
.ds-page-hero__title em {
    font-style: normal;
    color: var(--ds-emerald);
}

.ds-page-hero__lead {
    max-width: 640px;
    margin: 20px auto 0;
    font-size: 18px;
    line-height: 30px;
    color: var(--ds-text-muted);
}

/* A small emerald line above a section heading, for the sections that carry
   both a subtitle setting and a title setting. It sits OUTSIDE `.ds-home-head`
   on purpose: that component is a grid with explicitly placed areas (title
   1/1, subtitle 2/1, aside spanning column 2), so a third item inside it would
   be auto-placed onto a row of its own below the aside. */
.ds-page-eyebrow {
    margin: 0 0 12px;
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
}

.ds-page-hero__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 16px;
    margin-block-start: 36px;
}

/* --- Page hero, banner variant (`.ds-page-hero--banner`) --------------------
   The full-bleed opening band on /about and /contact. It is a BRAND GRAPHIC,
   not a photograph: navy → deep-emerald gradient, a soft emerald glow and a
   dot lattice, all drawn here. That is deliberate — the pages were stripped of
   purchased-theme stock art on purpose (see the section header above), and
   shipping a new stock photo would put it straight back.

   An admin CAN put a real photograph behind it by uploading `about_hero_image`
   / `contact_hero_image`; the Blade sets `--ds-page-hero-img` inline and the
   scrim below keeps the headline readable over anything. With no upload the
   custom property resolves to `none` and only the gradient shows, so the band
   never depends on a file existing.

   The band is full-bleed because the section element itself carries the
   background and the theme's `.container` lives INSIDE it — same call the
   footer and navbar make. Painting order is what makes the layers work: the
   element's own background (the photo) paints first, then the negative
   z-index pseudos, then the content. Don't give either pseudo a positive
   z-index or it covers the headline. */
.ds-page-hero--banner {
    position: relative;
    isolation: isolate;
    padding-block: 84px 92px;
    overflow: hidden;
    background-color: var(--ds-navy);
    background-image: var(--ds-page-hero-img, none);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Scrim + brand wash in one layer, so it reads the same with and without an
   uploaded photo. It is opaque enough to carry white text over a light image. */
.ds-page-hero--banner::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(120% 140% at 85% 0%, rgba(16, 185, 129, 0.38) 0%, rgba(16, 185, 129, 0) 55%),
        linear-gradient(135deg, rgba(19, 27, 46, 0.96) 0%, rgba(0, 81, 54, 0.94) 62%, rgba(11, 138, 95, 0.9) 100%);
}

/* With a photograph behind it the same scrim is far too opaque — at .96 the
   upload is invisible and the admin reasonably concludes it did not save. This
   is the ONE thing `--photo` changes: the wash thins to where the picture reads
   as texture, while the lightest stop is still .72 over navy, which keeps white
   headline text legible over a bright photo. Never let these drop further. */
.ds-page-hero--banner.ds-page-hero--photo::before {
    background:
        radial-gradient(120% 140% at 85% 0%, rgba(16, 185, 129, 0.26) 0%, rgba(16, 185, 129, 0) 55%),
        linear-gradient(135deg, rgba(19, 27, 46, 0.88) 0%, rgba(0, 81, 54, 0.8) 62%, rgba(11, 138, 95, 0.72) 100%);
}

/* The lattice. A 32px SVG tile rather than an image file — it is three dozen
   bytes, needs no request, and rescales with no artefacts. It is masked out
   towards the bottom so the pattern never competes with the CTAs. */
.ds-page-hero--banner::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Ccircle cx='2' cy='2' r='1.4' fill='%23ffffff' fill-opacity='0.16'/%3E%3C/svg%3E");
    -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 78%);
    mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 78%);
}

.ds-page-hero--banner .ds-page-hero__badge {
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.24);
    color: var(--ds-text-on-dark);
}

.ds-page-hero--banner .ds-page-hero__title {
    color: var(--ds-text-on-dark);
}

/* --ds-emerald-on-dark, not --ds-emerald: the brand green reaches only ~2.4:1
   against this band, the same reason section 28 keeps its own selected tone. */
.ds-page-hero--banner .ds-page-hero__title em {
    color: var(--ds-emerald-on-dark);
}

.ds-page-hero--banner .ds-page-hero__lead {
    color: rgba(255, 255, 255, 0.8);
}

/* The ghost CTA is drawn for a light page (hairline border, ink text), so it
   is re-drawn here rather than being a second modifier on the button. */
.ds-page-hero--banner .ds-home-btn--ghost {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.45);
    color: var(--ds-text-on-dark);
}

.ds-page-hero--banner .ds-home-btn--ghost:hover,
.ds-page-hero--banner .ds-home-btn--ghost:focus {
    background: rgba(255, 255, 255, 0.14);
    border-color: var(--ds-text-on-dark);
    color: var(--ds-text-on-dark);
}

/* The band brings its own bottom padding, so the first section after it does
   not need a full `--ds-home-gap` on top as well — that read as a hole. */
.ds-page-hero--banner + .ds-home-section {
    padding-block-start: 72px;
}

/* --- Page tail -------------------------------------------------------------
   `.ds-home-section` is `padding-block-START` only — the homepage gets away
   with that because its last band is the dark shorts strip, which brings its
   own vertical padding. These pages end on an ordinary section, so without a
   tail the last card would sit directly on the footer's hairline.

   It goes on a wrapper around the whole page rather than on the last section,
   because which section IS last depends on what the admin has filled in (the
   team, partners and FAQ bands each drop out when empty). */
.ds-page {
    padding-block-end: var(--ds-home-gap);
}

/* --- Narrow column ---------------------------------------------------------
   Both pages are text-only: there are no photographs anywhere on them, by
   product decision (see CLAUDE.md section 30). A block of body copy or a form
   set at the full 1320px container width is unreadable — the line length runs
   past 150 characters — so the two content blocks are capped and centred
   inside their container instead. */
.ds-page-narrow {
    max-width: 760px;
    margin-inline: auto;
}

/* --- Prose block -----------------------------------------------------------
   `.ds-page-prose` itself carries no rules — it exists so the elements below
   have a block to hang off. `--center` is /about's intro, which is a statement
   about the platform and reads as one centred column. */

.ds-page-prose--center {
    text-align: center;
}

.ds-page-prose--center .ds-page-prose__text {
    margin-inline: auto;
}

.ds-page-prose--center .ds-page-prose__actions {
    justify-content: center;
}

.ds-page-prose__badge {
    display: inline-flex;
    align-items: center;
    padding: 6px 16px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
    font-size: 13px;
    line-height: 20px;
    font-weight: var(--ds-weight-semibold);
}

.ds-page-prose__title {
    margin: 20px 0 0;
    font-size: 30px;
    line-height: 42px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-page-prose__text {
    margin: 20px 0 0;
    font-size: 16px;
    line-height: 28px;
    color: var(--ds-text-muted);
}

.ds-page-prose__text strong {
    color: var(--ds-home-ink);
    font-weight: var(--ds-weight-semibold);
}

.ds-page-prose__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-block-start: 32px;
}

/* --- Numbered steps ---------------------------------------------------------
   /about's «لماذا تتعلم مع دوراتنا؟» — four cards, each an icon tile plus a
   step number. The theme's version painted a ~100px ghost numeral bleeding out
   of the card; here the number is a small chip beside the icon, which stays
   readable at any card width. */
.ds-page-steps {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

.ds-page-step {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 32px 28px;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.3);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

.ds-page-step__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.ds-page-step__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: var(--ds-radius-lg);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 24px;
    line-height: 1;
}

/* LTR: a step number is a numeral, and «01» must not be reordered to «10». */
.ds-page-step__num {
    direction: ltr;
    font-size: 28px;
    line-height: 1;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-border-hairline);
}

.ds-page-step__title {
    margin: 0;
    font-size: 18px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-page-step__text {
    margin: 0;
    font-size: 14px;
    line-height: 24px;
    color: var(--ds-text-muted);
}

/* --- Partner logos ---------------------------------------------------------- */

.ds-page-brands {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-page-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 160px;
    height: 88px;
    padding: 16px 24px;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.6);
    border-radius: var(--ds-radius-lg);
}

.ds-page-brand img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* --- Contact channel cards -------------------------------------------------- */

/* Column count comes from the MARKUP as `--ds-channel-cols`, not from here —
   the same call section 28 makes. Which answer is right depends on how many
   cards the admin has filled in: three across reads well for three, but four
   want a 2×2 block rather than a row of three and an orphan underneath. The
   Blade sets it; the responsive rules below still override at every breakpoint. */
.ds-page-channels {
    display: grid;
    grid-template-columns: repeat(var(--ds-channel-cols, 3), 1fr);
    gap: 24px;
}

.ds-page-channel {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 32px;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.3);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

.ds-page-channel__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: var(--ds-radius-lg);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 24px;
    line-height: 1;
}

.ds-page-channel__title {
    margin: 0;
    font-size: 18px;
    line-height: 28px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-page-channel__list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-page-channel__value {
    margin: 0;
    font-size: 15px;
    line-height: 26px;
    color: var(--ds-text-muted);
    word-break: break-word;
}

/* Phone numbers and email addresses read left-to-right in every locale, but
   the card is right-aligned like the rest of the page — `isolate` keeps the
   value from dragging the surrounding Arabic around with it. */
.ds-page-channel__value--ltr {
    direction: ltr;
    text-align: right;
    unicode-bidi: isolate;
}

.ds-page-channel__value a {
    color: var(--ds-text-muted);
    text-decoration: none;
    transition: color 0.2s ease;
}

.ds-page-channel__value a:hover {
    color: var(--ds-emerald);
    text-decoration: none;
}

/* --- Contact form card ------------------------------------------------------ */

.ds-page-card {
    padding: 40px;
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.3);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

.ds-page-card__title {
    margin: 0;
    font-size: 24px;
    line-height: 34px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-home-ink);
}

.ds-page-prose__badge + .ds-page-card__title {
    margin-block-start: 16px;
}

.ds-page-card__text {
    margin: 8px 0 0;
    font-size: 15px;
    line-height: 26px;
    color: var(--ds-text-muted);
}

.ds-page-card__body {
    margin-block-start: 28px;
}

/* `.ds-form` is a 2-column grid (section 22); the contact form is a single
   stack of long fields, so it collapses to one column here rather than making
   every field carry `.ds-form__full`. */
.ds-page-form.ds-form {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
}

/* No top rule and no extra padding: the submit button is the last item in a
   single stack, not the footer of a two-column settings pane. */
.ds-page-form .ds-form__actions {
    margin: 0;
    padding: 0;
    border: 0;
}

.ds-page-form .ds-home-btn {
    width: 100%;
}

/* The AJAX result banners, toggled with the `hidden` ATTRIBUTE rather than an
   inline `display` — which is why this rule has to exist. `.ds-notice` declares
   `display: flex`, and any author declaration beats the UA's `[hidden]` rule
   regardless of specificity, so without this the banners would be permanently
   visible. Same trap as `.ds-reels[hidden]` in section 27.

   Toggling the attribute (instead of jQuery `.fadeIn()` / `.hide()`) is also
   what keeps the flex row intact: `.fadeIn()` writes `display: block`, which
   would stack the icon above the text. */
.ds-page-notice[hidden] {
    display: none;
}

/* --- FAQ accordion ----------------------------------------------------------
   Bootstrap collapse markup, restyled. The theme's `.rbt-accordion-style`
   paints a coloured header bar and its own chevron sprite; this is a flat list
   of hairline-bordered rows with a feather chevron that rotates.

   The same block serves the homepage's three-question taster
   (partials/home/faq.blade.php) — it is deliberately not cloned under a
   `.ds-home-` name, so the two can never drift. */
.ds-page-faq {
    max-width: 880px;
    margin-inline: auto;
}

/* The FAQ band on /contact is the homepage «عرض جميع الأسئلة» link's target, and
   the site navbar is `position: sticky` — so a bare anchor jump parks the
   heading underneath it. 73px of navbar plus air. */
#faq {
    scroll-margin-block-start: 96px;
}

.ds-page-faq__item {
    background: var(--ds-surface);
    border: 1px solid rgba(226, 232, 240, 0.6);
    border-radius: var(--ds-radius-lg);
    overflow: hidden;
}

.ds-page-faq__item + .ds-page-faq__item {
    margin-block-start: 12px;
}

/* A real <button>, so it carries the appearance/border reset every `.ds-*`
   class used on a button needs — see the note in CLAUDE.md. */
.ds-page-faq__q {
    -webkit-appearance: none;
    appearance: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    width: 100%;
    padding: 20px 24px;
    border: 0;
    background: transparent;
    color: var(--ds-home-ink);
    font-family: inherit;
    font-size: 16px;
    line-height: 26px;
    font-weight: var(--ds-weight-semibold);
    text-align: start;
    cursor: pointer;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-page-faq__q:hover {
    background: var(--ds-surface-sunken);
}

.ds-page-faq__q[aria-expanded="true"] {
    color: var(--ds-emerald-deep);
}

.ds-page-faq__q i {
    flex-shrink: 0;
    color: var(--ds-text-muted);
    font-size: 18px;
    line-height: 1;
    transition: transform 0.2s ease;
}

.ds-page-faq__q[aria-expanded="true"] i {
    transform: rotate(180deg);
    color: var(--ds-emerald);
}

.ds-page-faq__a {
    padding: 0 24px 20px;
    font-size: 15px;
    line-height: 28px;
    color: var(--ds-text-muted);
}

/* --- Responsive -------------------------------------------------------------- */

@media (max-width: 1199.98px) {
    .ds-page-steps,
    .ds-page-channels {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 991.98px) {
    .ds-page-hero {
        padding-block-start: 36px;
    }

    /* Same specificity as the rule above and later in the file, so this is what
       the banner variant resolves to — it needs its own bottom padding back. */
    .ds-page-hero--banner {
        padding-block: 56px 64px;
    }

    .ds-page-hero--banner + .ds-home-section {
        padding-block-start: 56px;
    }

    .ds-page-hero__title {
        font-size: 30px;
        line-height: 42px;
    }

    .ds-page-hero__lead {
        margin-block-start: 16px;
        font-size: 16px;
        line-height: 28px;
    }

    .ds-page-hero__actions {
        margin-block-start: 28px;
    }

    .ds-page-prose__title {
        font-size: 24px;
        line-height: 36px;
    }

    .ds-page-card {
        padding: 28px 24px;
    }

    .ds-page-card__title {
        font-size: 20px;
        line-height: 30px;
    }

    .ds-page-step,
    .ds-page-channel {
        padding: 24px 20px;
    }

    .ds-page-faq__q {
        padding: 16px 18px;
        font-size: 15px;
        line-height: 24px;
    }

    .ds-page-faq__a {
        padding: 0 18px 16px;
        font-size: 14px;
        line-height: 26px;
    }
}

@media (max-width: 575.98px) {
    .ds-page-hero--banner {
        padding-block: 44px 52px;
    }

    .ds-page-hero__title {
        font-size: 26px;
        line-height: 38px;
    }

    /* Same reasoning as the homepage hero: two pills side by side wrap
       awkwardly at this width and orphan one on its own line. */
    .ds-page-hero__actions,
    .ds-page-prose__actions {
        flex-direction: column;
        align-items: stretch;
    }

    .ds-page-steps,
    .ds-page-channels {
        grid-template-columns: 1fr;
        gap: 16px;
    }

    .ds-page-brand {
        min-width: 132px;
        height: 72px;
    }
}

/* ==========================================================================
   31. Instructor course form (.ds-eduform*, .ds-thumb*, .ds-courseform*)
   Markup in profile/course-create.blade.php, profile/course-edit.blade.php and
   partials/ds/course-education-picker.blade.php; behaviour in
   assets/js/darssly-course-education.js; the rules the picker draws are in
   docs/create_course_new_changes.md.

   The section is deliberately SMALL, because most of this page is built from
   vocabulary that already exists — the same call section 30 makes for the
   marketing pages. The panels are section 21's `.ds-panel`, the fields are
   section 22's `.ds-form` / `.ds-field` over the section-5 input theming, and
   the education picker's option boxes are section 28's `.ds-eduprofile__opt*`
   reused verbatim. DON'T clone those under a `.ds-course-` name: the whole
   point is that an instructor choosing a grade for a course sees the same
   control a student sees choosing their own.

   What is left is the three things that had no home: the progressive step
   stack, the course thumbnail dropzone, and the sticky action bar.
   ========================================================================== */

/* <x-input-error> renders a <ul>, while `.ds-field__error` (section 22) was
   written for a plain block. Reset the list chrome wherever the two meet —
   otherwise every validation message arrives with a bullet and 40px of
   inherited indent. */
ul.ds-field__error {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* --- The education picker ---
   A vertical stack of steps, each appearing once the one before it is answered
   and STAYING on screen. That is the one difference from the student dialog
   (section 28), which shows exactly one step at a time: an instructor is
   filling a form and needs to review the whole decision before submitting. */
.ds-eduform {
    display: flex;
    flex-direction: column;
}

/* A hidden step must take no space at all. `display: flex` below beats the UA
   `[hidden]` rule, so it has to opt back out by name — the same trap section 27
   documents for `.ds-reels[hidden]` and section 28 for `.ds-eduprofile__step`. */
.ds-eduform__step {
    display: flex;
    flex-direction: column;
}

.ds-eduform__step[hidden] {
    display: none;
}

/* The rule sits ABOVE each revealed step rather than below, so the last one
   never leaves a trailing line against the panel's padding. */
.ds-eduform__step + .ds-eduform__step {
    margin-block-start: 28px;
    padding-block-start: 28px;
    border-block-start: 1px solid var(--ds-border-subtle);
}

.ds-eduform__legend {
    margin: 0;
    font-size: 16px;
    line-height: 24px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-eduform__hint {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

/* The option grids come straight from section 28; only the rhythm is local. */
.ds-eduform .ds-eduprofile__opts {
    margin-block-start: 16px;
}

/* ...and one size override. The dialog's 132px boxes are drawn for a screen
   showing ONE question; here six steps stack in a single panel and fifteen
   grade boxes at that height push نظام الدراسة a long way down the page. The
   proportions are unchanged — this is the same component, one step quieter. */
.ds-eduform .ds-eduprofile__opt {
    min-height: 104px;
    gap: 10px;
    padding: 16px 12px;
}

.ds-eduform .ds-eduprofile__opt-icon {
    width: 40px;
    height: 40px;
    font-size: 17px;
}

.ds-eduform .ds-eduprofile__opt-icon--num {
    font-size: 18px;
}

.ds-eduform .ds-field__error {
    margin-block-start: 12px;
}

/* --- Course thumbnail ---
   A label wrapping a hidden file input, the same shape `.ds-cover` (section 22)
   uses — a real <input type="file"> is unstylable and its own button says
   «Choose file» in the browser's language, not ours. */
.ds-thumb {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.ds-thumb__drop {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    /* The 700x430 the copy asks for, so what the instructor sees while cropping
       is the shape the card will actually use. */
    aspect-ratio: 700 / 430;
    width: 100%;
    max-width: 520px;
    margin: 0;
    overflow: hidden;
    border: 1px dashed var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface-sunken);
    cursor: pointer;
    transition:
        border-color 0.2s ease-in-out,
        background-color 0.2s ease-in-out;
}

.ds-thumb__drop:hover {
    border-color: var(--ds-emerald);
}

.ds-thumb__drop img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Sits over the preview, so it reads on a photograph as well as on the empty
   placeholder. Pointer events stay off — the whole tile is the label. */
.ds-thumb__cta {
    position: absolute;
    inset-block-end: 12px;
    inset-inline-start: 12px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border-radius: var(--ds-radius-pill);
    background: rgba(19, 27, 46, 0.78);
    color: var(--ds-text-on-dark);
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    pointer-events: none;
}

.ds-thumb__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* --- Actions ---
   Outside the panels, on the page background, so it reads as "this submits the
   whole form" rather than as one more field in the last card. */
.ds-courseform__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-block-start: 24px;
}

.ds-courseform__actions .ds-btn {
    min-width: 168px;
    justify-content: center;
}

@media only screen and (max-width: 767px) {
    .ds-eduform__step + .ds-eduform__step {
        margin-block-start: 22px;
        padding-block-start: 22px;
    }

    .ds-courseform__actions .ds-btn {
        flex: 1 1 100%;
    }
}

/* ==========================================================================
   32. Course detail page (.ds-coursepage*, .ds-unit*, .ds-lesson*, .ds-stars*)
   Markup in student/lessons/index.blade.php — the public /courses/{slug}.

   Like section 31, this is deliberately small: the page is assembled from
   vocabulary that already exists — `.ds-page-hero--banner` and `.ds-page`
   (section 30), `.ds-home-section` / `.ds-home-courses` and the shared course
   card (26), `.ds-panel` / `.ds-info` / `.ds-tag` / `.ds-empty` /
   `.ds-progress__*` / `.ds-row` (21). What is here is only the four things that
   had no home: the two-column shell, the curriculum's unit and lesson rows, the
   star rating control, and the sticky purchase card.
   ========================================================================== */

/* --- The shell ---
   Grid columns flow with `direction`, so the FIRST child lands on the right
   under dir="rtl" — the content is first in the markup and reads first; the
   purchase card sits left. No `order` needed, and none should be added. */
.ds-coursepage {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 32px;
    align-items: start;
}

/* Sticky against the navbar (73px) plus air, matching `.ds-dash__aside`. */
.ds-coursepage__aside {
    position: sticky;
    inset-block-start: 89px;
}

.ds-coursepage__main > * + * {
    margin-block-start: 24px;
}

/* --- Page header ---
   NOT `.ds-page-hero--banner`. That dark navy→emerald band is right for /about
   and /contact, where there is nothing to show but a promise; on a course page
   it filled the first screen with a gradient while the one image the visitor
   actually wants — the course's own — sat thumbnail-sized in the sidebar. So:
   a light header, copy on the reading side, the course image large beside it.

   Grid columns flow with `direction`, so the copy is first in the markup and
   lands on the RIGHT under dir="rtl"; the image sits left. No `order`. */
.ds-coursehead {
    padding-block: 40px 8px;
}

.ds-coursehead__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 420px;
    gap: 40px;
    align-items: center;
}

.ds-coursehead__title {
    margin: 12px 0 0;
    font-size: var(--ds-headline-lg);
    line-height: var(--ds-headline-lg-lh);
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-coursehead__lead {
    margin: 12px 0 0;
    font-size: 15px;
    line-height: 26px;
    color: var(--ds-text-muted);
}

.ds-coursehead__by {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-block-start: 20px;
}

.ds-coursehead__avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--ds-radius-pill);
    object-fit: cover;
}

.ds-coursehead__byname {
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
    text-decoration: none;
}

.ds-coursehead__byname:hover {
    color: var(--ds-emerald);
}

/* Rating · lessons · students, as one quiet line rather than three pills. */
.ds-coursehead__facts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 18px;
    margin-block-start: 16px;
    padding: 0;
    list-style: none;
    font-size: 14px;
    color: var(--ds-text-muted);
}

.ds-coursehead__facts li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.ds-coursehead__facts i {
    font-size: 15px;
    color: var(--ds-text-muted);
}

.ds-coursehead__facts .feather-star {
    color: var(--ds-amber);
}

.ds-coursehead__media {
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-xl);
    background: var(--ds-surface-sunken);
    box-shadow: var(--ds-shadow-card);
}

.ds-coursehead__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}


/* --- Section jump nav ---
   Replaces the theme's `.rbt-inner-onepage-navigation`. Plain anchors: the
   browser's own fragment scrolling is enough, and it works with JavaScript off,
   where the theme's onePageNav did not. */
.ds-coursenav {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface);
}

.ds-coursenav__link {
    padding: 8px 16px;
    border-radius: var(--ds-radius-pill);
    color: var(--ds-text-body);
    font-size: 14px;
    font-weight: var(--ds-weight-medium);
    text-decoration: none;
    transition:
        background-color 0.2s ease-in-out,
        color 0.2s ease-in-out;
}

.ds-coursenav__link:hover {
    background: var(--ds-surface-sunken);
    color: var(--ds-emerald);
}

/* --- Curriculum ---
   Each unit is a native <details open>, not a Bootstrap accordion: it needs no
   JavaScript, it is keyboard- and screen-reader-correct for free, and it opens
   by default so the curriculum READS rather than being a stack of closed bars
   you have to click through. The marker is removed because the chevron is drawn
   in the markup, where it can sit at the inline end. */
.ds-unit + .ds-unit {
    margin-block-start: 12px;
}

.ds-unit__head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
    cursor: pointer;
    list-style: none;
}

/* Both are needed: WebKit uses the pseudo-element, everyone else list-style. */
.ds-unit__head::-webkit-details-marker {
    display: none;
}

.ds-unit__title {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-unit__count {
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--ds-text-muted);
}

.ds-unit__chevron {
    flex: 0 0 auto;
    color: var(--ds-text-muted);
    font-size: 15px;
    transition: transform 0.2s ease-in-out;
}

.ds-unit[open] .ds-unit__chevron {
    transform: rotate(180deg);
}

.ds-unit__body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-block-start: 8px;
}

/* --- Lesson row ---
   Built on `.ds-row` (section 21), which already supplies the flex row, border,
   radius and hover. Only the states are local. */
.ds-lesson {
    text-decoration: none;
    color: inherit;
}

/* A NUMBER, not another play triangle. A curriculum is an ordered list and the
   reader is counting it — twelve identical glyphs down the page tell them
   nothing, while "3 of 12" is the question they are actually asking. The play
   affordance moves to the row's end, where the action belongs. */
.ds-lesson__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    font-size: 13px;
    font-weight: var(--ds-weight-bold);
    font-variant-numeric: tabular-nums;
}

.ds-lesson__body {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-lesson__title {
    margin: 0;
    font-size: 14px;
    line-height: 21px;
    font-weight: var(--ds-weight-medium);
    color: var(--ds-text-heading);
    overflow-wrap: anywhere;
}

.ds-lesson__hint {
    margin: 2px 0 0;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

.ds-lesson__action {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
}

/* A locked lesson stays LEGIBLE rather than hidden — the point is to show what
   the course contains so a visitor can judge it, while making obvious what a
   subscription unlocks. `.is-locked` had no rule at all in the old page, so a
   locked row looked identical to a playable one. */
.ds-lesson.is-locked,
.ds-lesson.is-locked:hover {
    background: var(--ds-surface-sunken);
    cursor: default;
}

.ds-lesson.is-locked .ds-lesson__icon {
    background: var(--ds-border-subtle);
    color: var(--ds-text-muted);
}

.ds-lesson.is-locked .ds-lesson__title,
.ds-lesson.is-locked .ds-lesson__action {
    color: var(--ds-text-muted);
}

/* --- Star rating ---
   Real buttons, so the control is reachable by keyboard and announces itself.
   The theme's version was <a href="#"> wrappers around <i>. */
.ds-stars {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    direction: ltr; /* stars read left-to-right in every locale */
}

.ds-stars__btn {
    appearance: none;
    -webkit-appearance: none;
    padding: 2px;
    border: 0;
    background: none;
    color: var(--ds-border);
    font-size: 17px;
    line-height: 1;
    transition: color 0.15s ease-in-out;
}

.ds-stars__btn.is-on {
    color: var(--ds-amber);
}

.ds-stars--input .ds-stars__btn {
    cursor: pointer;
}

.ds-stars--static .ds-stars__btn {
    cursor: default;
    pointer-events: none;
}

/* The rating count, inside the widget so the script can find it without
   walking out into the surrounding markup. `direction: rtl` puts the
   parentheses back the right way round inside the ltr star row. */
.ds-stars__count {
    direction: rtl;
    margin-inline-start: 6px;
    font-size: 13px;
    color: var(--ds-text-muted);
}

.ds-ratesum {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 24px;
    align-items: center;
}

.ds-ratesum__score {
    text-align: center;
}

.ds-ratesum__number {
    font-size: 44px;
    line-height: 1.1;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-ratesum__caption {
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--ds-text-muted);
}

.ds-ratebar {
    display: grid;
    /* 52px, not 44: «5 نجوم» measures ~46px at 13px and wrapped to two lines. */
    grid-template-columns: 52px minmax(0, 1fr) 40px;
    gap: 12px;
    align-items: center;
}

.ds-ratebar + .ds-ratebar {
    margin-block-start: 8px;
}

.ds-ratebar__label,
.ds-ratebar__count {
    font-size: 13px;
    color: var(--ds-text-muted);
}

.ds-ratebar__count {
    text-align: end;
}

/* --- Purchase card ---
   No cover image here: the page header shows the course image at full width, and
   a second copy 360px wide only pushed the price and the CTA below the fold. */
.ds-buy__price {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    padding: 12px 0;
    border-block-end: 1px solid var(--ds-border-divider);
}

.ds-buy__price:last-of-type {
    border-block-end: 0;
}

.ds-buy__amount {
    font-size: 22px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald);
}

.ds-buy__amount small {
    font-size: 13px;
    font-weight: var(--ds-weight-medium);
}

.ds-buy__term {
    font-size: 13px;
    color: var(--ds-text-muted);
}

.ds-buy__cta {
    width: 100%;
    justify-content: center;
    margin-block-start: 16px;
}

@media only screen and (max-width: 1199px) {
    .ds-coursepage {
        grid-template-columns: minmax(0, 1fr) 320px;
        gap: 24px;
    }
}

@media only screen and (max-width: 1199px) {
    .ds-coursehead__grid {
        grid-template-columns: minmax(0, 1fr) 340px;
        gap: 28px;
    }
}

@media only screen and (max-width: 991px) {
    /* The image goes above the copy on a phone: it is the fastest thing to
       recognise, and 340px of it beside a wrapped headline reads as neither. */
    .ds-coursehead {
        padding-block-start: 28px;
    }

    .ds-coursehead__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }

    .ds-coursehead__media {
        order: -1;
    }

    .ds-coursehead__title {
        font-size: 26px;
        line-height: 36px;
    }

    /* One column — and the purchase card comes FIRST, because on a phone the
       price and the subscribe button are what the visitor came to check, and
       burying them under the whole curriculum hides them entirely. This is the
       one place `order` is correct here: it is a stacking decision, not a
       direction one. */
    .ds-coursepage {
        grid-template-columns: minmax(0, 1fr);
    }

    .ds-coursepage__aside {
        position: static;
        order: -1;
    }

    .ds-ratesum {
        grid-template-columns: minmax(0, 1fr);
        gap: 16px;
    }
}

/* --- Small screens ---
   The two blocks above take the page from three columns to one; these take it
   the rest of the way down to a 320px phone, where the failures are different:
   nothing is too wide any more, everything is too CRAMPED. Each rule below
   answers a specific collision measured at that width. */
@media only screen and (max-width: 767px) {
    .ds-coursehead {
        padding-block-start: 20px;
    }

    .ds-coursehead__title {
        font-size: 22px;
        line-height: 32px;
    }

    .ds-coursehead__lead {
        font-size: 14px;
        line-height: 24px;
    }

    .ds-coursehead__facts {
        gap: 6px 14px;
        font-size: 13px;
    }

    .ds-coursepage {
        gap: 20px;
    }

    /* The jump nav is four pills; at 16px each side they wrapped to three rows
       and pushed the content off the first screen. */
    .ds-coursenav {
        gap: 6px;
        padding: 6px;
    }

    .ds-coursenav__link {
        padding: 7px 12px;
        font-size: 13px;
    }

    .ds-unit__head {
        gap: 8px;
        padding: 12px;
    }

    .ds-unit__title {
        font-size: 14px;
    }

    .ds-unit__count {
        font-size: 12px;
    }

    .ds-lesson {
        gap: 10px;
        padding: 10px;
    }

    /* The related-courses strip lives inside the content column, which is much
       narrower than the page — three across (section 26's default) is ~180px a
       card here. Two, then one. */
    .ds-coursepage__main .ds-home-courses {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 16px;
    }
}

@media only screen and (max-width: 575px) {
    .ds-coursehead__title {
        font-size: 20px;
        line-height: 30px;
    }

    /* Panels keep 24px of padding at every width otherwise, which on a 320px
       screen is 48px of the 320 spent on nothing. */
    .ds-coursepage .ds-panel {
        padding: 16px;
    }

    /* The icon alone says «play»; the word was squeezing lesson titles to two
       words a line. The locked rows only ever showed an icon, so they are
       unaffected — which is the point: the two states stay distinguishable. */
    .ds-lesson__actiontext {
        display: none;
    }

    .ds-lesson__icon {
        width: 28px;
        height: 28px;
        font-size: 12px;
    }

    .ds-lesson__title {
        font-size: 13px;
        line-height: 20px;
    }

    .ds-coursepage__main .ds-home-courses {
        grid-template-columns: minmax(0, 1fr);
    }

    .ds-ratesum__number {
        font-size: 36px;
    }

    /* «5 نجوم» needs ~46px; the desktop 44px track wrapped it onto two lines. */
    .ds-ratebar {
        grid-template-columns: 48px minmax(0, 1fr) 30px;
        gap: 8px;
    }

    .ds-ratebar__label,
    .ds-ratebar__count {
        font-size: 12px;
    }

    .ds-buy__amount {
        font-size: 20px;
    }

    /* The facts list is a definition list; at this width the 38% key column
       leaves the value about twelve characters, so stack them instead. */
    .ds-info__row {
        flex-direction: column;
        gap: 2px;
    }

    .ds-info__key {
        flex: 0 0 auto;
        max-width: none;
    }
}

/* ==========================================================================
   33. Instructor pages (.ds-instrhead*, .ds-plan*, .ds-promo*)
   Markup in instructor/profile.blade.php (/instructors/{slug}),
   instructor/index.blade.php (/instructors, which adds nothing here) and
   instructor/subscribe.blade.php (/instructors/{slug}/plans).

   The page it opens was purchased-theme markup end to end: the dashboard's
   cover-photo shell (`.rbt-dashboard-area`, `.rbt-tutor-information`,
   `.rbt-avatars`, `.profile-content.rbt-shadow-box`), `.rbt-card variation-01`
   course cards with five hardcoded stars and a dead bookmark button, and a
   Swiper of raw reel iframes with two inline style blocks. None of that
   renders any more.

   LIKE SECTIONS 31 AND 32 THIS IS DELIBERATELY SMALL, because the rest of the
   page is vocabulary that already exists:

   - `.ds-coursepage` / `.ds-coursenav` (32) — the two-column shell, the sticky
     aside and the anchor row. Named for the course page, but neither carries
     anything course-specific, and a visitor moving between a course and its
     instructor should not cross a seam.
   - `.ds-panel` / `.ds-info` / `.ds-tag` / `.ds-empty` / `.ds-pagination` (21),
     `.ds-stars` / `.ds-ratesum` / `.ds-ratebar` / `.ds-buy` (32) — the panels,
     the facts list, the reviews block and the price rows.
   - `.ds-home-courses` + partials/ds/home-course-card (26) — the course grid is
     the SAME card as the homepage and /all-courses.
   - `.ds-home-shorts*` (26) + `.ds-reels*` (27) — the reels band is the
     homepage band and the homepage fullscreen player, via
     partials/ds/shorts-band.blade.php.

   What is left is the one thing with no home: the header, the only place in the
   product where a cover photo, an avatar and a CTA share a band.
   ========================================================================== */

/* --- In-page anchors ---
   `.ds-coursenav` is a row of in-page links and the site navbar is
   `position: sticky`, so a bare jump parks the target's heading underneath it —
   the same 96px `#faq` takes in section 30. Written against the shell rather
   than this page's ids, so the course page, which shares that nav, gets it too:
   its own four anchors had exactly the same problem. */
.ds-coursepage__main > [id],
#reels {
    scroll-margin-block-start: 96px;
}

/* --- The band ---
   Full-bleed, because the section carries the background and the theme's
   `.container` sits inside it — the call the navbar, the footer and
   `.ds-page-hero--banner` all make.

   With no upload `--ds-instrhead-img` resolves to `none` and only the brand
   graphic below shows, so the band never depends on a file existing. That
   matters more here than on /about: `users.cover_image` is optional and most
   instructors have never set one. */
.ds-instrhead {
    position: relative;
    isolation: isolate;
    padding-block: 108px 0;
    background-color: var(--ds-navy);
    background-image: var(--ds-instrhead-img, none);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Scrim + brand wash in one layer, thinned by `--photo` exactly as section 30
   thins the page hero — at full strength an uploaded cover is invisible and the
   instructor reasonably concludes it did not save. Negative z-index, so the
   element's own background (the photo) paints first and the card still paints
   over both; never give this a positive z-index. */
.ds-instrhead::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(120% 140% at 85% 0%, rgba(16, 185, 129, 0.38) 0%, rgba(16, 185, 129, 0) 55%),
        linear-gradient(135deg, rgba(19, 27, 46, 0.96) 0%, rgba(0, 81, 54, 0.94) 62%, rgba(11, 138, 95, 0.9) 100%);
}

.ds-instrhead--photo::before {
    background:
        radial-gradient(120% 140% at 85% 0%, rgba(16, 185, 129, 0.26) 0%, rgba(16, 185, 129, 0) 55%),
        linear-gradient(135deg, rgba(19, 27, 46, 0.86) 0%, rgba(0, 81, 54, 0.74) 62%, rgba(11, 138, 95, 0.66) 100%);
}

/* --- The card ---
   A white card sitting ON the band rather than under it: the cover is
   atmosphere, the card is the content, and overlapping them is what stops the
   band reading as a stripe of unused colour. The overlap is a negative bottom
   MARGIN and nothing else — the card stays in flow, ends the band 56px early
   and hangs that far past it, which `.ds-instrhead + .ds-home-section` clears.
   A `translate` on top of the margin would double the overhang (112px) and
   leave the card floating below its own band.

   Flex, not grid: the actions column is sized by its button. Children flow with
   `direction`, so the avatar is first in the markup and lands on the RIGHT
   under dir="rtl". No `order`, and none should be added. */
.ds-instrhead__card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 24px;
    margin-block-end: -56px;
    padding: 24px 28px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-hairline);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

/* The section after the header has to clear the overlap the card creates. */
.ds-instrhead + .ds-home-section {
    padding-block-start: 96px;
}

.ds-instrhead__avatar {
    flex: 0 0 auto;
    width: 104px;
    height: 104px;
    padding: 3px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    box-shadow: inset 0 0 0 2px var(--ds-emerald);
}

.ds-instrhead__avatar img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: var(--ds-radius-pill);
    object-fit: cover;
}

.ds-instrhead__body {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-instrhead__name {
    margin: 0;
    font-size: 28px;
    line-height: 38px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-instrhead__role {
    margin: 4px 0 0;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-muted);
}

/* The facts row — rating, courses, students. Same shape and same sizes as
   `.ds-coursehead__facts`, because they answer the same kind of question about
   the thing at the top of the page. */
.ds-instrhead__facts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
    margin: 14px 0 0;
    padding: 0;
    list-style: none;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-muted);
}

.ds-instrhead__facts li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.ds-instrhead__facts i {
    font-size: 15px;
    color: var(--ds-emerald);
}

.ds-instrhead__facts .feather-star {
    color: var(--ds-amber);
}

.ds-instrhead__actions {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    /* In a flex COLUMN the cross axis follows `direction`, so `flex-end` would
       be the LEFT edge under dir="rtl". `stretch` sidesteps the question and
       makes the social row exactly as wide as the button above it. */
    align-items: stretch;
    gap: 12px;
}

/* Icon-only chips, the shape `.ds-footer__social-link` uses — redrawn rather
   than reused, the footer being ink-on-navy and this a light card. */
.ds-instrhead__social {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ds-instrhead__social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
    font-size: 15px;
    text-decoration: none;
    transition:
        background-color 0.2s ease,
        color 0.2s ease;
}

.ds-instrhead__social-link:hover,
.ds-instrhead__social-link:focus {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
    text-decoration: none;
}

@media only screen and (max-width: 991px) {
    .ds-instrhead {
        padding-block-start: 72px;
    }

    /* Stacked and centred: at this width the name wraps beside a 104px avatar
       and the CTA is left with about half a word per line. */
    .ds-instrhead__card {
        flex-direction: column;
        text-align: center;
        gap: 16px;
        padding: 24px 20px;
    }

    .ds-instrhead__facts {
        justify-content: center;
    }

    .ds-instrhead__actions {
        width: 100%;
    }
}

@media only screen and (max-width: 575px) {
    .ds-instrhead {
        padding-block-start: 56px;
    }

    .ds-instrhead__avatar {
        width: 84px;
        height: 84px;
    }

    .ds-instrhead__name {
        font-size: 22px;
        line-height: 32px;
    }
}

/* Both tab rows on the plans page — the grade scopes and the شهري/سنوي switch
   — are centred by their WRAPPER, because `.ds-tabs` is `inline-flex` and a
   centred text line is all it takes. Not `justify-content: center` on the row:
   below 768px section 24 turns `.ds-tabs` into a full-width horizontal
   scroller, and a centred overflowing scroller starts with its first chip
   before the scroll origin, where no gesture can reach it. */
.ds-plans-tabs {
    text-align: center;
}

/* --- Plan cards (.ds-plan*) ---
   /instructors/{slug}/plans. The page was the theme's `.rbt-pricing-area` —
   `.pricing-table.style-2`, `.pricing-billing-duration`, `.rbt-badge`,
   `.price-wrap` — in a `col-xl-6`, so two plans filled a 1440px screen and one
   plan sat alone in half of it. None of that markup renders any more.

   auto-fit rather than a fixed column count: an instructor may offer one plan
   or six, and the cards should not be half the viewport wide in the first case.
   Capped at 3 across by the max width of the track, so a wide screen does not
   line six of them up at 200px each. */
.ds-plans {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 24px;
    max-width: 1060px;
    margin-inline: auto;
}

/* A single plan should not be stretched across the full track — a lone 1060px
   pricing card reads as a banner, not as a choice. */
.ds-plans--single {
    max-width: 420px;
}

.ds-plan {
    display: flex;
    flex-direction: column;
    padding: 28px;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-hairline);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-home-shadow);
}

/* The plan the viewer is already on. An emerald hairline, not a lift or a
   scale — the dashboard motion rule holds here too. */
.ds-plan.is-current {
    border-color: var(--ds-emerald);
    box-shadow: 0 0 0 1px var(--ds-emerald) inset, var(--ds-home-shadow);
}

.ds-plan__flag {
    align-self: flex-start;
    margin-block-end: 12px;
}

.ds-plan__name {
    margin: 0;
    font-size: 20px;
    line-height: 30px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-plan__grade {
    margin: 4px 0 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

/* Price block. `baseline` so the currency and the term sit on the number's
   baseline however large it is set. */
.ds-plan__price {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
    margin-block-start: 20px;
}

.ds-plan__amount {
    font-size: 34px;
    line-height: 44px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-emerald);
}

.ds-plan__amount small {
    font-size: 15px;
    font-weight: var(--ds-weight-medium);
}

.ds-plan__term {
    font-size: 14px;
    color: var(--ds-text-muted);
}

/* The struck comparison — twelve monthly payments against the yearly price, or
   the pre-discount price once a promo code applies. Two states, one line, and
   it is hidden until there is something true to put in it. */
.ds-plan__was {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-plan__was s {
    text-decoration-color: var(--ds-danger);
}

.ds-plan__save {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-inline-start: 6px;
    padding: 2px 10px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
    font-size: 12px;
    font-weight: var(--ds-weight-semibold);
}

.ds-plan__features {
    margin: 20px 0 0;
    padding: 20px 0 0;
    border-block-start: 1px solid var(--ds-border-divider);
    list-style: none;
}

.ds-plan__features li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 14px;
    line-height: 24px;
    color: var(--ds-text-body);
}

.ds-plan__features li + li {
    margin-block-start: 10px;
}

.ds-plan__features i {
    flex: 0 0 auto;
    margin-block-start: 5px;
    color: var(--ds-emerald);
    font-size: 13px;
}

/* Everything below the features is pinned to the card's bottom edge, so a
   four-feature card and a two-feature card still line their buttons up. */
.ds-plan__foot {
    margin-block-start: auto;
    padding-block-start: 20px;
}

.ds-plan__cta {
    width: 100%;
    justify-content: center;
}

.ds-plan__note {
    margin: 10px 0 0;
    font-size: 12px;
    line-height: 19px;
    text-align: center;
    color: var(--ds-text-muted);
}

/* --- Promo code (.ds-promo*) ---
   The coupon row inside a plan card. It used to be rendered TWICE per card —
   once in the "already subscribed" branch and once in the "can subscribe" one,
   as two identical copies of the same 30 lines, which is how the two came to
   carry the same element ids twice on one page. */
.ds-promo {
    margin-block-end: 14px;
    padding: 14px;
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
}

.ds-promo__label {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 10px;
    font-size: 13px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-promo__row {
    display: flex;
    gap: 8px;
}

/* The input carries the theme's field styling from section 5; only the flex
   behaviour is set here, because `styles.css` puts `width: 100%` on every
   input and a flex item with that plus a button beside it overflows the row. */
.ds-promo__row input {
    flex: 1 1 auto;
    min-width: 0;
    text-transform: uppercase;
}

.ds-promo__row .ds-btn {
    flex: 0 0 auto;
}

.ds-promo__msg {
    margin: 8px 0 0;
    font-size: 13px;
    line-height: 20px;
}

.ds-promo__msg.is-error {
    color: var(--ds-danger);
}

.ds-promo__msg.is-success {
    color: var(--ds-emerald-deep);
}

/* --- Reassurance row ---
   Three short facts under the grid: what a subscription actually buys, how it
   is paid for, and that the price is per grade. A pricing page that answers
   nothing but "how much" leaves the reader to guess the rest. */
.ds-plan-facts {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px 32px;
    margin-block-start: 32px;
    padding: 0;
    list-style: none;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-muted);
}

.ds-plan-facts li {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.ds-plan-facts i {
    color: var(--ds-emerald);
}

@media only screen and (max-width: 575px) {
    .ds-plan {
        padding: 20px;
    }

    .ds-plan__amount {
        font-size: 28px;
        line-height: 38px;
    }

    /* The apply button under the field rather than beside it: at 320px the two
       together leave the code input about six characters wide. */
    .ds-promo__row {
        flex-direction: column;
    }
}

/* ==========================================================================
   34. Lesson player (.ds-player*, .ds-quiz*, .ds-assign*, .ds-comment*)
   The page a subscribed student actually spends their time on:
   /courses/{slug}/lessons/{slug}, resources/views/student/lessons/show.blade.php.

   It was the purchased theme's .rbt-lesson-area — a fixed two-pane shell with
   .rbt-lesson-leftsidebar, a Bootstrap accordion of .rbt-course-main-content
   rows, .rbt-badge variation-03 pills, four separate inline <style> blocks and
   a dead search box posting to `#`. None of that renders any more.

   LIKE SECTIONS 30-33 THIS IS SMALLER THAN IT LOOKS, because the curriculum is
   section 32's .ds-unit* / .ds-lesson* reused verbatim — an instructor's
   syllabus and a student's playlist are the same list, and a second copy is a
   second thing to drift. What is genuinely new: the player shell and its bar,
   the video stage, the quiz and assignment screens, and the comment thread.

   This page renders NO site chrome — no navbar, no drawer, no footer (the view
   never included them) — so the bar below is the only navigation on screen and
   has to carry the way out.
   ========================================================================== */

:root {
    --ds-player-bar-h: 64px;
    --ds-player-aside-w: 372px;
}

.ds-player {
    min-height: 100vh;
    background: var(--ds-cloud);
}

/* --- The bar ---
   Sticky rather than fixed: fixed would need the body padded by exactly this
   height, and one number in two places is how the two get out of step. */
.ds-player__bar {
    position: sticky;
    inset-block-start: 0;
    z-index: 1030;
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: var(--ds-player-bar-h);
    padding: 10px 20px;
    background: var(--ds-surface);
    border-block-end: 1px solid var(--ds-border-hairline);
}

.ds-player__bar-main {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1 1 auto;
    min-width: 0;
}

.ds-player__bar-side {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 0 0 auto;
}

/* Real <a>/<button> elements, so the same appearance + border reset every
   other .ds-* control on a button needs (see the section-33 note). */
.ds-player__iconbtn {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: var(--ds-tile-sm);
    height: var(--ds-tile-sm);
    padding: 0;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-body);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    transition:
        background-color 0.2s ease,
        color 0.2s ease,
        border-color 0.2s ease;
}

.ds-player__iconbtn:hover {
    background: var(--ds-emerald-soft);
    border-color: var(--ds-emerald);
    color: var(--ds-emerald-deep);
}

.ds-player__titles {
    min-width: 0;
}

.ds-player__eyebrow {
    margin: 0;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

.ds-player__coursename {
    display: block;
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

a.ds-player__coursename:hover {
    color: var(--ds-emerald-deep);
}

/* --- Progress ---
   Numbers first, bar second. "7 من 12" is the answer; the bar is the shape of
   it, which is why the bar can drop out below 768px and nothing is lost. */
.ds-player__progress {
    display: flex;
    align-items: center;
    gap: 10px;
}

.ds-player__progress-label {
    font-size: 13px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-body);
    white-space: nowrap;
}

.ds-player__progress-track {
    position: relative;
    width: 132px;
    height: 6px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-border-hairline);
    overflow: hidden;
}

.ds-player__progress-fill {
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
    transition: width 0.3s ease;
}

/* --- The two panes ---
   Grid columns flow with `direction`, so the FIRST column is the right one
   under dir="rtl": the video is first in the markup and lands on the reading
   side, the curriculum beside it — the arrangement .ds-coursepage (32) makes,
   so moving between a course and its player crosses no seam. */
.ds-player__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--ds-player-aside-w);
    gap: 24px;
    max-width: 1560px;
    margin-inline: auto;
    padding: 24px 20px 64px;
}

.ds-player__main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.ds-player__aside {
    min-width: 0;
}

/* Its own scroll, pinned under the bar: a 40-lesson course must not make the
   video scroll off the screen to reach lesson 40. */
.ds-player__panel {
    position: sticky;
    inset-block-start: calc(var(--ds-player-bar-h) + 16px);
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - var(--ds-player-bar-h) - 32px);
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface);
    overflow: hidden;
}

.ds-player__panel-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 16px 12px;
    border-block-end: 1px solid var(--ds-border-divider);
}

.ds-player__panel-title {
    flex: 1 1 auto;
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-player__panel-body {
    flex: 1 1 auto;
    padding: 12px 16px 16px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* --- Curriculum search ---
   The theme shipped a search box whose form posted to `#` — decoration. This
   one filters the list in the browser, which is the only thing it could
   usefully do: the whole curriculum is already on the page. */
.ds-player__search {
    position: relative;
    padding: 0 16px 12px;
}

.ds-player__search input {
    width: 100%;
    height: 40px;
    padding-inline: 38px 12px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
    font-size: 14px;
    color: var(--ds-text-body);
}

.ds-player__search input:focus {
    outline: none;
    border-color: var(--ds-emerald);
    background: var(--ds-surface);
}

.ds-player__search i {
    position: absolute;
    inset-block-start: 12px;
    inset-inline-start: 28px;
    font-size: 15px;
    color: var(--ds-text-muted);
    pointer-events: none;
}

.ds-player__search-empty {
    padding: 4px 16px 12px;
    font-size: 13px;
    color: var(--ds-text-muted);
}

/* --- Curriculum, flattened ---
   `.ds-unit*` and `.ds-lesson*` come from section 32, but the SHAPE is not the
   same on both pages, and the first pass here got that wrong.

   On the course page a lesson row is a card (`.ds-row`) because the curriculum
   IS the content — a visitor is reading a syllabus. In this panel it is a
   navigation list, ten to forty rows deep in a 372px column, and a card per row
   drew a border, a radius and a fill around every single one: nested boxes
   inside a bordered unit inside a bordered panel, three frames deep before any
   text. So the sidebar rows deliberately do NOT carry `.ds-row` — they are flat
   list items with nothing but hover, and the only line in the whole panel is the
   hairline between units.

   The rule: an item is boxed when it is the thing you are reading, and flat when
   it is a way to get somewhere. */
.ds-player__aside .ds-unit + .ds-unit {
    margin-block-start: 0;
}

.ds-player__aside .ds-unit + .ds-unit .ds-unit__head {
    border-block-start: 1px solid var(--ds-border-divider);
}

/* No fill, no border, no radius — a heading, not a bar. */
.ds-player__aside .ds-unit__head {
    padding: 14px 4px 10px;
    border: 0;
    border-radius: 0;
    background: none;
    gap: 8px;
}

.ds-player__aside .ds-unit__title {
    font-size: 14px;
    line-height: 21px;
    font-weight: var(--ds-weight-bold);
}

.ds-player__aside .ds-unit__count {
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

.ds-player__aside .ds-unit__body {
    gap: 0;
    padding-block-start: 2px;
    padding-block-end: 6px;
}

.ds-player__aside .ds-lesson {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border: 0;
    border-radius: var(--ds-radius-sm);
    background: none;
    transition: background-color 0.15s ease;
}

.ds-player__aside .ds-lesson:hover {
    background: var(--ds-surface-sunken);
}

/* The current row is the one thing in the panel allowed a fill, and it gets an
   accent bar rather than a full border: a rule down the inline start marks the
   position in a list, where a box would just be a fourth frame. */
.ds-player__aside .ds-lesson.is-current {
    position: relative;
    background: var(--ds-emerald-soft);
}

.ds-player__aside .ds-lesson.is-current::before {
    content: "";
    position: absolute;
    inset-block: 6px;
    inset-inline-start: 0;
    width: 3px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald);
}

.ds-player__aside .ds-lesson.is-current .ds-lesson__title {
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald-deep);
}

/* A quiet numbered disc, not a 36px tile: at this size the number is a position
   marker, and a filled circle per row is another twelve shapes down the list. */
.ds-player__aside .ds-lesson__icon {
    width: 26px;
    height: 26px;
    background: var(--ds-surface-sunken);
    color: var(--ds-text-muted);
    font-size: 12px;
    font-weight: var(--ds-weight-semibold);
}

.ds-player__aside .ds-lesson.is-current .ds-lesson__icon {
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

/* A finished lesson is marked, not dimmed: the student may well be coming back
   to it, and greying out most of a course they have worked through reads as
   "this is over" rather than "you did this". The tick is emerald ON the sunken
   disc — a solid green circle per completed row turned a half-finished course
   into a column of buttons. */
.ds-player__aside .ds-lesson.is-done .ds-lesson__icon {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald);
}

.ds-player__aside .ds-lesson__title {
    font-size: 13.5px;
    line-height: 21px;
    font-weight: var(--ds-weight-regular);
}

/* The trailing state is an ICON ONLY. It used to print «الآن» beside a filled
   row that already said so in three other ways — fill, accent, bold title. */
.ds-lesson__state {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    font-size: 14px;
    color: var(--ds-text-muted);
}

.ds-lesson__state--done {
    color: var(--ds-emerald);
}

.ds-lesson__state--current {
    color: var(--ds-emerald-deep);
}

/* Free / Zoom markers. Small caps-weight text on a tint, and only where the
   information is not already obvious from the row itself. */
.ds-lesson__flag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-inline-start: 6px;
    padding: 0 6px;
    border-radius: var(--ds-radius-sm);
    background: var(--ds-chip-bg);
    color: var(--ds-chip-text);
    font-size: 10.5px;
    line-height: 17px;
    font-weight: var(--ds-weight-semibold);
    vertical-align: middle;
}

.ds-lesson__flag--free {
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
}

/* A required assignment is marked with a word in the danger INK, not a filled
   red pill: on a phone-width column that pill was the loudest thing in the
   panel, louder than the lesson you are actually watching. */
.ds-lesson__flag--danger {
    padding: 0;
    background: none;
    color: var(--ds-danger);
}

/* --- Quiz / assignment rows ---
   A quiz belongs TO its lesson, so it hangs under that row rather than sitting
   beside it as an equal — the old sidebar listed all three at one level and a
   unit of six lessons read as eighteen unrelated things. Indent and a smaller,
   muted type carry that on their own; the connector rule the first pass drew
   was one more line in a panel that needed fewer. */
.ds-sublesson {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-inline-start: 34px;
    padding: 5px 10px 5px 0;
    border-radius: var(--ds-radius-sm);
    color: var(--ds-text-muted);
    font-size: 12.5px;
    line-height: 20px;
    text-decoration: none;
    transition: color 0.15s ease;
}

.ds-sublesson:hover {
    color: var(--ds-emerald-deep);
}

.ds-sublesson.is-current {
    color: var(--ds-emerald-deep);
    font-weight: var(--ds-weight-semibold);
}

.ds-sublesson i {
    flex: 0 0 auto;
    font-size: 13px;
    color: inherit;
    opacity: 0.7;
}

.ds-sublesson__label {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}

.ds-sublesson__score {
    flex: 0 0 auto;
    font-size: 11px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-emerald);
    font-variant-numeric: tabular-nums;
}

/* --- The stage ---
   Navy, not black: a black box on a cloud page reads as a hole, and every
   provider letterboxes into it anyway. aspect-ratio replaces the theme's
   padding-bottom:56.25% trick — the iframe can then simply fill it. */
.ds-player__stage {
    position: relative;
    aspect-ratio: 16 / 9;
    width: 100%;
    border-radius: var(--ds-radius-lg);
    background: var(--ds-navy);
    overflow: hidden;
}

.ds-player__stage iframe,
.ds-player__stage video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* A lesson with no video at all, and the Zoom card, are content rather than
   media — they must not be squeezed into 16:9 on a phone. */
.ds-player__stage--auto {
    aspect-ratio: auto;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border-subtle);
}

.ds-player__placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 240px;
    height: 100%;
    padding: 32px 20px;
    color: rgba(255, 255, 255, 0.72);
    text-align: center;
}

.ds-player__placeholder i {
    font-size: 34px;
    opacity: 0.7;
}

.ds-player__placeholder p {
    margin: 0;
    font-size: 14px;
    line-height: 22px;
}

/* The «مكتمل» flag over the video. .lesson-completed-overlay is kept as an
   alias because the completion script creates one of these at runtime. */
.ds-player__flag,
.lesson-completed-overlay {
    position: absolute;
    inset-block-start: 12px;
    inset-inline-end: 12px;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: var(--ds-radius-pill);
    background: rgba(16, 185, 129, 0.92);
    color: var(--ds-text-on-dark);
    font-size: 12px;
    font-weight: var(--ds-weight-semibold);
    pointer-events: none;
}

/* --- Lesson header + panels --- */
.ds-player__lesson-head {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}

.ds-player__lesson-title {
    flex: 1 1 320px;
    min-width: 0;
    margin: 0;
    font-size: 22px;
    line-height: 32px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-player__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 16px;
    margin-block-start: 8px;
    font-size: 13px;
    line-height: 20px;
    color: var(--ds-text-muted);
}

.ds-player__meta span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.ds-player__meta i {
    font-size: 14px;
}

/* --- Prev / next ---
   A missing neighbour renders NOTHING rather than a disabled button: the old
   page drew two greyed pills on a one-lesson course, three words telling the
   reader there is nothing to tell. */
.ds-player__nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.ds-player__navbtn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 48%;
    padding: 11px 18px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    color: var(--ds-text-heading);
    font-size: 14px;
    font-weight: var(--ds-weight-semibold);
    text-decoration: none;
    transition:
        background-color 0.2s ease,
        border-color 0.2s ease,
        color 0.2s ease;
}

.ds-player__navbtn:hover {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
}

.ds-player__navbtn--next {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
    margin-inline-start: auto;
}

.ds-player__navbtn--next:hover {
    background: var(--ds-emerald-hover);
    border-color: var(--ds-emerald-hover);
    color: var(--ds-text-on-dark);
}

.ds-player__navbtn__text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Lesson prose (instructor-authored HTML) --- */
.ds-player__prose {
    font-size: 15px;
    line-height: 27px;
    color: var(--ds-text-body);
}

.ds-player__prose > *:first-child {
    margin-block-start: 0;
}

.ds-player__prose > *:last-child {
    margin-block-end: 0;
}

.ds-player__prose img {
    max-width: 100%;
    height: auto;
    border-radius: var(--ds-radius-md);
}

.ds-player__prose a {
    color: var(--ds-emerald-deep);
    text-decoration: underline;
}

/* Wide content scrolls inside itself rather than widening the page. */
.ds-player__prose table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
}

/* --- Zoom card --- */
.ds-zoom {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 40px 24px;
    text-align: center;
}

.ds-zoom__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: var(--ds-radius-pill);
    background: rgba(45, 140, 255, 0.12);
    color: #2d8cff;
    font-size: 28px;
}

.ds-zoom__title {
    margin: 0;
    font-size: 20px;
    line-height: 30px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
}

.ds-zoom__when {
    margin: 0;
    font-size: 15px;
    line-height: 24px;
    color: var(--ds-text-body);
    direction: ltr;
    font-variant-numeric: tabular-nums;
}

.ds-zoom__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}

/* --- Quiz ---
   Not .form-check: the theme paints its fake control on the FOLLOWING SIBLING
   label, which cannot express a disabled-but-answered option and fights every
   attempt to colour one (the reasoning behind .ds-question in section 24). Each
   option here is a label WRAPPING its input — the .ds-choice trick — so no
   theme selector matches it. */
.ds-quiz__result {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 20px;
    border-radius: var(--ds-radius-lg);
    border: 1px solid var(--ds-border-subtle);
    background: var(--ds-surface-sunken);
    text-align: center;
}

.ds-quiz__result--pass {
    border-color: rgba(16, 185, 129, 0.35);
    background: var(--ds-emerald-soft);
}

.ds-quiz__result--fail {
    border-color: rgba(186, 26, 26, 0.25);
    background: rgba(186, 26, 26, 0.07);
}

.ds-quiz__score {
    margin: 0;
    font-size: 26px;
    line-height: 34px;
    font-weight: var(--ds-weight-bold);
    color: var(--ds-text-heading);
    font-variant-numeric: tabular-nums;
}

.ds-quiz__verdict {
    margin: 0;
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
}

.ds-quiz__q {
    padding: 18px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface);
}

.ds-quiz__q + .ds-quiz__q {
    margin-block-start: 14px;
}

.ds-quiz__q-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-block-end: 4px;
}

.ds-quiz__q-num {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 26px;
    height: 26px;
    padding-inline: 6px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
    font-size: 12px;
    font-weight: var(--ds-weight-bold);
    font-variant-numeric: tabular-nums;
}

.ds-quiz__q-title {
    flex: 1 1 auto;
    margin: 0;
    font-size: 16px;
    line-height: 25px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-quiz__q-meta {
    margin: 0 0 12px;
    padding-inline-start: 36px;
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

.ds-quiz__opts {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ds-quiz__opt {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    font-size: 14px;
    line-height: 22px;
    color: var(--ds-text-body);
    cursor: pointer;
    transition:
        border-color 0.2s ease,
        background-color 0.2s ease;
}

.ds-quiz__opt:hover {
    border-color: var(--ds-emerald);
}

/* Pinned to a 1px box: styles.css has a blanket `input { width: 100% }`, and an
   absolutely-positioned input with no width of its own resolves that against
   its containing block — the phantom-horizontal-scroll bug sections 18 and 28
   each paid for once. */
.ds-quiz__opt input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.ds-quiz__opt-mark {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border: 2px solid var(--ds-border);
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface);
    color: transparent;
    font-size: 11px;
    transition:
        border-color 0.2s ease,
        background-color 0.2s ease;
}

/* A multiple-choice option is a square, a single-choice one a circle — the
   shape tells the student "you may pick more than one" before they read
   anything. */
.ds-quiz__opt input[type="checkbox"] ~ .ds-quiz__opt-mark {
    border-radius: 6px;
}

.ds-quiz__opt input:checked ~ .ds-quiz__opt-mark {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald);
    color: var(--ds-text-on-dark);
}

.ds-quiz__opt:has(input:checked) {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
}

.ds-quiz__opt:has(input:disabled) {
    cursor: default;
}

.ds-quiz__opt:has(input:disabled):hover {
    border-color: var(--ds-border-subtle);
}

/* --- Assignment --- */
.ds-assign__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-block-end: 14px;
}

.ds-assign__file {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border: 1px solid var(--ds-border-subtle);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-heading);
    font-size: 14px;
    font-weight: var(--ds-weight-medium);
    text-decoration: none;
}

.ds-assign__file:hover {
    border-color: var(--ds-emerald);
    color: var(--ds-emerald-deep);
}

/* The dropzone is a <label> wrapping a hidden file input — .ds-thumb (31) and
   .ds-cover (22) make the same move, so a click anywhere in the box opens the
   picker with no JS involved. */
.ds-drop {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 168px;
    padding: 24px;
    border: 2px dashed var(--ds-border);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface-sunken);
    color: var(--ds-text-body);
    text-align: center;
    cursor: pointer;
    transition:
        border-color 0.2s ease,
        background-color 0.2s ease;
}

.ds-drop:hover,
.ds-drop.drag-over {
    border-color: var(--ds-emerald);
    background: var(--ds-emerald-soft);
}

.ds-drop i {
    font-size: 26px;
    color: var(--ds-emerald);
}

.ds-drop__title {
    font-size: 15px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-drop__hint {
    font-size: 12px;
    line-height: 19px;
    color: var(--ds-text-muted);
}

.ds-drop input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.ds-drop.is-disabled {
    pointer-events: none;
    opacity: 0.55;
}

/* --- Comments ---
   li.comment[data-comment-id], ul.children, .lesson-reply-form,
   .comment-ajax-form, .reply-toggle and .cancel-reply are a CONTRACT with the
   AJAX block at the bottom of the view, which appends server-rendered markup
   from the same partial. Rename one and replies stop appearing, with no error
   anywhere. */
.ds-comments,
.ds-comments .children {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ds-comments > .comment + .comment {
    margin-block-start: 20px;
    padding-block-start: 20px;
    border-block-start: 1px solid var(--ds-border-divider);
}

.ds-comment {
    display: flex;
    gap: 12px;
}

.ds-comment__avatar {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: var(--ds-radius-pill);
    object-fit: cover;
    background: var(--ds-surface-avatar);
}

.ds-comment__body {
    flex: 1 1 auto;
    min-width: 0;
}

.ds-comment__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.ds-comment__name {
    margin: 0;
    font-size: 14px;
    line-height: 21px;
    font-weight: var(--ds-weight-semibold);
    color: var(--ds-text-heading);
}

.ds-comment__role {
    padding: 1px 8px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-emerald-soft);
    color: var(--ds-emerald-deep);
    font-size: 11px;
    line-height: 18px;
    font-weight: var(--ds-weight-semibold);
}

.ds-comment__time {
    font-size: 12px;
    line-height: 18px;
    color: var(--ds-text-muted);
}

.ds-comment__text {
    margin: 6px 0 0;
    font-size: 14px;
    line-height: 24px;
    color: var(--ds-text-body);
    overflow-wrap: anywhere;
}

.ds-comment__actions {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-block-start: 8px;
}

.ds-comment__action {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--ds-text-muted);
    font-size: 13px;
    font-weight: var(--ds-weight-medium);
    text-decoration: none;
    cursor: pointer;
}

.ds-comment__action:hover {
    color: var(--ds-emerald-deep);
}

.ds-comment__action--danger:hover {
    color: var(--ds-danger);
}

/* The thread rule is on the inline START — the side the reply is indented from
   under dir="rtl". A physical border-left puts it on the far side of the text,
   which is what the theme's copy did and why it needed an RTL override. */
.ds-comments .children {
    margin-block-start: 16px;
    margin-inline-start: 20px;
    padding-inline-start: 16px;
    border-inline-start: 2px solid var(--ds-border-hairline);
}

.ds-comments .children > .comment + .comment {
    margin-block-start: 16px;
}

.ds-comment-form__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-block-start: 12px;
}

.ds-comment-form__error {
    margin-block-start: 8px;
    font-size: 13px;
    color: var(--ds-danger);
}

/* --- Mobile: the curriculum becomes a drawer ---
   Below 992px the aside is a full-height off-canvas panel behind the bar's
   «المنهج» button, not a block under the video: a 40-lesson list stacked above
   the comments means scrolling past the whole course to reach the first reply.
   Same shape as the shell drawer (25) — and, as there, `transform` has no
   logical variant, so translateX(-100%) is direction-bound. This drawer sits at
   the inline END (the LEFT under dir="rtl"), so it leaves to the left. */
@media only screen and (max-width: 991px) {
    .ds-player__body {
        grid-template-columns: minmax(0, 1fr);
        padding: 16px 14px 40px;
        gap: 16px;
    }

    .ds-player__aside {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 1050;
        width: min(92vw, 400px);
        transform: translateX(-100%);
        transition:
            transform 0.25s ease,
            visibility 0.25s ease;
        visibility: hidden;
    }

    .ds-player__aside.is-open {
        transform: translateX(0);
        visibility: visible;
    }

    .ds-player__panel {
        position: static;
        height: 100%;
        max-height: none;
        border: 0;
        border-radius: 0;
        box-shadow: var(--ds-shadow-raised);
    }

    .ds-player__overlay {
        position: fixed;
        inset: 0;
        z-index: 1045;
        background: rgba(19, 27, 46, 0.5);
        opacity: 0;
        visibility: hidden;
        transition:
            opacity 0.25s ease,
            visibility 0.25s ease;
    }

    .ds-player__overlay.is-open {
        opacity: 1;
        visibility: visible;
    }

    .ds-player__lesson-title {
        font-size: 19px;
        line-height: 28px;
    }

    /* The stage goes edge to edge: on a phone a 14px gutter either side of a
       video is 28px of page not showing the thing you came for. */
    .ds-player__stage {
        margin-inline: -14px;
        width: calc(100% + 28px);
        border-radius: 0;
    }
}

/* At >=992px the drawer's own chrome must not appear in the docked panel. */
@media only screen and (min-width: 992px) {
    .ds-player__panel-close,
    .ds-player__curriculum-toggle,
    .ds-player__overlay {
        display: none;
    }
}

@media only screen and (max-width: 767px) {
    .ds-player__bar {
        padding: 10px 14px;
        gap: 10px;
    }

    /* Numbers survive, the bar goes — see the progress note above. */
    .ds-player__progress-track,
    .ds-player__eyebrow {
        display: none;
    }

    .ds-player__nav {
        flex-direction: column;
        align-items: stretch;
    }

    .ds-player__navbtn {
        max-width: none;
        justify-content: center;
        margin-inline-start: 0;
    }
}

@media only screen and (max-width: 575px) {
    .ds-player__progress-label {
        font-size: 12px;
    }

    .ds-quiz__q,
    .ds-assign__file {
        padding: 14px;
    }

    .ds-comment__avatar {
        width: 32px;
        height: 32px;
    }

    .ds-comments .children {
        margin-inline-start: 8px;
        padding-inline-start: 10px;
    }
}
