/*
 * Kulud Academy — base components
 * Phase 2 of the redesign. run_id KACAD_DS_20260805_200229_54ad1e44
 *
 * Framework-agnostic: plain classes, no build step, no JS dependency for
 * anything except tabs/accordion state (which is driven by ARIA attributes,
 * so the same markup works from a block, a shortcode or a PHP template).
 *
 * Everything is namespaced .kla-. A census of the live site found ZERO
 * existing uses of that prefix, so nothing here can collide with Eduma
 * (.thim-*), LearnPress (.lp-*, .course-*), Elementor (.elementor-*) or the
 * home template (.ka-*).
 *
 * ⚠ NOTE ON .ka- vs .kla- : the home template already uses .ka- heavily
 * (79 occurrences). These differ by one letter. If you mistype, the selector
 * will silently match a REAL existing class instead of failing loudly.
 *
 * ── THE ONE TRAP THIS FILE DEFENDS AGAINST ───────────────────────────
 * `element.hidden = true` relies on the user-agent rule [hidden]{display:none}.
 * A UA rule ALWAYS loses to an author rule, so any component declared
 * display:flex/grid stays visible when you set .hidden. That exact bug
 * already shipped once on this site (the "dead" course-category filter).
 * Every flex/grid component below therefore carries its own explicit
 * [hidden] rule. Do not remove them.
 */

/* ═══════════════════════════════════════════════════════════════════════
   BUTTON  —  .kla-btn
   Variants: --primary (default) | --secondary | --ghost
   ═══════════════════════════════════════════════════════════════════════ */

.kla-btn {
  /* Reset first: Eduma and LearnPress both style bare <button> and <a>, and
     this component is used as both. Without the reset the same class renders
     differently depending on which element it lands on. */
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  background: none;
  text-decoration: none;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--kla-space-2);

  /* 44px comes from the tap target token, but it is a MIN-height, not a
     fixed one — a button whose label wraps in Arabic must be allowed to
     grow rather than clip its own text. */
  min-height: var(--kla-tap-min);
  min-width: var(--kla-tap-min);
  padding: var(--kla-space-3) var(--kla-space-5);

  font-family: var(--kla-font);
  font-size: var(--kla-text-base);
  font-weight: var(--kla-weight-medium);
  line-height: var(--kla-leading-snug);
  text-align: center;

  border: 1px solid transparent;
  border-radius: var(--kla-radius);
  cursor: pointer;
  transition: background-color var(--kla-duration) var(--kla-ease),
              border-color var(--kla-duration) var(--kla-ease),
              color var(--kla-duration) var(--kla-ease);
}

.kla-btn[hidden] { display: none; }

/* One focus treatment for every interactive component in this file.
   :focus-visible rather than :focus so a mouse click does not leave a ring,
   but keyboard and assistive tech always do. */
.kla-btn:focus-visible,
.kla-tabs__tab:focus-visible,
.kla-accordion__trigger:focus-visible,
.kla-card--link:focus-visible {
  outline: var(--kla-focus-width) solid var(--kla-focus-ring);
  outline-offset: var(--kla-focus-offset);
}

.kla-btn--primary,
.kla-btn:not([class*="kla-btn--"]) {   /* bare .kla-btn defaults to primary */
  background-color: var(--kla-primary);
  color: var(--kla-text-on-primary);    /* 4.81:1 — verified               */
}
.kla-btn--primary:hover,
.kla-btn:not([class*="kla-btn--"]):hover {
  background-color: var(--kla-primary-dark);   /* 7.44:1 — still passes    */
}

/* Secondary is an outlined button. Its border is an interactive boundary,
   so it uses --kla-border-interactive (3.39:1), not the decorative hairline
   — an outlined control with a 1.24:1 border is invisible to a low-vision
   user and fails WCAG 1.4.11. */
.kla-btn--secondary {
  background-color: var(--kla-surface);
  color: var(--kla-primary);                   /* 4.81:1 on white          */
  border-color: var(--kla-border-interactive);
}
.kla-btn--secondary:hover {
  background-color: var(--kla-primary-tint);
  color: var(--kla-on-tint);                   /* 6.59:1 on tint           */
  border-color: var(--kla-primary);
}

.kla-btn--ghost {
  background-color: transparent;
  color: var(--kla-primary);
}
.kla-btn--ghost:hover { background-color: var(--kla-primary-tint); color: var(--kla-on-tint); }

.kla-btn--block { width: 100%; }
.kla-btn--sm { min-height: 36px; padding: var(--kla-space-2) var(--kla-space-4); font-size: var(--kla-text-sm); }

.kla-btn[disabled],
.kla-btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
  /* Deliberately NOT contrast-corrected: WCAG exempts inactive controls. */
}

/* ═══════════════════════════════════════════════════════════════════════
   CARD  —  .kla-card
   ONE base card + modifiers. Course, path, employee and branch cards differ
   only in the metadata they show, not in their box — five separate
   components would be five things to keep in sync.
   ═══════════════════════════════════════════════════════════════════════ */

.kla-card {
  display: flex;
  flex-direction: column;
  background-color: var(--kla-surface);
  border: 1px solid var(--kla-border);
  border-radius: var(--kla-radius);
  box-shadow: var(--kla-shadow-sm);
  overflow: hidden;
  transition: box-shadow var(--kla-duration) var(--kla-ease),
              border-color var(--kla-duration) var(--kla-ease);
}

/* See the header note — this is the rule that keeps .hidden working. */
.kla-card[hidden] { display: none; }

.kla-card--link:hover { box-shadow: var(--kla-shadow); border-color: var(--kla-primary-mid); }

.kla-card__media { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--kla-surface-alt); }
.kla-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }

.kla-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--kla-space-2);
  padding: var(--kla-space-5);
  flex: 1 1 auto;
}
.kla-card__body[hidden] { display: none; }

.kla-card__eyebrow {
  font-size: var(--kla-text-xs);
  font-weight: var(--kla-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--kla-text-muted);
}

.kla-card__title {
  font-size: var(--kla-text-md);
  font-weight: var(--kla-weight-semibold);
  line-height: var(--kla-leading-snug);
  color: var(--kla-text);
  margin: 0;
}

.kla-card__meta { font-size: var(--kla-text-sm); color: var(--kla-text-secondary); margin: 0; }

.kla-card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kla-space-3);
  padding: var(--kla-space-4) var(--kla-space-5);
  border-top: 1px solid var(--kla-border);
  margin-top: auto;
}
.kla-card__footer[hidden] { display: none; }

/* Modifiers — layout only, so a course card and an employee card stay
   recognisably the same object. */
.kla-card--horizontal { flex-direction: row; }
.kla-card--horizontal .kla-card__media { aspect-ratio: 1; flex: 0 0 33%; }
.kla-card--compact .kla-card__body { padding: var(--kla-space-4); }
.kla-card--flat { box-shadow: none; }

@media (max-width: 767px) {
  /* A horizontal card at phone width leaves ~120px for the title. Stack it. */
  .kla-card--horizontal { flex-direction: column; }
  .kla-card--horizontal .kla-card__media { aspect-ratio: 16 / 9; flex: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   BADGE / STATUS PILL  —  .kla-badge
   Green / Amber / Red / Grey for competency and compliance state.

   ⚠ COLOUR IS NEVER THE ONLY SIGNAL (WCAG 1.4.1). Every badge carries an
   icon slot AND a text label. Markup contract:

     <span class="kla-badge kla-badge--success">
       <span class="kla-badge__icon" aria-hidden="true">✓</span>
       <span class="kla-badge__label">Compliant</span>
     </span>

   The icon is decorative (aria-hidden) because the label already says it —
   otherwise a screen reader announces the state twice.
   ═══════════════════════════════════════════════════════════════════════ */

.kla-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--kla-space-2);
  padding: var(--kla-space-1) var(--kla-space-3);
  border-radius: var(--kla-radius-pill);
  font-size: var(--kla-text-sm);
  font-weight: var(--kla-weight-medium);
  line-height: var(--kla-leading-snug);
  white-space: nowrap;
  border: 1px solid transparent;
}
.kla-badge[hidden] { display: none; }

.kla-badge__icon { display: inline-flex; flex: none; width: 1em; height: 1em; align-items: center; justify-content: center; }

/* Each pairing below was measured against its own tint at >= 4.5:1. */
.kla-badge--success { background: var(--kla-success-tint); color: var(--kla-success-text); border-color: var(--kla-success); }
.kla-badge--warning { background: var(--kla-warning-tint); color: var(--kla-warning-text); border-color: var(--kla-warning); }
.kla-badge--danger  { background: var(--kla-danger-tint);  color: var(--kla-danger-text);  border-color: var(--kla-danger);  }
.kla-badge--neutral { background: var(--kla-neutral-tint); color: var(--kla-neutral-text); border-color: var(--kla-neutral); }
.kla-badge--info    { background: var(--kla-info-tint);    color: var(--kla-info-text);    border-color: var(--kla-info);    }

/* ═══════════════════════════════════════════════════════════════════════
   PROGRESS  —  .kla-progress   (determinate)

   Markup contract — the ARIA is what makes this readable, not the CSS:
     <div class="kla-progress" role="progressbar"
          aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"
          aria-label="Course progress">
       <div class="kla-progress__fill" style="inline-size:40%"></div>
     </div>

   ⚠ Use inline-size, not width, so the bar fills from the correct edge in
   Arabic without a second RTL rule.

   ⚠ A NULL progress value is NOT 0%. LearnPress returns 0 for assignment
   portals that are actually complete; rendering that as an empty bar states
   the opposite of the truth. Render .kla-progress--unknown instead.
   ═══════════════════════════════════════════════════════════════════════ */

.kla-progress {
  position: relative;
  inline-size: 100%;
  block-size: 8px;
  background-color: var(--kla-border);
  border-radius: var(--kla-radius-pill);
  overflow: hidden;
}

.kla-progress__fill {
  display: block;
  block-size: 100%;
  inline-size: 0;
  background-color: var(--kla-primary);   /* 3.88:1 on the track — passes */
  border-radius: inherit;
  transition: inline-size var(--kla-duration) var(--kla-ease);
}

.kla-progress--lg { block-size: 12px; }
.kla-progress--unknown { background-image: repeating-linear-gradient(135deg, var(--kla-border) 0 6px, var(--kla-surface-alt) 6px 12px); }
.kla-progress--unknown .kla-progress__fill { display: none; }

.kla-progress__label { display: block; margin-block-start: var(--kla-space-2); font-size: var(--kla-text-sm); color: var(--kla-text-secondary); }

/* ═══════════════════════════════════════════════════════════════════════
   TABS  —  .kla-tabs

   Markup contract (WCAG 2.2 AA + APG tabs pattern):
     <div class="kla-tabs">
       <div class="kla-tabs__list" role="tablist" aria-label="…">
         <button class="kla-tabs__tab" role="tab" id="t1"
                 aria-controls="p1" aria-selected="true"  tabindex="0">One</button>
         <button class="kla-tabs__tab" role="tab" id="t2"
                 aria-controls="p2" aria-selected="false" tabindex="-1">Two</button>
       </div>
       <div class="kla-tabs__panel" role="tabpanel" id="p1" aria-labelledby="t1">…</div>
       <div class="kla-tabs__panel" role="tabpanel" id="p2" aria-labelledby="t2" hidden>…</div>
     </div>

   Keyboard behaviour is the JS's job (Left/Right move, Home/End jump,
   roving tabindex). This file only guarantees the states are VISIBLE —
   including without colour, via the underline.
   ═══════════════════════════════════════════════════════════════════════ */

.kla-tabs__list {
  display: flex;
  gap: var(--kla-space-1);
  border-block-end: 1px solid var(--kla-border);
  overflow-x: auto;             /* many tabs on a phone must scroll, not wrap */
  scrollbar-width: thin;
}
.kla-tabs__list[hidden] { display: none; }

.kla-tabs__tab {
  -webkit-appearance: none;
  appearance: none;
  background: none;
  border: none;
  border-block-end: 3px solid transparent;   /* selected state, non-colour */
  margin-block-end: -1px;
  min-height: var(--kla-tap-min);
  padding: var(--kla-space-3) var(--kla-space-4);
  font-family: var(--kla-font);
  font-size: var(--kla-text-base);
  font-weight: var(--kla-weight-medium);
  color: var(--kla-text-secondary);
  white-space: nowrap;
  cursor: pointer;
}

.kla-tabs__tab[aria-selected="true"] {
  color: var(--kla-primary);
  border-block-end-color: var(--kla-primary);
  font-weight: var(--kla-weight-semibold);
}
.kla-tabs__tab:hover { color: var(--kla-text); }

.kla-tabs__panel { padding-block-start: var(--kla-space-5); }
.kla-tabs__panel[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════════
   ACCORDION  —  .kla-accordion

   Markup contract:
     <div class="kla-accordion">
       <h3 class="kla-accordion__heading">
         <button class="kla-accordion__trigger" aria-expanded="false"
                 aria-controls="s1" id="h1">
           Section <span class="kla-accordion__marker" aria-hidden="true"></span>
         </button>
       </h3>
       <div class="kla-accordion__panel" id="s1" role="region"
            aria-labelledby="h1" hidden>…</div>
     </div>

   The trigger must be a real <button> inside a heading — that is what lets a
   screen-reader user navigate by heading AND operate it with Space/Enter for
   free. A <div onclick> gets neither.
   ═══════════════════════════════════════════════════════════════════════ */

.kla-accordion { border: 1px solid var(--kla-border); border-radius: var(--kla-radius); overflow: hidden; }
.kla-accordion__heading { margin: 0; font-size: inherit; font-weight: inherit; }
.kla-accordion__heading + .kla-accordion__heading { border-block-start: 1px solid var(--kla-border); }

.kla-accordion__trigger {
  -webkit-appearance: none;
  appearance: none;
  background: none;
  border: none;
  inline-size: 100%;
  min-height: var(--kla-tap-min);
  padding: var(--kla-space-4) var(--kla-space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kla-space-3);
  font-family: var(--kla-font);
  font-size: var(--kla-text-base);
  font-weight: var(--kla-weight-medium);
  color: var(--kla-text);
  text-align: start;            /* flips for Arabic without an RTL rule    */
  cursor: pointer;
}
.kla-accordion__trigger:hover { background-color: var(--kla-surface-alt); }
.kla-accordion__trigger[hidden] { display: none; }

/* Chevron drawn in CSS so there is no icon-font dependency. It is rotated,
   not replaced, so the open/closed state survives a failed font load. */
.kla-accordion__marker {
  flex: none;
  inline-size: 0.6em;
  block-size: 0.6em;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(45deg);
  transform-origin: center;
  transition: transform var(--kla-duration) var(--kla-ease);
}
.kla-accordion__trigger[aria-expanded="true"] .kla-accordion__marker { transform: rotate(-135deg); }
.kla-accordion__trigger[aria-expanded="true"] { background-color: var(--kla-primary-tint); color: var(--kla-on-tint); }

.kla-accordion__panel { padding: var(--kla-space-4) var(--kla-space-5) var(--kla-space-5); }
.kla-accordion__panel[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════════
   UTILITIES
   ═══════════════════════════════════════════════════════════════════════ */

/* Visible to screen readers only. Needed for skip links and for giving an
   icon-only control a name. */
.kla-visually-hidden {
  position: absolute !important;
  inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.kla-stack { display: flex; flex-direction: column; gap: var(--kla-space-4); }
.kla-stack[hidden] { display: none; }

.kla-grid {
  display: grid;
  gap: var(--kla-space-5);
  grid-template-columns: 1fr;
}
.kla-grid[hidden] { display: none; }

@media (min-width: 768px)  { .kla-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .kla-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1440px) { .kla-grid--4 { grid-template-columns: repeat(4, 1fr); } }

/* ═══════════════════════════════════════════════════════════════════════
   SKIP LINK  —  .kla-skip-link   (WCAG 2.2 AA, 2.4.1 Bypass Blocks)

   The audit found NO skip link on any page, while the header carries 3 nav
   landmarks — so a keyboard or screen-reader user tabs through the entire
   menu on every single page before reaching the content.

   Hidden until focused. It is NOT display:none and NOT visibility:hidden:
   both remove the element from the tab order, which would defeat the whole
   point. It is positioned off-screen and pulled back on :focus.
   ═══════════════════════════════════════════════════════════════════════ */

.kla-skip-link {
  position: absolute;
  inset-inline-start: var(--kla-space-2);
  inset-block-start: -100vh;          /* off-screen, still focusable      */
  z-index: 100000;                    /* above Eduma's sticky header      */
  display: inline-block;
  padding: var(--kla-space-3) var(--kla-space-5);
  background-color: var(--kla-primary);
  color: var(--kla-text-on-primary);  /* 4.81:1 — verified                */
  font-family: var(--kla-font);
  font-size: var(--kla-text-base);
  font-weight: var(--kla-weight-medium);
  text-decoration: none;
  border-radius: var(--kla-radius-sm);
  box-shadow: var(--kla-shadow);
}

.kla-skip-link:focus,
.kla-skip-link:focus-visible {
  inset-block-start: var(--kla-space-2);
  outline: var(--kla-focus-width) solid var(--kla-text);
  outline-offset: var(--kla-focus-offset);
}

/* The skip target must not show a focus ring when focused programmatically —
   it is a landmark, not a control. Focus is still moved there. */
[tabindex="-1"]:focus { outline: none; }
