/* =========================================================================
   button.css — .ewa-btn and modifiers for EqualWeb Academy
   Real <button> (or <a> for --link). Consumes SEMANTIC tokens only.
   Logical properties only (RTL-safe). Global :focus-visible from base.css
   provides the ring — we never set outline:none.

   Variants:  --primary  --secondary  --ghost  --danger  --link  --icon
   Size mod:  --sm (stays >= --target-min)
   States:    rest / hover / :focus-visible(global) / active / [disabled]
              / [aria-disabled="true"] (still focusable, not actioned, muted)
   ========================================================================= */

.ewa-btn {
  /* layout */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);

  /* sizing: reach the comfortable 44px target via padding + min-block-size */
  min-block-size: var(--target-comfortable);
  padding-block: var(--space-2);
  padding-inline: var(--space-5);
  box-sizing: border-box;

  /* type */
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  text-align: center;
  text-decoration: none;
  white-space: nowrap;

  /* shape — pill, matching the EqualWeb platform */
  border: var(--border-2) solid transparent;
  border-radius: var(--radius-pill);

  /* default look = secondary-ish neutral; explicit variants override */
  background-color: var(--bg-elevated);
  color: var(--text);

  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  user-select: none;

  transition:
    background-color var(--duration-fast) var(--easing-standard),
    border-color var(--duration-fast) var(--easing-standard),
    color var(--duration-fast) var(--easing-standard),
    box-shadow var(--duration-fast) var(--easing-standard);
}

/* keep icon glyphs from baseline-misaligning */
.ewa-btn > svg {
  inline-size: 1.25em;
  block-size: 1.25em;
  flex: 0 0 auto;
}

/* =========================================================================
   VARIANT: --primary  (brand fill, dark text-on-brand)
   ========================================================================= */
.ewa-btn--primary {
  background-color: var(--color-brand);
  color: var(--text-on-brand);
  border-color: var(--color-brand);
}
/* No "darker brand" semantic token exists; darken the brand fill with a
   filter instead of reaching for a raw primitive ramp value. */
.ewa-btn--primary:hover {
  filter: brightness(0.94);
}
.ewa-btn--primary:active {
  filter: brightness(0.88);
}

/* =========================================================================
   VARIANT: --secondary  (outlined neutral)
   ========================================================================= */
.ewa-btn--secondary {
  background-color: var(--bg-elevated);
  color: var(--text);
  border-color: var(--border-strong);
}
.ewa-btn--secondary:hover {
  background-color: var(--bg-subtle);
  border-color: var(--text-muted);
}
.ewa-btn--secondary:active {
  background-color: var(--surface-sunken);
}

/* =========================================================================
   VARIANT: --ghost  (transparent until hover)
   ========================================================================= */
.ewa-btn--ghost {
  background-color: transparent;
  color: var(--color-brand-text);
  border-color: transparent;
}
.ewa-btn--ghost:hover {
  background-color: var(--bg-subtle);
}
.ewa-btn--ghost:active {
  background-color: var(--surface-sunken);
}

/* =========================================================================
   VARIANT: --danger  (destructive). Color is NOT the only signal: pair with
   an icon + text in markup. Fill carries readable inverse text.
   ========================================================================= */
.ewa-btn--danger {
  background-color: var(--danger-fg);
  color: var(--text-inverse);
  border-color: var(--danger-fg);
}
/* No "darker danger" semantic token exists; darken the danger fill with a
   filter instead of reaching for a raw primitive ramp value. */
.ewa-btn--danger:hover {
  filter: brightness(0.92);
}
.ewa-btn--danger:active {
  filter: brightness(0.88);
}

/* =========================================================================
   VARIANT: --link  (button that reads like an inline link, e.g. on <button>
   that performs an action but should look textual). Underlined for 1.4.1.
   ========================================================================= */
.ewa-btn--link {
  min-block-size: auto;
  padding-block: var(--space-1);
  padding-inline: var(--space-1);
  background-color: transparent;
  border-color: transparent;
  color: var(--link);
  font-weight: var(--weight-medium);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.ewa-btn--link:hover {
  color: var(--link-hover);
  background-color: transparent;
}
.ewa-btn--link:active {
  color: var(--link-hover);
}

/* =========================================================================
   VARIANT: --icon  (square icon-only control). Pair with a .visually-hidden
   label in markup for an accessible name. Square >= --target-min, grows to
   --target-comfortable.
   ========================================================================= */
.ewa-btn--icon {
  padding-inline: var(--space-2);
  padding-block: var(--space-2);
  inline-size: var(--target-comfortable);
  min-inline-size: var(--target-min);
  block-size: var(--target-comfortable);
  min-block-size: var(--target-min);
}
.ewa-btn--icon > svg {
  inline-size: 1.5em;
  block-size: 1.5em;
}

/* =========================================================================
   SIZE: --sm  (compact; still meets the 24px floor via min-block-size)
   ========================================================================= */
.ewa-btn--sm {
  min-block-size: var(--target-min);
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
  font-size: var(--text-sm);
}
.ewa-btn--sm.ewa-btn--icon {
  inline-size: var(--target-min);
  min-inline-size: var(--target-min);
  block-size: var(--target-min);
  padding-inline: var(--space-1);
  padding-block: var(--space-1);
}

/* =========================================================================
   DISABLED — two flavors
     [disabled]                 : native, removed from tab order, not actioned
     [aria-disabled="true"]     : STILL focusable (so users can discover it),
                                   not actioned (JS/markup blocks the action),
                                   visually muted like [disabled]
   ========================================================================= */
.ewa-btn[disabled],
.ewa-btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
  background-color: var(--surface-sunken);
  color: var(--text-muted);
  border-color: var(--border);
  box-shadow: none;
}
/* neutralize hover/active changes while disabled */
.ewa-btn[disabled]:hover,
.ewa-btn[disabled]:active,
.ewa-btn[aria-disabled="true"]:hover,
.ewa-btn[aria-disabled="true"]:active {
  background-color: var(--surface-sunken);
  color: var(--text-muted);
  border-color: var(--border);
  filter: none;
}
/* link variant disabled: drop underline affordance but keep it readable */
.ewa-btn--link[disabled],
.ewa-btn--link[aria-disabled="true"] {
  background-color: transparent;
  border-color: transparent;
  text-decoration: none;
}

/* =========================================================================
   FORCED COLORS — we lean on background-color to convey variant/state, which
   is dropped in forced-colors mode. Restore borders + system colors so each
   button still reads as a distinct, bounded control. Focus ring handled by
   base.css (Highlight).
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-btn {
    border-color: ButtonText;
    /* let the UA paint Button/ButtonText; don't fight it */
    forced-color-adjust: none;
    background-color: ButtonFace;
    color: ButtonText;
  }
  .ewa-btn--primary,
  .ewa-btn--danger {
    background-color: ButtonFace;
    color: ButtonText;
    border-color: ButtonText;
  }
  /* don't dim system colors on hover/active in forced-colors */
  .ewa-btn:hover,
  .ewa-btn:active {
    filter: none;
  }
  .ewa-btn--link {
    border-color: transparent;
    color: LinkText;
    text-decoration: underline;
  }
  .ewa-btn[disabled],
  .ewa-btn[aria-disabled="true"] {
    color: GrayText;
    border-color: GrayText;
    opacity: 1;
  }
}

/* =========================================================================
   REDUCED MOTION — strip our color/shadow transitions. (Global safety net
   exists; explicit here for the essential interactive control.)
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-btn {
    transition: none;
  }
}

/* =========================================================================
   POLISH — a tactile lift + soft shadow on the solid/outline buttons so they
   feel pressable. Motion-safe (no lift under reduced motion or forced colors).
   ========================================================================= */
.ewa-btn {
  transition: background-color var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard),
              box-shadow var(--duration-fast) var(--easing-standard),
              transform var(--duration-fast) var(--easing-standard);
}
.ewa-btn--primary:hover,
.ewa-btn--secondary:hover,
.ewa-btn--danger:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.ewa-btn--primary:active,
.ewa-btn--secondary:active,
.ewa-btn--danger:active {
  transform: translateY(0);
  box-shadow: none;
}
@media (prefers-reduced-motion: reduce) {
  .ewa-btn { transition: none; }
  .ewa-btn:hover, .ewa-btn:active { transform: none; }
}
@media (forced-colors: active) {
  .ewa-btn--primary:hover,
  .ewa-btn--secondary:hover,
  .ewa-btn--danger:hover { box-shadow: none; transform: none; }
}


/* =========================================================================
   form.css — accessible form field pattern for EqualWeb Academy
   Block: .ewa-field (stacked label / control / hint / error)
   Controls: .ewa-input / .ewa-select / .ewa-textarea
   Composes: base.css form defaults + global :focus-visible ring.

   Accessibility contract honored here:
     - real <label for> (never placeholder-as-label)
     - hint + error linked via aria-describedby
     - error: icon + words (color is never the only signal, 1.4.1)
     - error control also carries aria-invalid="true"
     - required marked with text ("required"), not asterisk-color alone
     - logical properties only; >=24px targets; forced-colors handled
   ========================================================================= */

/* ---- Field wrapper: vertical stack --------------------------------- */
.ewa-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-block-end: var(--space-5);
  max-inline-size: var(--measure);
}

/* ---- Label --------------------------------------------------------- */
.ewa-field__label {
  font-weight: var(--weight-semibold);
  color: var(--text);
  line-height: var(--leading-snug);
}

/* "required" / "optional" qualifier — TEXT, not colour/asterisk alone */
.ewa-field__req {
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-inline-start: var(--space-1);
}
.ewa-field__req--required {
  color: var(--danger-fg);
  font-weight: var(--weight-medium);
}
/* The visual asterisk is decorative; the word "required" carries meaning. */
.ewa-field__req--required::before {
  /* Empty alt ("" after the slash) hides the asterisk from the
     accessible name; the word "required" carries the meaning. */
  content: "\2217" / ""; /* asterisk, decorative */
  margin-inline-end: var(--space-1);
}

/* ---- Controls ------------------------------------------------------ */
.ewa-input,
.ewa-select,
.ewa-textarea {
  inline-size: 100%;
  min-block-size: var(--target-comfortable); /* >= 44px comfortable target */
  font: inherit;
  color: var(--text);
  background-color: var(--bg-elevated);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  transition: border-color var(--duration-fast) var(--easing-standard),
              box-shadow var(--duration-fast) var(--easing-standard);
}

.ewa-textarea {
  min-block-size: calc(var(--target-comfortable) * 2);
  line-height: var(--leading-base);
  resize: vertical;
}

/* Native arrow stays for <select>; just give breathing room at the end. */
.ewa-select {
  padding-inline-end: var(--space-5);
}

/* Hover (pointer affordance, not a state signal) */
.ewa-input:hover:not(:disabled),
.ewa-select:hover:not(:disabled),
.ewa-textarea:hover:not(:disabled) {
  border-color: var(--text-muted);
}

/* Disabled */
.ewa-input:disabled,
.ewa-select:disabled,
.ewa-textarea:disabled {
  background-color: var(--surface-sunken);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* ---- Hint ---------------------------------------------------------- */
.ewa-field__hint {
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}

/* ---- Error message ------------------------------------------------- */
/* role="none" text: an icon (decorative) + real words, plus colour.    */
.ewa-field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
  color: var(--danger-fg);
}
.ewa-field__error-icon {
  flex: none;
  inline-size: 1.1em;
  block-size: 1.1em;
  margin-block-start: 0.1em;
  fill: currentColor;     /* inherits danger colour */
}

/* ---- Errored control: aria-invalid drives the visual ---------------- */
.ewa-input[aria-invalid="true"],
.ewa-select[aria-invalid="true"],
.ewa-textarea[aria-invalid="true"] {
  border-color: var(--danger-border);
  border-inline-start-width: var(--border-2);
}
.ewa-input[aria-invalid="true"]:focus-visible,
.ewa-select[aria-invalid="true"]:focus-visible,
.ewa-textarea[aria-invalid="true"]:focus-visible {
  /* keep the global focus ring; just signal the danger boundary too */
  box-shadow: 0 0 0 var(--border-1) var(--danger-fg) inset;
}

/* =========================================================================
   CHECKBOX / RADIO group — grouped with <fieldset><legend>
   ========================================================================= */
.ewa-fieldset {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-md);
  padding-block: var(--space-3) var(--space-4);
  padding-inline: var(--space-4);
  margin-block-end: var(--space-5);
  max-inline-size: var(--measure);
}
.ewa-fieldset__legend {
  font-weight: var(--weight-semibold);
  padding-inline: var(--space-2);
  color: var(--text);
}

/* one choice = label wrapping (or adjacent to) a native control */
.ewa-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-block-size: var(--target-min);  /* >= 24px row */
  padding-block: var(--space-2);
  font-weight: var(--weight-regular);
  cursor: pointer;
}
.ewa-choice__control {
  flex: none;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  margin-block-start: 0.15em; /* align with first line of text */
  accent-color: var(--color-brand);
  cursor: pointer;
}
.ewa-choice__text {
  line-height: var(--leading-snug);
}
.ewa-choice__desc {
  display: block;
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.ewa-choice:has(.ewa-choice__control:disabled) {
  color: var(--text-muted);
  cursor: not-allowed;
}
.ewa-choice:has(.ewa-choice__control:disabled) .ewa-choice__control {
  cursor: not-allowed;
}

/* =========================================================================
   FORCED COLORS — we lean on border-color / box-shadow to show the
   error boundary; remap to system keywords so it survives the OS palette.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-input,
  .ewa-select,
  .ewa-textarea {
    border-color: ButtonText;
  }
  .ewa-input[aria-invalid="true"],
  .ewa-select[aria-invalid="true"],
  .ewa-textarea[aria-invalid="true"] {
    border-color: Mark;        /* error boundary uses the Mark keyword */
  }
  .ewa-field__error,
  .ewa-field__error-icon {
    color: Mark;
    fill: Mark;
  }
  .ewa-choice__control {
    accent-color: Highlight;
  }
}

/* =========================================================================
   REDUCED MOTION — drop the control transitions (global net exists; be
   explicit for this component's essential interactivity).
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-input,
  .ewa-select,
  .ewa-textarea {
    transition: none;
  }
}


/* =========================================================================
   callout.css — Callouts / admonitions for EqualWeb Academy
   .ewa-callout + modifiers: --note --tip --warning --success --danger
   Parts: .ewa-callout__icon (decorative SVG), .ewa-callout__title,
          .ewa-callout__body

   Accessibility:
     - Meaning never rides on color (1.4.1): every variant pairs a status
       color with a decorative icon AND a visible word label in the title.
     - The accent rides on the inline-start edge via border-inline-start so it
       flips correctly for RTL/Hebrew (logical properties only).
     - Forced-colors keeps a visible boundary using system color keywords.
   Consumes SEMANTIC tokens only — no hardcoded colors.
   ========================================================================= */

.ewa-callout {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-3);
  row-gap: var(--space-1);
  align-items: start;

  /* default = note / info palette; modifiers re-point these locals */
  --_callout-fg: var(--info-fg);
  --_callout-bg: var(--info-bg);
  --_callout-border: var(--info-border);

  color: var(--text);
  background-color: var(--_callout-bg);
  border: var(--border-1) solid var(--_callout-border);
  border-inline-start: var(--space-1) solid var(--_callout-fg);
  border-radius: var(--radius-md);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  margin-block: 0 var(--space-4);
}

/* ---- Parts -------------------------------------------------------------- */

.ewa-callout__icon {
  grid-column: 1;
  grid-row: 1;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  color: var(--_callout-fg);
  /* SVG inherits currentColor for fill/stroke */
}

.ewa-callout__title {
  grid-column: 2;
  grid-row: 1;
  margin-block: 0;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
  color: var(--_callout-fg);
}

.ewa-callout__body {
  grid-column: 2;
  grid-row: 2;
  color: var(--text);
}

/* Tidy spacing for prose that authors drop inside the body */
.ewa-callout__body > :first-child { margin-block-start: 0; }
.ewa-callout__body > :last-child { margin-block-end: 0; }

/* A callout with no separate title: let the body span both rows */
.ewa-callout:not(:has(.ewa-callout__title)) .ewa-callout__body {
  grid-row: 1;
}

/* ---- Variants — status colors from the semantic token set --------------- */

/* note → informational (blue / --info) — also the default above */
.ewa-callout--note {
  --_callout-fg: var(--info-fg);
  --_callout-bg: var(--info-bg);
  --_callout-border: var(--info-border);
}

/* tip → helpful aside, carries the readable brand color so it stays
   distinct from the green "success" variant */
.ewa-callout--tip {
  --_callout-fg: var(--color-brand-text);
  --_callout-bg: var(--bg-subtle);
  --_callout-border: var(--border-strong);
}

/* warning → caution (amber / --warning) */
.ewa-callout--warning {
  --_callout-fg: var(--warning-fg);
  --_callout-bg: var(--warning-bg);
  --_callout-border: var(--warning-border);
}

/* success → positive confirmation (green / --success) */
.ewa-callout--success {
  --_callout-fg: var(--success-fg);
  --_callout-bg: var(--success-bg);
  --_callout-border: var(--success-border);
}

/* danger → critical / destructive (red / --danger) */
.ewa-callout--danger {
  --_callout-fg: var(--danger-fg);
  --_callout-bg: var(--danger-bg);
  --_callout-border: var(--danger-border);
}

/* =========================================================================
   FORCED COLORS — background tints are dropped by the OS palette, so make
   sure each callout keeps a visible boundary and the icon stays perceivable.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-callout {
    border: var(--border-1) solid CanvasText;
    border-inline-start: var(--space-1) solid CanvasText;
  }
  .ewa-callout__icon,
  .ewa-callout__title {
    color: CanvasText;
    forced-color-adjust: auto;
  }
}


/* =========================================================================
   badge.css — standards / conformance badges for EqualWeb Academy
   .ewa-badge is a small inline pill carrying a TEXT label that IS the meaning
   (e.g. "WCAG 2.2 AA", "EN 301 549"). Color/tone is supplementary only — the
   text label always conveys the standard, so the component is never
   color-only (WCAG 1.4.1). An optional decorative __icon glyph reinforces the
   tone but is aria-hidden because the visible text already names the standard.

   Tone modifiers (jurisdiction / family):
     --wcag  W3C / WCAG family            (brand teal tint)
     --eu    European law / EN standards  (info / blue tint)
     --us    United States law            (warning / amber tint)
     --intl  Other national standards     (success / green tint)
   Emphasis modifier:
     --level small conformance-level pill (A / AA / AAA), pairs with a tone

   Contrast: every tone uses a status -fg on its matching -bg, which the token
   layer verifies at >= 4.5:1 on the badge background in every theme.
   ========================================================================= */

.ewa-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  /* min target keeps standalone/linked badges tappable; inline text badges
     stay compact but still clear the 24px floor in the block axis */
  min-block-size: var(--target-min);
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-pill);
  background-color: var(--bg-subtle);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: 0.01em;
  white-space: nowrap;
  text-decoration: none;          /* in case the badge is an <a> */
  vertical-align: baseline;
}

/* When the badge is itself a link, keep the label readable and underline on
   interaction so it is not color-only as an interactive element. */
a.ewa-badge {
  color: var(--text);
}
a.ewa-badge:hover,
a.ewa-badge:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* Decorative leading glyph — reinforces tone, hidden from AT (aria-hidden). */
.ewa-badge__icon {
  flex: none;
  display: inline-flex;
  inline-size: 0.85em;
  block-size: 0.85em;
}
.ewa-badge__icon svg {
  inline-size: 100%;
  block-size: 100%;
  fill: currentColor;
}

/* The standard's full name as the meaning-bearing label. */
.ewa-badge__label {
  font-weight: inherit;
}

/* -------- Tone modifiers ------------------------------------------------- */
.ewa-badge--wcag {
  color: var(--color-brand-text);
  background-color: var(--bg-subtle);
  border-color: var(--color-brand-text);
}
.ewa-badge--eu {
  color: var(--info-fg);
  background-color: var(--info-bg);
  border-color: var(--info-border);
}
.ewa-badge--us {
  color: var(--warning-fg);
  background-color: var(--warning-bg);
  border-color: var(--warning-border);
}
.ewa-badge--intl {
  color: var(--success-fg);
  background-color: var(--success-bg);
  border-color: var(--success-border);
}

/* Keep the link color in step with the tone when a tone badge is a link. */
a.ewa-badge--wcag { color: var(--color-brand-text); }
a.ewa-badge--eu   { color: var(--info-fg); }
a.ewa-badge--us   { color: var(--warning-fg); }
a.ewa-badge--intl { color: var(--success-fg); }

/* -------- Level emphasis pill (A / AA / AAA) ---------------------------- */
/* A compact, higher-emphasis chip used after a WCAG name. It is filled so the
   level reads as a distinct token; the letters themselves carry the meaning. */
.ewa-badge--level {
  padding-inline: var(--space-2);
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  color: var(--text-on-brand);
  background-color: var(--color-brand);
  border-color: var(--color-brand-text);
}

/* -------- Forced colors ------------------------------------------------- */
/* Backgrounds/borders are dropped in forced-colors; restore a visible pill
   outline and ensure the label/glyph use system colors so each badge keeps a
   clear boundary and the level chip stays distinguishable. */
@media (forced-colors: active) {
  .ewa-badge {
    border: var(--border-1) solid CanvasText;
    color: CanvasText;
    background-color: Canvas;
  }
  .ewa-badge__icon svg { fill: CanvasText; }
  a.ewa-badge,
  a.ewa-badge--wcag,
  a.ewa-badge--eu,
  a.ewa-badge--us,
  a.ewa-badge--intl {
    color: LinkText;
  }
  .ewa-badge--level {
    color: Canvas;
    background-color: CanvasText;
    border-color: CanvasText;
    forced-color-adjust: none;
  }
}

/* -------- Reduced motion ------------------------------------------------ */
/* The badge has no essential motion of its own; this is a safety net so any
   inherited hover transition is removed when the user asks for less motion. */
@media (prefers-reduced-motion: reduce) {
  .ewa-badge,
  a.ewa-badge {
    transition: none;
  }
}


/* =========================================================================
   code-block.css — .ewa-code
   A code example block: <figure> with a header bar (filename + copy button)
   and a <pre><code> body. Includes a live region for the copy status.
   Markup is fully usable with JS off (code is selectable; the copy button is
   only revealed by copy-button.js once the Clipboard API is confirmed).
   Consumes semantic tokens only; logical properties only.
   ========================================================================= */

.ewa-code {
  margin: 0;
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  overflow: hidden; /* clip children to the rounded corners */
}

/* ---- Header bar: filename + copy button -------------------------------- */
.ewa-code__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  background: var(--bg-subtle);
  border-block-end: var(--border-1) solid var(--border);
}

.ewa-code__filename {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--text-muted);
  /* keep long names from blowing out the bar */
  overflow-wrap: anywhere;
}

/* ---- Copy button ------------------------------------------------------- */
.ewa-code__copy {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  /* >= --target-min and comfortably toward 44px via padding */
  min-block-size: var(--target-min);
  min-inline-size: var(--target-min);
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  color: var(--text);
  background: var(--bg-elevated);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard);
}

.ewa-code__copy:hover {
  background: var(--surface-sunken);
  border-color: var(--text-muted);
}

.ewa-code__copy:active {
  background: var(--surface-sunken);
}

/* The icon paired with the text label (never icon-only). */
.ewa-code__copy-icon {
  inline-size: 1em;
  block-size: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- Body -------------------------------------------------------------- */
.ewa-code__body {
  margin: 0;
  padding-block: var(--space-4);
  padding-inline: var(--space-4);
  overflow-x: auto; /* horizontal scroll for long lines, no layout break */
  background: var(--bg-elevated);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-base);
  /* keep tab rendering compact and predictable */
  tab-size: 2;
}

.ewa-code__body code {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  background: none;
  padding: 0;
  /* Wrap long lines instead of forcing a horizontal scroll. This keeps code
     readable at 320px / 400% zoom (SC 1.4.10) and avoids a scrollable region
     that would otherwise need to be keyboard-focusable (SC 2.1.1). */
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

/* ---- Status live region ------------------------------------------------ */
/* Visually hidden until JS writes a message; paired with an icon + text so
   color is never the only signal (it is, however, primarily an SR cue). */
.ewa-code__status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-inline-start: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--success-fg);
}

/* Hidden while empty (no [data-status]) — keeps the bar clean pre-copy and
   avoids announcing an empty region. JS sets data-status to reveal it. */
.ewa-code__status:not([data-status]) {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.ewa-code__status-icon {
  inline-size: 1em;
  block-size: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* =========================================================================
   Forced colors (Windows High Contrast): box-shadow/background are dropped,
   so lean on system color keywords for borders + the success status.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-code,
  .ewa-code__bar,
  .ewa-code__copy {
    border-color: ButtonText;
  }
  .ewa-code__copy {
    color: ButtonText;
  }
  .ewa-code__copy:hover {
    color: Highlight;
    border-color: Highlight;
  }
  .ewa-code__status {
    color: CanvasText;
  }
}

/* =========================================================================
   Reduced motion: remove the button's hover transition.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-code__copy {
    transition: none;
  }
}


/* ==========================================================================
   EqualWeb Academy — Table component
   Accessible data table. Semantic <table> only (no layout tables).
   - .ewa-table-wrap : scroll region (role=region + tabindex via JS/markup)
   - .ewa-table      : the <table> itself, with <caption>, scoped headers,
                       zebra striping via --bg-subtle.
   Tokens only · logical properties only · RTL-safe.
   ========================================================================== */

.ewa-table-wrap {
  overflow-x: auto;
  max-inline-size: 100%;
  /* Smooth-but-honest scrollbar gutter so wide tables stay reachable. */
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-md);
  background-color: var(--bg);
  /* Keyboard scroll containers get the global :focus-visible ring; nothing to add. */
}

/* Subtle inset shadow hint that more content exists when scrolled (decorative). */
@supports (animation-timeline: scroll(self inline)) {
  .ewa-table-wrap {
    background:
      linear-gradient(to right, var(--bg) 30%, transparent),
      linear-gradient(to left, var(--bg) 30%, transparent) 100% 0,
      radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--text) 12%, transparent), transparent),
      radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--text) 12%, transparent), transparent) 100% 0;
    background-repeat: no-repeat;
    background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
  }
}

.ewa-table {
  inline-size: 100%;
  border-collapse: collapse;
  /* Keep columns from collapsing in the scroll region. */
  min-inline-size: max-content;
  font-size: var(--text-sm);
  line-height: var(--leading-normal, 1.5);
  color: var(--text);
  text-align: start;
}

/* Caption: the table's accessible name; visible by design. */
.ewa-table > caption {
  caption-side: top;
  text-align: start;
  font-weight: var(--weight-semibold, 600);
  color: var(--text);
  padding-block: var(--space-3);
  padding-inline: var(--space-3);
  font-size: var(--text-base);
}

.ewa-table th,
.ewa-table td {
  padding-block: var(--space-3);
  padding-inline: var(--space-3);
  text-align: start;
  vertical-align: top;
  border-block-end: var(--border-1) solid var(--border);
}

/* Column headers */
.ewa-table thead th[scope="col"] {
  background-color: var(--surface-sunken, var(--bg-subtle));
  color: var(--text);
  font-weight: var(--weight-semibold, 600);
  border-block-end: var(--border-2) solid var(--border-strong);
  white-space: nowrap;
}

/* Row headers (scope=row) — emphasized but not heavy. */
.ewa-table tbody th[scope="row"] {
  font-weight: var(--weight-semibold, 600);
  color: var(--text);
}

/* Zebra striping for scannability (decorative; not the only grouping cue). */
.ewa-table tbody tr:nth-child(even) > * {
  background-color: var(--bg-subtle);
}

/* Hover affordance on rows (pointer only; no state meaning). */
@media (hover: hover) {
  .ewa-table tbody tr:hover > * {
    background-color: var(--surface-sunken, var(--bg-subtle));
  }
}

.ewa-table tbody tr:last-child > * {
  border-block-end: 0;
}

/* Numeric / end-aligned cells opt-in modifier. */
.ewa-table .ewa-table__num {
  text-align: end;
  font-variant-numeric: tabular-nums;
}

/* Inline status pairing inside cells (icon + label; color never alone, SC 1.4.1). */
.ewa-table__status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1, 0.25rem);
  font-weight: var(--weight-medium, 500);
}
.ewa-table__status-icon {
  flex: none;
  inline-size: 1em;
  block-size: 1em;
  /* Icon inherits the status text color via currentColor. */
}
.ewa-table__status--success { color: var(--success-fg); }
.ewa-table__status--info    { color: var(--info-fg); }
.ewa-table__status--warning { color: var(--warning-fg); }
.ewa-table__status--danger  { color: var(--danger-fg); }

/* ---- Forced colors: keep boundaries & header emphasis without our bg/shadows ---- */
@media (forced-colors: active) {
  .ewa-table-wrap {
    border-color: CanvasText;
    background: Canvas;
  }
  .ewa-table th,
  .ewa-table td {
    border-block-end-color: CanvasText;
  }
  .ewa-table thead th[scope="col"] {
    background-color: Canvas;
    border-block-end-color: CanvasText;
  }
  /* Zebra background is invisible in forced colors; that is acceptable —
     structure comes from real <th>/<td> + borders, not the stripe. */
  .ewa-table tbody tr:nth-child(even) > *,
  .ewa-table tbody tr:hover > * {
    background-color: Canvas;
  }
  .ewa-table__status { color: CanvasText; }
}

/* ---- Reduced motion: nothing animates here, but be explicit & safe. ---- */
@media (prefers-reduced-motion: reduce) {
  .ewa-table-wrap { scroll-behavior: auto; }
}


/* ==========================================================================
   Breadcrumb  —  .ewa-breadcrumb
   Semantic markup:  <nav class="ewa-breadcrumb" aria-label="Breadcrumb">
                       <ol class="ewa-breadcrumb__list">
                         <li class="ewa-breadcrumb__item"><a>…</a></li>
                         …
                         <li class="ewa-breadcrumb__item"><span aria-current="page">…</span></li>
                       </ol>
                     </nav>
   - Separator is a CSS ::before chevron on each item except the first.
     It is decorative (generated content, role announced as nothing) and
     MIRRORS automatically under [dir="rtl"].
   - Last crumb is the current page: aria-current="page", NOT a link.
   ========================================================================== */

.ewa-breadcrumb {
  display: block;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}

.ewa-breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  margin-block: 0;
  margin-inline: 0;
  padding-inline-start: 0;
  list-style: none;
}

.ewa-breadcrumb__item {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--target-min);
}

/* --- Separator (decorative chevron, mirrors in RTL) ----------------------- */
.ewa-breadcrumb__item + .ewa-breadcrumb__item::before {
  content: "";
  flex: none;
  inline-size: 0.5em;
  block-size: 0.5em;
  margin-inline-end: var(--space-2);
  border-block-start: var(--border-2) solid var(--border-strong);
  border-inline-end: var(--border-2) solid var(--border-strong);
  /* In LTR the border-inline-end resolves to the right edge, so top+right
     borders rotated 45deg make a ">" pointing toward the next crumb. */
  transform: rotate(45deg);
  /* keep the chevron optically centred with the text baseline */
  transform-origin: center;
}

[dir="rtl"] .ewa-breadcrumb__item + .ewa-breadcrumb__item::before {
  /* In RTL the border-inline-end resolves to the LEFT edge, so the corner
     becomes top+left; rotate(-45deg) turns that into a "<" pointing toward
     the next crumb (which is to the left). transform is not a logical
     property, so this explicit RTL value is required. */
  transform: rotate(-45deg);
}

/* --- Links ---------------------------------------------------------------- */
.ewa-breadcrumb__item a {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--target-min);
  padding-block: var(--space-1);
  padding-inline: var(--space-1);
  margin-inline: calc(var(--space-1) * -1); /* keep visual alignment, grow target */
  color: var(--link);
  border-radius: var(--radius-sm);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.ewa-breadcrumb__item a:hover {
  color: var(--link-hover);
}

/* --- Current page (last item) -------------------------------------------- */
.ewa-breadcrumb__item [aria-current="page"] {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--target-min);
  color: var(--text);
  font-weight: var(--weight-medium, 500);
  text-decoration: none;
}

/* --- Forced colors -------------------------------------------------------- */
@media (forced-colors: active) {
  .ewa-breadcrumb__item + .ewa-breadcrumb__item::before {
    border-block-start-color: CanvasText;
    border-inline-end-color: CanvasText;
  }
  .ewa-breadcrumb__item a {
    color: LinkText;
  }
  .ewa-breadcrumb__item [aria-current="page"] {
    color: CanvasText;
  }
}


/* =========================================================================
   disclosure.css — Disclosure + Accordion for EqualWeb Academy
   - .ewa-disclosure   : a single show/hide region (root carries [data-disclosure])
   - .ewa-accordion    : a group of independent disclosures (NO single-open)
   Markup is usable with JS off (panel visible, button aria-expanded="true").
   JS adds `hidden` on init and toggles aria-expanded + hidden on click.
   ========================================================================= */

/* ---- Accordion group ---------------------------------------------------- */
.ewa-accordion {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* ---- Disclosure block --------------------------------------------------- */
.ewa-disclosure {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-md);
  background-color: var(--bg-elevated);
  /* NOTE: no `overflow:hidden`. The global focus ring is an *outset* outline
     (outline-offset) on the trigger; clipping the root would crop that ring on
     the top/side edges. Instead we round child corners individually so the
     hover fill still respects the container radius. */
}

/* ---- Trigger (a real <button>) ----------------------------------------- */
.ewa-disclosure__trigger {
  /* layout */
  display: flex;
  align-items: center;
  gap: var(--space-3);
  inline-size: 100%;
  min-block-size: var(--target-comfortable); /* >= 44px, well over --target-min */
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  margin: 0;

  /* type */
  font-family: var(--font-sans);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  text-align: start;
  color: var(--text);

  /* reset button chrome (focus stays global — no outline:none) */
  background-color: transparent;
  border: 0;
  cursor: pointer;

  /* Match the container's leading corners so the hover fill stays rounded
     without an `overflow:hidden` that would clip the keyboard focus ring. */
  border-start-start-radius: var(--radius-md);
  border-start-end-radius: var(--radius-md);

  /* When focused, lift the trigger so its outset focus outline is never
     painted behind the panel/border. */
  position: relative;
}

/* When collapsed the trigger is the last visible child, so round its trailing
   corners too (the panel is `hidden`). */
.ewa-disclosure__trigger[aria-expanded="false"] {
  border-end-start-radius: var(--radius-md);
  border-end-end-radius: var(--radius-md);
}

.ewa-disclosure__trigger:hover {
  background-color: var(--bg-subtle);
}

/* Label fills the row so the chevron is pushed to the inline-end edge. */
.ewa-disclosure__label {
  flex: 1 1 auto;
}

/* ---- Chevron icon ------------------------------------------------------- */
.ewa-disclosure__icon {
  flex: 0 0 auto;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  color: var(--text-muted);
  transition: transform var(--duration-base) var(--easing-standard);
}

/* Mirror the chevron under RTL (logical mirroring for Hebrew/Arabic). */
[dir="rtl"] .ewa-disclosure__icon {
  scale: -1 1;
}

/* Rotate the chevron when expanded. */
.ewa-disclosure__trigger[aria-expanded="true"] .ewa-disclosure__icon {
  transform: rotate(90deg);
}
[dir="rtl"] .ewa-disclosure__trigger[aria-expanded="true"] .ewa-disclosure__icon {
  /* combine the RTL mirror with the open rotation */
  transform: rotate(-90deg);
}

/* ---- Panel (region) ----------------------------------------------------- */
.ewa-disclosure__panel {
  padding-block: var(--space-3) var(--space-4);
  padding-inline: var(--space-4);
  border-block-start: var(--border-1) solid var(--border);
  color: var(--text);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  /* Round the trailing corners so the open panel matches the container radius
     (we no longer rely on the parent's `overflow:hidden`). */
  border-end-start-radius: var(--radius-md);
  border-end-end-radius: var(--radius-md);
}

.ewa-disclosure__panel > :first-child { margin-block-start: 0; }
.ewa-disclosure__panel > :last-child  { margin-block-end: 0; }

/* The native `hidden` attribute does the hiding — keep its default display:none
   robust even if a utility sets display on the panel. */
.ewa-disclosure__panel[hidden] {
  display: none;
}

/* ---- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ewa-disclosure__icon {
    transition: none;
  }
}

/* ---- Forced colors (Windows High Contrast) ------------------------------ */
@media (forced-colors: active) {
  .ewa-disclosure {
    border-color: ButtonBorder;
  }
  .ewa-disclosure__panel {
    border-block-start-color: ButtonBorder;
  }
  /* hover background is dropped in forced colors; keep the label readable */
  .ewa-disclosure__trigger:hover {
    background-color: Canvas;
  }
  .ewa-disclosure__icon {
    color: ButtonText;
  }
}


/* =========================================================================
   tabs.css — EqualWeb Academy tabs component
   Pattern: WAI-ARIA APG Tabs (automatic activation).

   Progressive enhancement contract:
     - NO JS  → markup is a heading-led list of <section>s, all visible &
                stacked (a perfectly usable document outline).
     - WITH JS→ tabs.js upgrades the root to role="tablist"/tab/tabpanel,
                sets [data-tabs-ready] on the root, and only then do the
                tab-strip / hidden-panel styles below apply.
   Until upgraded, the [data-tabs-ready] guarded rules don't fire, so the
   no-JS view never looks "broken".
   ========================================================================= */

.ewa-tabs {
  display: block;
  margin-block: var(--space-5);
}

/* -------------------------------------------------------------------------
   NO-JS / pre-upgrade view: stacked sections with clear separators.
   ------------------------------------------------------------------------- */
.ewa-tabs > section {
  border-block-start: var(--border-1) solid var(--border);
  padding-block: var(--space-4);
}

.ewa-tabs > section:first-of-type {
  border-block-start: 0;
}

/* The author may wrap the panels in a list element; flatten its default look. */
.ewa-tabs__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* =========================================================================
   UPGRADED VIEW (JS added [data-tabs-ready] to the root)
   ========================================================================= */

/* The tab strip becomes a horizontal, wrapping row of buttons. */
.ewa-tabs[data-tabs-ready] .ewa-tabs__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
  border-block-end: var(--border-2) solid var(--border);
}

/* Each tab is a real <button> the JS generated. */
.ewa-tabs__tab {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--target-comfortable);
  min-inline-size: var(--target-min);
  padding-block: var(--space-2);
  padding-inline: var(--space-4);
  margin-block-end: calc(-1 * var(--border-2)); /* sit on the strip's bottom rule */
  border: var(--border-1) solid transparent;
  border-block-end: var(--border-2) solid transparent;
  border-start-start-radius: var(--radius-md);
  border-start-end-radius: var(--radius-md);
  background-color: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  text-align: start;
  cursor: pointer;
  transition: color var(--duration-fast) var(--easing-standard),
              background-color var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard);
}

.ewa-tabs__tab:hover {
  color: var(--text);
  background-color: var(--bg-subtle);
}

/* Selected tab: color is NOT the only signal — a 2px active edge + bold weight
   + the connected panel all reinforce it. */
.ewa-tabs__tab[aria-selected="true"] {
  color: var(--color-brand-text);
  font-weight: var(--weight-semibold);
  border-color: var(--border);
  border-block-end-color: var(--bg);
  background-color: var(--bg);
}

/* A leading accent bar so selection survives without relying on hue alone. */
.ewa-tabs__tab[aria-selected="true"]::before {
  content: "";
  inline-size: var(--space-2);
  block-size: var(--space-2);
  border-radius: var(--radius-pill);
  background-color: var(--color-brand);
  flex: 0 0 auto;
}

/* -------------------------------------------------------------------------
   Panels
   ------------------------------------------------------------------------- */
.ewa-tabs[data-tabs-ready] .ewa-tabs__panel {
  border: 0;
  border-block-end: 0;
  padding-block: var(--space-5) var(--space-4);
  padding-inline: 0;
}

/* JS sets [hidden] on inactive panels; honor it over the flex/visible rules. */
.ewa-tabs[data-tabs-ready] .ewa-tabs__panel[hidden] {
  display: none;
}

/* Panel gets a visible focus ring only via the global :focus-visible (base.css)
   when JS made it programmatically focusable (tabindex=0). Nothing to add. */

/* =========================================================================
   FORCED COLORS (Windows High Contrast) — selection relies on bg/border, so
   restate boundaries with system colors.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-tabs[data-tabs-ready] .ewa-tabs__list {
    border-block-end-color: ButtonText;
  }

  .ewa-tabs__tab {
    color: ButtonText;
    border-color: ButtonText;
  }

  .ewa-tabs__tab[aria-selected="true"] {
    color: Highlight;
    border-color: Highlight;
    border-block-end-color: Canvas;
    forced-color-adjust: none;
  }

  .ewa-tabs__tab[aria-selected="true"]::before {
    background-color: Highlight;
  }
}

/* =========================================================================
   REDUCED MOTION — drop the hover/selection transition.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-tabs__tab {
    transition: none;
  }
}


/* =========================================================================
   nav.css — primary site navigation + header inner bar + footer glue.
   Layout.css owns .site-header / .site-footer (sticky shell + borders);
   this file styles the INNER bar (logo + nav + submenus) and the .ewa-nav block.

   Mobile nav model: the toggle opens a FULL-WIDTH dropdown PANEL anchored to
   the bottom of the sticky header (position:absolute, inset-inline:0). This
   avoids the old "list squeezed into the right column" bug. Submenus expand
   inline (accordion) on mobile and drop down (absolute) on desktop.
   With JS off every link is reachable: submenus render open (html.no-js).
   ========================================================================= */

/* ---- Header inner bar: logo + nav + theme ------------------------------ */
.site-header__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  min-block-size: var(--target-comfortable);
  padding-block: var(--space-3);
}

.site-header__logo {
  display: inline-flex;
  align-items: center;
  margin-inline-end: auto; /* push nav + theme to the far inline-end */
  color: var(--text);
  text-decoration: none;
  border-radius: var(--radius-sm);
}

/* ---- Inline, theme-aware logo ---------------------------------------- */
/* Wordmark follows --text (black in light, white in dark); mark stays brand. */
.site-logo {
  display: block;
  block-size: 1.9rem;
  inline-size: auto;
}
.site-logo__mark { fill: var(--color-brand); }
.site-logo__word { fill: var(--text); font: 700 17px var(--font-sans); }
.site-logo__sub  { fill: var(--text-muted); font: 600 12px var(--font-sans); letter-spacing: 0.18em; }
@media (forced-colors: active) {
  .site-logo__mark,
  .site-logo__word,
  .site-logo__sub { fill: CanvasText; forced-color-adjust: none; }
}

/* ---- Nav block ------------------------------------------------------ */
.ewa-nav {
  display: flex;
  align-items: center;
}

/* Toggle: only meaningful < lg. Hidden (and inert) at/above lg via CSS. */
.ewa-nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-block-size: var(--target-comfortable);
  min-inline-size: var(--target-comfortable);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  color: var(--text);
  font: inherit;
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  cursor: pointer;
}
.ewa-nav__toggle:hover { background: var(--bg-subtle); }

.ewa-nav__toggle-icon { inline-size: 24px; block-size: 24px; flex: none; }
.ewa-nav__toggle-icon path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}
.ewa-nav__toggle-icon .ewa-nav__bar--top,
.ewa-nav__toggle-icon .ewa-nav__bar--bottom,
.ewa-nav__toggle-icon .ewa-nav__bar--x {
  transition: opacity var(--duration-fast) var(--easing-standard);
}
.ewa-nav__toggle-icon .ewa-nav__bar--x { opacity: 0; }
.ewa-nav__toggle[aria-expanded="true"] .ewa-nav__bar--top,
.ewa-nav__toggle[aria-expanded="true"] .ewa-nav__bar--bottom { opacity: 0; }
.ewa-nav__toggle[aria-expanded="true"] .ewa-nav__bar--x { opacity: 1; }

/* ---- The top-level list -------------------------------------------- */
.ewa-nav__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ewa-nav__item { position: relative; }

/* Top-level entries: real links AND submenu toggles share this look. */
.ewa-nav__link {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  inline-size: 100%;
  min-block-size: var(--target-comfortable);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: var(--weight-medium);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}
.ewa-nav__link:hover {
  background: var(--bg-subtle);
  color: var(--link-hover);
}

/* Chevron on submenu toggles; rotates when open (motion-safe). */
.ewa-nav__chevron {
  inline-size: 1rem;
  block-size: 1rem;
  flex: none;
  margin-inline-start: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--duration-fast) var(--easing-standard);
}
.ewa-nav__link[aria-expanded="true"] .ewa-nav__chevron { transform: rotate(180deg); }

/* Current page (link) / current section (toggle): non-colour signals too. */
.ewa-nav__link[aria-current="page"],
.ewa-nav__link[data-current-section] {
  color: var(--color-brand-text);
  font-weight: var(--weight-bold);
  background: var(--bg-subtle);
  border-inline-start: var(--border-2) solid var(--color-brand-text);
}

/* ---- Submenus ------------------------------------------------------- */
.ewa-nav__submenu {
  margin: 0;
  padding: 0;
  list-style: none;
}
.ewa-nav__submenu[hidden] { display: none; }
/* JS-off: reveal every submenu so all links stay reachable. */
.no-js .ewa-nav__submenu[hidden] { display: block; }

.ewa-nav__sublink {
  display: flex;
  align-items: center;
  min-block-size: var(--target-min);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.ewa-nav__sublink:hover { background: var(--bg-subtle); color: var(--link-hover); }
.ewa-nav__sublink[aria-current="page"] {
  color: var(--color-brand-text);
  font-weight: var(--weight-bold);
  background: var(--bg-subtle);
}

/* =========================================================================
   MOBILE (< lg): toggle visible; the list is a full-width dropdown panel
   anchored to the bottom of the sticky header. Submenus expand inline.
   ========================================================================= */
@media (max-width: 63.999rem) {
  .ewa-nav { position: static; }

  .ewa-nav__list {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 100%;
    z-index: var(--z-header);
    max-block-size: calc(100dvh - 100%);
    overflow-y: auto;
    padding: var(--space-2);
    background: var(--bg-elevated);
    border-block: var(--border-1) solid var(--border);
    box-shadow: var(--shadow-lg);
  }
  .ewa-nav__submenu {
    padding-inline-start: var(--space-4);
    border-inline-start: var(--border-1) solid var(--border);
    margin-inline-start: var(--space-3);
  }
  .ewa-nav__link[aria-current="page"],
  .ewa-nav__link[data-current-section] { border-inline-start-width: var(--border-2); }
}

/* =========================================================================
   DESKTOP (>= lg): toggle hidden; list is a horizontal row; submenus are
   absolutely-positioned dropdowns anchored to their top-level item.
   ========================================================================= */
@media (min-width: 64rem) {
  .ewa-nav__toggle { display: none; }

  .ewa-nav__list,
  .ewa-nav__list[hidden] {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-1);
    inline-size: auto;
  }

  /* Horizontal row: current marker as an underline-style block-end bar */
  .ewa-nav__link[aria-current="page"],
  .ewa-nav__link[data-current-section] {
    background: transparent;
    border-inline-start: 0;
    border-block-end: var(--border-2) solid var(--color-brand-text);
    border-end-start-radius: 0;
    border-end-end-radius: 0;
  }
  .ewa-nav__link[aria-current="page"]:hover,
  .ewa-nav__link[data-current-section]:hover { background: var(--bg-subtle); }

  .ewa-nav__submenu {
    position: absolute;
    inset-block-start: calc(100% + var(--space-1));
    inset-inline-start: 0;
    min-inline-size: 15rem;
    padding: var(--space-2);
    background: var(--bg-elevated);
    border: var(--border-1) solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
  }
}

/* =========================================================================
   FOOTER inner content (composes with layout.css .site-footer)
   ========================================================================= */
.site-footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  padding-block: var(--space-8) var(--space-5);
}
@media (min-width: 48rem) {
  .site-footer__grid { grid-template-columns: 1.5fr 1fr 1fr; gap: var(--space-8); }
}
.site-footer__brand .site-logo { block-size: 2rem; margin-block-end: var(--space-3); }
.site-footer__tagline { color: var(--text-muted); max-inline-size: 42ch; margin: 0; }
.site-footer__heading {
  margin: 0 0 var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}
.site-footer__col ul { display: grid; gap: var(--space-2); font-size: var(--text-sm); }
.site-footer__col a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--link);
}
.ewa-external-icon {
  inline-size: 0.8em;
  block-size: 0.8em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.65;
}
.site-footer__bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-5);
  border-block-start: var(--border-1) solid var(--border);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.site-footer__bar a { color: var(--link); }

/* =========================================================================
   REDUCED MOTION
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-nav__toggle-icon .ewa-nav__bar--top,
  .ewa-nav__toggle-icon .ewa-nav__bar--bottom,
  .ewa-nav__toggle-icon .ewa-nav__bar--x,
  .ewa-nav__chevron { transition: none; }
}

/* =========================================================================
   FORCED COLORS
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-nav__toggle { border-color: ButtonText; }
  .ewa-nav__link,
  .ewa-nav__sublink { color: LinkText; }
  .ewa-nav__link[aria-current="page"],
  .ewa-nav__link[data-current-section],
  .ewa-nav__sublink[aria-current="page"] {
    color: LinkText;
    border-color: Highlight;
    forced-color-adjust: none;
    text-decoration: underline;
    text-decoration-thickness: 2px;
  }
  .ewa-nav__list,
  .ewa-nav__submenu { border-color: CanvasText; }
}


/* ==========================================================================
   ewa-sidenav — Sidebar section navigation
   Section nav with optional one-level nesting. Current page is marked with
   aria-current="page" and signalled by a strong inline-start indicator
   (border + weight), never by color alone.
   Consumes semantic tokens only; logical properties only (RTL-safe).
   No JS required — this component is pure semantic markup.
   ========================================================================== */

.ewa-sidenav {
  /* Self-contained sidebar region; let the layout decide its column width. */
  font-family: var(--font-sans);
  color: var(--text);
}

/* ---- Optional group heading above a list ------------------------------- */
.ewa-sidenav__heading {
  margin-block: var(--space-4) var(--space-2);
  padding-inline: var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.ewa-sidenav__heading:first-child {
  margin-block-start: 0;
}

/* ---- Lists -------------------------------------------------------------- */
.ewa-sidenav__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ewa-sidenav__item {
  margin: 0;
}

/* Nested list (one level deep) is indented from the inline-start edge. */
.ewa-sidenav__list .ewa-sidenav__list {
  margin-inline-start: var(--space-4);
  border-inline-start: var(--border-1) solid var(--border);
}

/* ---- Links -------------------------------------------------------------- */
.ewa-sidenav__link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* >=44px tall target: padding + min-block-size. */
  min-block-size: var(--target-comfortable);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  /* Reserve the indicator gutter so text doesn't shift when current. */
  border-inline-start: var(--border-2) solid transparent;
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  line-height: var(--leading-snug);
  text-decoration: none;
  text-align: start;
  border-radius: var(--radius-sm);
  transition: background-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}

.ewa-sidenav__link:hover {
  background-color: var(--bg-subtle);
  color: var(--link-hover);
}

/* Marker dot/icon slot — kept visually subtle until current. */
.ewa-sidenav__marker {
  flex: none;
  inline-size: 1em;
  block-size: 1em;
  line-height: 1;
}

.ewa-sidenav__label {
  min-inline-size: 0;
}

/* ---- Current page ------------------------------------------------------- */
/* Strong, color-independent signal: inline-start border + bold weight,
   PLUS a check-mark icon so the cue survives grayscale and Forced Colors. */
.ewa-sidenav__link[aria-current="page"] {
  border-inline-start-color: var(--color-brand);
  background-color: var(--bg-subtle);
  color: var(--color-brand-text);
  font-weight: var(--weight-bold);
}

.ewa-sidenav__link[aria-current="page"] .ewa-sidenav__marker {
  color: var(--color-brand-text);
}

/* ---- Forced colors ------------------------------------------------------ */
@media (forced-colors: active) {
  .ewa-sidenav__link {
    border-inline-start-color: transparent;
  }

  .ewa-sidenav__link:hover {
    color: LinkText;
  }

  /* Boundary + state must come from system colors, not custom bg/box-shadow. */
  .ewa-sidenav__link[aria-current="page"] {
    border-inline-start-color: Highlight;
    background-color: Canvas;
    color: Highlight;
    forced-color-adjust: none;
  }

  .ewa-sidenav__link[aria-current="page"] .ewa-sidenav__marker {
    color: Highlight;
  }

  .ewa-sidenav__list .ewa-sidenav__list {
    border-inline-start-color: CanvasText;
  }
}

/* ---- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ewa-sidenav__link {
    transition: none;
  }
}


/* =========================================================================
   theme-switcher.css — .ewa-theme
   A <fieldset> of 4 native radios (system | light | dark | hc).
   Works partially without JS (radios are focusable/announced); JS persists
   the choice to <html data-theme> + localStorage. Tokens-only, logical props.
   ========================================================================= */

.ewa-theme {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin: 0;
  padding: var(--space-3);
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-md);
  background-color: var(--bg-elevated);
  color: var(--text);
}

.ewa-theme__legend {
  /* Rendered as part of the inline group rather than a floating legend. */
  float: none;
  width: auto;
  margin-inline-end: var(--space-2);
  padding: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-muted);
}

/* Each option is a label wrapping its radio → the whole pill is the target. */
.ewa-theme__option {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--target-min);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-pill);
  background-color: var(--bg);
  color: var(--text);
  font-size: var(--text-sm);
  line-height: var(--leading-tight);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard);
}

.ewa-theme__option:hover {
  background-color: var(--bg-subtle);
  border-color: var(--text-muted);
}

/* The native radio stays visible (real control, robust for SR + no-JS). */
.ewa-theme__radio {
  inline-size: 1rem;
  block-size: 1rem;
  margin: 0;
  accent-color: var(--color-brand-text);
  flex: 0 0 auto;
}

/* Icon + text label — color is never the only signal for the checked state. */
.ewa-theme__icon {
  flex: 0 0 auto;
  inline-size: 1rem;
  block-size: 1rem;
}

.ewa-theme__text {
  white-space: nowrap;
}

/* Checked option gets a filled, bordered pill (icon + radio dot also signal). */
.ewa-theme__option:has(.ewa-theme__radio:checked) {
  background-color: var(--surface-sunken);
  border-color: var(--color-brand-text);
  font-weight: var(--weight-semibold);
}

/* Keyboard focus moves to the radio; mirror the ring onto the whole pill so
   the hit area reads as focused. Transparent outline survives Forced Colors. */
.ewa-theme__option:has(.ewa-theme__radio:focus-visible) {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: var(--focus-offset);
}

/* -------------------------------------------------------------------------
   Forced colors (Windows High Contrast): backgrounds are dropped by the OS,
   so lean on borders + system keywords to keep the checked state visible.
   ------------------------------------------------------------------------- */
@media (forced-colors: active) {
  .ewa-theme {
    border-color: CanvasText;
  }
  .ewa-theme__option {
    border-color: ButtonText;
  }
  .ewa-theme__option:has(.ewa-theme__radio:checked) {
    border-color: Highlight;
    outline: var(--border-2) solid Highlight;
    outline-offset: calc(-1 * var(--border-2));
  }
  .ewa-theme__icon {
    /* Let glyph strokes adopt the system text color. */
    forced-color-adjust: auto;
  }
}

/* -------------------------------------------------------------------------
   Reduced motion: drop the hover/checked transitions.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ewa-theme__option {
    transition: none;
  }
}

/* =========================================================================
   THEME SELECT — header combobox variant.
   A native <select> is the most robust "select-only combobox": full keyboard
   support, screen-reader-correct, and it degrades to a usable control. We only
   restyle the box + supply a custom chevron; the popup stays native.
   ========================================================================= */
.ewa-theme-select {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.ewa-theme-select__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
}
.ewa-theme-select__field {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.ewa-theme-select__input {
  min-block-size: var(--target-comfortable);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  padding-inline-end: var(--space-7); /* room for the chevron */
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  line-height: var(--leading-tight);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.ewa-theme-select__input:hover { background: var(--bg-subtle); border-color: var(--text-muted); }
/* Native options render in the OS popup — theme their colours where honoured. */
.ewa-theme-select__input option { background: var(--bg-elevated); color: var(--text); }
.ewa-theme-select__chevron {
  position: absolute;
  inset-inline-end: var(--space-2);
  inline-size: 1rem;
  block-size: 1rem;
  pointer-events: none;
  fill: none;
  stroke: var(--text-muted);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
@media (forced-colors: active) {
  .ewa-theme-select__input { border-color: ButtonText; }
  .ewa-theme-select__chevron { stroke: ButtonText; }
}

/* =========================================================================
   HEADER VARIANT — the site header uses bare <label> wrappers (no __option
   class), so make that compact + refined: a light, borderless group whose
   labels read as small selectable pills.
   ========================================================================= */
.site-header .ewa-theme {
  gap: var(--space-1);
  padding: var(--space-1);
  border: 0;
  background: transparent;
  margin-inline-start: auto; /* sit at the far inline-end of the header bar */
}
/* Hide the "Theme" legend visually (the pills are self-evident) but keep it as
   the fieldset's accessible name for screen readers — so the header stays
   compact and fits on one row. */
.site-header .ewa-theme > legend {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.site-header .ewa-theme > label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-block-size: var(--target-min);
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  color: var(--text-muted);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}
.site-header .ewa-theme > label:hover {
  background: var(--bg-subtle);
  color: var(--text);
}
.site-header .ewa-theme > label:has(input:checked) {
  background: var(--surface-sunken);
  color: var(--text);
  font-weight: var(--weight-semibold);
}
.site-header .ewa-theme > label:has(input:focus-visible) {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: var(--focus-offset);
}
.site-header .ewa-theme input[type="radio"] {
  accent-color: var(--color-brand-text);
}
@media (prefers-reduced-motion: reduce) {
  .site-header .ewa-theme > label { transition: none; }
}
@media (forced-colors: active) {
  .site-header .ewa-theme > label:has(input:checked) {
    outline: var(--border-2) solid Highlight;
    outline-offset: calc(-1 * var(--border-2));
  }
}


/* ==========================================================================
   ewa-compare — Do / Don't comparison
   Two columns: a recommended ("Do") and a discouraged ("Don't") pattern.
   Accent border uses --success / --danger tokens. Status is ALWAYS conveyed by
   an icon AND the literal word "Do" / "Don't" — never color alone (WCAG 1.4.1).
   Logical properties throughout for RTL (Israeli Std 5568). Forced-colors safe.
   ========================================================================== */

.ewa-compare {
  display: grid;
  grid-template-columns: 1fr;            /* 1 column on mobile */
  gap: var(--space-4);
  margin-block: var(--space-4);
}

@media (min-width: 48em) {                /* >= md → 2 columns */
  .ewa-compare {
    grid-template-columns: 1fr 1fr;
  }
}

.ewa-compare__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background-color: var(--bg-elevated);
  border: var(--border-1) solid var(--border);
  /* Accent edge — color is decorative reinforcement, not the sole signal. */
  border-inline-start-width: var(--border-2);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}

.ewa-compare__col--do {
  border-inline-start-color: var(--success-border);
}

.ewa-compare__col--dont {
  border-inline-start-color: var(--danger-border);
}

/* --- Heading: icon + the WORD ("Do" / "Don't") --------------------------- */
.ewa-compare__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  font-weight: var(--weight-bold);
  color: var(--text);
}

.ewa-compare__icon {
  flex: none;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  /* currentColor keeps the glyph visible in Forced Colors mode. */
  fill: currentColor;
}

.ewa-compare__col--do .ewa-compare__icon {
  color: var(--success-fg);
}

.ewa-compare__col--dont .ewa-compare__icon {
  color: var(--danger-fg);
}

/* The visible label word — required text signal alongside the icon. */
.ewa-compare__label {
  color: var(--text);
}

/* --- Body ----------------------------------------------------------------- */
.ewa-compare__body {
  margin: 0;
  color: var(--text);
  line-height: var(--leading-base);
  max-inline-size: var(--measure);
}

.ewa-compare__body > :last-child {
  margin-block-end: 0;
}

/* Any standalone control inside a column meets the target floor. */
.ewa-compare__body .ewa-btn {
  min-block-size: var(--target-comfortable);
}

/* --- Forced colors -------------------------------------------------------- */
@media (forced-colors: active) {
  .ewa-compare__col {
    border: var(--border-1) solid CanvasText;
    /* Reassert the accent edge with a system color so it survives. */
    border-inline-start-width: var(--border-2);
  }
  .ewa-compare__col--do {
    border-inline-start-color: CanvasText;
  }
  .ewa-compare__col--dont {
    border-inline-start-color: CanvasText;
  }
  .ewa-compare__icon {
    color: CanvasText;
  }
}


/* =========================================================================
   issue-card.css — .ewa-issue (the key teaching component)
   Scope: ONLY the wrapper / head / body of the issue card.
   It COMPOSES other components which bring their own styles:
     - .ewa-tabs  (Bad / Good / Code)   → tabs.css
     - .ewa-badge (mapped standards)    → badge.css
     - .ewa-callout--tip (How to fix)   → callout.css
     - .ewa-code  (escaped bad markup)  → code.css
   Tokens-only, logical properties only, no hardcoded hex. See contract.
   ========================================================================= */

/* ---- Block: the article -------------------------------------------- */
.ewa-issue {
  display: block;
  background: var(--bg-elevated);
  color: var(--text);
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  /* a quiet brand edge so a stack of cards reads as discrete teaching units */
  border-inline-start: var(--space-1) solid var(--color-brand);
  overflow: clip; /* keep rounded corners over composed children */
}

.ewa-issue + .ewa-issue {
  margin-block-start: var(--space-6);
}

/* ---- Element: head (title + mapped-standard badges) ---------------- */
.ewa-issue__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  background: var(--bg-subtle);
  border-block-end: var(--border-1) solid var(--border);
}

.ewa-issue__title {
  /* h3 lives in base.css; neutralise its default vertical rhythm here */
  margin-block: 0;
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  color: var(--text);
}

/* Badge row. Uses the shared .cluster utility for wrapping; this only
   tunes the gap and keeps the group from stretching the head. */
.ewa-issue__badges {
  --gap: var(--space-2);
  flex: 1 1 auto;
  justify-content: flex-end;
}

/* ---- Element: body (problem statement + tabs + fix callout) -------- */
.ewa-issue__body {
  padding: var(--space-5);
}

/* Vertical rhythm between the composed blocks inside the body without
   reaching into their internals. */
.ewa-issue__body > * + * {
  margin-block-start: var(--space-5);
}

/* The lede / problem statement sits at a readable measure. */
.ewa-issue__problem {
  max-width: var(--measure);
  margin-block: 0;
  color: var(--text);
}

/* The isolated bad-demo region (utility .u-demo-region styles the frame).
   We only add a small "demonstration only" caption affordance + spacing so
   the inaccessible markup reads as quarantined, never as a real control set. */
.ewa-issue .u-demo-region {
  margin-block: 0;
}

.ewa-issue__demo-note {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--warning-fg);
}

/* status is never colour-alone: an icon glyph rides next to the label */
.ewa-issue__demo-note::before {
  content: "";
  flex: none;
  inline-size: var(--space-4);
  block-size: var(--space-4);
  background: currentColor;
  /* warning triangle, drawn with a mask so it inherits the token colour */
  -webkit-mask: var(--ewa-issue-warn-icon) center / contain no-repeat;
          mask: var(--ewa-issue-warn-icon) center / contain no-repeat;
}

.ewa-issue {
  --ewa-issue-warn-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2 1 21h22L12 2Zm0 6a1 1 0 0 1 1 1v5a1 1 0 0 1-2 0V9a1 1 0 0 1 1-1Zm0 9a1.2 1.2 0 1 1 0 2.4 1.2 1.2 0 0 1 0-2.4Z'/%3E%3C/svg%3E");
}

/* =========================================================================
   Forced colors (Windows High Contrast): box-shadow + tinted surfaces are
   dropped, so re-assert structural boundaries with system colour keywords
   and keep the brand edge visible as a real border.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-issue {
    border: var(--border-1) solid CanvasText;
    border-inline-start: var(--space-1) solid CanvasText;
  }
  .ewa-issue__head {
    border-block-end: var(--border-1) solid CanvasText;
  }
  .ewa-issue__demo-note {
    color: CanvasText;
  }
  .ewa-issue__demo-note::before {
    background: CanvasText; /* the mask still cuts the glyph shape */
  }
}

/* =========================================================================
   Reduced motion: this component has no essential motion of its own, but be
   explicit so any inherited transition is neutralised on the card surface.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-issue,
  .ewa-issue * {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}


/* =========================================================================
   dialog.css — styling for the NATIVE <dialog> element (modal pattern).
   Targets the [data-dialog] dialog opened via showModal() and its ::backdrop.

   Accessibility / robustness:
     - Logical properties only (inline/block) so it flips for RTL/Hebrew.
     - Consumes SEMANTIC tokens — no hardcoded colors.
     - Forced-colors: keep a visible boundary; the OS supplies the backdrop.
     - Reduced-motion: the entrance transition is opt-in and suppressed.
   The dialog only becomes a centered overlay once showModal() promotes it to
   the top layer; with JS off it stays an in-flow, visible region (the
   acceptable fallback), so we don't force display:none here.
   ========================================================================= */

.ewa-dialog[data-dialog] {
  max-inline-size: min(32rem, calc(100vw - 2 * var(--space-4)));
  inline-size: 100%;
  margin: auto; /* centers in the top layer */
  padding: var(--space-5);
  color: var(--text);
  background-color: var(--bg-elevated);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

/* Tidy the flow of authored content inside the dialog. */
.ewa-dialog[data-dialog] > :first-child { margin-block-start: 0; }
.ewa-dialog[data-dialog] > :last-child { margin-block-end: 0; }

/* Semi-transparent dark scrim behind the modal. ::backdrop only exists while
   the dialog is open via showModal(), so this never affects the fallback. */
.ewa-dialog[data-dialog]::backdrop {
  background-color: rgba(17, 24, 28, 0.55);
}

/* ---- Motion — opt-in entrance, gated by reduced-motion ------------------ */
@media (prefers-reduced-motion: no-preference) {
  .ewa-dialog[data-dialog][open] {
    animation: ewa-dialog-in 160ms ease-out;
  }
  .ewa-dialog[data-dialog][open]::backdrop {
    animation: ewa-dialog-backdrop-in 160ms ease-out;
  }
}

@keyframes ewa-dialog-in {
  from { opacity: 0; transform: translateY(var(--space-2)); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes ewa-dialog-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* =========================================================================
   FORCED COLORS — the tinted scrim and shadow are dropped by the OS palette,
   so guarantee the dialog keeps a perceivable boundary against the page.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-dialog[data-dialog] {
    border: var(--border-2) solid CanvasText;
  }
}


/* =========================================================================
   tooltip.css — WAI-ARIA APG tooltip for EqualWeb Academy
   A small text bubble that supplements a control's visible label. It is
   text-only and non-interactive — never the control's ONLY accessible name.

   Structure:
     .ewa-tooltip            positioning context around the trigger
       <button> …            the real, focusable trigger (aria-describedby)
       .ewa-tooltip__bubble  role="tooltip" element, [hidden] by default

   Behaviour:
     - JS (tooltip.js) toggles [hidden] on focus/hover, keeps it visible while
       the pointer is over trigger OR bubble (WCAG 1.4.13 hoverable), and hides
       it on Escape (1.4.13 dismissible).
     - This file also reveals the bubble on :hover / :focus-within purely in
       CSS so the pattern still works with JavaScript OFF.

   Consumes SEMANTIC tokens only · logical properties only (RTL-safe) ·
   forced-colors + reduced-motion safe.
   ========================================================================= */

/* Bordered stage that frames a live pattern demo on a docs page. Generic
   enough to host any pattern's demo; lives here so the tooltip page has a
   defined wrapper to reference. */
.ewa-demo {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-md);
  background-color: var(--bg-subtle);
  padding: var(--space-5);
  margin-block: 0 var(--space-4);
}

.ewa-tooltip {
  position: relative;
  display: inline-block;
}

.ewa-tooltip__bubble {
  /* take it out of flow, anchored just above the trigger's inline-start edge */
  position: absolute;
  inset-block-end: calc(100% + var(--space-2));
  inset-inline-start: 0;

  /* sit above surrounding content */
  z-index: var(--z-overlay);

  /* keep long hints from stretching across the viewport */
  max-inline-size: 16rem;
  inline-size: max-content;

  /* surface look — elevated card with a soft border + shadow */
  background-color: var(--bg-elevated);
  color: var(--text);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);

  /* small, readable body text */
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  text-align: start;

  /* a tooltip never traps the pointer or gets selected as content */
  white-space: normal;

  /* gentle fade-in; stripped under reduced-motion below */
  transition: opacity var(--duration-fast) var(--easing-standard);
}

/* The hidden contract: when [hidden] is present the bubble is gone for
   everyone (visually + a11y tree). Beat any display from utilities. */
.ewa-tooltip__bubble[hidden] {
  display: none;
}

/* =========================================================================
   NO-JS FALLBACK — reveal on pointer hover or keyboard focus purely in CSS.
   :focus-within covers focusing the trigger; :hover covers the pointer. The
   JS enhancement layers dismiss/hoverable behaviour on top of this.
   ========================================================================= */
.ewa-tooltip:hover .ewa-tooltip__bubble,
.ewa-tooltip:focus-within .ewa-tooltip__bubble {
  display: block;
}

/* =========================================================================
   FORCED COLORS — the shadow + tinted surface are dropped by the OS palette,
   so guarantee a visible boundary with a system-color border.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-tooltip__bubble {
    border: var(--border-1) solid CanvasText;
    box-shadow: none;
  }
}

/* =========================================================================
   REDUCED MOTION — drop the fade so the bubble appears instantly.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-tooltip__bubble {
    transition: none;
  }
}


/* =========================================================================
   combobox.css — editable combobox / autocomplete for EqualWeb Academy
   Pattern: WAI-ARIA APG combobox with list autocomplete.

   Block:  .ewa-combobox            (position anchor for the popup)
   Parts:  .ewa-combobox__input     (the <input role="combobox">, composes
                                      .ewa-input from form.css)
           .ewa-combobox__listbox   (the popup <ul role="listbox">)
           .ewa-combobox__option    (each <li role="option">)

   Accessibility contract honored here:
     - DOM focus never leaves the input; the active option is shown with
       .is-active (driven by aria-activedescendant in combobox.js), so the
       selection cue is a real background, not just an outline.
     - The active-option cue is NOT color-only: it pairs a token background
       with a leading accent bar so it survives forced-colors / mono themes.
     - [hidden] fully hides the popup; the popup is never keyboard-focusable
       (no tabindex) — arrow keys move aria-activedescendant on the input.
     - Disabled "no matches" row is muted and inert (aria-disabled).
     - Logical properties only (RTL-safe); >=24px option rows; tokens only.
   ========================================================================= */

/* ---- Anchor: lets the popup position against the input ---------------- */
.ewa-combobox {
  position: relative;
  max-inline-size: 24rem;
}

/* The input composes .ewa-input; we only need to guarantee full width so the
   popup edges line up with the field. */
.ewa-combobox__input {
  inline-size: 100%;
}

/* ---- Popup listbox ---------------------------------------------------- */
.ewa-combobox__listbox {
  /* float over following content, anchored to the field's inline-start edge */
  position: absolute;
  inset-block-start: calc(100% + var(--space-1));
  inset-inline: 0;
  z-index: var(--z-sticky);

  margin: 0;
  padding-block: var(--space-1);
  padding-inline: 0;
  list-style: none;

  max-block-size: 16rem;
  overflow-y: auto;
  overscroll-behavior: contain;

  background-color: var(--bg-elevated);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}

/* The native `hidden` attribute closes the popup — keep it authoritative even
   if a utility sets display on the list. */
.ewa-combobox__listbox[hidden] {
  display: none;
}

/* ---- Option rows ------------------------------------------------------ */
.ewa-combobox__option {
  /* a leading accent slot (rendered by ::before) sits in this start padding */
  position: relative;
  min-block-size: var(--target-min); /* >= 24px row (SC 2.5.8) */
  display: flex;
  align-items: center;
  padding-block: var(--space-2);
  padding-inline: var(--space-4);
  color: var(--text);
  line-height: var(--leading-snug);
  cursor: pointer;
}

/* Pointer affordance — hover is not a selection state, just a hint. */
@media (hover: hover) {
  .ewa-combobox__option:hover {
    background-color: var(--bg-subtle);
  }
}

/* Active option (aria-activedescendant target). Color is NOT the only signal:
   a leading accent bar reinforces the highlighted row. The brand-text token
   keeps the label readable on the tinted background in every theme. */
.ewa-combobox__option.is-active {
  background-color: var(--bg-subtle);
  color: var(--color-brand-text);
  font-weight: var(--weight-medium);
}
.ewa-combobox__option.is-active::before {
  content: "";
  position: absolute;
  inset-block: var(--space-1);
  inset-inline-start: 0;
  inline-size: var(--space-1);
  border-start-end-radius: var(--radius-pill);
  border-end-end-radius: var(--radius-pill);
  background-color: var(--color-brand);
}

/* Inert "No matches" row — muted, not hoverable, never the active descendant. */
.ewa-combobox__option[aria-disabled="true"] {
  color: var(--text-muted);
  cursor: default;
  font-style: italic;
}
@media (hover: hover) {
  .ewa-combobox__option[aria-disabled="true"]:hover {
    background-color: transparent;
  }
}

/* JS hides filtered-out options with the native `hidden` attribute. */
.ewa-combobox__option[hidden] {
  display: none;
}

/* =========================================================================
   FORCED COLORS (Windows High Contrast) — token backgrounds are dropped, so
   the active row must use the system Highlight pair to stay perceivable, and
   the popup must keep a visible boundary.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-combobox__listbox {
    border-color: CanvasText;
  }
  .ewa-combobox__option.is-active {
    background-color: Highlight;
    color: HighlightText;
    forced-color-adjust: none;
  }
  .ewa-combobox__option.is-active::before {
    background-color: HighlightText;
  }
  .ewa-combobox__option[aria-disabled="true"] {
    color: GrayText;
  }
}

/* =========================================================================
   REDUCED MOTION — the popup has no essential animation, but be explicit so
   any inherited scroll/transition is dropped when the user asks for less.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-combobox__listbox {
    scroll-behavior: auto;
  }
}


/* =========================================================================
   menu.css — .ewa-menu actions menu (WAI-ARIA APG "Menu Button" pattern)
   A button (aria-haspopup) opens a role="menu" list of ACTIONS (commands),
   NOT a navigation list. JS (menu-button.js) drives open/close + roving focus.

   Accessibility:
     - Roving tabindex: only the active menuitem is focusable; JS calls
       .focus() on it. The list never enters the page tab order.
     - The focused item's state never rides on color alone — it pairs a token
       background with the global :focus-visible ring (base.css), and in
       forced-colors mode it uses Highlight / HighlightText.
     - Logical properties only (RTL/Hebrew safe).
     - Reduced-motion: no essential motion; transitions stripped.
   Consumes SEMANTIC tokens only — no hardcoded colors.
   ========================================================================= */

.ewa-menu {
  position: relative;
  display: inline-block;
}

/* The popup list ------------------------------------------------------------
   Absolutely positioned under the trigger, raised above page content. */
.ewa-menu__list {
  position: absolute;
  inset-block-start: calc(100% + var(--space-1));
  inset-inline-start: 0;
  z-index: var(--z-overlay);

  margin: 0;
  padding-block: var(--space-1);
  padding-inline: 0;
  list-style: none;

  min-inline-size: 12rem;
  background-color: var(--bg-elevated);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}

/* [hidden] must win even with display:absolute above. */
.ewa-menu__list[hidden] {
  display: none;
}

/* Menu items ---------------------------------------------------------------- */
.ewa-menu__item {
  display: flex;
  align-items: center;

  /* comfortable target: padding + min-block-size reaches 44px */
  min-block-size: var(--target-comfortable);
  padding-block: var(--space-2);
  padding-inline: var(--space-4);

  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-snug);
  cursor: pointer;
  user-select: none;

  transition: background-color var(--duration-fast) var(--easing-standard);
}

/* Hover + the roving-focused item share a clear, high-contrast background.
   The global :focus-visible ring (base.css) also paints around the item. */
.ewa-menu__item:hover,
.ewa-menu__item:focus,
.ewa-menu__item:focus-visible {
  background-color: var(--bg-subtle);
  color: var(--text);
  outline-offset: -2px; /* keep the ring inside the rounded popup */
}

.ewa-menu__item:active {
  background-color: var(--surface-sunken);
}

/* =========================================================================
   FORCED COLORS — background is dropped, so the focused/hovered item must
   re-acquire a visible selection using system colors. forced-color-adjust
   lets us paint Highlight/HighlightText for the active item.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-menu__list {
    border-color: CanvasText;
  }
  .ewa-menu__item:hover,
  .ewa-menu__item:focus,
  .ewa-menu__item:focus-visible {
    forced-color-adjust: none;
    background-color: Highlight;
    color: HighlightText;
  }
}

/* =========================================================================
   REDUCED MOTION — strip the background transition. (Global net exists;
   explicit here for this interactive control.)
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-menu__item {
    transition: none;
  }
}


/* =========================================================================
   glossary.css — definition-list layout for the accessibility glossary.
   Markup: <dl class="ewa-glossary"> with each term/definition pair wrapped in
   a .ewa-glossary__item <div> (valid in the HTML living standard, and the
   wrapper is what catalog-filter.js shows/hides).

   Logical properties + semantic tokens only, so it flips correctly for RTL.
   ========================================================================= */

.ewa-glossary {
  margin-block: var(--space-4) 0;
}

.ewa-glossary__item {
  margin-block-end: var(--space-4);
}

.ewa-glossary__item:last-child {
  margin-block-end: 0;
}

.ewa-glossary dt {
  font-weight: var(--weight-bold);
  color: var(--text);
}

.ewa-glossary dd {
  margin-block-start: var(--space-1);
  margin-inline-start: var(--space-4);
  color: var(--text);
}


/* =========================================================================
   pager.css — Previous / next lesson pager for EqualWeb Academy
   .ewa-pager (flex row), .ewa-pager__link (+ --prev / --next),
   parts: .ewa-pager__dir (muted eyebrow), .ewa-pager__title

   Accessibility:
     - Wrapped in a <nav aria-label="Lesson navigation"> by the author.
     - Logical properties only, so it flips correctly for RTL/Hebrew.
     - Forced-colors keeps a visible boundary (CanvasText) and a perceivable
       hover/focus (Highlight).
     - Reduced-motion safe: the only transition is disabled below.
   Consumes SEMANTIC tokens only — no hardcoded colors.
   ========================================================================= */

.ewa-pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3);
  margin-block-start: var(--space-8);
  padding-block-start: var(--space-5);
  border-block-start: var(--border-1) solid var(--border);
}

/* ---- Link ---------------------------------------------------------------- */

.ewa-pager__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1 1 14rem;

  color: var(--text);
  background-color: var(--bg-elevated);
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-md);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  text-decoration: none;

  transition: border-color 120ms ease;
}

.ewa-pager__link:hover {
  border-color: var(--color-brand);
}

/* The next link reads right-to-left of meaning: align its text to the end. */
.ewa-pager__link--next {
  text-align: end;
}

/* ---- Parts --------------------------------------------------------------- */

.ewa-pager__dir {
  display: block;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.ewa-pager__title {
  display: block;
  font-weight: var(--weight-bold);
}

/* =========================================================================
   FORCED COLORS — keep a visible boundary and a perceivable hover/focus.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-pager__link {
    border: var(--border-1) solid CanvasText;
  }
  .ewa-pager__link:hover,
  .ewa-pager__link:focus-visible {
    border-color: Highlight;
  }
}

/* =========================================================================
   REDUCED MOTION — drop the hover transition.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-pager__link {
    transition: none;
  }
}


/* =========================================================================
   nav-menu.css — navigation menu (disclosure) for EqualWeb Academy
   Pattern: WAI-ARIA APG disclosure navigation menu (correct for SITE nav).

   Block:  .ewa-navmenu              (the <nav> landmark)
   Parts:  .ewa-navmenu__list        (top-level <ul> of items)
           .ewa-navmenu__link        (a plain top-level <a>)
           .ewa-navmenu__toggle       (the dropdown <button>, aria-expanded)
           .ewa-navmenu__submenu      (the disclosed <ul>, [hidden] when closed)

   Accessibility contract honored here:
     - The control is a real <button>; its non-text boundary keeps >= 3:1
       contrast against the surrounding surface (token border), and the open
       state is conveyed by a rotated caret AND aria-expanded — never colour
       alone.
     - [hidden] fully closes the submenu. With JS off the document is not
       .js, so authored-hidden submenus are revealed (links stay reachable).
     - Logical properties only (RTL-safe); visible :focus-visible rings come
       from base.css; forced-colors uses the system palette; motion is gated
       on prefers-reduced-motion.
   ========================================================================= */

/* ---- Landmark + top-level list --------------------------------------- */
.ewa-navmenu {
  --navmenu-gap: var(--space-1);
}

.ewa-navmenu__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--navmenu-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The dropdown item anchors its submenu. */
.ewa-navmenu__list > li {
  position: relative;
}

/* ---- Shared look for links and the toggle ---------------------------- */
.ewa-navmenu__link,
.ewa-navmenu__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);

  /* >= 24px target with comfortable padding via logical properties. */
  min-block-size: 2.75rem;
  padding-block: var(--space-2);
  padding-inline: var(--space-3);

  color: var(--text);
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;

  border: var(--border-1) solid transparent;
  border-radius: var(--radius-md);
  background-color: transparent;
}

.ewa-navmenu__link:hover,
.ewa-navmenu__toggle:hover {
  background-color: var(--bg-subtle);
}

/* ---- The disclosure toggle ------------------------------------------- */
.ewa-navmenu__toggle {
  /* A real, hit-testable control boundary: token border keeps >= 3:1 non-text
     contrast against both light and dark surfaces. */
  border-color: var(--border-strong);
  cursor: pointer;
}

/* Caret: rotates on open. This is a SECOND, non-colour cue paired with
   aria-expanded, so open state is never colour-only. */
.ewa-navmenu__toggle::after {
  content: "";
  inline-size: 0.5rem;
  block-size: 0.5rem;
  border-inline-end: var(--border-2) solid currentColor;
  border-block-end: var(--border-2) solid currentColor;
  transform: rotate(45deg);
  transform-origin: center;
  transition: transform 150ms ease;
}

.ewa-navmenu__toggle[aria-expanded="true"]::after {
  transform: rotate(-135deg);
}

/* ---- Submenu (the disclosed list) ------------------------------------ */
.ewa-navmenu__submenu {
  position: absolute;
  inset-block-start: calc(100% + var(--space-1));
  inset-inline-start: 0;
  z-index: var(--z-sticky);

  min-inline-size: 12rem;
  margin: 0;
  padding-block: var(--space-1);
  padding-inline: 0;
  list-style: none;

  background-color: var(--bg-elevated);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}

/* The native [hidden] attribute closes the submenu — keep it authoritative
   even if a utility sets display on the list. */
.ewa-navmenu__submenu[hidden] {
  display: none;
}

/* GRACEFUL DEGRADATION: with scripting off the toggle can't manage state, so
   reveal any authored-hidden submenu and let it sit in normal flow. Every link
   stays reachable. The .no-js / .js switch is set on <html> before paint. */
.no-js .ewa-navmenu__submenu[hidden] {
  display: block;
  position: static;
  box-shadow: none;
}

.ewa-navmenu__submenu > li {
  margin: 0;
}

.ewa-navmenu__submenu a {
  display: block;
  min-block-size: 2.75rem;
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  color: var(--text);
  font-weight: 500;
  text-decoration: none;
}

.ewa-navmenu__submenu a:hover {
  background-color: var(--bg-subtle);
}

/* =========================================================================
   FORCED COLORS (Windows High Contrast) — token colours are dropped, so pin
   the control boundary and submenu edge to system colours and keep the caret
   visible.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-navmenu__toggle {
    border-color: ButtonText;
  }
  .ewa-navmenu__toggle::after {
    border-color: ButtonText;
  }
  .ewa-navmenu__submenu {
    border-color: CanvasText;
    background-color: Canvas;
  }
  .ewa-navmenu__link:hover,
  .ewa-navmenu__toggle:hover,
  .ewa-navmenu__submenu a:hover {
    background-color: Highlight;
    color: HighlightText;
    forced-color-adjust: none;
  }
}

/* =========================================================================
   REDUCED MOTION — drop the caret rotation transition when less motion is
   requested; the rotated end-state still conveys open/closed.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-navmenu__toggle::after {
    transition: none;
  }
}


/* =========================================================================
   switch.css — on/off switch for EqualWeb Academy
   Pattern: WAI-ARIA APG switch.

   Block:  .ewa-switch              (the <button role="switch">)
   Parts:  .ewa-switch__text        (visible label text, sits beside the track)
           .ewa-switch__track       (the pill the thumb slides within)
           .ewa-switch__thumb        (the moving knob)
           .ewa-switch__state        (on/off WORD — state is never colour-only)

   Accessibility contract honored here:
     - The control is a real <button>, so Space/Enter and focus come for free.
     - On/off is conveyed by MORE than thumb position: a visible "On/Off" word
       (.ewa-switch__state) changes too, so the state is never colour-only.
     - :focus-visible draws a clear outline; the track keeps a >=3:1 non-text
       border against its surroundings in both states.
     - Forced-colors: the track/thumb use system colours (ButtonText / Canvas /
       Highlight) so the on/off difference survives high-contrast themes.
     - Reduced-motion: the thumb jumps instead of sliding.
     - Logical properties only (RTL-safe); tokens only.
   ========================================================================= */

/* ---- Control: a button laid out as [ label  track  state ] ------------- */
.ewa-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);

  margin: 0;
  padding-block: var(--space-1);
  padding-inline: 0;

  background: none;
  border: 0;
  color: var(--text);
  font: inherit;
  text-align: start;
  cursor: pointer;
}

/* Visible label text tied to the control's accessible name. */
.ewa-switch__text {
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
}

/* ---- Track: the pill the thumb travels in ----------------------------- */
.ewa-switch__track {
  position: relative;
  flex: 0 0 auto;
  inline-size: 3rem;
  block-size: 1.625rem;

  border: var(--border-2) solid var(--border-strong);
  border-radius: var(--radius-pill);
  background-color: var(--bg-subtle);

  transition: background-color var(--duration-fast, 150ms) ease,
    border-color var(--duration-fast, 150ms) ease;
}

/* ---- Thumb: the moving knob ------------------------------------------- */
.ewa-switch__thumb {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: var(--space-1);
  inline-size: 1.125rem;
  block-size: 1.125rem;

  border-radius: var(--radius-pill);
  background-color: var(--text);
  transform: translateY(-50%);

  transition: inset-inline-start var(--duration-fast, 150ms) ease,
    background-color var(--duration-fast, 150ms) ease;
}

/* ---- ON state (aria-checked="true") ----------------------------------- */
/* The track fills with brand colour AND the thumb slides to the end AND the
   adjacent state word flips to "On" — three independent cues, not colour only. */
.ewa-switch[aria-checked="true"] .ewa-switch__track {
  background-color: var(--color-brand);
  border-color: var(--color-brand);
}
.ewa-switch[aria-checked="true"] .ewa-switch__thumb {
  inset-inline-start: calc(100% - 1.125rem - var(--space-1));
  background-color: var(--text-on-brand);
}

/* ---- State word — the non-visual-position cue ------------------------- */
.ewa-switch__state {
  min-inline-size: 2ch;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-medium);
}
.ewa-switch[aria-checked="true"] .ewa-switch__state {
  color: var(--color-brand-text);
}

/* ---- Focus ------------------------------------------------------------ */
.ewa-switch:focus-visible {
  outline: none;
}
.ewa-switch:focus-visible .ewa-switch__track {
  outline: var(--border-2) solid var(--color-focus, var(--color-brand));
  outline-offset: var(--space-1);
}

/* ---- Hover affordance (not a state) ----------------------------------- */
@media (hover: hover) {
  .ewa-switch:hover .ewa-switch__track {
    border-color: var(--color-brand);
  }
}

/* =========================================================================
   FORCED COLORS (Windows High Contrast) — token fills are dropped, so the
   on/off difference must ride on system colours: an "off" track is hollow
   (Canvas) and an "on" track is filled (Highlight).
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-switch__track {
    border-color: ButtonText;
    background-color: Canvas;
    forced-color-adjust: none;
  }
  .ewa-switch__thumb {
    background-color: ButtonText;
  }
  .ewa-switch[aria-checked="true"] .ewa-switch__track {
    background-color: Highlight;
    border-color: Highlight;
  }
  .ewa-switch[aria-checked="true"] .ewa-switch__thumb {
    background-color: HighlightText;
  }
  .ewa-switch:focus-visible .ewa-switch__track {
    outline-color: CanvasText;
  }
}

/* =========================================================================
   REDUCED MOTION — the thumb jumps to its position instead of sliding.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-switch__track,
  .ewa-switch__thumb {
    transition: none;
  }
}


/* =========================================================================
   checkbox.css — custom (ARIA) checkbox widget for EqualWeb Academy
   Pattern: WAI-ARIA APG checkbox.

   Block:  .ewa-check   (a <span role="checkbox" tabindex="0" aria-checked>)

   PREFER a native <input type="checkbox">. This widget is ONLY for the rare
   case where the native control genuinely cannot be styled, and it must then
   replicate ALL of the native behaviour (focus, toggle, name, state).

   Accessibility contract honored here:
     - State is NEVER color-only: aria-checked drives a drawn tick mark, so the
       checked/unchecked difference is a shape, not just a fill.
     - Non-text contrast: the box border and the tick read >= 3:1 against the
       page (SC 1.4.11) via --border-strong / brand tokens.
     - Visible :focus-visible ring (inherits the global ring in base.css; we
       only round the focus box to the control).
     - Forced-colors safe: box + tick remap to system colours
       (ButtonText / Highlight / Canvas) so the state survives high contrast.
     - Reduced-motion safe: the tick reveal has no essential animation.
     - Logical properties only (RTL-safe); >= 24px target (SC 2.5.8).
   ========================================================================= */

/* ---- Row layout: aligns a checkbox with its visible label ------------- */
.ewa-checkbox-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-block: 0;
  cursor: pointer;
}

/* ---- The control: a styled box that draws its own tick ---------------- */
.ewa-check {
  /* sit inline with its label */
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;

  inline-size: var(--target-min);   /* >= 24px hit + paint area (SC 2.5.8) */
  block-size: var(--target-min);
  vertical-align: middle;

  border: var(--border-2, 2px) solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--bg-elevated);
  color: var(--text-on-brand);      /* colour of the tick when on a fill */

  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}

/* Round the global focus ring to the control. */
.ewa-check:focus-visible {
  border-radius: var(--radius-sm);
}

/* Pointer affordance only — hover is a hint, not a state. */
@media (hover: hover) {
  .ewa-check:hover {
    border-color: var(--color-brand-text);
  }
}

/* ---- The tick (drawn, not a font glyph) -------------------------------
   Always present in the DOM as a child-less ::before so the box can size to
   it; visibility is toggled purely by aria-checked, never by colour alone. */
.ewa-check::before {
  content: "";
  inline-size: 0.625em;
  block-size: 0.375em;
  /* a check mark = the two trailing sides of a box, rotated */
  border-inline-start: var(--border-2, 2px) solid currentColor;
  border-block-end: var(--border-2, 2px) solid currentColor;
  /* nudge up slightly, then rotate the corner into a check mark */
  transform: translateY(-0.08em) rotate(-45deg);
  /* hidden until checked */
  opacity: 0;
}

/* ---- Checked state: fill the box and reveal the tick ------------------- */
.ewa-check[aria-checked="true"] {
  background-color: var(--color-brand);
  border-color: var(--color-brand);
}
.ewa-check[aria-checked="true"]::before {
  opacity: 1;
}

/* ---- Disabled (optional, mirrors native [disabled]) ------------------- */
.ewa-check[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
}

/* =========================================================================
   FORCED COLORS (Windows High Contrast) — token fills are dropped, so map the
   box and tick onto system colours and keep them perceivable.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-check {
    border-color: ButtonText;
    background-color: Canvas;
    color: ButtonText;
    forced-color-adjust: none;
  }
  .ewa-check:focus-visible {
    outline-color: Highlight;
  }
  .ewa-check[aria-checked="true"] {
    background-color: Highlight;
    border-color: Highlight;
  }
  .ewa-check[aria-checked="true"]::before {
    /* tick must contrast the Highlight fill */
    border-color: HighlightText;
  }
  .ewa-check[aria-disabled="true"] {
    opacity: 1;
    border-color: GrayText;
    color: GrayText;
  }
}

/* =========================================================================
   REDUCED MOTION — the tick reveal is instant by design; be explicit so any
   inherited transition is dropped when the user asks for less.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-check,
  .ewa-check::before {
    transition: none;
  }
}


/* =========================================================================
   radio.css — custom radio group for EqualWeb Academy
   Pattern: WAI-ARIA APG radio group (role="radiogroup" + role="radio").

   Block:  .ewa-radiogroup           (the role="radiogroup" container)
   Parts:  .ewa-radiogroup__label    (visible group name, aria-labelledby target)
           .ewa-radiogroup__options  (vertical stack of options)
           .ewa-radio                (each role="radio" option)

   Accessibility contract honored here:
     - The checked state is NOT color-only: each option draws a real control
       (a ring + filled dot) that fills in when aria-checked="true", so the
       selection survives mono / forced-colors themes.
     - Non-text contrast: the control ring uses --border-strong and the
       checked fill uses --color-brand, both >= 3:1 against the surface.
     - The global :focus-visible ring from base.css is used as-is; we never
       set outline:none. (Roving tabindex means only one radio is tabbable.)
     - Logical properties only (RTL-safe); >=24px target rows; tokens only.
   ========================================================================= */

/* ---- Group container -------------------------------------------------- */
.ewa-radiogroup {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-inline-size: 28rem;
}

.ewa-radiogroup__label {
  display: block;
  font-weight: var(--weight-medium, 500);
  color: var(--text);
}

.ewa-radiogroup__options {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* ---- Option ----------------------------------------------------------- */
.ewa-radio {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--target-min); /* >= 24px target (SC 2.5.8) */
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border-radius: var(--radius-md);
  color: var(--text);
  line-height: var(--leading-snug);
  cursor: pointer;
  user-select: none;
}

/* The visual control: an outlined circle that gains a filled dot when checked.
   Drawn as a ::before so the checked cue is a shape change, not color alone. */
.ewa-radio::before {
  content: "";
  flex: 0 0 auto;
  inline-size: 1.125rem;
  block-size: 1.125rem;
  border: var(--border-2, 2px) solid var(--border-strong);
  border-radius: var(--radius-pill);
  background-color: var(--bg-elevated);
  /* the filled dot, hidden until checked, grown via a box-shadow inset */
  box-shadow: inset 0 0 0 0.5rem transparent;
}

@media (hover: hover) {
  .ewa-radio:hover {
    background-color: var(--bg-subtle);
  }
}

/* Checked: the control ring goes brand and the inner dot fills in. Two cues
   (ring color + a real filled dot) so the state is never color-only. */
.ewa-radio[aria-checked="true"]::before {
  border-color: var(--color-brand);
  box-shadow: inset 0 0 0 0.28rem var(--color-brand);
}

/* =========================================================================
   FORCED COLORS (Windows High Contrast) — token fills are dropped, so the
   control must be drawn with system colors. Use ButtonText for the ring and
   Highlight for the checked dot so the state stays perceivable.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-radio::before {
    border-color: ButtonText;
    background-color: Canvas;
    box-shadow: inset 0 0 0 0.5rem transparent;
    forced-color-adjust: none;
  }
  .ewa-radio[aria-checked="true"]::before {
    border-color: Highlight;
    box-shadow: inset 0 0 0 0.28rem Highlight;
  }
}

/* =========================================================================
   REDUCED MOTION — the control has no essential animation, but be explicit
   so any inherited transition on the fill is dropped when less is requested.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-radio,
  .ewa-radio::before {
    transition: none;
  }
}


/* =========================================================================
   slider.css — single-thumb horizontal slider for EqualWeb Academy
   Pattern: WAI-ARIA APG slider.

   Block:  .ewa-slider               (the widget wrapper)
   Parts:  .ewa-slider__track        (the rail the thumb travels along)
           .ewa-slider__fill         (filled portion from min to value)
           .ewa-slider__thumb        (<div role="slider" tabindex="0">)
           .ewa-slider__readout      (visible current-value text)

   Accessibility contract honored here:
     - The thumb is the focusable control; :focus-visible draws a real ring
       that becomes a system outline under forced colors.
     - Non-text contrast (SC 1.4.11): track, fill, and thumb each use tokens
       that clear 3:1 against their surroundings; under forced colors they
       remap to system colors (ButtonText / Highlight / Canvas).
     - State is never color-only: the thumb position and the text readout both
       convey the value, and the fill reinforces it.
     - Logical properties only (RTL-safe); reduced-motion safe.
   ========================================================================= */

.ewa-slider {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-inline-size: 28rem;
}

.ewa-slider__label {
  font-weight: var(--weight-medium);
  color: var(--text);
}

/* ---- Track: the rail the thumb travels along -------------------------- */
.ewa-slider__track {
  position: relative;
  inline-size: 100%;
  block-size: var(--space-2);
  margin-block: var(--space-4);
  background-color: var(--bg-subtle);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-pill);
}

/* Filled portion (min -> current value). Width set inline by slider.js. */
.ewa-slider__fill {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 0%;
  background-color: var(--color-brand);
  border-radius: var(--radius-pill);
}

/* ---- Thumb: the focusable role="slider" control ----------------------- */
.ewa-slider__thumb {
  position: absolute;
  inset-block-start: 50%;
  /* inset-inline-start (percentage) is set inline by slider.js */
  inset-inline-start: 0%;
  inline-size: var(--target-min);
  block-size: var(--target-min);
  translate: -50% -50%;

  background-color: var(--bg-elevated);
  border: var(--border-2) solid var(--color-brand);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  cursor: grab;
  touch-action: none;
}

.ewa-slider__thumb:active {
  cursor: grabbing;
}

/* Keyboard focus ring — relies on the global :focus-visible token style and
   reinforces it with offset so the ring clears the thumb border. */
.ewa-slider__thumb:focus-visible {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: var(--focus-offset);
}

/* ---- Visible value readout -------------------------------------------- */
.ewa-slider__readout {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
  color: var(--text);
}

/* =========================================================================
   FORCED COLORS (Windows High Contrast) — token fills are dropped, so the
   track, fill, and thumb must use system colors to stay perceivable.
   ========================================================================= */
@media (forced-colors: active) {
  .ewa-slider__track {
    border-color: ButtonText;
    background-color: Canvas;
  }
  .ewa-slider__fill {
    background-color: Highlight;
  }
  .ewa-slider__thumb {
    background-color: Canvas;
    border-color: ButtonText;
    forced-color-adjust: none;
  }
  .ewa-slider__thumb:focus-visible {
    outline-color: Highlight;
  }
}

/* =========================================================================
   REDUCED MOTION — the thumb has no essential animation; be explicit so any
   inherited transition on position is dropped when the user asks for less.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .ewa-slider__fill,
  .ewa-slider__thumb {
    transition: none;
  }
}
