/* ============================================================================
   IT-Husets Arkitekturprogram — Component Styles
   Hand-written CSS (ADR-002), tokens only — no hardcoded colors/sizes.
   Native controls + native <dialog>; Stimulus-enhanced where noted.
   Pairs with tokens.css. All interactive elements meet WCAG 2.1 AA.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   BASE / RESET
   --------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* The [hidden] attribute must win over component display rules (e.g. a flex
   overlay toggled by Stimulus). The UA default is too weak against inline
   display, so enforce it. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--ink);
  background: var(--surface-1);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background var(--transition), color var(--transition);
}

/* Staff-only S06 affordance. The wrapper exists only with the link, so
   anonymous/participant layouts reserve no space. */
.editorial-edit-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: 44px;
  padding: var(--space-2) var(--space-4);
  border: 1.5px dashed var(--border-strong);
  border-radius: 999px;
  background: var(--surface-1);
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}

.editorial-edit-link:hover { border-style: solid; color: var(--color-primary-ink); }
.editorial-edit-link:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.editorial-edit-link--corner { position: absolute; inset-block-start: var(--space-2); inset-inline-end: var(--space-2); z-index: 2; }
*:has(> .editorial-edit-link--corner) { position: relative; }
img, svg, video { max-width: 100%; display: block; }
hr { border: none; border-top: 1px solid var(--border); margin: var(--space-8) 0; }

/* Visible focus for keyboard users on every interactive element (WCAG 2.4.7) */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--color-primary-soft); color: var(--ink-strong); }

/* Skip-link — first focusable element; closes WCAG 2.4.1 on every page. */
.skip-link {
  position: absolute; left: var(--space-3); top: -120px; z-index: var(--z-toast);
  display: inline-flex; align-items: center; min-block-size: var(--tap);
  background: var(--color-primary); color: var(--ink-on-primary);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius);
  font-family: var(--font-heading); font-weight: var(--font-semibold); text-decoration: none;
  transition: top var(--transition);
}
.skip-link:focus { top: var(--space-3); }

/* Inline SVG <symbol> sprite holder — present in DOM, never displayed. */
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------------------------------------------------------------------------
   TYPOGRAPHY
   --------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  color: var(--ink-strong);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin: 0 0 var(--space-4);
  font-weight: var(--font-bold);
  overflow-wrap: break-word;
}
h1 { font-size: var(--text-5xl); }
h2 { font-size: var(--text-4xl); }
h3 { font-size: var(--text-3xl); }
h4 { font-size: var(--text-2xl); }
h5 { font-size: var(--text-xl); }
h6 { font-size: var(--text-lg); }

p { margin: 0 0 var(--space-4); }
a { color: var(--color-primary-ink); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--color-primary-hover); }

small, .text-sm { font-size: var(--text-sm); }
.text-xs { font-size: var(--text-xs); }

/* Display — for hero "ARKITEKTUR"-scale type. Uppercase + wide tracking, geometric. */
.display {
  font-family: var(--font-heading);
  font-size: var(--text-6xl);
  font-weight: var(--font-extrabold);
  line-height: 0.95;
  letter-spacing: var(--tracking-tight);
  color: var(--ink-strong);
  margin: 0 0 var(--space-6);
}
.eyebrow {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--color-primary-ink);
  margin: 0 0 var(--space-3);
}
.lead { font-size: var(--text-lg); color: var(--ink-muted); line-height: var(--leading-relaxed); }
.muted { color: var(--ink-muted); }
.mono { font-family: var(--font-mono); font-feature-settings: "tnum" 1; }
.text-gradient {
  background: var(--gradient-brand);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  /* inline-block + descender room so background-clip text never clips j/p/g. */
  display: inline-block; padding-bottom: 0.08em;
}

/* ---------------------------------------------------------------------------
   BUTTONS  (FR1 login CTA, FR3 "Rensa filter", FR4/FR5 CTAs, quiz submit …)
   --------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  line-height: 1;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--transition), border-color var(--transition),
              color var(--transition), transform var(--transition-fast), box-shadow var(--transition);
}
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 0.5; cursor: not-allowed; transform: none;
}

/* Anchor buttons keep their variant ink on hover. The generic `a:hover` rule
   (specificity 0,1,1) otherwise beats the class-level `.btn-*` color (0,1,0) and
   recolors the label to the link-hover gold — matching text to fill (invisible).
   The `:hover:not(:disabled)` selectors below are 0,3,0, so they win. */
.btn-primary {
  background: var(--color-primary);
  color: var(--ink-on-primary);
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover:not(:disabled) { background: var(--color-primary-hover); color: var(--ink-on-primary); box-shadow: var(--shadow-md); }

.btn-secondary {
  background: var(--color-secondary);
  color: var(--ink-on-secondary);
}
.btn-secondary:hover:not(:disabled) { filter: brightness(1.12); color: var(--ink-on-secondary); }

.btn-danger {
  background: var(--color-error-soft);
  color: var(--color-error);
  border-color: var(--color-error);
}
.btn-danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--color-error) 18%, var(--color-error-soft));
  border-color: var(--color-error);
  color: var(--color-error);
}

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--border-strong);
}
.btn-ghost:hover:not(:disabled) { background: var(--surface-4); border-color: var(--color-primary); color: var(--ink); }

.btn-sm { min-height: var(--tap-compact); padding: var(--space-2) var(--space-4); font-size: var(--text-sm); }
.btn-lg { min-height: 52px; padding: var(--space-4) var(--space-8); font-size: var(--text-lg); }
.btn-block { display: flex; width: 100%; }
.btn-icon {
  min-height: var(--space-8);
  min-inline-size: var(--space-8);
  padding: var(--space-1);
  border-radius: var(--radius-sm);
}
.btn-icon svg { inline-size: 1rem; block-size: 1rem; }

/* ---------------------------------------------------------------------------
   FORMS  (FR3 filters, FR10 profile, FR15 quiz radio/checkbox)
   --------------------------------------------------------------------------- */
.field { margin-bottom: var(--space-5); }
.label {
  display: block;
  font-weight: var(--font-semibold);
  font-size: var(--text-sm);
  color: var(--ink-strong);
  margin-bottom: var(--space-2);
}
.input, .select, .textarea {
  width: 100%;
  min-height: var(--tap);
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--ink);
  background: var(--surface-0);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  transition: border-color var(--transition), box-shadow var(--transition);
}
/* Single-line fields (text inputs + selects, both .input) lock to the 44px tap
   height so they align with buttons; `line-height: normal` otherwise pushed them
   to ~48px. .textarea keeps its own auto height (see below). */
.input { height: var(--tap); line-height: var(--leading-tight); }
/* Selects: strip the native widget (Safari's double-arrow stepper vs Chrome's
   single chevron differ in look and height) and draw one theme-aware caret so
   both browsers render an identical control. */
select.input, .select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: calc(var(--space-4) + 1.5rem);
  background-image: var(--field-caret);
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  background-size: 0.875rem;
}
select.input::-ms-expand, .select::-ms-expand { display: none; }
.textarea { min-height: 7rem; resize: vertical; line-height: var(--leading-normal); }
.input::placeholder, .textarea::placeholder { color: var(--ink-subtle); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.input:disabled, .select:disabled, .textarea:disabled { opacity: 0.55; cursor: not-allowed; }
.input[aria-invalid="true"], .textarea[aria-invalid="true"] {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px var(--color-error-soft);
}
.field-help { font-size: var(--text-sm); color: var(--ink-muted); margin-top: var(--space-2); }
.field-error { font-size: var(--text-sm); color: var(--color-error); margin-top: var(--space-2); font-weight: var(--font-semibold); }

/* HTMX pending state for live-filtered list fragments (admin toolbars swap the
   results section on input/change). Class-scoped so normal forms keep their
   existing disabled-control affordance. */
.admin-live-results.htmx-request {
  opacity: 0.68;
  cursor: progress;
  transition: opacity var(--transition-fast);
}

/* Choice controls — native radio/checkbox, accent-tinted, 44px row.
   Quiz: single-answer => radio, multi-answer => checkbox (FR15). */
.choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: var(--tap);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.choice:hover { border-color: var(--color-primary); background: var(--surface-3); }
.choice input { width: 1.25rem; height: 1.25rem; margin: 0.18em 0 0; accent-color: var(--color-primary); flex: none; }
.choice__icon { flex: none; margin-block-start: 0.2em; color: var(--color-primary-ink); }
.choice:has(input:checked) { border-color: var(--color-primary); background: var(--color-primary-soft); }
.choice-text { font-size: var(--text-base); color: var(--ink); }
/* Segmented choice group — each .choice keeps its own rounded rect (don't wrap
   them in a single .toggle pill). Equal-width, stacks on narrow widths. */
.choice-group { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.choice-group .choice { flex: 1 1 180px; }

/* ---------------------------------------------------------------------------
   BADGES  (FR2 level, FR2/FR3 path, status, "Kunskapskontroll ingår")
   --------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.2em 0.7em;
  font-family: var(--font-heading);
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  border-radius: var(--radius-full);
  white-space: nowrap;
  line-height: 1.5;
}

/* Level (color-coded per PRD FR2) */
.badge-level-1 { background: var(--level-1-soft); color: var(--level-1); }
.badge-level-2 { background: var(--level-2-soft); color: var(--level-2); }
.badge-level-3 { background: var(--level-3-soft); color: var(--level-3); }

/* Utbildningsspår */
.badge-path-dev  { background: var(--path-dev-soft);  color: var(--path-dev); }
.badge-path-arch { background: var(--path-arch-soft); color: var(--path-arch); }
.badge-path-lead { background: var(--path-lead-soft); color: var(--path-lead); }

/* Status */
.badge-success { background: var(--color-success-soft); color: var(--color-success); }
.badge-warning { background: var(--color-warning-soft); color: var(--color-warning); }
.badge-error   { background: var(--color-error-soft);   color: var(--color-error); }
.badge-info    { background: var(--color-info-soft);    color: var(--color-info); }
.badge-muted   { background: var(--surface-3); color: var(--ink-muted); border: 1px solid var(--border); }

/* Feature flag — "Kunskapskontroll ingår", preview-available, step count */
.badge-feature {
  background: var(--color-primary-soft);
  color: var(--color-primary-ink);
  text-transform: none;
  letter-spacing: var(--tracking-normal);
}

.priority-marker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  width: fit-content;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-full);
  background: var(--color-primary-soft);
  color: var(--color-primary-ink);
  font-family: var(--font-heading);
  font-weight: var(--font-semibold);
  line-height: var(--leading-snug);
  white-space: nowrap;
}
.priority-marker--full { padding: var(--space-1) var(--space-3); font-size: var(--text-sm); }
.priority-marker--compact { padding: 0 var(--space-2); font-size: var(--text-xs); }
.priority-marker--compact .icon { width: var(--space-3); height: var(--space-3); }

/* ---------------------------------------------------------------------------
   CARDS
   --------------------------------------------------------------------------- */
.card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  /* Default inset so bare content never sits flush against the frame. Full-bleed
     variants (.segment-card, .resume-hero) and self-padded ones (.cockpit,
     .quiz-qcard) reset/override this below or in the surface partials. */
  padding: var(--space-6);
}
.card-body { padding: var(--space-6); }
.card-title { font-size: var(--text-xl); margin-bottom: var(--space-2); }

/* Segment / course card — the core matrix cell (FR2). Min 280×200 on desktop. */
.segment-card {
  display: flex;
  flex-direction: column;
  min-width: 280px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  padding: 0;  /* full-bleed media + self-padded __body; reset the base .card inset */
  text-decoration: none;
  color: inherit;
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.segment-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
  border-color: var(--color-primary);
}
.segment-card--access-granted {
  border-color: var(--color-success);
}
.segment-card--access-granted:hover {
  border-color: var(--color-success);
}
.segment-card--access-missing {
  border-color: var(--border);
  background: var(--surface-1);
}
.segment-card--access-missing .segment-card__media {
  opacity: 0.72;
}
.segment-card--access-missing .segment-card__title,
.segment-card--access-missing .segment-card__meta {
  color: var(--ink-muted);
}
.segment-card__media {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--surface-0);
  object-fit: cover;
}
.segment-card__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); flex: 1; }
.segment-card__badges { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.segment-card__title { font-family: var(--font-heading); font-size: var(--text-lg); font-weight: var(--font-semibold); color: var(--ink-strong); line-height: var(--leading-snug); margin: 0; }
.segment-card__meta { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--ink-muted); margin-top: auto; }
.segment-card__teacher { display: flex; align-items: center; gap: var(--space-2); }
.segment-card__teacher > span:last-child { overflow-wrap: anywhere; }
.segment-card__avatar { width: 28px; height: 28px; border-radius: var(--radius-full); object-fit: cover; flex: none; }
.segment-card__format-list { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-1); }
.minichip {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-2);
  font-size: var(--text-xs);
  color: var(--ink-muted);
  background: var(--surface-1);
}

/* Teacher / Lärare card (FR7) */
.teacher-card { display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--space-6); gap: var(--space-3); height: 100%; }
/* A .card wrapping a .teacher-card must not double the inset (.card adds its own
   padding). The inner .teacher-card owns the inset. */
.card:has(> .teacher-card) { padding: 0; }
.teacher-card__photo { width: 96px; height: 96px; border-radius: var(--radius-full); object-fit: cover; border: 2px solid var(--color-primary); }
.teacher-card__name { font-family: var(--font-heading); font-size: var(--text-xl); font-weight: var(--font-bold); color: var(--ink-strong); margin: 0; }
.teacher-card__role { font-size: var(--text-sm); color: var(--color-primary-ink); font-weight: var(--font-semibold); }

/* Session card (FR6 calendar) */
.session-card { display: flex; gap: var(--space-4); padding: var(--space-5); align-items: flex-start; }
.session-card__date {
  flex: none; text-align: center; min-width: 56px;
  font-family: var(--font-heading); color: var(--color-primary-ink);
}
.session-card__day { font-size: var(--text-2xl); font-weight: var(--font-extrabold); line-height: 1; }
.session-card__mon { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); }

/* Stat card (FR11 progress, FR17 aggregates) */
.stat-card { padding: var(--space-6); text-align: center; }
.stat-card__num { font-family: var(--font-heading); font-size: var(--text-4xl); font-weight: var(--font-extrabold); color: var(--color-primary-ink); line-height: 1; }
.stat-card__label { font-size: var(--text-sm); color: var(--ink-muted); text-transform: uppercase; letter-spacing: var(--tracking-wide); margin-top: var(--space-2); }

/* Path card (FR1 — three learning paths) */
.path-card { padding: var(--space-8); display: flex; flex-direction: column; gap: var(--space-3); border-top: 3px solid var(--color-primary); }

/* ---------------------------------------------------------------------------
   NAVIGATION  (FR1 header + footer)
   --------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: var(--z-header);
  height: var(--header-h);
  display: flex; align-items: center;
  padding: 0 var(--space-6);
  background: color-mix(in srgb, var(--surface-1) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.nav { display: flex; align-items: center; gap: var(--space-5); width: 100%; max-width: var(--container); margin: 0 auto; }
.brand { display: flex; align-items: center; gap: var(--space-3); min-height: var(--tap); font-family: var(--font-heading); font-weight: var(--font-extrabold); font-size: var(--text-lg); color: var(--ink-strong); text-decoration: none; letter-spacing: var(--tracking-tight); }
.brand__mark { width: 32px; height: 32px; border-radius: var(--radius-sm); background: var(--gradient-brand-mark, var(--gradient-brand)); flex: none; }
.nav__menu { display: flex; align-items: center; gap: var(--space-5); list-style: none; margin: 0; padding: 0; }
.nav__spacer { margin-left: auto; }
.nav-link { display: inline-flex; align-items: center; min-height: var(--tap); font-family: var(--font-heading); font-weight: var(--font-medium); color: var(--ink-muted); text-decoration: none; padding: var(--space-2) 0; position: relative; white-space: nowrap; }
.nav-link:hover, .nav-link[aria-current="page"] { color: var(--ink-strong); }
.nav-link[aria-current="page"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; background: var(--color-primary); }
.nav__toggle { display: none; }  /* mobile hamburger — shown via media query below */
.nav__menu-compact { display: none; }

/* Signed-in identity in the header (who am I?). Avatar monogram + name (+ email),
   links to the profile. Anonymous visitors don't render it (see shell.html). */
.nav__user { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); margin-left: var(--space-4); text-decoration: none; color: var(--ink); max-width: 16rem; min-width: 0; }
.nav__user:hover .nav__user-name { color: var(--color-primary-ink); }
.nav__user-avatar {
  flex: none; width: 34px; height: 34px; border-radius: var(--radius-full);
  display: grid; place-items: center;
  background: var(--color-primary-soft); color: var(--color-primary-ink);
  border: 1.5px solid var(--color-primary);
  font-family: var(--font-heading); font-weight: var(--font-bold); font-size: var(--text-xs);
}
.nav__user-text { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.nav__user-name { font-family: var(--font-heading); font-weight: var(--font-semibold); font-size: var(--text-sm); color: var(--ink-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav__user-email { font-size: var(--text-xs); color: var(--ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Admin section bar: secondary nav under the header on /admin pages. It stays
   in normal page flow so it never floats over scrolled content. */
.subnav {
  background: var(--surface-4);
  border-bottom: 1px solid var(--border);
  /* Gold hairline on top keeps it distinct from the header band (esp. dark). */
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--color-primary) 30%, transparent);
}
.subnav__inner {
  display: flex; align-items: center; gap: var(--space-6);
  width: 100%; max-width: var(--container); margin: 0 auto;
  padding: var(--space-2) var(--space-6); min-height: 48px;
}
.subnav__menu { display: flex; align-items: center; gap: var(--space-5); list-style: none; margin: 0; padding: 0; }

.site-footer {
  background: var(--surface-6);
  color: var(--ink-on-inverse);
  padding: var(--space-16) var(--space-6) var(--space-8);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--color-primary) 38%, transparent);
}
/* The footer is dark in both themes, so the near-black light-theme focus ring
   would vanish here — keep it gold for visible keyboard focus on dark. */
.site-footer { --focus-ring: var(--color-primary); }
.site-footer a { color: inherit; }
.footer__inner {
  max-width: var(--container);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(280px, 1.7fr) repeat(3, minmax(145px, 1fr));
  gap: var(--space-10);
  align-items: start;
}
.footer__brand { max-width: 390px; }
.footer__tagline {
  max-width: 36ch;
  margin-top: var(--space-4);
  color: color-mix(in srgb, var(--ink-on-inverse) 78%, transparent);
}
.footer__nav { min-width: 0; }
.footer__heading {
  margin: 0 0 var(--space-3);
  color: var(--ink-on-inverse);
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: var(--font-bold);
  line-height: var(--leading-tight);
}
.footer__links {
  display: grid;
  gap: var(--space-1);
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-compact);
  width: fit-content;
  max-width: 100%;
  padding: var(--space-1) var(--space-2);
  margin-left: calc(-1 * var(--space-2));
  border-radius: var(--radius-sm);
  color: color-mix(in srgb, var(--ink-on-inverse) 82%, transparent);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
}
.footer__link:hover {
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
  transform: translateX(2px);
}
.footer__link:focus-visible { color: var(--color-primary); }
.footer__bottom {
  max-width: var(--container);
  margin: var(--space-12) auto 0;
  padding-top: var(--space-6);
  border-top: 1px solid rgba(255,255,255,0.12);
  color: color-mix(in srgb, var(--ink-on-inverse) 72%, transparent);
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.footer__version {
  color: color-mix(in srgb, var(--ink-on-inverse) 62%, transparent);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   MODAL  — native <dialog> (FR4 segment detail; ADR-002)
   --------------------------------------------------------------------------- */
dialog.modal {
  width: min(720px, calc(100vw - var(--space-8)));
  max-height: calc(100vh - var(--space-12));
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-5);
  color: var(--ink);
  box-shadow: var(--shadow-lg);
  /* Don't show a focus ring on the dialog itself; we move open-focus here (see
     dc-dialog / dc-confirm-delete) so no control gets a spurious keyboard ring. */
  outline: none;
}
/* Flex column when open so the body owns the overflow and actually scrolls. A
   block dialog clamped to max-height just clips its content (notably Chrome).
   Scoped to [open] so the closed-dialog `display:none` (UA) is preserved. */
dialog.modal[open] { display: flex; flex-direction: column; }
dialog.modal::backdrop { background: rgba(8, 8, 11, 0.6); backdrop-filter: blur(2px); }
.modal__header { flex: none; display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); padding: var(--space-6); border-bottom: 1px solid var(--border); }
.modal__body {
  flex: 1 1 auto; min-height: 0;
  padding: var(--space-6); overflow-y: auto; overscroll-behavior: contain;
  /* Bottom scroll-shadow so clipped content reads as scrollable, not broken. */
  background:
    linear-gradient(var(--surface-5) 30%, transparent) top / 100% var(--space-6) no-repeat,
    linear-gradient(transparent, var(--surface-5) 70%) bottom / 100% var(--space-6) no-repeat,
    radial-gradient(farthest-side at 50% 0, rgba(8,8,11,0.12), transparent) top / 100% var(--space-3) no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(8,8,11,0.12), transparent) bottom / 100% var(--space-3) no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.modal__close { flex: none; width: var(--tap); height: var(--tap); display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--ink-muted); border-radius: var(--radius); cursor: pointer; }
.modal__close:hover { background: var(--surface-4); color: var(--ink-strong); }
/* Don't paint a focus ring on programmatic open-focus; keep it for keyboard. */
.modal__close:focus:not(:focus-visible) { outline: none; }
/* Mobile: reclaim vertical room and tighten the header so the body isn't crushed. */
@media (max-width: 767px) {
  dialog.modal { width: calc(100vw - var(--space-4)); max-height: calc(100dvh - var(--space-6)); }
  .modal__header { padding: var(--space-4) var(--space-5); }
  .modal__body { padding: var(--space-5); }
}

/* ---------------------------------------------------------------------------
   PROGRESS  (FR5 preview position, FR11 path completion)
   --------------------------------------------------------------------------- */
.progress {
  height: 8px; width: 100%;
  background: var(--surface-0);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.progress__bar { height: 100%; background: var(--color-primary); border-radius: inherit; transition: width var(--transition-slow); }
/* Video preview: portion played vs full length (FR5) */
.progress--preview .progress__bar { background: var(--gradient-brand); }
.progress__meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-1) var(--space-4); font-size: var(--text-sm); color: var(--ink-muted); margin-top: var(--space-2); }

/* ---------------------------------------------------------------------------
   STEP LIST  (FR14 multi-step Moment — resume at first incomplete)
   --------------------------------------------------------------------------- */
.steplist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.step {
  display: flex; align-items: center; gap: var(--space-3);
  min-height: var(--tap); padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2); color: var(--ink); text-decoration: none;
  transition: border-color var(--transition), background var(--transition);
}
.step:hover { border-color: var(--color-primary); background: var(--surface-3); }
/* Status marker: grid-centered chip. Upcoming = outlined ring; current = filled
   chip with a centered dot; done = success fill with a centered check (SVG). */
.step__icon { flex: none; width: 26px; height: 26px; border-radius: var(--radius-full); display: grid; place-items: center; background: var(--surface-0); color: var(--ink-muted); border: 1px solid var(--border); }
.step--done .step__icon { background: var(--color-success); color: #fff; border-color: transparent; }
.step--current { border-color: var(--color-primary); background: var(--color-primary-soft); }
.step--current .step__icon { background: var(--color-primary); border-color: transparent; }
.step--current .step__icon::after { content: ""; width: 9px; height: 9px; border-radius: var(--radius-full); background: var(--ink-on-primary); }
.step--current .step__status { color: var(--color-primary-ink); }
.step--done.step--current .step__icon { background: var(--color-success); color: #fff; border-color: transparent; }
.step--done.step--current .step__icon::after { content: none; }
/* Stacked label + status so every row shares one structure regardless of length. */
.step__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.step__label { font-weight: var(--font-medium); overflow-wrap: break-word; }
.step__title { font-size: var(--text-sm); color: var(--ink-muted); line-height: 1.35; overflow-wrap: break-word; }
.step__status { font-size: var(--text-xs); color: var(--ink-subtle); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.step__type { margin-left: auto; font-size: var(--text-xs); color: var(--ink-subtle); text-transform: uppercase; letter-spacing: var(--tracking-wide); }

/* ---------------------------------------------------------------------------
   QUIZ FEEDBACK  (FR15 — per-question right/wrong, correct answers, explanations)
   Applied to .choice after server-side scored submission.
   --------------------------------------------------------------------------- */
/* Result states must beat the .choice:has(input:checked) selected style,
   so the chosen answer reads green/red after scoring — not brand gold. */
.choice.is-correct,
.choice.is-correct:has(input:checked) { border-color: var(--color-success); background: var(--color-success-soft); }
.choice.is-incorrect,
.choice.is-incorrect:has(input:checked) { border-color: var(--color-error); background: var(--color-error-soft); }
.choice.is-missed { border-color: var(--color-success); border-style: dashed; }  /* correct but not chosen */
.choice--review { cursor: default; }
.choice--review:hover { border-color: var(--border); background: var(--surface-2); }
.choice--review.is-correct:hover { border-color: var(--color-success); background: var(--color-success-soft); }
.choice--review.is-incorrect:hover { border-color: var(--color-error); background: var(--color-error-soft); }
.choice--review.is-missed:hover { border-color: var(--color-success); background: var(--surface-2); }
.choice--review .choice-text { flex: 1 1 auto; min-width: 0; text-align: left; }
.choice__result-control {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.18em;
  border: 1px solid var(--border-strong);
  background: var(--surface-0);
  color: transparent;
}
.choice__result-control--radio { border-radius: var(--radius-full); }
.choice__result-control--checkbox { border-radius: var(--radius-sm); }
.choice__result-control .icon { width: 0.85rem; height: 0.85rem; stroke-width: 3; }
.choice.is-correct .choice__result-control,
.choice.is-missed .choice__result-control {
  border-color: var(--color-success);
  background: var(--color-success);
  color: #fff;
}
.choice.is-incorrect .choice__result-control {
  border-color: var(--color-error);
  background: var(--color-error);
  color: #fff;
}
.choice__answer-tags {
  display: inline-flex;
  flex: none;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-left: auto;
}
.choice__answer-tags .badge {
  border: 1px solid currentColor;
}
.quiz-explanation {
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  color: var(--ink-muted);
  background: var(--surface-0);
  border-left: 3px solid var(--color-info);
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* ---------------------------------------------------------------------------
   ALERT  (inline errors/notices — FR15 "Kunde inte skicka in", empty states)
   --------------------------------------------------------------------------- */
.alert {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-4) var(--space-5);
  border: 1px solid; border-radius: var(--radius);
  font-size: var(--text-sm);
}
.alert-success { background: var(--color-success-soft); border-color: var(--color-success); color: var(--color-success); }
.alert-warning { background: var(--color-warning-soft); border-color: var(--color-warning); color: var(--color-warning); }
.alert-error   { background: var(--color-error-soft);   border-color: var(--color-error);   color: var(--color-error); }
.alert-info    { background: var(--color-info-soft);    border-color: var(--color-info);    color: var(--color-info); }

/* ---------------------------------------------------------------------------
   EMPTY STATE  (FR3 zero-result filter, FR11/FR12 no-enrollment, FR17 "Inga försök ännu")
   --------------------------------------------------------------------------- */
.empty-state { text-align: center; padding: var(--space-12) var(--space-6); color: var(--ink-muted); }
.empty-state__title { font-family: var(--font-heading); font-size: var(--text-xl); color: var(--ink-strong); margin-bottom: var(--space-2); }

/* ---------------------------------------------------------------------------
   THEME TOGGLE  (FR8 — accessible, keyboard-operable, persisted via Stimulus)
   --------------------------------------------------------------------------- */
.theme-toggle {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: var(--tap); padding: var(--space-2) var(--space-3);
  background: var(--surface-2); border: 1px solid var(--border-strong);
  border-radius: var(--radius-full); cursor: pointer; color: var(--ink);
}
.theme-toggle:hover { border-color: var(--color-primary); color: var(--ink-strong); }
/* Sun/moon icon swap lives in the foundation layer (.theme-toggle .icon-sun/-moon). */

.locale-switcher {
  display: inline-flex; align-items: center; gap: var(--space-1);
  min-height: var(--tap); padding: var(--space-1);
  background: var(--surface-2); border: 1px solid var(--border-strong);
  border-radius: var(--radius-full); color: var(--ink);
}
.locale-switcher__label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.locale-switcher__form { margin: 0; }
.locale-switcher__option {
  min-width: var(--space-10); min-height: var(--tap-compact); padding: 0 var(--space-2);
  border: 0; border-radius: var(--radius-full); background: transparent;
  color: var(--ink); cursor: pointer; font-family: var(--font-heading);
  font-size: var(--text-sm); font-weight: var(--font-semibold);
}
.locale-switcher__option:hover { background: var(--surface-3); color: var(--ink-strong); }
.locale-switcher__option--current,
.locale-switcher__option:disabled {
  background: var(--color-primary); color: var(--ink-on-primary); cursor: default;
}

/* ---------------------------------------------------------------------------
   LAYOUT UTILITIES
   --------------------------------------------------------------------------- */
.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--space-6); }
.section { padding: var(--space-20) 0; }
.section--tint { background: var(--surface-4); }

.grid { display: grid; gap: var(--gutter); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-auto { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* Segment detail two-column body (FR4): content + teacher/meta sidebar.
   Stacks on mobile so the 300px sidebar never forces horizontal scroll. */
.detail-cols { display: grid; grid-template-columns: 1fr 300px; gap: var(--space-6); align-items: start; }

/* Course matrix: Topics (rows) × Levels (3 cols) — FR2 */
.matrix { display: grid; grid-template-columns: minmax(140px, 1fr) repeat(3, 2fr); gap: var(--space-4); }
.matrix__head { font-family: var(--font-heading); font-weight: var(--font-bold); color: var(--ink-strong); padding: var(--space-3); }
/* Grid stretches cells to the row height; stretch the card/empty-state inside to
   match so every card in a row shares the same height regardless of content. */
.matrix__cell { min-height: 120px; display: flex; flex-direction: column; }
.matrix__cell > .segment-card,
.matrix__cell > .cell-empty { flex: 1; }
/* Empty matrix cell — quiet, not a heavy dashed card (FR2 shows the gap). */
/* Quiet placeholder: a faint recess (mostly the page showing through) + soft
   dashed outline, so empty cells recede behind the real cards. */
.cell-empty { display: flex; align-items: center; justify-content: center; min-height: 140px; border: 1px dashed var(--border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--surface-0) 40%, transparent); color: var(--ink-subtle); text-align: center; padding: var(--space-4); }

.flex { display: flex; gap: var(--space-4); }
.flex-center { align-items: center; justify-content: center; }
.flex-between { align-items: center; justify-content: space-between; }
.flex-wrap { flex-wrap: wrap; }
.stack > * + * { margin-top: var(--space-4); }

.text-center { text-align: center; }
.w-full { width: 100%; }

/* Screen-reader-only (labels for icon controls, theme toggle, etc.) */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------------------------
   RESPONSIVE  (mobile 320px+ → tablet 768px+ → desktop 1024px+)
   --------------------------------------------------------------------------- */
@media (max-width: 1023px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .footer__inner { grid-template-columns: 1fr 1fr; }
  .theme-toggle { justify-content: center; min-width: var(--tap); padding-inline: 0; }
  .theme-toggle span:not([class]) { display: none; }
  /* The rigid topic×level grid doesn't fit below ~1024px, so drop it and flow
     each topic's cards in a responsive auto-fit grid (3→2→1 across) – keeping
     cards card-sized instead of ballooning to full width (FR2 topic grouping
     preserved via the full-row topic label). min(280px,100%) avoids overflow on
     phones narrower than the card minimum. */
  .matrix { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
  /* Hide the standalone level-column heads when stacked; each card already
     carries its level badge. The topic label spans the full row to head its
     group and force the next topic onto a new row. */
  .matrix__head:not([data-topic]) { display: none; }
  .matrix__head[data-topic] { grid-column: 1 / -1; margin-top: var(--space-4); }
  .detail-cols { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .nav { gap: var(--space-1); }
  .nav__menu { display: none; }
  .nav > .theme-toggle,
  .nav > .locale-switcher,
  .nav__user { display: none; }
  .nav .btn-primary, .nav .btn-secondary { order: 4; margin-left: auto !important; min-height: var(--tap-compact); }
  .nav .btn-secondary { padding-inline: var(--space-2); }
  .nav__toggle { display: inline-flex; order: 5; min-width: var(--tap-compact); min-height: var(--tap-compact); justify-content: center; padding: 0; }
  .nav__menu--open {
    display: flex; flex-direction: column; align-items: flex-start;
    position: absolute; top: var(--header-h); left: 0; right: 0;
    background: var(--surface-2); border-bottom: 1px solid var(--border);
    padding: var(--space-4) var(--space-6); gap: var(--space-3); z-index: var(--z-header);
  }
  .nav__menu--open .nav__menu-compact { display: block; }
  .nav__menu--open .nav__menu-controls {
    display: flex; align-items: center; gap: var(--space-3);
    width: 100%; padding-top: var(--space-2); border-top: 1px solid var(--border);
  }
  .nav__menu--open .theme-toggle { min-height: var(--tap-compact); }
  .nav__menu--open .locale-switcher { min-height: var(--tap-compact); }
  .nav__menu--open .locale-switcher__option { min-height: var(--space-8); }
}
@media (max-width: 767px) {
  .site-header { height: var(--header-h-mobile); padding: 0 var(--space-3); }
  .nav .brand { font-size: var(--text-base); min-width: 0; flex: none; }
  /* The gold mark alone is the mobile logo — hiding the wordmark frees the row so
     the auth control + toggle never truncate the brand mid-word. */
  .nav .brand__label { display: none; }
  .nav__menu--open { top: var(--header-h-mobile); }
  .nav__toggle { display: inline-flex; }
  /* Admin section bar scrolls horizontally once the admin area has more links
     than fit in the viewport. */
  .subnav { overflow-x: auto; }
  .subnav__inner {
    flex-wrap: nowrap;
    gap: var(--space-5);
    width: max-content;
    min-width: 100%;
  }
  .subnav__menu { flex: 0 0 auto; }
  .subnav .nav-link { white-space: nowrap; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .detail-cols { grid-template-columns: 1fr; }  /* stack content + sidebar */
  /* .matrix keeps the auto-fit card grid from the 1023px breakpoint – at phone
     widths min(280px,100%) already collapses it to a single column. */
  .footer__inner { grid-template-columns: 1fr; }
  h1 { font-size: var(--text-4xl); }
  .display { font-size: var(--text-5xl); }
  .section { padding: var(--space-12) 0; }
}

/* ---------------------------------------------------------------------------
   SCHEMAN CALENDAR  (FR6 / S04) — month grid, week strip, agenda, detail
   Format is distinguished by a text label + left-border style, never color
   alone (WCAG 2.1 AA, design-system "color-not-only" rule).
   --------------------------------------------------------------------------- */
.schedule-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }

.viewtoggle { display: inline-flex; border: 2px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.viewtoggle__btn { min-height: 44px; padding: var(--space-2) var(--space-5); background: var(--surface-2); color: var(--ink-muted); border: none; border-right: 2px solid var(--border); font-size: var(--text-sm); cursor: pointer; }
.viewtoggle__btn:last-child { border-right: none; }
.viewtoggle__btn[aria-pressed="true"] { background: var(--color-primary); color: var(--ink-on-primary); font-weight: var(--font-bold); }

.legend { display: flex; flex-wrap: wrap; gap: var(--space-4); margin: var(--space-4) 0; font-size: var(--text-xs); color: var(--ink-muted); align-items: center; }
.legend__item { display: inline-flex; align-items: center; gap: var(--space-2); }
.legend__swatch { width: 18px; height: 14px; border: 1.5px solid var(--border); border-radius: var(--radius-sm); display: inline-block; }
.legend__swatch--webinar { border-left: 5px solid var(--color-primary); }
.legend__swatch--onsite { border-left: 6px double var(--color-primary); }

.monthnav { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); flex-wrap: wrap; }
.monthnav .navbtn { inline-size: var(--tap); block-size: var(--tap); min-height: var(--tap); padding: 0; }
/* The reserved width stops the next-arrow shifting between "Maj" and
   "September"; centring keeps the label from hanging off the left of that
   reserved box, which read as a stray gap before the arrow. */
.monthlabel { font-size: var(--text-xl); font-weight: var(--font-bold); min-width: 160px; text-align: center; font-family: var(--font-heading); }
/* Separate the jump-to-today action from the prev/label/next group. */
.monthnav > .btn:last-child { margin-inline-start: var(--space-3); }

.cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-2); }
.calhead { background: var(--surface-4); border: 1px solid var(--border); border-radius: var(--radius-sm); text-align: center; padding: var(--space-2); font-weight: var(--font-bold); font-size: var(--text-sm); }
.daycell { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); min-height: 120px; padding: var(--space-2); display: flex; flex-direction: column; gap: var(--space-1); }
.daycell--outside { background: var(--surface-1); color: var(--ink-subtle); border-style: dashed; }
.daycell--today { border: 2px solid var(--color-primary); }
.daynum { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--ink-muted); }
.daycell--outside .daynum { color: var(--ink-subtle); font-weight: 400; }
.todaybadge { display: inline-block; font-size: 10px; font-weight: var(--font-bold); color: var(--ink-on-primary); background: var(--color-primary); border-radius: var(--radius-sm); padding: 1px 6px; margin-left: var(--space-1); vertical-align: middle; }

.weekstrip { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-2); }
.weekcol { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); min-height: 140px; padding: var(--space-2); display: flex; flex-direction: column; gap: var(--space-1); }
.weekcol--today { border: 2px solid var(--color-primary); }
.wchead { font-size: var(--text-xs); font-weight: var(--font-bold); color: var(--ink-muted); text-align: center; border-bottom: 1px solid var(--border); padding-bottom: var(--space-1); }

/* Session chip — text + border-style distinguishes format (no color alone). */
.sess { display: block; border: 1.5px solid var(--border); border-left: 5px solid var(--color-primary); border-radius: var(--radius-sm); background: var(--surface-1); padding: var(--space-2); font-size: var(--text-xs); color: var(--ink-strong); text-decoration: none; cursor: pointer; min-height: 44px; }
.sess:hover { border-color: var(--color-primary); background: var(--surface-3); }
.sess--onsite { border-left: 6px double var(--color-primary); }
.sess__time { font-weight: var(--font-bold); display: block; }
.sess__title { display: block; }
.sess__fmt { display: inline-block; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0 4px; font-size: 10px; background: var(--surface-2); margin-top: 2px; }
.sess__teacher { display: block; }

/* Mobile agenda (shown ≤767px) */
.agenda { display: none; }
.agday { margin-bottom: var(--space-5); }
.agdate { font-weight: var(--font-bold); font-size: var(--text-base); padding: var(--space-2) 0; border-bottom: 2px solid var(--border); margin-bottom: var(--space-3); display: flex; align-items: center; gap: var(--space-2); }
.agdate--today { border-bottom-color: var(--color-primary); }
.agenda .sess { font-size: var(--text-sm); margin-bottom: var(--space-2); }

/* Session detail key/value list + CTA panel */
.breadcrumb { color: var(--ink-muted); margin-bottom: var(--space-4); }
.kvlist { margin: var(--space-4) 0; }
.kv { display: flex; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--border); font-size: var(--text-sm); }
.kv:last-child { border-bottom: none; }
.kv__k { min-width: 130px; color: var(--ink-subtle); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.kv__v { color: var(--ink-strong); }
.cta-panel { border: 2px solid var(--color-primary); border-radius: var(--radius); background: var(--surface-4); padding: var(--space-5); margin: var(--space-6) 0; }
.h3 { font-family: var(--font-heading); font-size: var(--text-xl); color: var(--ink-strong); }

@media (max-width: 767px) {
  .kv { flex-direction: column; gap: var(--space-1); }
  .kv__k { min-width: 0; }
  /* Scheman mobile: collapse month grid + week strip into the agenda list so
     there is never horizontal scroll (FR6 / TI04). Placed after the base
     `.agenda { display: none }` so source order makes the agenda visible. */
  [data-controller~="dc-schedule"] [data-dc-schedule-target="monthView"],
  [data-controller~="dc-schedule"] [data-dc-schedule-target="weekView"],
  .viewtoggle { display: none !important; }
  .agenda { display: block; }
}

.section-gap { margin-top: var(--space-6); }

/* ============================================================================
   UI/UX OVERHAUL — FOUNDATION LAYER
   Additive, tokens-only. Expresses the brand's geometric ornament (gold hairlines,
   stepped frames, monograms, sunburst) defined in DESIGN.md but previously
   unexpressed on real pages. Every keyframe is reduced-motion-gated locally
   (the global token-zeroing only neutralizes --transition-*).
   ============================================================================ */

/* ---------------------------------------------------------------------------
   ICONS — inline SVG sprite (see #icon-sprite in layout.html). Font Awesome
   path icons inherit currentColor; sized in em so they track adjacent text.
   --------------------------------------------------------------------------- */
.icon {
  width: 1.25em; height: 1.25em; flex: none; display: inline-block;
  vertical-align: -0.18em; fill: currentColor; stroke: none;
}
.icon-sm, .icon--sm { width: 1em; height: 1em; }
/* Icon-only controls (calendar nav, modal close): a glyph with no adjacent text
   has nothing to scale against, so the em-relative .icon default leaves a speck
   inside a 44px target. Size these to the target instead. Each such control
   carries its accessible name in aria-label. */
.navbtn .icon, .modal__close .icon { width: 1.5rem; height: 1.5rem; }

.icon-lg, .icon--lg { width: 1.5em; height: 1.5em; }
.icon-xl, .icon--xl { width: 2em; height: 2em; }

/* ---------------------------------------------------------------------------
   GEOMETRIC ORNAMENT — gold hairlines, eyebrow rule, sunburst, stepped frame
   --------------------------------------------------------------------------- */
.rule-gold { height: 1px; border: 0; background: var(--gradient-gold-line); opacity: 0.7; margin: var(--space-10) 0; }

/* Section header: eyebrow + flanking gold hairline + title + lead. */
.section-head { margin-bottom: var(--space-8); }
.section-head--center { text-align: center; }
.section-head .eyebrow { display: inline-flex; align-items: center; gap: var(--space-3); }
.section-head--center .eyebrow::before,
.section-head--center .eyebrow::after { content: ""; width: var(--space-8); height: 1px; background: var(--color-primary); opacity: 0.5; }
.section-head h2 { margin-bottom: var(--space-3); }
.section-head__lead { color: var(--ink-muted); font-size: var(--text-lg); max-width: 60ch; }
.section-head__lead--wide { max-width: 90ch; }
.section-head--center .section-head__lead { margin-left: auto; margin-right: auto; }

/* Stepped gold corner brackets — wrap any framed media/panel. */
.deco-frame { position: relative; }
.deco-frame::before, .deco-frame::after {
  content: ""; position: absolute; width: 22px; height: 22px; pointer-events: none; z-index: 2;
  border: 2px solid var(--color-primary);
}
.deco-frame::before { top: -6px; left: -6px; border-right: 0; border-bottom: 0; }
.deco-frame::after  { bottom: -6px; right: -6px; border-left: 0; border-top: 0; }
/* Keep the outset brackets clear of the viewport edge inside narrow gutters. */
@media (max-width: 767px) {
  .deco-frame::before { top: -2px; left: -2px; }
  .deco-frame::after  { bottom: -2px; right: -2px; }
}

/* Sunburst hairline motif (decorative, aria-hidden in markup). */
.sunburst {
  --rays: repeating-conic-gradient(from 0deg, var(--color-primary) 0deg 0.6deg, transparent 0.6deg 9deg);
  background: var(--rays); opacity: 0.5;
  -webkit-mask: radial-gradient(circle, #000 38%, transparent 39%, transparent 60%, #000 61%, #000 62%, transparent 63%);
          mask: radial-gradient(circle, #000 38%, transparent 39%, transparent 60%, #000 61%, #000 62%, transparent 63%);
}

/* System states (404 / 500 / 403 / expired) are shared across public, learning,
   and admin surfaces, so they live in the foundation layer. */
.state-panel {
  max-width: var(--container-narrow);
  margin-inline: auto;
  text-align: center;
}
.state-panel__medallion {
  position: relative;
  width: 96px;
  height: 96px;
  margin: 0 auto var(--space-6);
  display: grid;
  place-items: center;
}
.state-panel__medallion .sunburst {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-full);
}
.state-panel__medallion .icon {
  position: relative;
  width: 2.5em;
  height: 2.5em;
  color: var(--color-primary-ink);
  stroke-width: 1.5;
}
.state-panel__code {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--ink-subtle);
  text-transform: uppercase;
}
.state-panel h1 { margin: var(--space-2) 0 var(--space-3); }
.state-panel__msg { color: var(--ink-muted); max-width: 52ch; margin: 0 auto var(--space-6); }
.state-panel__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; }

/* ---------------------------------------------------------------------------
   MEDIA + POSTER — real <img> over a tokenized geometric fallback. The poster
   shows through when an image is absent or 404s (img[onerror] removed/hidden).
   --------------------------------------------------------------------------- */
.media { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--surface-0); }
.media__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }
.media-poster {
  position: absolute; inset: 0; display: grid; place-items: center; z-index: 0;
  background:
    radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--color-primary) 24%, transparent), transparent 58%),
    linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 12%, transparent), transparent 48%),
    var(--surface-0);
  color: var(--color-primary-ink);
}
/* Faint gold ray fan behind the monogram so empty tiles read as designed. */
.media-poster::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-conic-gradient(from 0deg at 50% 50%, var(--color-primary) 0deg 0.5deg, transparent 0.5deg 11deg);
  -webkit-mask: radial-gradient(circle at 50% 50%, #000 0%, transparent 62%);
          mask: radial-gradient(circle at 50% 50%, #000 0%, transparent 62%);
  opacity: 0.06;
}
.media-poster__mono {
  position: relative; font-family: var(--font-heading); font-weight: var(--font-extrabold);
  font-size: clamp(2rem, 8vw, 3.5rem); letter-spacing: var(--tracking-tight);
  color: var(--color-primary-ink); opacity: 0.92;
}
.media__badge {
  position: absolute; z-index: 2; bottom: var(--space-2); right: var(--space-2);
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: var(--font-semibold);
  color: #fff; background: rgba(8,8,11,0.72); padding: 2px 8px; border-radius: var(--radius-sm);
  backdrop-filter: blur(2px);
}
.media__tag {
  position: absolute; z-index: 2; top: var(--space-2); left: var(--space-2);
}
.media__tag.badge-success,
.media__tag.badge-muted {
  background: var(--surface-2);
  backdrop-filter: blur(2px);
}
.media__tag.badge-success {
  border: 1px solid var(--color-success);
}

/* Rounded avatar with gold ring + initials fallback (teacher portraits, meta). */
.avatar { border-radius: var(--radius-full); object-fit: cover; flex: none; background: var(--surface-0); }
.avatar--ring { border: 2px solid var(--color-primary); }
.avatar-fallback {
  display: grid; place-items: center; flex: none; border-radius: var(--radius-full);
  background: radial-gradient(circle at 50% 35%, var(--color-primary-soft), var(--surface-0));
  color: var(--color-primary-ink); font-family: var(--font-heading); font-weight: var(--font-bold);
  border: 2px solid var(--color-primary);
}

/* ---------------------------------------------------------------------------
   PROSE — article/reading step body (was referenced-but-undefined).
   --------------------------------------------------------------------------- */
/* Checklist — shared: segment detail objectives/prerequisites and the
   session page's objectives. Global because two surface sheets need it. */
.checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.checklist__item { display: flex; align-items: flex-start; gap: var(--space-3); line-height: var(--leading-snug); }
.checklist__check { flex: none; margin-top: 0.15em; color: var(--color-primary); }
.checklist--links a { color: var(--color-primary-ink); text-decoration: none; }
.checklist--links a:hover { text-decoration: underline; }

.prose { max-width: 68ch; color: var(--ink); line-height: var(--leading-relaxed); font-size: var(--text-lg); }
.prose > * + * { margin-top: var(--space-5); }
.prose h2, .prose h3, .prose h4 { margin-top: var(--space-10); margin-bottom: var(--space-2); }
.prose h2 { font-size: var(--text-2xl); } .prose h3 { font-size: var(--text-xl); }
.prose ul, .prose ol { padding-left: var(--space-6); }
.prose li + li { margin-top: var(--space-2); }
.prose a { color: var(--color-primary-ink); }
.prose strong { color: var(--ink-strong); font-weight: var(--font-bold); }
.prose code { font-family: var(--font-mono); font-size: 0.9em; background: var(--surface-0); padding: 0.12em 0.4em; border-radius: var(--radius-sm); }
.prose pre { background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-4); overflow: auto; }
.prose pre code { background: none; padding: 0; }
.prose blockquote { border-left: 3px solid var(--color-primary); padding-left: var(--space-4); color: var(--ink-muted); font-style: italic; margin-left: 0; }
.prose img { border-radius: var(--radius); border: 1px solid var(--border); }

/* ---------------------------------------------------------------------------
   VERDICT — quiz per-question result label (was referenced-but-undefined).
   --------------------------------------------------------------------------- */
.verdict { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-heading); font-weight: var(--font-bold); font-size: var(--text-sm); }
.verdict--correct { color: var(--color-success); }
.verdict--incorrect { color: var(--color-error); }

/* Quiz result hero band (FR15 feedback). */
.result-hero { text-align: center; padding: var(--space-10) var(--space-6); border-radius: var(--radius-lg); border: 1px solid var(--border); background: var(--surface-2); position: relative; overflow: hidden; }
.result-hero__score { font-family: var(--font-heading); font-weight: var(--font-extrabold); font-size: var(--text-6xl); line-height: 1; color: var(--color-primary-ink); }
.result-hero--pass { background: var(--color-success-soft); border-color: var(--color-success); }
.result-hero--pass .result-hero__score { color: var(--color-success); }
.result-hero__tally { display: inline-flex; gap: var(--space-4); margin-top: var(--space-4); font-size: var(--text-sm); color: var(--ink-muted); }

/* ---------------------------------------------------------------------------
   HERO — public landing (FR1). Editorial asymmetric grid + framed media.
   --------------------------------------------------------------------------- */
.hero { position: relative; padding: var(--space-16) 0 var(--space-20); overflow: hidden; }
.hero__grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: var(--space-12); align-items: center; }
.hero__media { position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-lg); border: 1px solid var(--border); }
.hero__media .media-poster__mono { font-size: clamp(3rem, 10vw, 6rem); }
.hero h1 { font-size: clamp(var(--text-4xl), 6vw, var(--text-6xl)); line-height: 1.04; letter-spacing: var(--tracking-tight); }
.hero__sun { position: absolute; top: -120px; right: -120px; width: 360px; height: 360px; z-index: 0; pointer-events: none; }
.hero__inner { position: relative; z-index: 1; }
.proof { display: flex; flex-wrap: wrap; gap: var(--space-6) var(--space-8); margin-top: var(--space-8); padding-top: var(--space-6); border-top: 1px solid var(--border); }
.proof__num { font-family: var(--font-heading); font-weight: var(--font-extrabold); font-size: var(--text-3xl); color: var(--color-primary-ink); line-height: 1; }
.proof__label { font-size: var(--text-sm); color: var(--ink-muted); margin-top: var(--space-1); }

/* ---------------------------------------------------------------------------
   CARD POLISH — lift, media composition, link cards
   --------------------------------------------------------------------------- */
.card--hover { transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition); }
.card--hover:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--color-primary); }

/* Path card gets a path-tinted top rail when given a .path-card--<slug> class. */
.path-card { position: relative; }
.path-card__icon { width: 44px; height: 44px; border-radius: var(--radius); display: grid; place-items: center; background: var(--color-primary-soft); color: var(--color-primary-ink); margin-bottom: var(--space-2); }
.path-card .badge { align-self: flex-start; }  /* don't stretch in the column flex */
.path-card--dev  { border-top-color: var(--path-dev); }
.path-card--arch { border-top-color: var(--path-arch); }
.path-card--lead { border-top-color: var(--path-lead); }
.path-card--dev  .path-card__icon { background: var(--path-dev-soft);  color: var(--path-dev); }
.path-card--arch .path-card__icon { background: var(--path-arch-soft); color: var(--path-arch); }
.path-card--lead .path-card__icon { background: var(--path-lead-soft); color: var(--path-lead); }

/* Portrait: layered round media — initials fallback beneath, photo on top.
   On image error the <img> removes itself, revealing the monogram beneath. */
.portrait { position: relative; flex: none; width: 96px; height: 96px; }
.portrait--sm { width: 28px; height: 28px; }
.portrait-stack { display: inline-flex; align-items: center; flex: none; padding-right: var(--space-1); }
.portrait-stack .portrait + .portrait { margin-left: -8px; }
.portrait__fill { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: var(--radius-full); }
.portrait__img { object-fit: cover; border: 2px solid var(--color-primary); z-index: 1; }
.portrait .avatar-fallback { font-size: var(--text-2xl); }
.portrait--sm .avatar-fallback { font-size: var(--text-xs); border-width: 1.5px; }
.portrait--sm .portrait__img { border-width: 1.5px; }
.teacher-card__photo { background: var(--surface-0); }

/* ---------------------------------------------------------------------------
   FILTER COMMAND BAR — one labelled row per dimension, in normal document flow.
   Deliberately NOT sticky: a multi-row toolbar pinned over the content it
   filters hides more than the saved scrolling is worth (same held for the
   smaller Kursmoment bar), so the bar scrolls away with the page.
   --------------------------------------------------------------------------- */
.cmdbar { position: relative; background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: var(--radius-lg); padding: var(--space-2) var(--space-5) var(--space-3); margin: var(--space-6) 0; box-shadow: var(--shadow-sm); }
/* Gold hairline anchors the bar as a seated geometric toolbar, not a floating chip. */
.cmdbar::before { content: ""; position: absolute; left: var(--space-4); right: var(--space-4); top: 0; height: 1px; background: var(--gradient-gold-line); opacity: 0.5; pointer-events: none; }

/* One row per dimension, laid out on a shared two-column grid so every chip run
   starts at the same vertical edge; hairlines between rows replace the
   free-floating vertical dividers, which landed wherever the old single flex
   happened to wrap. The rows are `display: contents` so the label column sizes
   itself to the longest label on THIS bar — "Utbildningsspår" on Scheman needs
   far more room than "Spår" on Kursmoment, and a fixed width fits neither. */
.cmdbar__rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); align-items: start; }
.cmdbar__row { display: contents; }
/* The hairline is drawn per grid cell, so the columns must butt together — a
   column-gap would break each rule into two visibly separate segments. The
   label carries the gutter as padding instead. */
.cmdbar__row > * { padding: var(--space-2) 0; border-top: 1px solid var(--border); }
.cmdbar__row:first-child > * { border-top: none; }
/* A meta row holding only a clear button that has nothing to clear must not
   leave an empty band behind; a meta row with a live result count always shows. */
.cmdbar:not(:has(.chip[aria-pressed="true"])) .cmdbar__row--meta:not(:has(.cmdbar__count)) { display: none; }
.cmdbar__row--meta .cmdbar__chips { grid-column: 1 / -1; justify-content: flex-end; }

/* Match the compact chip height so dimension labels and their controls remain
   optically aligned after wrapping. */
.cmdbar__label { display: inline-flex; align-items: center; gap: var(--space-2); line-height: 2rem; padding-inline-end: var(--space-5); font-family: var(--font-heading); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--ink-subtle); font-weight: var(--font-semibold); white-space: nowrap; }
.cmdbar__label .icon { flex: none; color: var(--ink-subtle); }
/* Colour marks the dimensions actually narrowing the result — the one signal
   worth carrying, and it needs no controller state (aria-pressed is the source). */
.cmdbar__row:has(.chip[aria-pressed="true"]) .cmdbar__label,
.cmdbar__row:has(.chip[aria-pressed="true"]) .cmdbar__label .icon { color: var(--color-primary-ink); }

.cmdbar__chips { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.cmdbar__count { font-size: var(--text-sm); color: var(--ink-muted); }

/* Compact pill toggle. The 2rem height clears the 24px WCAG 2.5.8 target while
   preserving the filter bars' dense visual hierarchy. */
.chip { display: inline-flex; align-items: center; gap: var(--space-1); min-height: 2rem; padding: var(--space-1) var(--space-3); border: 1.5px solid var(--border-strong); border-radius: var(--radius-full); background: var(--surface-1); color: var(--ink-muted); font-family: var(--font-heading); font-size: var(--text-sm); font-weight: var(--font-medium); cursor: pointer; transition: border-color var(--transition), background var(--transition), color var(--transition); white-space: nowrap; }
.chip:hover { border-color: var(--color-primary); color: var(--ink-strong); }
.chip[aria-pressed="true"] { background: var(--color-primary); color: var(--ink-on-primary); border-color: var(--color-primary); font-weight: var(--font-semibold); }
/* The tick is the non-colour signal for "selected" (AA). While unpressed the
   negative end-margin cancels both the icon's own width and the flex gap, so an
   unselected pill carries no blank slot and its label stays optically centred;
   selecting expands the tick in place. --transition is zeroed under
   prefers-reduced-motion, so this degrades to an instant swap. */
.chip__check { flex: none; width: 0.75rem; height: 0.75rem; opacity: 0; margin-inline-end: calc(-0.75rem - var(--space-1)); transition: margin-inline-end var(--transition), opacity var(--transition); }
.chip[aria-pressed="true"] .chip__check { opacity: 1; margin-inline-end: 0; }
.chip--clear { border-style: dashed; }
.chip--clear[hidden] { display: none; }
/* Nothing selected → nothing to clear. Pure CSS so both filter controllers
   (dc-schedule, dc-filter) stay untouched. */
.cmdbar:not(:has(.chip[aria-pressed="true"])) .chip--clear { display: none; }

@media (max-width: 767px) {
  /* Single column — a label column plus chips leaves neither enough room. */
  .cmdbar { padding-inline: var(--space-4); }
  .cmdbar__rows { grid-template-columns: minmax(0, 1fr); }
  .cmdbar__label { line-height: var(--leading-normal); padding-bottom: 0; }
  .cmdbar__chips { border-top: none; padding-top: 0; }
  .cmdbar__row--meta .cmdbar__chips { justify-content: flex-start; }
}

/* Hero stacks below tablet so the framed media never crushes the headline. */
@media (max-width: 900px) {
  .hero { padding: var(--space-10) 0 var(--space-12); }
  .hero__grid { grid-template-columns: 1fr; gap: var(--space-8); }
  .hero__sun { width: 160px; height: 160px; top: -56px; right: -84px; opacity: 0.7; }
}

/* ---------------------------------------------------------------------------
   STAGGERED REVEAL — opt-in scroll/enter animation, reduced-motion-safe.
   Elements start hidden ONLY when motion is allowed; otherwise fully visible.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(12px); animation: reveal-in 0.55s var(--ease-out, cubic-bezier(0.22,1,0.36,1)) forwards; }
  .reveal-1 { animation-delay: 0.05s; }
  .reveal-2 { animation-delay: 0.12s; }
  .reveal-3 { animation-delay: 0.19s; }
  .reveal-4 { animation-delay: 0.26s; }
  @keyframes reveal-in { to { opacity: 1; transform: none; } }
}

/* Theme-toggle: swap to crisp SVG icons (sun/moon) sized via .icon. */
.theme-toggle .icon { width: 1.1em; height: 1.1em; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: inline-block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: inline-block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* Gold keyline as structure on the shared chrome (gold hairline). */
.site-header { position: relative; }
.site-header::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--gradient-gold-line); opacity: 0.55; pointer-events: none; }
.brand__mark { display: grid; place-items: center; }
.brand__mark svg { width: 66%; height: 66%; color: var(--ink-on-primary); }
/* Optional brand-supplied logo mark (BRAND_MARK_PATH) sits on the same tile. */
.brand__mark-img { width: 78%; height: 78%; object-fit: contain; }
.site-footer { position: relative; }
.site-footer::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--gradient-gold-line); opacity: 0.45; pointer-events: none; }
.footer__tagline { opacity: 0.82; margin-top: var(--space-3); max-width: 38ch; }
/* Header contact CTA sits before login on the public funnel. */
.nav__contact { margin-left: auto; }
.nav__menu + .nav__contact { margin-left: var(--space-2); }
.announcement-banner-stack { margin-block: var(--space-5) var(--space-6); }
.announcement-banner {
  display: grid;
  grid-template-columns: var(--tap) minmax(0, 1fr) auto;
  align-items: flex-start;
  gap: var(--space-4);
  margin: 0;
  padding: var(--space-4) var(--space-5);
  border-inline-start: 4px solid var(--color-primary);
  border-color: var(--border-strong);
  border-inline-start-color: var(--color-primary);
  background:
    linear-gradient(120deg, var(--color-primary-soft), transparent 62%),
    var(--surface-2);
  box-shadow: var(--shadow-md);
}

.announcement-banner__mark {
  display: grid;
  place-items: center;
  inline-size: var(--tap);
  block-size: var(--tap);
  border-radius: var(--radius);
  background: var(--color-primary);
  color: var(--ink-on-primary);
  box-shadow: var(--shadow-sm);
}
.announcement-banner__body { min-inline-size: 0; }
.announcement-banner__body .eyebrow { margin-block-end: var(--space-1); font-size: var(--text-xs); }
.announcement-banner__body h2 { margin-block: 0 var(--space-1); font-size: var(--text-2xl); }
.announcement-banner__excerpt {
  max-inline-size: 64ch;
  font-size: var(--text-base);
  overflow-wrap: anywhere;
}
.announcement-banner__excerpt > * { margin-block-end: 0; }
.announcement-banner__excerpt > * + * { margin-block-start: var(--space-2); }
.announcement-banner__excerpt > :is(h3, h4, h5, h6) {
  margin-block: var(--space-2) 0;
  font-size: var(--text-base);
  line-height: var(--leading-snug);
}
.announcement-banner__excerpt > :first-child { margin-block-start: 0; }
.announcement-banner__excerpt > :last-child { margin-block-end: var(--space-2); }
.announcement-banner__archive-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-block-size: var(--tap);
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-primary-ink);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}
.announcement-banner__dismiss {
  border-color: transparent;
  color: var(--ink-muted);
}

.announcement-archive { display: grid; gap: var(--space-5); }
.announcement-card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); color: var(--ink-muted); font-size: var(--text-sm); }
.announcement-card h2 { margin-block: var(--space-2) var(--space-3); }

@media (max-width: 42rem) {
  .announcement-banner {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
  }
  .announcement-banner__mark { display: none; }
  .announcement-banner__body h2 { font-size: var(--text-xl); }
}
