/* dar.kolegium.org — application styles. Tokens only; no hex values outside css/tokens/. */

:root {
  --dur-accordion: 280ms;
  --dur-crossfade: 700ms;
  --dur-dot-morph: 380ms;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-accordion: 0ms;
    --dur-crossfade: 0ms;
    --dur-dot-morph: 0ms;
  }
}

/* Staging badge (13-additions §H.1): permanently visible, never on production. */
.kan-env-badge {
  position: sticky;
  top: 0;
  z-index: var(--z-toast);
  padding: var(--space-2) var(--space-4);
  background: var(--warning-surface);
  color: var(--warning-text);
  border-bottom: 1px solid var(--warning-border);
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
}

/* ============================================================
   Icon — Lucide via CSS mask, painted with currentColor
   (10-design-system §3; SVGs self-hosted in public/icons/).
   ============================================================ */
.kan-icon {
  display: inline-block;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask-image: var(--icon-url);
  mask-image: var(--icon-url);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* ============================================================
   Button (core/Button.jsx)
   ============================================================ */
.kan-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-ui);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-button);
  text-transform: uppercase;
  border-radius: var(--radius-button);
  border: 1.5px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: var(--transition-colors), var(--transition-shadow);
  position: relative;
  white-space: nowrap;
}

.kan-btn--sm { min-height: var(--touch-min); padding: 0 var(--space-5); font-size: var(--fs-legal); }
.kan-btn--md { min-height: var(--control-h); padding: 0 var(--space-6); font-size: var(--fs-small); }
.kan-btn--lg { min-height: var(--control-h-lg); padding: 0 var(--space-8); font-size: var(--fs-body-sm); }
.kan-btn--full { width: 100%; }

.kan-btn--primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.kan-btn--primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }
.kan-btn--primary:active:not(:disabled) { background: var(--accent-active); border-color: var(--accent-active); }

.kan-btn--donate { background: var(--highlight); color: var(--on-highlight); border-color: var(--highlight); }
.kan-btn--donate:hover:not(:disabled) { background: var(--highlight-hover); border-color: var(--highlight-hover); }

.kan-btn--secondary { background: transparent; color: var(--accent); border-color: var(--accent-border); }
.kan-btn--secondary:hover:not(:disabled) { background: var(--accent-subtle); border-color: var(--accent); }

.kan-btn--link {
  background: transparent;
  color: var(--text-link);
  border-color: transparent;
  text-transform: none;
  letter-spacing: var(--ls-ui);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  padding: 0 var(--space-1);
}
.kan-btn--link:hover:not(:disabled) { color: var(--text-link-hover); text-decoration-thickness: 2px; }

.kan-btn:disabled,
.kan-btn[aria-disabled="true"] {
  color: var(--text-disabled);
  border-color: var(--border-default);
  cursor: not-allowed;
}
.kan-btn--primary:disabled,
.kan-btn--donate:disabled { background: var(--surface-disabled); }
.kan-btn--secondary:disabled,
.kan-btn--link:disabled { background: transparent; }

/* 24. 9. 2026 — `.kan-result-actions` (result screens + the donor portal, both through
   `x-result-shell` / `x-donor-shell`) sometimes carries a long primary label („Poslať
   potvrdzovací odkaz", „Chcem potvrdiť nový e-mail", „Áno, chcem zrušiť podporu"): wider
   than `.kan-btn`'s own `white-space: nowrap` allows once the viewport drops under ~400 px,
   which pushed the whole `.kan-result-card` into horizontal scroll. Letting the label wrap
   there is enough — the flex item already shrinks to fit once `nowrap` is gone (no `min-width`
   override needed), the pill's own min-height keeps it ≥44 px, and a label that already fits
   on one line (every other `.kan-result-actions` button) renders exactly as before. Desktop
   is untouched. */
@media (max-width: 400px) {
  .kan-result-actions .kan-btn { white-space: normal; text-align: center; }
}

/* ============================================================
   Field + inputs (forms/Field.jsx, forms/TextInput.jsx)
   ============================================================ */
.kan-field { display: flex; flex-direction: column; gap: var(--space-2); }

.kan-field__label {
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  line-height: var(--lh-ui);
}

.kan-field__hint { margin: 0; font-size: var(--fs-legal); line-height: 1.5; color: var(--text-muted); }

.kan-field__error {
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--fs-legal);
  line-height: 1.5;
  color: var(--danger-text);
  font-weight: var(--fw-medium);
}
.kan-field__error .kan-icon { width: 15px; height: 15px; margin-top: 1px; }

.kan-input-wrap { position: relative; display: flex; align-items: center; }

.kan-input {
  width: 100%;
  min-height: var(--control-h);
  padding: 0 var(--space-4);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--text-heading);
  background: var(--paper);
  border: 1.5px solid var(--border-input);
  border-radius: var(--radius-input);
  box-shadow: var(--shadow-inset-input);
  outline: none; /* focus is the 1.5px accent border below — never invisible */
  transition: var(--transition-colors);
}
.kan-input:focus { border-color: var(--accent); }
.kan-input[aria-invalid="true"] { border-color: var(--danger); }
.kan-input--suffixed { padding-right: var(--space-10); }
.kan-input--numeric { font-variant-numeric: tabular-nums; }

.kan-input-wrap__suffix {
  position: absolute;
  right: var(--space-4);
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  pointer-events: none;
}

/* ============================================================
   Checkbox (forms/Checkbox.jsx)
   ============================================================ */
.kan-checkbox { display: flex; gap: var(--space-3); align-items: flex-start; min-height: var(--touch-min); padding-block: var(--space-2); }

.kan-checkbox__box { position: relative; display: grid; place-items: center; flex: 0 0 auto; width: 24px; height: 24px; margin-top: 1px; }

.kan-checkbox__input {
  appearance: none;
  margin: 0;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--border-input);
  background: var(--paper);
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-checkbox__input:checked { background: var(--accent); border-color: var(--accent); }
.kan-checkbox__input[aria-invalid="true"] { border-color: var(--danger); }

.kan-checkbox__glyph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--on-accent);
  pointer-events: none;
  opacity: 0;
}
.kan-checkbox__input:checked + .kan-checkbox__glyph { opacity: 1; }
.kan-checkbox__glyph .kan-icon { width: 16px; height: 16px; }

.kan-checkbox__label {
  display: block;
  font-size: var(--fs-body-sm);
  line-height: 1.5;
  color: var(--text-body);
  cursor: pointer;
}
.kan-checkbox__label a { color: var(--text-link); text-underline-offset: 0.18em; }
.kan-checkbox__error { margin: 0 0 0 36px; }

/* ============================================================
   Frequency toggle (donation/FrequencyToggle.jsx)
   ============================================================ */
.kan-freq { margin: 0; padding: 0; border: 0; }

.kan-freq__legend {
  padding: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
}

.kan-freq__track {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin-top: var(--space-3);
  padding: 4px;
  background: var(--surface-sunken);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
}

.kan-freq__option {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 38px;
  border-radius: var(--radius-pill);
  background: transparent;
  border: 1.5px solid transparent;
  color: var(--text-body);
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: var(--transition-colors), var(--transition-shadow);
}
.kan-freq__option:has(input:checked) {
  background: var(--paper);
  border-color: var(--accent);
  box-shadow: var(--shadow-1);
  color: var(--accent);
}
.kan-freq__option:has(input:focus-visible) {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.kan-freq__radio { position: absolute; opacity: 0; width: 1px; height: 1px; }

/* The sliding pill (1. 10. 2026): the selected face is one layer under the two options that
   glides from one to the other instead of blinking. Two equal columns only — the giving form's
   one-off / monthly switch and its two-campaign switch (.kan-acc__seg below). */
.kan-freq--slide .kan-freq__track,
.kan-acc__seg { position: relative; }
.kan-freq--slide .kan-freq__track::before,
.kan-acc__seg::before {
  content: "";
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc(50% - 6px);
  background: var(--paper);
  border: 1.5px solid var(--accent);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-1);
  transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur-fast) var(--ease-standard);
}
.kan-freq--slide .kan-freq__track:has(.kan-freq__option:nth-child(2) input:checked)::before,
.kan-acc__seg:has(> .kan-acc__seg-btn:nth-child(2).is-selected)::before { transform: translateX(calc(100% + 4px)); }
.kan-freq--slide .kan-freq__track:not(:has(input:checked))::before,
.kan-acc__seg:not(:has(> .is-selected))::before { opacity: 0; }
.kan-freq--slide .kan-freq__option,
.kan-acc__seg-btn { z-index: 1; }
.kan-freq--slide .kan-freq__option:has(input:checked) {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}

/* ============================================================
   Amount chips (DarovaciAkordeon.dc.html step 2). The "Priemer" marker
   was dropped on 4. 9. 2026 (client) — plain pills only.
   ============================================================ */
.kan-chips {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  padding-top: 4px;
}

/* The label is a transparent cell; the visible pill is .kan-chip__face — a separate layer. */
.kan-chip {
  position: relative;
  display: grid;
  cursor: pointer;
  font-family: var(--font-ui);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-legal);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.kan-chip__face {
  position: relative; /* paints above the ::before envelope */
  overflow: hidden; /* the rolling sum (campaign.js rollText) stays inside the pill */
  display: grid;
  place-items: center;
  min-height: 38px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--border-input);
  background: var(--paper);
  color: var(--text-heading);
  transition: var(--transition-colors);
}
.kan-chip:has(input:checked) .kan-chip__face { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.kan-chip:has(input:focus-visible) {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.kan-chip__radio { position: absolute; opacity: 0; width: 1px; height: 1px; }

/* Visually 38px pills keep the 44px WCAG target through an invisible extension
   (the same trick as the rotation dots — 10-design-system, accessibility floor). */
.kan-chip::after,
.kan-freq__option::after,
.kan-acc__seg-btn::after {
  content: "";
  position: absolute;
  inset: -3px 0;
}

/* ============================================================
   Alert (core/Alert.jsx)
   ============================================================ */
.kan-alert {
  display: flex;
  gap: var(--space-3);
  border: 1px solid;
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  font-family: var(--font-body);
}
.kan-alert--success { background: var(--success-surface); border-color: var(--success-border); }
.kan-alert--success .kan-alert__tone { color: var(--success-text); }
.kan-alert--error { background: var(--danger-surface); border-color: var(--danger-border); }
.kan-alert--error .kan-alert__tone { color: var(--danger-text); }
.kan-alert--warning { background: var(--warning-surface); border-color: var(--warning-border); }
.kan-alert--warning .kan-alert__tone { color: var(--warning-text); }
.kan-alert--info { background: var(--info-surface); border-color: var(--info-border); }
.kan-alert--info .kan-alert__tone { color: var(--info-text); }

.kan-alert__icon { margin-top: 2px; }
.kan-alert__content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.kan-alert__title {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-ui);
}
.kan-alert__body { font-size: var(--fs-body-sm); line-height: 1.55; color: var(--text-body); }

/* ============================================================
   Empty state (core/EmptyState.jsx)
   ============================================================ */
.kan-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  /* P0 ▸ B13: no dotted frame, no grey backing (admin and portal alike). */
  padding: var(--space-8) var(--space-4);
}
.kan-empty__icon {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-pill);
  background: var(--paper);
  border: 1px solid var(--border-default);
  display: grid;
  place-items: center;
  color: var(--navy-400);
}
.kan-empty__icon .kan-icon { width: 26px; height: 26px; }
.kan-empty__title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  color: var(--text-heading);
}
.kan-empty__body { margin: 0; max-width: 42ch; font-size: var(--fs-body-sm); line-height: 1.6; color: var(--text-muted); }
/* P0 ▸ B13: the buttons under the sentence — only when something can be added. */
.kan-empty__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); margin-top: var(--space-1); }
/* P0 ▸ B13: the small size — one grey sentence in a card. */
.kan-empty--inline { display: block; margin: 0; padding: var(--space-3) var(--space-4); text-align: left; font-size: var(--fs-small); line-height: 1.5; color: var(--text-muted); }

/* ============================================================
   Donation accordion (DarovaciAkordeon.dc.html)
   ============================================================ */
.kan-acc {
  font-family: var(--font-ui);
  color: var(--text-body);
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

.kan-acc__step + .kan-acc__step { border-top: 1px solid var(--border-subtle); }

.kan-acc__head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: var(--space-2) var(--space-4);
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}

.kan-acc__dot {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: var(--fw-bold);
  background: var(--surface-sunken);
  color: var(--accent);
  border: 1.5px solid var(--border-default);
}
.kan-acc__step.is-current .kan-acc__dot { background: var(--accent-subtle); border-color: var(--accent); }
.kan-acc__step.is-done .kan-acc__dot { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.kan-acc__step.is-reachable .kan-acc__dot { border-color: var(--accent); }

.kan-acc__label { flex: 1; min-width: 0; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-muted); }
.kan-acc__step.is-current .kan-acc__label,
.kan-acc__step.is-done .kan-acc__label,
.kan-acc__step.is-reachable .kan-acc__label { color: var(--text-heading); }

.kan-acc__summary {
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  color: var(--text-link);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 16ch;
}

/* Collapsed panels: visibility hidden at the end of the transition so nothing inside is
   focusable (AC 14). campaign.js drives max-height with the panel's real measured height,
   so opening and closing move the card by exactly the content difference — no overshoot.
   Without JS every panel stays open and the form still submits. */
.kan-acc__body {
  overflow: hidden;
  transition:
    max-height var(--dur-accordion) var(--ease-standard),
    opacity 200ms var(--ease-standard),
    visibility 0s linear var(--dur-accordion);
  max-height: 0;
  opacity: 0;
  visibility: hidden;
}
.kan-acc__step.is-open > .kan-acc__body,
.no-js .kan-acc__body {
  max-height: none;
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.kan-acc__inner { padding: 0 var(--space-4) var(--space-4); display: flex; flex-direction: column; gap: 14px; }

.kan-acc__seg {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  background: var(--surface-sunken);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
}
.kan-acc__seg-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 38px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  text-align: center;
  text-decoration: none;
  transition: var(--transition-colors), var(--transition-shadow);
  background: transparent;
  border: 1.5px solid transparent;
  color: var(--text-body);
}
.kan-acc__seg-btn.is-selected { color: var(--accent); } /* the face is the sliding ::before above */

.kan-acc__custom {
  overflow: hidden;
  transition: max-height 240ms var(--ease-standard), visibility 0s linear 240ms;
  max-height: 0;
  visibility: hidden;
}
.kan-acc__custom.is-open,
.no-js .kan-acc__custom {
  max-height: 240px;
  visibility: visible;
  transition-delay: 0s;
}
/* Under the chips: the custom sum's own error and „Ďalej" (24. 9. 2026). Without JavaScript
   every step is open already, so „Ďalej" would do nothing — hidden, as [data-continue-pay]. */
.kan-acc__custom .kan-acc__next { margin-top: var(--space-3); }
.kan-acc__custom-error { margin-top: var(--space-2); }
.no-js .kan-acc__custom .kan-acc__next { display: none; }

/* „Iná" turns into the field in its own cell (24. 9. 2026, Matej) — the same pill, the same
   height, so the grid does not move; the field keeps the 44px target through the same
   invisible extension as the chips, a click on it focuses the input. */
.kan-chip-other { position: relative; display: grid; min-width: 0; }
.kan-chip-other__field { display: none; position: relative; align-items: center; }
.kan-chip-other.is-open .kan-chip,
.no-js .kan-chip-other .kan-chip { display: none; }
.kan-chip-other.is-open .kan-chip-other__field,
.no-js .kan-chip-other__field { display: grid; }
.kan-chip-other__field::after { content: ""; position: absolute; inset: -3px 0; pointer-events: none; }
.kan-chip-other__input {
  width: 100%;
  min-width: 0;
  min-height: 38px;
  box-sizing: border-box;
  padding: 0 var(--space-6) 0 var(--space-3);
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--accent);
  background: var(--paper);
  color: var(--text-heading);
  font-family: var(--font-ui);
  font-size: 1rem; /* 16px — iOS zooms into anything smaller */
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  text-align: center;
  transition: var(--transition-colors);
}
.kan-chip-other__input[aria-invalid="true"] { border-color: var(--danger); }
.kan-chip-other__suffix {
  position: absolute;
  right: var(--space-3);
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  pointer-events: none;
}

.kan-acc__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.kan-acc__info { margin: 0; font-size: var(--fs-legal); line-height: 1.5; color: var(--text-muted); }
.kan-acc__info a { color: var(--text-link); text-underline-offset: 0.18em; }

/* „Pokračovať k platbe" (24. 9. 2026) only ever opens step „Platba" — without JavaScript
   every step is already open, so the button would do nothing; hidden rather than harmless. */
.no-js [data-continue-pay] { display: none; }

/* ============================================================
   Campaign page hero (KampusStranka / VyrocnaKampan)
   ============================================================ */
.kan-page { background: var(--surface-inverse); font-family: var(--font-ui); color: var(--text-body); }

.kan-hero {
  position: relative;
  background: var(--surface-inverse);
  overflow: hidden;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.kan-hero__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity var(--dur-crossfade) var(--ease-standard);
}
.kan-hero__photo.is-active { opacity: 1; }

.kan-hero__scrim { position: absolute; inset: 0; background: var(--scrim); pointer-events: none; }

/* Desktop: the accordion lives inside the hero, so opening a taller step used to grow the
   section and re-crop the photo mid-animation (a zoom flicker). Pinning the photo to the
   viewport height keeps it perfectly still; if the hero ever grows past one screen, the
   overflow is plain navy under the scrim. */
@media (min-width: 720px) {
  .kan-hero__photo {
    height: 100vh;
    height: 100lvh;
  }
}

.kan-hero__top { position: relative; z-index: 2; padding: 20px var(--space-6) 0; }
.kan-hero__top-inner {
  max-width: 1180px;
  margin-inline: auto;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}
.kan-hero__logo { display: inline-flex; align-items: center; min-height: var(--touch-min); }
.kan-hero__logo img { height: 100px; width: auto; display: block; object-fit: contain; }
.kan-hero__manage {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0 var(--space-1);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  color: var(--text-on-dark);
  opacity: 0.86;
  text-decoration: none;
  /* The text's first line sits level with the top of the logo (Matej, 28. 9. 2026); the
     44 px target stays whole and simply reaches above it. */
  margin-top: calc((1lh - var(--touch-min)) / 2);
}
.kan-hero__manage:hover { opacity: 1; text-decoration: underline; text-underline-offset: 0.25em; }

.kan-hero__content {
  position: relative;
  z-index: 2;
  flex: 1 1 auto;
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  padding: var(--space-2) var(--space-6) var(--space-6);
  display: flex;
  gap: var(--space-10);
  align-items: stretch;
  min-height: 0;
}
.kan-hero__left {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-6);
}
.kan-hero__h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: clamp(44px, 5.4vw, 68px);
  line-height: 1.02;
  letter-spacing: var(--ls-display);
  color: var(--text-on-dark);
  max-width: 16ch;
  text-wrap: balance;
}
.kan-hero__form { flex: 0 0 auto; width: 368px; }
@media (min-width: 940px) { .kan-hero__form { width: 396px; } }
@media (min-width: 1080px) { .kan-hero__form { width: 420px; } }

/* Rotation dots — "So zlatou stopou" (client pick, 31. 8. 2026): tight 6px gaps, the active
   dot morphs into a 26px pill with a linear gold fill, already-seen photos keep a muted gold
   trace. Invisible ::after extensions keep the 44px touch targets (10-design-system trick). */
.kan-hero__dots {
  display: flex;
  gap: 6px;
  align-items: center;
}
.kan-hero__dots--corner {
  position: absolute;
  z-index: 3;
  right: var(--space-6);
  bottom: var(--space-6);
}
.kan-hero__dots--inline { display: none; }
.kan-dot {
  position: relative;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.kan-dot::after {
  content: "";
  position: absolute;
  inset: -20px -17px;
}
.kan-dot__pill {
  display: block;
  width: 5px;
  height: 5px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.35);
  overflow: hidden;
  transition:
    width var(--dur-dot-morph) var(--ease-standard),
    background-color 500ms var(--ease-standard);
}
.kan-dot.is-active .kan-dot__pill { width: 26px; background: rgba(255, 255, 255, 0.28); }
/* Already-seen photos keep a muted trace of the brand gold (#D5C242 → rgba). */
.kan-dot.is-past .kan-dot__pill { background: rgba(213, 194, 66, 0.55); }
.kan-dot__fill {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: var(--radius-pill);
  background: var(--meter-marker);
  transition: width 80ms linear;
}
.kan-dot.is-active.is-still .kan-dot__fill { width: 100%; }
.kan-page.kan-on-dark .kan-dot:focus-visible { outline-color: var(--focus-ring-on-dark); }

/* Hero meter (desktop, on navy): spans the content width — wide, with side gutters
   (client request, 31. 8. 2026). */
.kan-hero__meter {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 0 var(--space-6) var(--space-8);
}
.kan-hero__meter-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.kan-hero__meter-eyebrow {
  margin: 0;
  font-size: 11px;
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-on-dark-muted);
}
.kan-hero__meter-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }
.kan-hero__meter-raised {
  margin: 0;
  font-size: 22px;
  font-weight: var(--fw-bold);
  color: var(--text-on-dark);
  font-variant-numeric: tabular-nums;
}
.kan-hero__meter-goal {
  margin: 0;
  font-size: var(--fs-legal);
  color: var(--text-on-dark-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.kan-hero__meter-track {
  position: relative;
  height: 8px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.24);
  overflow: hidden;
}
.kan-hero__meter-fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--meter-marker);
  transition: var(--transition-meter);
}
.kan-meter-chipline { position: relative; height: 22px; }
.kan-meter-chip {
  position: absolute;
  top: 0;
  background: var(--meter-marker);
  color: var(--on-highlight);
  font-size: var(--fs-overline);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

/* Mobile layout (<720 px): shrunken photo band, white meter strip, no sticky CTA (AC 1). */
.kan-mobile-meter { display: none; }
.kan-mobile-lead { display: none; }
@media (max-width: 719.98px) {
  .kan-page { background: var(--paper); }
  /* A fixed photo band (SESSION-11C §5), scaled with the width: the proportion is one config
     value (media.hero_mobile_ratio, set on the section as --hero-mobile-ratio) that the
     cropper's dashed lines read too. The text never grows it — the lead lives below. */
  .kan-hero { min-height: 0; aspect-ratio: var(--hero-mobile-ratio, 5 / 4); }
  .kan-hero__lead { display: none; }
  .kan-mobile-lead {
    display: block;
    margin: 0;
    padding: var(--space-4) var(--space-4) 0;
    background: var(--paper);
    font-size: var(--fs-lead);
    line-height: var(--lh-lead);
    color: var(--text-body);
    text-wrap: pretty;
  }
  .kan-hero__content { padding: 12px var(--space-4) var(--space-4); gap: var(--space-3); align-items: flex-end; }
  .kan-hero__left { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: var(--space-3); }
  .kan-hero__h1 { font-size: 34px; line-height: 1.04; }
  .kan-hero__scrim { background: rgba(6, 42, 71, 0.6); }
  .kan-hero__top { padding: 14px var(--space-4) 0; }
  .kan-hero__logo img { height: 80px; }
  .kan-hero__manage { font-size: var(--fs-overline); }
  .kan-hero__form { display: none; }
  .kan-hero__meter { display: none; }
  .kan-hero__dots--corner { display: none; }
  .kan-hero__dots--inline { display: flex; padding-bottom: var(--space-2); flex: 0 0 auto; }

  .kan-mobile-meter {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
    background: var(--paper);
  }
  .kan-mobile-meter__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
  .kan-mobile-meter__raised {
    margin: 0;
    font-size: 16px;
    font-weight: var(--fw-bold);
    color: var(--text-heading);
    font-variant-numeric: tabular-nums;
  }
  .kan-mobile-meter__goal { margin: 0; font-size: var(--fs-overline); color: var(--text-muted); font-variant-numeric: tabular-nums; }
  .kan-mobile-meter__track { position: relative; height: 6px; border-radius: var(--radius-pill); background: var(--meter-track); overflow: hidden; }
  .kan-mobile-meter__fill { height: 100%; border-radius: var(--radius-pill); background: var(--meter-fill); }
  .kan-mobile-meter .kan-meter-chipline { height: 18px; }
  .kan-mobile-meter .kan-meter-chip { font-size: 11px; padding: 1px 6px; }

  .kan-mobile-form { display: block; padding: var(--space-4); background: var(--paper); }
}
@media (min-width: 720px) { .kan-mobile-form { display: none; } }

/* ============================================================
   Result screens (StavPlatby.dc.html) + slim public header
   ============================================================ */
.kan-result-page {
  background: var(--bg-alt);
  font-family: var(--font-ui);
  color: var(--text-body);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.kan-subheader { background: var(--bg-alt); }
/* Lines up with the footer's own content frame (`--container-wide` + `--space-6`, defined
   below at the footer) so the logo's left edge and „Moja podpora"'s right edge sit exactly
   above the footer's left/right content edges at every width (Matej, 24. 9. 2026). */
.kan-subheader__inner {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding: 10px var(--space-6);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--touch-min);
}
.kan-subheader__logo { display: flex; align-items: center; min-height: var(--touch-min); }
.kan-subheader__logo img { height: 82px; width: auto; display: block; object-fit: contain; }
.kan-subheader__back {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  color: var(--text-link);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

.kan-result-main { flex: 1 1 auto; padding: clamp(24px, 5vw, 56px) var(--space-4) clamp(40px, 6vw, 72px); }
.kan-result-col { max-width: 620px; margin-inline: auto; display: flex; flex-direction: column; gap: var(--space-4); }

.kan-result-card {
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-1);
  padding: clamp(20px, 4vw, 32px);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.kan-result-head { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
.kan-result-badge {
  width: 52px;
  height: 52px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  display: grid;
  place-items: center;
}
.kan-result-badge .kan-icon { width: 26px; height: 26px; }
.kan-result-badge--danger { background: var(--danger-surface); color: var(--danger-text); }
.kan-result-h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: clamp(30px, 5vw, 42px);
  line-height: 1.08;
  letter-spacing: var(--ls-display);
  color: var(--text-heading);
}
.kan-result-lead { margin: 0; font-size: 16px; line-height: var(--lh-body); color: var(--text-body); text-wrap: pretty; font-family: var(--font-body); }

.kan-result-rows { margin: 0; border-top: 1px solid var(--border-subtle); display: flex; flex-direction: column; }
.kan-result-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  justify-content: space-between;
  align-items: baseline;
  padding: 11px 0;
  border-bottom: 1px solid var(--border-subtle);
}
.kan-result-row dt { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-result-row dd {
  margin: 0;
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.kan-result-overline {
  margin: 0;
  font-size: var(--fs-legal);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.kan-result-amount {
  margin: 0;
  font-family: var(--font-numeric);
  font-weight: var(--fw-bold);
  font-size: 2rem;
  color: var(--text-heading);
}
.kan-result-amount span { font-size: var(--fs-body-sm); font-weight: var(--fw-semibold); color: var(--text-muted); }

.kan-result-list { display: flex; flex-direction: column; gap: 10px; }
.kan-result-item { display: flex; gap: 10px; align-items: flex-start; }
.kan-result-item__icon {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--accent-subtle);
  color: var(--accent);
  display: grid;
  place-items: center;
  margin-top: 1px;
}
.kan-result-item__icon .kan-icon { width: 15px; height: 15px; }
.kan-result-item__bullet { flex: 0 0 auto; width: 5px; height: 5px; border-radius: var(--radius-pill); background: var(--text-muted); margin-top: 9px; }
.kan-result-item p { margin: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--text-body); text-wrap: pretty; font-family: var(--font-body); }
.kan-result-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.kan-result-note { margin: 0; font-size: var(--fs-legal); line-height: 1.6; color: var(--text-muted); text-wrap: pretty; }


/* ============================================================
   Footer (Paticka.dc.html)
   ============================================================ */
/* The frame the footer draws is the widest container on the page — wider than
   `--container-content` and not one of the design tokens, which is why it is named here and not
   in `css/tokens/`. Both rows of the footer wear it, and since SESSION-11E §8c so does the body
   of the donor portal: one number, one side padding, so the two can never drift apart. (The
   hero draws the same width from its own copy of it; that is older than this name and was
   left alone. The subheader (above) now draws on this same token instead of its own copy —
   Matej, 24. 9. 2026 — so its logo and „Moja podpora" line up with the footer exactly.) */
:root { --container-wide: 1180px; }

.kan-footer { background: var(--surface-inverse); color: var(--text-on-dark); font-family: var(--font-ui); }
.kan-footer__grid {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding: var(--space-10) var(--space-6);
  display: grid;
  gap: var(--space-8);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  align-items: start;
}
.kan-footer__brand { display: flex; flex-direction: column; gap: var(--space-4); align-items: flex-start; }
.kan-footer__brand img { width: 120px; height: auto; display: block; flex: 0 0 auto; object-fit: contain; }
.kan-footer__address { margin: 0; font-size: var(--fs-legal); line-height: 1.6; color: var(--text-on-dark-muted); max-width: 32ch; }
.kan-footer__col { display: flex; flex-direction: column; gap: 10px; }
.kan-footer__overline {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-overline);
  line-height: 1.3;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-on-dark-muted);
}
.kan-footer__link {
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  color: var(--text-on-dark);
  font-size: var(--fs-legal);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.kan-footer__plain { min-height: 32px; display: inline-flex; align-items: center; color: var(--text-on-dark); font-size: var(--fs-legal); text-decoration: none; }
.kan-footer__meta { margin: 0; font-size: var(--fs-legal); line-height: 1.7; color: var(--text-on-dark-muted); font-variant-numeric: tabular-nums; }
.kan-footer__bottom { border-top: 1px solid var(--border-inverse); }
.kan-footer__bottom-inner { max-width: var(--container-wide); margin-inline: auto; padding: 18px var(--space-6); }
.kan-footer__copyright { margin: 0; font-size: var(--fs-overline); color: var(--text-on-dark-muted); }

/* ============================================================
   Dev gallery /e-maily (TransakcneEmaily.dc.html) — local + staging only
   ============================================================ */
.kan-gal { min-height: 100vh; background: var(--mist); display: flex; flex-direction: column; color: var(--text-body); }
.kan-gal__bar { background: var(--paper); border-bottom: 1px solid var(--border-default); padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
.kan-gal__bar-row { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: baseline; justify-content: space-between; }
.kan-gal__eyebrow { margin: 0 0 2px; font-size: 11px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); }
.kan-gal__title { margin: 0; font-size: 26px; line-height: 1.1; }
.kan-gal__chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.kan-gal__chips--center { justify-content: center; }
.kan-gal__chip {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px;
  border-radius: var(--radius-chip); border: 1.5px solid var(--border-default);
  background: var(--paper); color: var(--text-body); font: inherit; font-size: 13px; font-weight: 600;
  text-decoration: none; transition: background 120ms, color 120ms, border-color 120ms;
}
.kan-gal__chip--sm { font-size: 12.5px; padding: 0 14px; }
.kan-gal__chip:hover { border-color: var(--accent); color: var(--accent); }
.kan-gal__chip--active, .kan-gal__chip--active:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.kan-gal__main { padding: clamp(16px, 3vw, 28px) 16px clamp(32px, 5vw, 56px); display: flex; flex-direction: column; align-items: center; gap: 14px; }
.kan-gal__list { width: 100%; max-width: 900px; display: flex; flex-direction: column; gap: 12px; }
.kan-gal__lead { margin: 0 0 4px; font-size: 14px; line-height: 1.65; max-width: 62ch; }
.kan-gal__card {
  width: 100%; max-width: 640px; box-sizing: border-box; background: var(--paper);
  border: 1px solid var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow-card);
  padding: 16px 18px; display: flex; flex-direction: column; gap: 8px;
}
.kan-gal__card--link { max-width: 900px; text-decoration: none; color: inherit; }
.kan-gal__card--link:hover { box-shadow: var(--shadow-card-hover); }
.kan-gal__meta { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: baseline; justify-content: space-between; }
.kan-gal__label { font-size: 11px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); }
.kan-gal__label--accent { color: var(--accent); }
.kan-gal__count { font-size: 11.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-gal__subject { margin: 0; font-size: 17px; font-weight: 600; line-height: 1.4; color: var(--text-heading); }
.kan-gal__pre { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--text-muted); }
.kan-gal__pre strong { color: var(--text-body); }
.kan-gal__trigger { margin: 0; padding-top: 8px; border-top: 1px solid var(--border-default); font-size: 12.5px; line-height: 1.6; }
.kan-gal__stage {
  width: 100%; box-sizing: border-box; background: var(--paper); border: 1px solid var(--border-default);
  border-radius: var(--radius-card); padding: clamp(14px, 3vw, 28px) clamp(8px, 2vw, 20px); overflow: hidden;
}
.kan-gal__stage--600 { max-width: 680px; }
.kan-gal__stage--375 { max-width: 375px; }
.kan-gal__frame { display: block; width: 100%; height: 1240px; border: 0; background: transparent; }
.kan-gal__text {
  width: 100%; max-width: 600px; box-sizing: border-box; margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; line-height: 1.6;
  background: var(--paper); border: 1px solid var(--border-default); border-radius: var(--radius-md); padding: 20px;
}
.kan-gal__note { margin: 0; max-width: 600px; font-size: 12.5px; line-height: 1.7; color: var(--text-muted); text-align: center; }

/* ============================================================
   Moja podpora (MojaPodpora.dc.html) — donor area
   ============================================================ */
.kan-result-col--wide { max-width: 720px; }

.kan-result-badge--soft { background: var(--accent-subtle); color: var(--accent); }

.kan-account-head { display: flex; flex-direction: column; gap: var(--space-2); }
.kan-account-section { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-account-h2 {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.kan-account-card {
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: clamp(18px, 3vw, 24px);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.kan-account-form { display: flex; flex-direction: column; gap: var(--admin-field-gap, var(--space-5)); }
.kan-account-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
@media (max-width: 479px) { .kan-account-grid { grid-template-columns: 1fr; } }
.kan-account-fieldset { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.kan-account-fieldset > legend { padding: 0; margin-bottom: var(--space-1); }

/* SupportCard: one per support, each with its own card mask and dates (13-§D.2). */
.kan-support {
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: clamp(18px, 3vw, 24px);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.kan-support__top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: var(--space-2) var(--space-4); }
.kan-support__amount {
  margin: 0;
  font-family: var(--font-numeric);
  font-weight: var(--fw-bold);
  font-size: 1.5rem;
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
}
.kan-support__amount span { font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-muted); }
.kan-support__title { margin: 0; display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-body-sm); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-support__campaign { margin: 0; font-size: var(--fs-body-sm); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-support__line { margin: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--text-body); text-wrap: pretty; }
.kan-support__actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* Status badge — always icon + word, never colour alone (10-design-system). */
.kan-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--radius-badge);
  border: 1px solid var(--border-default);
  background: var(--surface-sunken);
  color: var(--text-body);
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}
.kan-badge .kan-icon { width: 14px; height: 14px; }
/* S11F 1.6 (decision 8): ONE semantics across the whole admin, written once.
   Green = out there and working (Živá, Aktívna, Zaplatené) · yellow = there but not out
   (Neaktívna, Skrytá) · grey = over (Skončená, Zrušená) · red = a failure, and nothing else.
   `admin_off` stays muted: no access is not a warning. */
.kan-badge--active,
.kan-badge--fund-live { background: var(--success-surface); border-color: var(--success-border); color: var(--success-text); }
.kan-badge--fund-hidden { background: var(--warning-surface); border-color: var(--warning-border); color: var(--warning-text); }
.kan-badge--fund-ended,
.kan-badge--cancelled { background: var(--status-paused-bg); border-color: var(--status-paused-bd); color: var(--status-paused-fg); }
.kan-badge--fund-draft { background: var(--accent-subtle); border-color: var(--accent-border); color: var(--accent); }
.kan-badge--past-due { background: var(--warning-surface); border-color: var(--warning-border); color: var(--warning-text); }
.kan-badge--paused { background: var(--info-surface); border-color: var(--info-border); color: var(--info-text); }
/* „Vzťah pokračuje" (SESSION-11B §1.2): the reason travels in `title`. */
.kan-badge--hold { background: var(--accent-subtle); border-color: var(--accent-border); color: var(--accent); }
/* P0 ▸ F2 #6 (B10, K2): the tones of `x-admin.status-badge`, one light pill everywhere (admin and
   public). Green live/paid · yellow inactive/needs a look · grey over · red failed · blue „Čaká"
   · navy a neutral accent („Presun"). Specificity of two classes beats every legacy
   `.kan-badge--{state}` rule above, so the tone is the one truth. */
.kan-badge.kan-badge--tone-green { background: var(--success-surface); border-color: var(--success-border); color: var(--success-text); }
.kan-badge.kan-badge--tone-yellow { background: var(--warning-surface); border-color: var(--warning-border); color: var(--warning-text); }
.kan-badge.kan-badge--tone-grey { background: var(--status-paused-bg); border-color: var(--status-paused-bd); color: var(--status-paused-fg); }
.kan-badge.kan-badge--tone-red { background: var(--danger-surface); border-color: var(--danger-border); color: var(--danger-text); }
.kan-badge.kan-badge--tone-blue { background: var(--info-surface); border-color: var(--info-border); color: var(--info-text); }
.kan-badge.kan-badge--tone-navy { background: var(--accent-subtle); border-color: var(--accent-border); color: var(--accent); }

/* Cream note block (calendar / card notes) and the sunken "current value" row. */
.kan-note-block { background: var(--cream-deep); border-radius: var(--radius-md); padding: 14px 16px; display: flex; gap: 10px; align-items: flex-start; }
.kan-note-block .kan-icon { color: var(--accent); flex: 0 0 auto; margin-top: 1px; }
.kan-note-block p { margin: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--text-body); text-wrap: pretty; }
.kan-current-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  justify-content: space-between;
  align-items: baseline;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  padding: 12px 16px;
}
.kan-current-row__label { font-size: var(--fs-legal); color: var(--text-muted); }
.kan-current-row__value { font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-heading); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }

/* Amount chips outside the accordion: custom field revealed by JS (open without it). */
.kan-chips--plain { padding-top: 0; }
.kan-account-custom { display: none; }
.kan-account-custom.is-open,
html.no-js .kan-account-custom { display: block; }

.kan-select { appearance: auto; padding-right: var(--space-4); }

/* ============================================================
   Pravidlá darovania — the document page (/pravidla-darovania)
   ============================================================ */
.kan-doc {
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-1);
  padding: clamp(24px, 5vw, 48px);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  font-family: var(--font-body);
  color: var(--text-body);
}
.kan-result-col:has(.kan-doc) { max-width: 760px; }
.kan-doc__head { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-doc__subtitle { margin: 0; font-family: var(--font-ui); font-size: var(--fs-body-sm); font-weight: var(--fw-semibold); color: var(--text-muted); }
.kan-doc__meta {
  margin: var(--space-2) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3) var(--space-5);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-sunken);
  border-radius: var(--radius-md);
}
.kan-doc__meta-row { display: flex; flex-direction: column; gap: 2px; }
.kan-doc__meta dt { font-family: var(--font-ui); font-size: var(--fs-overline); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.kan-doc__meta dd { margin: 0; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-heading); }
/* Rules body (rules_versions HTML, sanitised to h2/h3/p/ol/ul/li/strong/em/a): CSS counters
   number the sections (h2 → 1., 2., …) and the top-level clauses (ol > li → 1.1, 1.2, …).
   The same class styles the admin editor so it is WYSIWYG. */
.kan-doc__body { display: flex; flex-direction: column; gap: var(--space-3); counter-reset: section; min-width: 0; }
.kan-doc__body > p { margin: 0; font-size: var(--fs-body); line-height: var(--lh-body); text-wrap: pretty; }
.kan-doc__body h2 {
  margin: var(--space-4) 0 0;
  font-family: var(--font-heading);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  color: var(--text-heading);
  counter-increment: section;
  counter-reset: clause;
}
.kan-doc__body h2:first-child { margin-top: 0; }
.kan-doc__body h2::before { content: counter(section) ". "; color: var(--accent); font-variant-numeric: tabular-nums; }
.kan-doc__body h3 { margin: 0; font-family: var(--font-ui); font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-doc__body > ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.kan-doc__body > ol > li { position: relative; padding-left: 3.25rem; font-size: var(--fs-body-sm); line-height: var(--lh-body); text-wrap: pretty; counter-increment: clause; }
.kan-doc__body > ol > li::before {
  content: counter(section) "." counter(clause);
  position: absolute;
  left: 0;
  top: 2px;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.kan-doc__body li p { margin: 0; }
.kan-doc__body ul, .kan-doc__body li ol { margin: var(--space-2) 0 0; padding-left: 1.25rem; display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-body-sm); line-height: var(--lh-body); }
.kan-doc__body ul { list-style: disc; }
.kan-doc__body li ol { list-style: lower-alpha; }
.kan-doc__body a { color: var(--text-link); text-underline-offset: 0.18em; }
.kan-doc__notice { margin: 0; padding: var(--space-3) var(--space-4); background: var(--surface-sunken); border-radius: var(--radius-md); font-family: var(--font-ui); font-size: var(--fs-small); line-height: 1.5; color: var(--text-heading); }
.kan-doc__notice a { color: var(--text-link); text-underline-offset: 0.18em; }
.kan-doc__history { display: flex; flex-direction: column; gap: var(--space-3); border-top: 1px solid var(--border-subtle); padding-top: var(--space-5); }
.kan-doc__history a { color: var(--text-link); text-underline-offset: 0.18em; }
@media (max-width: 479px) { .kan-doc__body > ol > li { padding-left: 2.5rem; } }
.kan-doc__foot { border-top: 1px solid var(--border-subtle); padding-top: var(--space-4); }
.kan-doc__foot p { margin: 0; font-size: var(--fs-legal); line-height: 1.6; color: var(--text-muted); }
@media print { .kan-doc { box-shadow: none; border: 0; padding: 0; } .kan-subheader, .kan-footer, .kan-env-badge { display: none; } }

/* Sentence under every donate button (rules acknowledgement + privacy line). */
.kan-consent-line a { color: var(--text-link); text-underline-offset: 0.18em; }
/* 24. 9. 2026 (Matej) · base.css sets `text-wrap: pretty` on every <p>, which on a phone
   pulls a word that still fits on the first line down to the second, to spare the last line
   a lone word. These short legal lines fill their lines normally instead. */
.kan-consent-line { text-wrap: wrap; }

/* Cancellation (client, 3. 9. 2026): one-click lower amounts, then the secondary pair. */
.kan-cancel-lower { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-cancel-lower__lead { margin: 0; font-family: var(--font-ui); font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-cancel-secondary {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-subtle);
}
.kan-rector {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--cream-deep);
  border-radius: var(--radius-lg);
  padding: clamp(16px, 3vw, 22px);
}
.kan-rector__text { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.kan-rector__text p { margin: 0; font-family: var(--font-body); font-size: var(--fs-body-sm); line-height: var(--lh-body); color: var(--text-body); text-wrap: pretty; }
.kan-rector__sign { display: flex; align-items: center; gap: var(--space-4); }
.kan-rector__portrait { flex: 0 0 auto; width: 96px; height: 96px; border-radius: var(--radius-pill); object-fit: cover; }
.kan-rector__name { margin: 0; font-family: var(--font-ui); font-size: var(--fs-body-sm); font-weight: var(--fw-regular); line-height: 1.5; color: var(--text-heading); }
.kan-rector__name span { color: var(--text-muted); }
.kan-textarea { min-height: 120px; padding: 12px var(--space-4); resize: vertical; line-height: 1.5; }

/* ============================================================
   Admin (Admin.dc.html, AdminPrihlasenie.dc.html — SESSION-8).
   Tokens only. Desktop-first grid + main; below 900 px the
   sidebar becomes a top bar with a scrolling nav.

   Every size the admin used to hard-code is a variable here (SESSION-11B §3.1), so
   admin-density.css — loaded only by the admin shell, only on a fine pointer — can
   redefine them without touching a single component rule. These are the touch values.
   ============================================================ */
.kan-admin,
.kan-admin-signin {
  --admin-side-w: 236px;
  --admin-nav-h: var(--touch-min);
  --admin-nav-fs: var(--fs-small);
  --admin-main-pad: var(--space-8);
  --admin-stack: var(--space-6);
  --admin-h1: 36px;
  --admin-overline-fs: var(--fs-overline);
  --admin-card-pad: var(--space-5);
  --admin-card-gap: var(--space-4);
  --admin-stat-value: 1.75rem;
  --admin-cell-py: 10px;
  --admin-cell-px: var(--space-4);
  --admin-modal-pad: 28px;
  --admin-modal-gap: 18px;
  --admin-modal-title: 26px;
  --admin-dialog-pad: var(--space-6);
  --admin-signin-pad: clamp(24px, 4vw, 36px);
  --admin-signin-gap: 22px;
  --admin-signin-h1: clamp(28px, 4.6vw, 36px);
  --admin-signin-logo-w: 160px;
  --admin-field-gap: var(--space-5);
}
.kan-admin__main { padding: var(--admin-main-pad); display: flex; flex-direction: column; gap: var(--admin-stack); min-width: 0; }
.kan-admin__main--narrow > * { max-width: 720px; }
.kan-admin__header { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.kan-admin__header-text { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.kan-admin__header-actions { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.kan-admin__h1-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.kan-admin__h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: var(--admin-h1);
  line-height: 1.15;
  color: var(--text-heading);
}
.kan-admin__header .kan-overline { font-size: var(--admin-overline-fs); }
.kan-admin-h2 { margin: 0; font-family: var(--font-ui); font-size: var(--fs-h4); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-admin-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.kan-admin-section { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-inline-link { color: var(--text-link); font-weight: var(--fw-semibold); text-underline-offset: 0.18em; display: inline-flex; align-items: center; min-height: var(--touch-min); }

.kan-kpi__value { margin: 0; font-family: var(--font-numeric); font-weight: var(--fw-bold); font-size: var(--admin-stat-value); line-height: 1.1; color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-kpi__note { margin: 0; font-size: var(--fs-overline); color: var(--text-muted); }

/* Search */
/* The field and its button stay on one line: with `flex-wrap: wrap` the form's shrink-to-fit
   width collapsed to the input alone and dropped "Hľadať" underneath it on every admin list. */
.kan-search { display: flex; align-items: center; gap: var(--space-2); flex-wrap: nowrap; flex: 0 1 452px; }
.kan-search__wrap { position: relative; display: flex; align-items: center; flex: 0 1 320px; min-width: 0; color: var(--text-muted); }
@media (max-width: 560px) { .kan-search { flex-wrap: wrap; } }
.kan-search__wrap .kan-icon { position: absolute; left: var(--space-4); pointer-events: none; }
.kan-search__input { padding-left: var(--space-10); font-size: var(--fs-small); }

/* DataTable */
.kan-table-wrap {
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-1);
  overflow-x: auto;
  /* SESSION-11N §10 fix · a flex item's automatic min-width is content-based by default —
     `overflow-x: auto` is supposed to reset that to 0 per spec, but this wrapper sits
     directly in `main.kan-admin__main` (display: flex) and a wide table (many columns, every
     header `white-space: nowrap`) still stretched the whole page instead of scrolling inside
     its own box (measured: hiding it dropped `documentElement.scrollWidth` back to the
     viewport width). An explicit `min-width: 0` is the standard, engine-independent fix. */
  min-width: 0;
  /* 28. 9. 2026 · the containing block of what is positioned inside the rows — above all the
     `.kan-sr-only` spans. Without it they were placed against the page, outside this scrolling
     box, so on a fine pointer (admin-density.css caps the box's height) every row below the fold
     still stretched the page with an empty band under the admin. */
  position: relative;
}
.kan-table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.kan-table th, .kan-table td { padding: var(--admin-cell-py) var(--admin-cell-px); text-align: left; vertical-align: middle; border-bottom: 1px solid var(--border-subtle); }
.kan-table thead th { background: transparent; font-size: var(--fs-overline); font-weight: var(--fw-medium); letter-spacing: 0.06em; color: var(--text-muted); white-space: nowrap; }
.kan-table tbody tr:last-child td { border-bottom: 0; }
.kan-table__head { display: inline-flex; align-items: center; min-height: var(--touch-min); }
.kan-table__sort { display: inline-flex; align-items: center; gap: 4px; min-height: var(--touch-min); color: inherit; text-decoration: none; }
.kan-table__sort:hover { color: var(--text-heading); }
.kan-table th.is-sorted .kan-table__sort { color: var(--text-heading); }
.kan-table__num { text-align: right !important; font-variant-numeric: tabular-nums; white-space: nowrap; }
.kan-table__strong { font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-table__sub { display: block; font-size: var(--fs-overline); font-weight: var(--fw-regular); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-table__muted { font-size: var(--fs-legal); color: var(--text-muted); display: inline-flex; align-items: center; min-height: var(--touch-min); }
.kan-table__actions { text-align: right !important; white-space: nowrap; }
.kan-table__actions .kan-btn + .kan-btn { margin-left: var(--space-2); }
.kan-table tr.is-flagged td { border-bottom: 0; }
.kan-table__review td { background: var(--warning-surface); padding-top: 0; }
.kan-review { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; padding: var(--space-2) 0 var(--space-3); }
.kan-review__text { margin: 0; display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; font-size: var(--fs-legal); color: var(--warning-text); }
.kan-review__text .kan-table__sub { display: inline; }
.kan-review__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.kan-status-cell { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.kan-status-cell__line { font-size: var(--fs-overline); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-status-cell__flag { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-overline); font-weight: var(--fw-semibold); color: var(--warning-text); }

.kan-badge--pending { background: var(--status-paused-bg); border-color: var(--status-paused-bd); color: var(--status-paused-fg); }

/* Pagination */
.kan-pagination { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.kan-pagination__summary { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-pagination__links { display: flex; gap: var(--space-2); }
/* SESSION-11N §10 fix · „Predchádzajúca strana"/„Ďalšia strana" together are wider than a
   375 px viewport (with icon + gutters) — `.kan-pagination` itself already wraps, but that
   only helps once the LINKS as a whole drop to their own line; the two buttons inside them
   never did, so they ran the whole page wide instead. Below the same breakpoint the summary
   already used (`.kan-search`, S11I), each button takes half the row instead. */
@media (max-width: 560px) {
  .kan-pagination__links { width: 100%; }
  .kan-pagination__links .kan-btn { flex: 1 1 0; min-width: 0; text-align: center; }
}

/* Buttons: the quiet destructive variant (10-design-system) */
.kan-btn--destructive-quiet { background: var(--destructive-quiet-bg); color: var(--destructive-quiet-text); border-color: var(--destructive-quiet-border); }
.kan-btn--destructive-quiet:hover:not(:disabled) { background: var(--destructive-quiet-bg-hover); }
.kan-btn--destructive-quiet:disabled { background: transparent; }

.kan-note { border-left: 1px solid var(--border-default); padding: 2px 0 2px 14px; display: flex; flex-direction: column; gap: 4px; }
.kan-note__head { margin: 0; font-size: var(--fs-overline); color: var(--text-muted); }
.kan-note__body { margin: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--text-body); text-wrap: pretty; white-space: pre-line; }
.kan-contact { margin: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.kan-contact div { display: flex; flex-direction: column; gap: 2px; }
.kan-contact dd { margin: 0; font-size: var(--fs-small); color: var(--text-body); overflow-wrap: anywhere; }
.kan-admin-grid-zip { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: var(--space-3); }

/* Refund / cancel "modal" as a page */
.kan-admin-modal {
  width: 100%;
  max-width: 540px;
  background: var(--surface-card);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
  padding: var(--admin-modal-pad);
  display: flex;
  flex-direction: column;
  gap: var(--admin-modal-gap);
}
.kan-admin-modal__head { display: flex; align-items: center; gap: var(--space-3); }
.kan-admin-modal__icon { width: 40px; height: 40px; border-radius: var(--radius-pill); flex: 0 0 auto; display: grid; place-items: center; background: var(--accent-subtle); color: var(--accent); }
.kan-admin-modal__title { margin: 0; font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--admin-modal-title); line-height: 1.12; color: var(--text-heading); }
.kan-summary {
  margin: 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  padding: 14px var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.kan-summary div { display: flex; justify-content: space-between; gap: var(--space-4); font-size: var(--fs-legal); }
.kan-summary dt { color: var(--text-muted); }
.kan-summary dd { margin: 0; color: var(--text-heading); font-weight: var(--fw-semibold); text-align: right; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.kan-checkbox__hint { margin: 4px 0 0 34px; }
.kan-file { padding-top: 10px; }

/* Kill switch */
.kan-kill {
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-1);
  padding: var(--admin-card-pad);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.kan-kill.is-on { border-color: var(--warning-border); background: var(--warning-surface); }
.kan-kill__body { margin: 4px 0 0; font-size: var(--fs-legal); line-height: 1.55; color: var(--text-body); text-wrap: pretty; }

/* Sign-in card (AdminPrihlasenie.dc.html) */
.kan-admin-signin {
  min-height: 100vh;
  background: var(--bg-alt);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: clamp(32px, 6vw, 72px) var(--space-4);
}
.kan-admin-signin__card {
  width: 100%;
  max-width: 460px;
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-1);
  padding: var(--admin-signin-pad);
  display: flex;
  flex-direction: column;
  gap: var(--admin-signin-gap);
}
.kan-admin-signin__head { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.kan-admin-signin__logo { width: var(--admin-signin-logo-w); max-width: 100%; height: auto; display: block; align-self: center; }
.kan-admin-signin__h1 { margin: 0; font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--admin-signin-h1); line-height: 1.08; letter-spacing: var(--ls-display); color: var(--text-heading); }
.kan-admin-signin__who { justify-content: flex-start; align-items: center; gap: 10px; }
.kan-admin-signin__shield { color: var(--accent); display: grid; }
.kan-admin-signin__clock { margin: 0; display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-legal); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-totp-input {
  font-family: var(--font-numeric);
  font-size: 1.75rem;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.45em;
  text-align: center;
  min-height: var(--control-h-lg);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 899px) {
  .kan-admin { --admin-main-pad: var(--space-5) var(--space-4); --admin-h1: 30px; }
  .kan-admin-modal { padding: var(--space-5); }
}

/* Paused donations (04 §7): the bank-transfer block with the static Pay by Square QR. */
.kan-transfer-switch { display: flex; flex-direction: column; gap: var(--space-4); }
.kan-transfer-switch__nav .kan-freq__legend { margin: 0; }
.kan-transfer-switch__track { margin-top: var(--space-2); }
.kan-transfer-switch__link { text-decoration: none; min-height: var(--touch-min); }
.kan-transfer-switch__link:hover { color: var(--accent); }
.kan-transfer-switch__link.is-active { background: var(--paper); border-color: var(--accent); box-shadow: var(--shadow-1); color: var(--accent); }
.kan-transfer-switch__link:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }

/* Pravidlá darovania in the admin: the versions, the draft form, the WYSIWYG editor
   (contenteditable + toolbar of real 44 px buttons) and the SK/EN tabs. Without JS the
   textarea is the editor and both languages show stacked. */
.kan-rules { display: flex; flex-direction: column; gap: var(--space-5); max-width: 920px; }
.kan-rules__fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-4); }
/* S11F §5: the translation lives beside „Zobraziť na portáli" as the card's second small
   action; opened, it takes a row of its own. */
.kan-rules__details { flex: 0 0 auto; min-width: 0; }
.kan-rules__details[open] { flex: 1 1 100%; }
.kan-rules__summary {
  cursor: pointer;
  min-height: var(--control-h-sm);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--accent);
}
.kan-rules__summary:hover { background: var(--accent-subtle); }
.kan-rules__summary:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-rules__details[open] .kan-rules__summary { margin-bottom: var(--space-3); }
.kan-rules__archive { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); font-size: var(--fs-small); }
.kan-rules__archive li { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: baseline; }
.kan-rules__archive a { color: var(--text-link); font-weight: var(--fw-semibold); text-underline-offset: 0.18em; }
.kan-rules__archive span { color: var(--text-muted); }

.kan-editor { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.kan-editor__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2);
  background: var(--surface-sunken);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
/* S11F §5 (decision 13): an icon and nothing else — the word travels in aria-label/title. */
.kan-editor__btn {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: var(--control-h);
  height: var(--control-h);
  padding: 0;
  color: var(--text-heading);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-editor__btn:hover { border-color: var(--accent); color: var(--accent); }
.kan-editor__btn:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-editor__btn[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.kan-editor__area {
  min-height: 360px;
  max-height: 70vh;
  overflow: auto;
  padding: var(--space-5);
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-top: 0;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  color: var(--text-body);
}
.kan-editor__area:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: -3px; }
.kan-editor__area[aria-invalid="true"] { border-color: var(--danger-border); }
.kan-editor__source { min-height: 280px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-small); }
.no-js .kan-editor__toolbar, .no-js .kan-editor__area { display: none; }
html:not(.no-js) .kan-editor__source, html:not(.no-js) .kan-editor__source-label { display: none; }

.kan-lang-tabs { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-lang-tabs__list { display: flex; gap: var(--space-2); }
.kan-lang-tabs__tab {
  min-height: 44px;
  padding: 0 var(--space-3);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  cursor: pointer;
}
.kan-lang-tabs__tab:hover { color: var(--accent); }
.kan-lang-tabs__tab[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); }
.no-js .kan-lang-tabs__head { display: none; }
.no-js .kan-lang-tabs__panel[hidden] { display: block; }

/* The calm day-level deadline under a page's own meter (SESSION-10 §1). */
.kan-deadline { margin: 0; font-size: var(--fs-overline); color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* ============================================================================
   SESSION-10 · Darovacie stránky
   Public: the lead under the H1, the labelled amount chip, the single-frequency
   line and the preview note. Admin: the Stránky list, the two-column editor with
   its sticky preview, the photo library and its picker.
   Tokens only — no new colours, radii or shadows (CLAUDE.md rule 9).
   ========================================================================== */

/* --- Public page ---------------------------------------------------------- */
.kan-hero__lead {
  margin: var(--space-3) 0 0;
  max-width: 52ch;
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: var(--text-on-dark-muted);
}
.kan-hero__meter-deadline { margin: var(--space-1) 0 0; color: var(--text-on-dark-muted); }
/* A chip with a short label stacks the amount over it — two lines inside one pill. */
.kan-chip__note {
  display: block;
  margin-top: 1px;
  font-size: var(--fs-overline);
  font-weight: var(--fw-regular);
  color: var(--text-muted);
}
.kan-chip:has(input:checked) .kan-chip__note { color: var(--navy-100); }
.kan-chip:has(.kan-chip__note:not([hidden])) .kan-chip__face { min-height: 46px; }
/* One frequency: a plain readable line, no dot and no recommendation (SESSION-10B §4). */
.kan-acc__single-kind {
  margin: 0 0 var(--space-4);
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
}
/* Three or more campaigns: a vertical list of choices, because the pills break the row. */
.kan-acc__switch { display: flex; flex-direction: column; gap: var(--space-1); }
.kan-acc__switch-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  font-family: var(--font-ui);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-body);
  text-decoration: none;
}
.kan-acc__switch-item:hover { background: var(--bg-alt); }
.kan-acc__switch-item.is-selected { color: var(--text-heading); }
.kan-acc__switch-mark {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-pill);
  color: var(--on-accent);
}
.kan-acc__switch-item.is-selected .kan-acc__switch-mark { border-color: var(--accent); background: var(--accent); }
.kan-acc__preview-note {
  margin: var(--space-2) 0 0;
  text-align: center;
  font-size: var(--fs-legal);
  color: var(--text-muted);
}

/* --- Admin: shared small controls ---------------------------------------- */
.kan-iconbtn:hover { color: var(--text-heading); }
/* `display: inline-grid` of the icon button below would otherwise beat the `hidden` attribute (S11F: the photo submit icon
   stands down once the upload button takes over). */
.kan-iconbtn[hidden] { display: none; }
.kan-counter {
  margin-left: auto;
  padding-left: var(--space-3);
  font-size: var(--fs-legal);
  font-weight: var(--fw-regular);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.kan-field__label { display: flex; align-items: baseline; }

/* S11F 1.3 (decision 6): the track is the SAME length in every row — fixed, never `flex: 1`,
   so two lists read as one. The percentage is right-aligned and tabular, and the pencil sits
   in a slot that is there even when it is empty, so no bar ever shifts. */
.kan-fill { display: flex; align-items: center; gap: var(--space-3); }
.kan-fill__track { display: block; flex: 0 0 auto; width: 120px; height: 6px; border-radius: var(--radius-meter); background: var(--meter-track); overflow: hidden; }
.kan-fill__bar { display: block; height: 100%; border-radius: var(--radius-meter); background: var(--meter-fill); }
.kan-fill__bar.is-complete { background: var(--meter-fill-complete); }
.kan-fill__pct {
  flex: 0 0 auto;
  width: 46px;
  text-align: right;
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text-heading);
}
.kan-fill__slot {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch-min);
  height: var(--touch-min);
}

/* --- Admin: the page editor ---------------------------------------------- */
.kan-pageform { display: flex; flex-direction: column; gap: var(--space-5); }
/* Fifty-fifty (SESSION-10B §2.1): the editor is a deliberate desktop screen, and the
   preview grows with it. Below 1180 px it is one column, as before. */
.kan-pageform__cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); align-items: start; }
.kan-pageform__main { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }
.kan-pageform__side { position: sticky; top: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
@media (max-width: 1180px) {
  .kan-pageform__cols { grid-template-columns: minmax(0, 1fr); }
  .kan-pageform__side { position: static; }
}

/* The address, written from the title: read-only text plus „Upraviť adresu" (§1.5). */
.kan-slugline {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: calc(var(--space-2) * -1);
}
.kan-slugline__url { margin: 0; font-size: var(--fs-body-sm); color: var(--text-muted); word-break: break-all; }
.kan-slugline__url strong { color: var(--text-heading); }
.kan-slugline__note { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--fs-legal); color: var(--text-muted); }

/* The prefix and the field are one box: the wrapper carries the input's chrome, because the
   input itself gives it up to sit flush against „dar.kolegium.org/" (SESSION-10C — without
   this the field was simply invisible). */
.kan-slug {
  align-items: center;
  min-height: var(--control-h);
  background: var(--paper);
  border: 1.5px solid var(--border-input);
  border-radius: var(--radius-input);
  box-shadow: var(--shadow-inset-input);
  transition: var(--transition-colors);
}
.kan-slug:focus-within { border-color: var(--accent); }
.kan-slug__prefix { padding-left: var(--space-4); font-size: var(--fs-body-sm); color: var(--text-muted); white-space: nowrap; }
.kan-slug__input { border: 0; box-shadow: none; padding-left: var(--space-1); background: transparent; }
.kan-slug__input:focus { border: 0; }

/* Four photos and „Pridať" always fit one row (SESSION-10B §1.2), and each tile is a square
   with its buttons on the photo rather than under it (SESSION-10C): the row stays short and
   the thumbnail stays big enough to recognise. */
.kan-photos { display: flex; flex-wrap: nowrap; gap: var(--space-3); align-items: flex-start; }
.kan-photos__item { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.kan-photos__frame {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-image);
  background: var(--bg-alt);
  overflow: hidden;
}
.kan-photos__frame img { display: block; width: 100%; height: 100%; object-fit: cover; }
.kan-photos__order {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--paper);
  color: var(--text-heading);
  font-size: var(--fs-legal);
  font-weight: var(--fw-bold);
}
.kan-photos__name {
  margin: 0;
  overflow: hidden;
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The buttons sit on the photo: a strip along the bottom edge, over a soft scrim so the
   icons stay legible on any picture. 44 px targets are kept (CLAUDE.md 12). */
.kan-photos__actions {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  gap: 0;
  padding: 2px;
  background: var(--scrim);
}
.kan-photos__actions .kan-iconbtn { width: auto; flex: 1 1 0; min-width: 0; height: 40px; color: var(--text-on-dark); }
.kan-photos__actions .kan-iconbtn:hover { background: var(--surface-inverse); color: var(--text-on-dark); }
.kan-photos__actions .kan-iconbtn:focus-visible { outline-offset: -2px; }
.kan-photos__add {
  flex: 1 1 0;
  min-width: 0;
  aspect-ratio: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-image);
  background: transparent;
  color: var(--text-link);
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.kan-photos__add:hover { background: var(--bg-alt); }

.kan-amounts { display: flex; flex-direction: column; gap: var(--space-2); }
.kan-amountrow { display: grid; grid-template-columns: 116px minmax(0, 1fr) var(--touch-min); gap: var(--space-2); align-items: center; }
/* Two equal fields side by side — the meter's four boxes, a campaign's name/short pair. */
.kan-pairs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
@media (max-width: 720px) { .kan-pairs { grid-template-columns: minmax(0, 1fr); } }

/* SESSION-11K · „Meradlo": what the page measures, in the rhythm of every other card of this
   form — and folded away entirely while the page shows the zbierka's meter. */
.kan-meterfields { display: flex; flex-direction: column; gap: var(--admin-field-gap, var(--space-5)); min-width: 0; }
.kan-meterfields[hidden] { display: none; }

.kan-preview { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--admin-card-pad); background: var(--surface-card); border: 1px solid var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow-1); }
.kan-preview__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.kan-preview__sizes { display: flex; gap: var(--space-1); padding: 3px; border-radius: var(--radius-pill); background: var(--bg-alt); }
.kan-preview__size {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 32px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  color: var(--text-body);
  cursor: pointer;
}
.kan-preview__size.is-active { background: var(--paper); color: var(--text-heading); box-shadow: var(--shadow-1); }
.kan-preview__url {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--bg-alt);
  font-size: var(--fs-body-sm);
  color: var(--text-muted);
}
.kan-preview__url strong { color: var(--text-heading); }
.kan-preview__url .kan-inline-link { margin-left: auto; display: inline-flex; align-items: center; gap: var(--space-2); }
/* The stage: admin.js computes the scale from its real width and sets the height to match
   (SESSION-10B §1.3), so no band of stage is ever left showing beside the frame. These are
   the values before the script runs and the fallback without it. */
.kan-preview__stage { border-radius: var(--radius-image); background: var(--bg-alt); overflow: hidden; height: 320px; }
.kan-preview__frame { display: block; width: 1180px; height: 760px; border: 0; transform-origin: top left; transform: scale(0.42); }
.kan-preview__stage.is-mobile .kan-preview__frame { width: 375px; height: 667px; transform: scale(0.85); }

/* The live/draft state, in the kill switch's grammar (SESSION-10B §6). The copy button sits
   at the right end of the banner (SESSION-10C). */
.kan-pagestate__copy { margin-left: auto; align-self: flex-start; }
.kan-btn.is-copied { color: var(--success-text); border-color: var(--success-border); }

/* --- Admin: Knižnica fotiek + zdieľaný dialóg -------------------------------- */

.kan-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: var(--space-4); }
.kan-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2);
  border: 1.5px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-tile:hover { background: var(--bg-alt); }
.kan-tile.is-selected { border-color: var(--accent); background: var(--accent-subtle); }
.kan-tile__frame { position: relative; display: block; border-radius: var(--radius-image); background: var(--bg-alt); overflow: hidden; }
.kan-tile__frame img { display: block; width: 100%; height: 112px; object-fit: cover; }
.kan-tile__name {
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-ui);
  color: var(--text-heading);
  text-decoration: none;
}

.kan-media__meta { margin: 0; font-size: var(--fs-legal); line-height: var(--lh-ui); color: var(--text-muted); }

/* One dialog vocabulary for the whole admin: the photo picker and the upload form.
   Native <dialog> — no library, no cookie. */
.kan-dialog { width: min(560px, 94vw); max-height: 90vh; padding: 0; border: 0; border-radius: var(--radius-xl); background: transparent; }
.kan-dialog--wide { width: min(1120px, 94vw); }
.kan-dialog::backdrop { background: var(--scrim); }
.kan-dialog__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-height: 90vh;
  overflow: auto;
  padding: var(--admin-dialog-pad);
  background: var(--surface-card);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card);
  text-align: left;
}
.kan-dialog--wide .kan-dialog__card { gap: var(--space-5); }
.kan-dialog__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.kan-dialog__head p, .kan-dialog__head h2 { margin: 0; }
.kan-dialog__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }

/* Poistky kódom (25. 9. 2026) · x-admin.step-up: one dialog, two steps (confirm, then the
   code). A step and the overline hide with the plain `hidden` attribute. */
.kan-step-up__step { display: flex; flex-direction: column; gap: var(--space-4); }
.kan-step-up [hidden] { display: none; }
.kan-step-up__step .kan-kill__body p { margin: 0; }

.kan-file { padding: 10px var(--space-3); line-height: 1.4; }

/* --- The cropper (SESSION-10C) -------------------------------------------------------
   The whole photo, with a 16:9 rectangle on it: drag it, drag its corners and edges, and
   everything outside dims away. The dashed inner lines are the narrow-screen crop — a phone
   paints the photo in a 375 x 300 box, so it keeps the height and trims the sides. */
.kan-cropper { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-cropper__stage {
  position: relative;
  /* Replaced by the photo's own shape as soon as it loads (admin.js). */
  aspect-ratio: 16 / 9;
  max-height: 62vh;
  border-radius: var(--radius-image);
  background: var(--bg-alt);
  overflow: hidden;
  touch-action: none;
  user-select: none;
}
.kan-cropper__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }
/* SESSION-11J §A: only the square dialog wraps the image in `.kan-cropper__mask` (client
   feedback 17. 9. 2026) — the mask, not the stage, clips the photo and the dimming `__scrim`
   to the photo's own bounds, so `.kan-cropper__sel` and its handles can sit OUTSIDE it,
   unclipped, even when the crop touches an edge. Unused by the 16:9 media cropper, which still
   clips on the stage itself. */
.kan-cropper__mask { position: absolute; inset: 0; overflow: hidden; border-radius: var(--radius-image); }
.kan-cropper__scrim { position: absolute; box-shadow: 0 0 0 9999px var(--scrim); pointer-events: none; }
.kan-cropper__sel {
  --crop-edge: 1.5px;
  position: absolute;
  border: var(--crop-edge) solid var(--paper);
  box-shadow: 0 0 0 9999px var(--scrim);
  cursor: move;
}
.kan-cropper__sel.is-dragging { cursor: grabbing; }
.kan-cropper__sel:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: 2px; }
/* What a narrow screen still shows: the middle of the width, full height. The insets are
   fractions of the crop's width from the same config as the phone's band (HeroBand, set on
   .kan-cropper) — S11C §5. The guide lives inside the selection's border, so the fraction is
   taken of the OUTER width (100% + both edges) and shifted back by one edge: pixel-exact. */
.kan-cropper__safe {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc((100% + 2 * var(--crop-edge)) * var(--crop-mobile-inset, 0) - var(--crop-edge));
  right: calc((100% + 2 * var(--crop-edge)) * var(--crop-mobile-inset, 0) - var(--crop-edge));
  border-left: 1.5px dashed var(--paper);
  border-right: 1.5px dashed var(--paper);
  opacity: 0.8;
  pointer-events: none;
}
/* The lighter second guide: a common laptop window. */
.kan-cropper__safe--desktop {
  left: calc((100% + 2 * var(--crop-edge)) * var(--crop-desktop-inset, 0) - var(--crop-edge));
  right: calc((100% + 2 * var(--crop-edge)) * var(--crop-desktop-inset, 0) - var(--crop-edge));
  border-left-style: dotted;
  border-right-style: dotted;
  opacity: 0.55;
}
.kan-cropper__handle {
  position: absolute;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-pill);
}
/* The visible grip is small; the target around it is not. SESSION-11J §A: added a border in an
   existing token colour so the grip reads as a grab point rather than a stray mark on the
   photo (client feedback 17. 9. 2026). */
.kan-cropper__handle::after {
  content: '';
  position: absolute;
  inset: 8px;
  border-radius: 3px;
  background: var(--paper);
  border: 1.5px solid var(--border-strong);
  box-shadow: var(--shadow-1);
}
.kan-cropper__handle--nw { top: -13px; left: -13px; cursor: nwse-resize; }
.kan-cropper__handle--ne { top: -13px; right: -13px; cursor: nesw-resize; }
.kan-cropper__handle--se { bottom: -13px; right: -13px; cursor: nwse-resize; }
.kan-cropper__handle--sw { bottom: -13px; left: -13px; cursor: nesw-resize; }
.kan-cropper__handle--n { top: -13px; left: 50%; margin-left: -13px; cursor: ns-resize; }
.kan-cropper__handle--s { bottom: -13px; left: 50%; margin-left: -13px; cursor: ns-resize; }
.kan-cropper__handle--w { left: -13px; top: 50%; margin-top: -13px; cursor: ew-resize; }
.kan-cropper__handle--e { right: -13px; top: 50%; margin-top: -13px; cursor: ew-resize; }
/* What the crop will actually produce; it turns to a warning at the quality floor. */
.kan-cropper__result {
  margin: 0;
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.kan-cropper__result.is-floor { color: var(--warning-text); }
.kan-cropper__sel.is-floor { border-color: var(--warning-text); }
.kan-cropper__controls { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.kan-cropper__legend { display: flex; align-items: flex-start; gap: var(--space-2); margin: 0; max-width: 52ch; font-size: var(--fs-legal); line-height: var(--lh-ui); color: var(--text-muted); }
.kan-cropper__legend-key { flex: 0 0 auto; width: 14px; height: 14px; margin-top: 2px; border-left: 1.5px dashed var(--text-muted); border-right: 1.5px dashed var(--text-muted); }
.kan-cropper__legend-key--desktop { width: 18px; border-left-style: dotted; border-right-style: dotted; }
.kan-cropper__legends { display: flex; flex-direction: column; gap: var(--space-1); }

/* A class that sets `display` beats the UA's `[hidden]` rule — these are all toggled by JS
   (chips of the other frequency, the reveals in the page editor), so say it explicitly. */
.kan-btn[hidden],
.kan-field__error[hidden],
.kan-cropper__result[hidden],
.kan-cropper[hidden],
.kan-slugline[hidden],
.kan-chip[hidden],
.kan-chip__note[hidden],
.kan-acc__single-kind[hidden],
.kan-field[hidden],
.kan-amounts[hidden],
.kan-photos__add[hidden],
.kan-admin-grid-zip[hidden],
.kan-pairs[hidden] { display: none; }
/* Etapy zbierky (25. 9. 2026) · the ladder under „Zbierka má etapy": one row per stage, the
   remove button level with the input, half the form's width on a desktop. */
.kan-stages { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: var(--space-3); }
.kan-stages[hidden] { display: none; }
.kan-stages__list { display: grid; gap: var(--space-3); }
.kan-stages__row { display: flex; align-items: flex-end; gap: var(--space-2); max-width: 26rem; }
.kan-stages__row > .kan-field { flex: 1 1 auto; min-width: 0; }
.kan-stages__row > .kan-iconbtn { flex: none; margin-bottom: var(--space-1); }

/* SESSION-11B §3.4 · Moja podpora on a desk: the support cards and the gift history use
   md controls at 40 px and a 15 px body, so three years of history fit one screen. Mobile
   is byte-for-byte what it was — this block exists only on a wide screen with a mouse, and
   it never touches the giving accordion, the result screens or the e-mails. */
@media (min-width: 1024px) and (pointer: fine) {
  .kan-support,
  .kan-account-card {
    --control-h: 40px;
    --fs-body: 0.9375rem;
    padding: var(--space-4) var(--space-5);
    gap: var(--space-3);
  }
  .kan-support__amount { font-size: 1.25rem; }
  .kan-support .kan-result-row,
  .kan-account-card .kan-result-row { padding: 8px 0; }
}

/* SESSION-11 · Trvalé príkazy: the rows a CSV import would skip, in the file's own numbering. */
.kan-import-problems { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-small); line-height: var(--lh-ui); color: var(--text-body); }
.kan-import-problems li { text-wrap: pretty; }

.kan-totp-secret { margin: 0; font-family: var(--font-numeric); font-size: var(--fs-h4); font-weight: var(--fw-semibold); letter-spacing: 0.12em; color: var(--text-heading); overflow-wrap: anywhere; }

/* S11D · A — účet a prihlásenie kódom */
/* A1: the portal's three uses — the board's kan-result-list, as a real list. */
.kan-entry-list { margin: 0; padding: 0; list-style: none; }
/* „Zadajte kód": six digits, read at a glance; the field is as wide as they need. */
.kan-code-field .kan-input {
  max-width: 14rem;
  font-family: var(--font-numeric);
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.3em;
}
/* A5: name, surname and phone sit as one group, closer than the form's other rows. */
.kan-register-fields { display: flex; flex-direction: column; gap: var(--space-3); }

/* S11D · B — verejná osobná kampaň a dar */
/* The author's box (decision 18): a white card, the square photo floated left so the text
   flows round it, the text dark, the grey signature last — the page's H1. Tokens only. */
.kan-fund-box {
  display: flow-root;
  padding: 14px;
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  color: var(--text-heading);
  text-align: left;
}
.kan-fund-box__photo {
  float: left;
  width: 88px;
  height: 88px;
  margin: 0 14px 6px 0;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.kan-fund-box__text {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: 1.6;
  color: var(--text-heading);
  overflow-wrap: anywhere;
  text-wrap: pretty;
}
.kan-fund-box__signature {
  clear: both;
  margin: 0;
  padding-top: 10px;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  line-height: 1.5;
  letter-spacing: normal;
  color: var(--text-muted);
  text-wrap: pretty;
}
.kan-fund-box__signature a { color: inherit; text-underline-offset: 0.18em; }
.kan-fund-box__signature a:hover { color: var(--text-heading); }
/* The white cards sit inside the dark page: its gold focus ring would vanish on them. */
.kan-on-dark .kan-fund-box :where(a):focus-visible,
.kan-on-dark .kan-fund-form :where(a, button, input, select, textarea):focus-visible,
.kan-on-dark .kan-fund-ended-card :where(a, button):focus-visible { outline-color: var(--focus-ring); }

/* The gold tag on the photo, a link to the explainer: the meter's gold pill in tracked caps.
   The invisible extension keeps the 44 px target. */
.kan-fund-tag {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: var(--highlight);
  color: var(--on-highlight);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: var(--fw-bold);
  line-height: 1.4;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  text-decoration: none;
}
.kan-fund-tag::after { content: ""; position: absolute; inset: -10px -4px; }
.kan-fund-tag:hover { background: var(--highlight-hover); color: var(--on-highlight); text-decoration: none; }

/* The page around them (B7/B8/B9): the darovacia stránka's hero, one meter, no chip. */
.kan-fund-page .kan-hero__left { gap: var(--space-5); }
.kan-fund-meter--hero { padding-bottom: var(--space-12); }
/* The form (decision 20): the accordion's card. Its two steps and the author's opener are
   in the „Jeden box" block at the end of this file. */
.kan-fund-form .kan-acc__single-kind { margin: 0; font-family: var(--font-ui); line-height: var(--lh-ui); }

/* The meter as a standalone light card (x-fundraiser.meter variant="card"). */
.kan-fund-meter--card { display: flex; flex-direction: column; gap: 10px; }
.kan-fund-meter__eyebrow { margin: 0; font-size: 11px; font-weight: var(--fw-semibold); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.kan-fund-meter__raised { margin: 0; font-family: var(--font-numeric); font-weight: var(--fw-bold); font-size: var(--fs-amount); line-height: 1.05; color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-fund-meter__track { height: 6px; border-radius: var(--radius-pill); background: var(--meter-track); overflow: hidden; }
.kan-fund-meter__fill { height: 100%; border-radius: var(--radius-pill); background: var(--meter-fill); }
.kan-fund-meter__next { margin: 0; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-body); font-variant-numeric: tabular-nums; }

@media (max-width: 719.98px) {
  /* One group of dots, bottom right of the band. */
  .kan-fund-page .kan-hero__dots--corner { display: flex; right: var(--space-4); bottom: 18px; }
}

/* B1 · the explainer at /osobna-kampan. */
.kan-fund-about .kan-result-main { padding-top: var(--space-8); }
.kan-fund-about__col { gap: var(--space-6); }
.kan-fund-about__head { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-fund-about__h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: clamp(38px, 4.2vw, 52px);
  line-height: 1.05;
  letter-spacing: var(--ls-display);
  color: var(--text-heading);
  text-wrap: balance;
}
.kan-fund-about__lead { margin: 0; font-size: var(--fs-lead); line-height: var(--lh-lead); color: var(--text-body); text-wrap: pretty; }
.kan-fund-steps { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--space-3); }
.kan-fund-steps__item {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: var(--space-4);
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.kan-fund-steps__num {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
}
.kan-fund-steps__title { margin: 0; font-family: var(--font-ui); font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: var(--lh-ui); color: var(--text-heading); }
.kan-fund-steps__body { margin: var(--space-1) 0 0; font-size: var(--fs-small); line-height: 1.5; color: var(--text-body); }

/* S11D · C — autor: sprievodca, zoznam, detail */
/* The wizard's place: the overline plus one bar per step (two when step 1 has no choice). */
.kan-fund-steps { display: flex; flex-direction: column; gap: var(--space-2); }
.kan-steps { display: grid; grid-template-columns: repeat(var(--steps, 3), minmax(0, 1fr)); gap: 6px; }
.kan-steps__bar { height: 4px; border-radius: var(--radius-pill); background: var(--border-default); }
.kan-steps__bar--on { background: var(--accent); }

/* Step 1: one card per campaign, a real radio inside (keyboard and screen reader for free). */
.kan-picks { margin: 0; padding: 0; border: 0; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.kan-pick {
  position: relative;
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  min-height: var(--touch-min);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border: 1.5px solid var(--border-default);
  background: var(--paper);
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-pick:hover { border-color: var(--accent-border); }
.kan-pick:has(.kan-pick__input:checked) { border-color: var(--accent); background: var(--accent-subtle); box-shadow: var(--shadow-1); }
.kan-pick:has(.kan-pick__input:focus-visible) { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-pick__input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.kan-pick__mark {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--border-input);
  background: var(--paper);
  display: grid;
  place-items: center;
  color: var(--on-accent);
}
.kan-pick__mark .kan-icon { visibility: hidden; }
.kan-pick:has(.kan-pick__input:checked) .kan-pick__mark { background: var(--accent); border-color: var(--accent); }
.kan-pick:has(.kan-pick__input:checked) .kan-pick__mark .kan-icon { visibility: visible; }
.kan-pick__text { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.kan-pick__title { display: block; font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-pick__line { display: block; font-size: var(--fs-small); line-height: 1.5; color: var(--text-body); }

/* Step 2 · the photo (S11H §5: the stored square and the file button moved into `x-photo-crop`
   below — the wizard and the admin now share one field, so there is no `.kan-fund-photo*` of
   its own here any more). */
/* The square cropper reuses the library's cropper (S10C) with 44 px handles — the visible
   grip stays 12 px, the target around it is the full touch size (CLAUDE.md 12).
   SESSION-11J §A (client feedback 17. 9. 2026): the stage no longer clips (`.kan-cropper__mask`
   does, see above) — a corner dot is 20 px, an edge dot 12 px, so corners read as the more
   prominent grab points and edges as the lesser ones. `.kan-cropper__sel` carries no shadow of
   its own here; `.kan-cropper__scrim`, inside the clipped mask, dims the photo instead. */
.kan-cropper--square .kan-cropper__stage { max-height: 60vh; overflow: visible; }
.kan-cropper--square .kan-cropper__sel { box-shadow: none; }
.kan-cropper--square .kan-cropper__handle { width: var(--touch-min); height: var(--touch-min); }
.kan-cropper--square .kan-cropper__handle::after { inset: 12px; border-radius: 4px; }
.kan-cropper--square .kan-cropper__handle--n::after,
.kan-cropper--square .kan-cropper__handle--s::after,
.kan-cropper--square .kan-cropper__handle--e::after,
.kan-cropper--square .kan-cropper__handle--w::after { inset: 14px; }
.kan-cropper--square .kan-cropper__handle--nw { top: -22px; left: -22px; }
.kan-cropper--square .kan-cropper__handle--ne { top: -22px; right: -22px; }
.kan-cropper--square .kan-cropper__handle--se { bottom: -22px; right: -22px; }
.kan-cropper--square .kan-cropper__handle--sw { bottom: -22px; left: -22px; }
.kan-cropper--square .kan-cropper__handle--n { top: -22px; left: 50%; margin-left: -22px; }
.kan-cropper--square .kan-cropper__handle--s { bottom: -22px; left: 50%; margin-left: -22px; }
.kan-cropper--square .kan-cropper__handle--w { left: -22px; top: 50%; margin-top: -22px; }
.kan-cropper--square .kan-cropper__handle--e { right: -22px; top: 50%; margin-top: -22px; }
/* Desktop only (the ≤ 719.98px rule below makes the dialog full-screen, where the stage must
   still stretch to fill it): let a portrait or landscape photo's own aspect-ratio shrink the
   stage's WIDTH once `max-height` caps its height, instead of the flex column's default
   stretch holding it at the full card width and letterboxing wide (point 5, client feedback
   17. 9. 2026). */
@media (min-width: 720px) {
  /* The stage holds only absolutely positioned children, so without a width of its own a
     centred flex item collapses to nothing. `--crop-ratio` (width / height, set by
     photo-crop.js with the photo) gives it one: as wide as the card allows, never so wide
     that its height would pass the 60vh cap. */
  .kan-cropper--square .kan-cropper__stage { align-self: center; width: min(100%, calc(60vh * var(--crop-ratio, 1))); }
}

/* SESSION-11H §1, bod 7: `x-photo-crop` — the field itself is only ever a preview square, its
   two icon actions, or the plain file picker; the square itself is cropped in the ONE shared
   dialog below, which reuses `.kan-cropper--square` above (the same handles, the same 60vh
   cap) instead of a copy of its own. */
.kan-photo-crop__preview { display: block; width: 200px; height: 200px; border-radius: var(--radius-image); object-fit: cover; }
.kan-photo-crop__preview--sm { width: 120px; height: 120px; }
.kan-photo-crop__preview[hidden] { display: none; }
.kan-photo-crop__actions { display: flex; gap: var(--space-2); margin-top: var(--space-2); }
.kan-photo-crop__actions[hidden] { display: none; }
.kan-photo-crop__pick { position: relative; display: flex; align-items: center; }
.kan-photo-crop__pick[hidden] { display: none; }
/* The input stays in the tab order; its label is the visible button and wears its focus. */
.kan-photo-crop__file { position: absolute; left: 0; top: 0; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.kan-photo-crop__file:focus-visible + .kan-photo-crop__pick-label { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-photo-crop__pick-label { cursor: pointer; }
.no-js .kan-photo-crop__file { position: static; width: auto; height: auto; opacity: 1; font-size: var(--fs-small); }
.no-js .kan-photo-crop__pick-label { display: none; }
/* Decision 7: 200 px, 120 px on a narrow screen — both the wizard and the admin, no separate
   `size` prop needed for it. */
@media (max-width: 479.98px) {
  .kan-photo-crop__preview { width: 120px; height: 120px; }
}

/* Step 2 · the text and its counter „169 / 400". */
.kan-fund-text__area { min-height: 148px; }
.kan-fund-text__counter { align-self: flex-end; margin: 0; font-size: var(--fs-legal); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-fund-text__counter.is-over { color: var(--danger-text); font-weight: var(--fw-semibold); }

/* SESSION-11J §C: since the private-note block above the actions is gone, the publish form's
   only child is the action row — `align-items: stretch` (not the original `flex-start`) lets
   it span the card so the chevron and the CTA sit exactly as they do on step 2. */
.kan-fund-publish { display: flex; flex-direction: column; gap: var(--space-4); align-items: stretch; }

/* An icon-only action (the secondary button's colours); its name lives in aria-label. */
.kan-iconbtn {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: var(--touch-min);
  height: var(--touch-min);
  padding: 0;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--accent-border);
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  text-decoration: none;
  transition: var(--transition-colors);
}
.kan-iconbtn:hover { background: var(--accent-subtle); border-color: var(--accent); }
.kan-iconbtn:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-iconbtn--lg { width: var(--control-h); height: var(--control-h); }
/* Copied: the icon turns into a check for a moment, in the success colour. */
.kan-fund-copy .kan-fund-copy__done { display: none; }
.kan-fund-copy.is-copied .kan-fund-copy__idle { display: none; }
.kan-fund-copy.is-copied .kan-fund-copy__done { display: inline-block; }
.kan-fund-copy.is-copied { color: var(--success-text); border-color: var(--success-border); }
/* Copy and share need JavaScript — without it they are not offered at all. */
.no-js .kan-fund-copy,
.no-js .kan-fund-share { display: none; }
.kan-fund-url { overflow-wrap: anywhere; }

/* B6 · a personal campaign in the overview.
   SESSION-11J §C: `.kan-support` already gives the article `flex-direction: column`, so this
   block only needs to stand on its own — never rely on the parent's `align-items` staying at
   its default `stretch`, an admin block elsewhere in this file also answers to `.kan-fund-card`
   and does set its own `align-items`. `width: 100%` on the top row is the same guard from the
   other side: the row spans the card even if a future rule shrinks the article to fit content. */
.kan-fund-card { gap: var(--space-3); align-items: stretch; }
.kan-fund-card__top { display: flex; align-items: flex-start; gap: var(--space-2); width: 100%; }
.kan-fund-card__head { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.kan-fund-card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.kan-fund-card__sum { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.kan-fund-card__amount { margin: 0; font-family: var(--font-numeric); font-size: var(--fs-h4); font-weight: var(--fw-bold); color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-fund-card__next { margin: 0; font-size: var(--fs-overline); color: var(--text-muted); font-variant-numeric: tabular-nums; text-align: right; }
.kan-fund-card__track { height: 6px; border-radius: var(--radius-pill); background: var(--meter-track); overflow: hidden; }
.kan-fund-card__fill { height: 100%; border-radius: var(--radius-pill); background: var(--meter-fill); }
.kan-fund-card__note { margin: 6px 0 0; font-size: var(--fs-small); line-height: var(--lh-ui); color: var(--text-muted); }

/* The personal campaign's badge — icon + word, like every status; its colours live in the
   one semantic block beside .kan-badge--active (S11F 1.6). */

/* B6b · the author's meter: the sum against the next milestone, and the number of gifts. */
.kan-fund-meter { gap: var(--space-4); }
.kan-fund-meter__figures { display: flex; flex-direction: column; gap: 10px; }
.kan-fund-meter__eyebrow { margin: 0; font-size: 11px; font-weight: var(--fw-semibold); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.kan-fund-meter__raised { margin: 0; font-family: var(--font-numeric); font-weight: var(--fw-bold); font-size: var(--fs-amount); line-height: 1.05; color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-fund-meter__track { height: 8px; border-radius: var(--radius-pill); background: var(--meter-track); overflow: hidden; }
.kan-fund-meter__fill { height: 100%; border-radius: var(--radius-pill); background: var(--meter-fill); }
.kan-fund-meter__row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-1) var(--space-3); }
.kan-fund-meter__next { margin: 0; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-body); font-variant-numeric: tabular-nums; }
.kan-fund-meter__count { margin: 0; font-size: var(--fs-small); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-fund-end { border-top: 1px solid var(--border-default); padding-top: var(--space-3); }

/* S11D · D — admin */
/* Osobné kampane: the donor's „Účet bez daru" badge (the S11F detail owns the rest). */
.kan-badge--account { background: var(--info-surface); border-color: var(--info-border); color: var(--info-text); }

/* S11E · A · portál so sidebarom */

/* Moja podpora is a portal (SESSION-11E section 2, decision A1): a top bar with the logo in
   the middle, the three places on the left, the content on the right. Section 8d added the
   account menu on the right of the bar — the donor's name, and under it the address and
   „sign out", which used to sit at the foot of the sidebar.

   SESSION-11E section 8 (Matej, after the staging click-through) took the navy column away on
   a wide screen. The bar spans the whole width, the footer spans the whole width, and between
   them `.kan-portal__body` holds the two columns — so the navigation never runs behind either
   of them. It is a plain list on the page background: no surface, no border, no shadow, only
   the lit item carries a tint. It still does not scroll with the content (sticky, and it
   scrolls inside itself when it is taller than the viewport).

   Below 900 px (the admin's own breakpoint) the same element becomes a drawer over the
   content, opened by the icon on the left of the bar — and only there is it navy. Everything
   dark lives under `html:not(.no-js)` inside that media query, so without JavaScript there is
   no drawer and no dark styling either: the light list simply sits above the content. */
.kan-portal {
  --portal-side-w: 248px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-alt);
  color: var(--text-body);
  font-family: var(--font-ui);
}
.kan-portal__body { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.kan-portal__side { display: flex; flex-direction: column; min-width: 0; }
/* Everything the column holds lives in this wrapper (§8b): the padding, the gap and the three
   places. On a wide screen it is also what sticks and what scrolls, so the `<aside>` itself can
   stay stretched to the whole height of the body. */
.kan-portal__side-inner {
  /* Never `flex-grow`: the height below is the whole point, and growing would undo it. */
  flex: 0 1 auto;
  height: 100%;
  min-height: 0;
  min-width: 0;
  padding: var(--space-6) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  overflow-y: auto;
}
.kan-portal__nav { display: flex; flex-direction: column; gap: 2px; }
.kan-portal__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-body);
  text-align: left;
  text-decoration: none;
  transition: var(--transition-colors);
}
.kan-portal__link:hover { background: var(--accent-subtle); color: var(--text-heading); }
.kan-portal__link.is-active { background: var(--accent-subtle-hover); color: var(--text-heading); }
/* Wide screen: the list on the left of the content, both inside the body — and the body is
   bounded (§8b, Matej at 2000 px). §8c gave that bound the footer's own frame instead of the
   public `--container-content`: the same `--container-wide` and the same `--space-6` on both
   sides, centred, so the two columns sit inside the footer's frame. The bar and the footer keep
   the whole width.

   The `<aside>` is stretched to the whole height of that body row and the wrapper inside it
   sticks: `height: min(100dvh, 100%)` means it is as tall as the body while the page is short
   and as tall as the viewport once the content is long, where sticky keeps it at the top and
   its own containing block stops it before the footer. Its top padding, the same one the
   content column carries, is the breathing space. */
@media (min-width: 900px) {
  .kan-portal__body {
    display: grid;
    grid-template-columns: var(--portal-side-w) minmax(0, 1fr);
    width: 100%;
    max-width: var(--container-wide);
    margin-inline: auto;
    padding-inline: var(--space-6);
  }
  /* The column is pulled out by exactly the inset every item carries (`--space-3`), so the
     icons — the first pixel of the list — land on the first pixel of the footer logo, which
     starts where the frame's padding ends. What overhangs is only the lit item's tint and the
     rule above the foot, both of which stay inside the frame's own side padding (§8c). */
  .kan-portal__side { align-self: stretch; height: 100%; margin-inline-start: calc(var(--space-3) * -1); }
  .kan-portal__side-inner {
    position: sticky;
    top: 0;
    height: min(100dvh, 100%);
    /* No side padding of its own: the items' inset above is what sets the column's edge. */
    padding: clamp(24px, 5vw, 56px) 0 var(--space-6);
    gap: var(--space-4);
  }
}

/* Three tracks, and the logo sits in the middle one (§8d). The outer two are `1fr` — not a fixed
   44 px any more, because the account menu on the right is as wide as the donor's name: equal
   shares that both grow to whatever the wider side needs, so the middle track stays in the
   centre of the bar whatever is in them. Plain `1fr` and never `minmax(0, 1fr)`: a track that
   may shrink under its content would let the name spill over the logo. */
.kan-portal__bar {
  background: var(--bg-alt);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-2);
  padding: 10px var(--space-4);
  min-height: var(--touch-min);
}
.kan-portal__logo { grid-column: 2; justify-self: center; display: flex; align-items: center; min-height: var(--touch-min); }
.kan-portal__logo img { height: 68px; width: auto; display: block; object-fit: contain; }
.kan-portal__menu {
  grid-column: 1;
  justify-self: start;
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--touch-min);
  height: var(--touch-min);
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-heading);
  cursor: pointer;
}
.kan-portal__scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  border: 0;
  padding: 0;
  background: var(--scrim);
  cursor: pointer;
}
.kan-portal__scrim[hidden] { display: none; }

/* The account menu on the right of the bar (SESSION-11E §8d). A native `<details>`: the click
   that opens it is the browser's, so it works with no script at all, and portal.js only adds
   Escape, a click outside and `aria-expanded`. The card hangs off the summary, right-aligned,
   and is the last thing in the bar — nothing on the page can sit over it. */
.kan-account { grid-column: 3; justify-self: end; position: relative; min-width: 0; }
.kan-account__summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  cursor: pointer;
  transition: var(--transition-colors);
  /* The disclosure triangle is the browser's idea of a summary, not ours. Both spellings. */
  list-style: none;
}
.kan-account__summary::-webkit-details-marker { display: none; }
.kan-account__summary:hover { background: var(--accent-subtle); }
.kan-account__summary:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
/* The name never pushes the logo off centre: it ends in an ellipsis instead. */
.kan-account__name { min-width: 0; max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kan-account__icon { display: none; }
.kan-account[open] .kan-account__chevron { transform: rotate(180deg); }
.kan-account__menu {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: var(--z-header);
  width: max-content;
  max-width: min(320px, 90vw);
  padding: var(--space-2);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-raised);
}
/* A line to read, not to click: one line, the muted colour, the `title` carries the rest. */
.kan-account__email {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-legal);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kan-account__sep { margin: var(--space-1) 0; border: 0; border-top: 1px solid var(--border-subtle); }
.kan-account__signout {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-body);
  text-align: left;
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-account__signout:hover { background: var(--accent-subtle); color: var(--text-heading); }
.kan-account__signout:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: calc(-1 * var(--focus-ring-width)); }

/* The guest pages of Moja podpora keep the plain header, with the logo centred too — a size
   smaller than the other slim headers, and the card closer under it (Matej, 28. 9. 2026). */
.kan-subheader__inner--centred { justify-content: center; }
.kan-donor-guest .kan-subheader__logo img { height: 68px; }
.kan-donor-guest .kan-result-main { padding-top: var(--space-5); }

/* A wide screen (Matej, 28. 9. 2026): the logo at the left edge of the body's frame, above the
   sidebar's icons, and the donor's name level with the top of the logo — the same frame the
   body and the footer use (`--container-wide` with `--space-6` inside it). */
@media (min-width: 900px) {
  .kan-portal__bar {
    grid-template-columns: auto 1fr auto;
    align-items: start;
    padding-inline: max(var(--space-6), calc((100% - var(--container-wide)) / 2 + var(--space-6)));
  }
  .kan-portal__logo { grid-column: 1; justify-self: start; }
  .kan-account__summary { margin-top: calc((1lh - var(--touch-min)) / 2); }
}

/* A phone: the whole logo at the slim headers' height would take half the screen. */
@media (max-width: 899px) {
  .kan-portal__logo img,
  .kan-donor-guest .kan-subheader__logo img { height: 56px; }
}

@media (max-width: 899px) {
  .kan-portal__menu { display: inline-flex; }

  /* Next to the logo there is no room for a name, so the account menu is a 44 × 44 icon and
     the name is what a screen reader hears instead (`aria-label` in the template). The card
     under it is unchanged. */
  .kan-account__summary { width: var(--touch-min); padding: 0; }
  .kan-account__icon { display: block; }
  .kan-account__name,
  .kan-account__chevron { display: none; }

  /* The drawer — and with it every dark colour in this component — exists only where the
     script that opens it does. Under `html.no-js` none of these rules match, so the same
     markup stays the light list above the content (CLAUDE.md rule 9: the colours are the
     tokens the admin drawer already uses, nothing new). */
  html:not(.no-js) .kan-portal__side {
    position: fixed;
    inset-block: 0;
    left: 0;
    width: min(300px, 86vw);
    overflow-y: auto;
    background: var(--surface-inverse);
    /* Closed, the drawer is out of the tab order as well as out of sight. `visibility`
       switches at once on the way in (so the first link can take the focus) and only after
       the slide on the way out — a duration on it would keep it hidden for that first frame. */
    visibility: hidden;
    transform: translateX(-100%);
    transition: transform var(--dur-base) var(--ease-out), visibility 0s linear var(--dur-base);
    z-index: var(--z-modal);
    box-shadow: var(--shadow-2);
  }
  html:not(.no-js) .kan-portal__side :where(a, button):focus-visible { outline-color: var(--focus-ring-on-dark); }
  html:not(.no-js) .kan-portal__link { color: var(--text-on-dark-muted); }
  html:not(.no-js) .kan-portal__link:hover { background: transparent; color: var(--text-on-dark); }
  html:not(.no-js) .kan-portal__link.is-active { background: var(--border-inverse); color: var(--text-on-dark); }

  /* Open, the drawer and its scrim have to clear the staging badge, which is sticky at
     `--z-toast` and would otherwise cut the first navigation item in half on staging — where
     the badge is always on. The same token: the drawer comes later in the document, so it
     wins, and no new value is invented (CLAUDE.md rule 9). */
  .kan-portal.is-open .kan-portal__side,
  .kan-portal.is-open .kan-portal__scrim {
    z-index: var(--z-toast);
  }
  .kan-portal.is-open .kan-portal__side {
    visibility: visible;
    transform: translateX(0);
    transition: transform var(--dur-base) var(--ease-out), visibility 0s linear 0s;
  }
}

/* No JavaScript, no drawer: the icon is gone and the navigation is simply above the content. */
.no-js .kan-portal__menu { display: none; }
.no-js .kan-portal__scrim { display: none; }

/* SupportCard, tidied (decision A3): under the campaign name one line — „Ďalšia platba
   {dátum}" — and the card's mask on its right. The three rows below it are gone. */
.kan-support__meta { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-2) var(--space-4); }
.kan-support__meta .kan-support__line { flex: 1 1 auto; }
.kan-support__card { margin: 0; flex: 0 0 auto; font-size: var(--fs-small); color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* „Zadajte kód" as six boxes (decision A4). The single field ships in the HTML and account.js
   builds these from it, so without JavaScript nothing here is ever painted. */
.kan-code-boxes { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.kan-code-boxes__box {
  width: var(--touch-min);
  min-width: var(--touch-min);
  min-height: var(--control-h);
  padding: 0;
  text-align: center;
  font-family: var(--font-numeric);
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text-heading);
  background: var(--paper);
  border: 1.5px solid var(--border-input);
  border-radius: var(--radius-input);
  box-shadow: var(--shadow-inset-input);
  transition: var(--transition-colors);
}
.kan-code-boxes__box:focus { border-color: var(--accent); }
.kan-code-boxes__box:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-code-boxes.is-wrong .kan-code-boxes__box { border-color: var(--danger); background: var(--danger-surface); }

/* S11E · B · sprievodca */

/* Kroky 2 a 3: hlavné tlačidlo vpravo, vľavo chevron späť (rozhodnutie 6). Bez chevronu
   (krok 1 nemá čo ponúknuť) ostáva tlačidlo samo vpravo — preto `margin-left: auto`. */
.kan-wizard-actions { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.kan-wizard-actions__cta { margin-left: auto; }
.kan-wizard-back { text-decoration: none; }

/* Panel nad textom: jediné tlačidlo „Tučné" (rozhodnutie 8). Trieda, ktorá nastavuje
   `display`, prebije `[hidden]` — preto tu má každý skrývaný prvok vlastné pravidlo. */
.kan-fund-text__tools { display: flex; align-items: center; gap: var(--space-2); }
.kan-fund-text__tools[hidden] { display: none; }
.kan-fund-text__bold {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  /* Rovnaký cieľ ako všade v darcovskej časti: 44 × 44 px (pravidlo 12). Hustejší admin sa
     tohto tlačidla netýka — žije len v sprievodcovi. */
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-body);
  background: var(--bg-alt);
  border: 1.5px solid transparent;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-fund-text__bold:hover { color: var(--text-heading); border-color: var(--border-default); }
.kan-fund-text__bold:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-fund-text__bold[aria-pressed="true"] { background: var(--accent-subtle); color: var(--accent); border-color: var(--accent-border); }

/* Textové pole po vylepšení: ten istý rám, len editovateľný. `pre-wrap` drží zalomenia,
   ktoré server ukladá ako `\n`, a `word-break` bráni tomu, aby dlhé slovo pretieklo. */
.kan-fund-text__editor {
  display: block;
  overflow-y: auto;
  max-height: 340px;
  padding-top: 12px;
  padding-bottom: 12px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.kan-fund-text__editor[hidden] { display: none; }
.kan-fund-text__editor:focus { border-color: var(--accent); }
.kan-fund-text__editor:empty::before { content: attr(data-placeholder); color: var(--text-muted); }
.kan-fund-text__area[hidden] { display: none; }
.kan-fund-text__foot { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.kan-fund-text__saved { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-fund-text__saved.is-failed { color: var(--danger-text); }
.kan-fund-text__foot .kan-fund-text__counter { margin-left: auto; }

/* Náhľad v kroku 3 (rozhodnutie 10) — vzor z editora darovacích stránok, len bez vlastnej
   karty: sedí vnútri `kan-result-card`. */
.kan-preview--flat { padding: 0; background: transparent; border: 0; box-shadow: none; }
.kan-preview--flat .kan-preview__stage { border: 1px solid var(--border-default); }
/* „Počítač / Mobil" je pôvodom ovládač admina (32 px). Tu stojí v darcovskej časti, kde platí
   44 px aj na myši (pravidlo 12) — `admin-density.css` sa tejto stránky netýka. */
.kan-preview--flat .kan-preview__size { min-height: var(--touch-min); }

/* Adresa kampane celá, zalomená na toľko riadkov, koľko treba (rozhodnutie 11). Žiadne
   `text-overflow: ellipsis` — adresa, ktorú nevidno celú, sa nedá prečítať nahlas.
   SESSION-11J §C: „Kopírovať odkaz" už nestojí pod adresou so svojím slovom — je to ikonové
   tlačidlo v tom istom orámovanom boxe ako text adresy (`__box`), pritlačené k pravému okraju. */
.kan-fund-link { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); width: 100%; }
.kan-fund-link__label { margin: 0; font-family: var(--font-ui); font-size: var(--fs-legal); font-weight: var(--fw-medium); color: var(--text-muted); }
.kan-fund-link__box {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  background: var(--surface-sunken);
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-input);
}
.kan-fund-link__value {
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--text-heading);
  overflow-wrap: anywhere;
}
/* The button keeps its own pill (kan-iconbtn); only its background goes transparent-on-sunken
   so it reads as part of the box rather than a chip floating on top of it. */
.kan-fund-link__box .kan-iconbtn { flex: 0 0 auto; background: transparent; }
/* Without JavaScript the button is gone (.no-js) — give the value back the box's own padding
   so the address does not sit flush against the border on its own. */
.no-js .kan-fund-link__box { padding: var(--space-3) var(--space-4); }

/* S11E · C · verejná stránka */

/* Náhľad v kroku 3 (§6c): formulár je `inert` a nad ním stojí jedna veta. Karta si odsadenie
   nesie v `.kan-acc__inner`, takže tento riadok si ho musí priniesť sám. */
.kan-fund-preview-note {
  margin: 0;
  padding: var(--space-4) var(--space-4) 0;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--text-muted);
}

/* The author's text (decision 8, second half). Two things happen here.

   1. It may now hold <strong> and <br>, and it is rendered with `white-space: pre-line`, so a
      body that arrived as plain text with newlines and one that arrived from the bold-capable
      editor with <br> both break in the same places. (The rule above still sets the type; this
      only replaces the line-break handling that nl2br used to do in the Blade.)
   2. A long text is clamped to four lines, three on a phone, and the control under it opens the
      whole of it in the box's own <dialog>. The clamp hangs off `html:not(.no-js)` — the class
      the inline snippet in layout/base removes before the stylesheets even load — and off
      `.kan-fund-page`, the one page that ships campaign.js. So without JavaScript, and in every
      other place the box is used, the text is simply whole; nothing can hide it with no way back.
      Whether the control is needed at all is measured in campaign.js: only the browser knows
      where the words wrapped. */
.kan-fund-box { --kan-fund-lines: 4; }
.kan-fund-box__text { white-space: pre-line; }
html:not(.no-js) .kan-fund-page .kan-fund-box__text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--kan-fund-lines);
  line-clamp: var(--kan-fund-lines);
  overflow: hidden;
}
/* „Zobraziť celý text": quiet, the width of its words, a full 44 px tall. `hidden` has to beat
   the display above — an attribute loses to a class or an element rule otherwise (10 §2). */
.kan-fund-box__more {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--touch-min);
  margin: 0;
  padding: 6px 0;
  border: 0;
  background: none;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  line-height: 1.4;
  color: var(--text-link);
  cursor: pointer;
}
.kan-fund-box__more[hidden] { display: none; }
.kan-fund-box__more:hover { color: var(--text-link-hover); }
.kan-fund-box__more:hover .kan-fund-box__more-text { text-decoration: underline; }
/* The box is a white card inside the dark page: the gold ring would vanish on it (as for its
   links, above). */
.kan-on-dark .kan-fund-box :where(button):focus-visible { outline-color: var(--focus-ring); }

/* The whole text, with the author's square photo when there is one. Same card as the admin's
   dialogs, without the admin's density variables. */
.kan-fund-dialog__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-height: 90vh;
  overflow: auto;
  padding: var(--space-5);
  background: var(--surface-card);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card);
  text-align: left;
}
.kan-fund-dialog__head { display: flex; align-items: center; gap: var(--space-3); }
.kan-fund-dialog__photo {
  flex: none;
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.kan-fund-dialog__title {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  line-height: 1.4;
  letter-spacing: normal;
  color: var(--text-muted);
  text-wrap: pretty;
}
.kan-fund-dialog__text {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-heading);
  white-space: pre-line;
  overflow-wrap: anywhere;
  text-wrap: pretty;
}
.kan-fund-dialog__foot { display: flex; justify-content: flex-end; }
@media (max-width: 719.98px) {
  .kan-fund-box { --kan-fund-lines: 3; }
  .kan-fund-dialog__photo { width: 56px; height: 56px; }
}

/* S11E · D · telefón */

/* One field, two controls (decision 13): the picker keeps a readable width, the number takes
   the rest of the row, and where the two no longer fit side by side each takes its own line.
   Both are .kan-input, so the height, the focus border and the admin's denser --control-h
   apply without a word here. */
.kan-phone { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2); }
.kan-phone__prefix { flex: 0 1 11.5rem; min-width: 8.5rem; }
.kan-phone__rest { flex: 1 1 11rem; min-width: 0; }
@media (max-width: 380px) {
  .kan-phone__prefix,
  .kan-phone__rest { flex-basis: 100%; }
}

/* ============================================================
   SESSION-11F §1 · Foundations under the four streams
   Tokens only: no new hex, no new radius, no new shadow (CLAUDE.md 9). Sizes come from
   --touch-min / --control-h, which the density layer redefines on a fine pointer (32 / 28 px
   in the admin) and leaves at 44 px everywhere else.
   ============================================================ */

/* --- 1.2 · the „i" beside a label (decision 10) ---------------------------- */
/* The label and the icon share one row; the character counter (data-counter in admin.js)
   still appends into the label itself, so it keeps its place at the right end of it. */
.kan-field__head { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.kan-field__head > .kan-field__label { flex: 1 1 auto; min-width: 0; }
.kan-checkbox__text { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: var(--space-2); }

.kan-help { position: relative; display: inline-flex; align-items: center; flex: 0 0 auto; }
.kan-help__btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: var(--transition-colors);
}
/* The visual circle is small on purpose; the target under the finger is not. */
.kan-help__btn::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--touch-min);
  height: var(--touch-min);
  transform: translate(-50%, -50%);
}
.kan-help__btn:hover { color: var(--text-heading); }
.kan-help__btn:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-help__btn[aria-expanded="true"] { color: var(--text-heading); background: var(--bg-alt); }
.kan-help__pop {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  z-index: var(--z-sticky);
  width: max-content;
  max-width: 320px;
  padding: var(--space-3);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  font-weight: var(--fw-regular);
  line-height: 1.5;
  letter-spacing: normal;
  text-transform: none;
  text-align: left;
  white-space: normal;
  color: var(--text-body);
}
.kan-help__pop[hidden] { display: none; }
/* 26. 9. 2026 · an „i" in a dialog's foot (Spárovať prevod) sits on the card's last line — the
   card scrolls (`overflow: auto`), so a bubble dropping below would be cut off. It opens upward,
   over the fields, where the card always has room. */
.kan-dialog__foot .kan-help__pop { top: auto; bottom: calc(100% + var(--space-1)); }
/* On a narrow screen a floating bubble has nowhere to go: it becomes a block under the field. */
@media (max-width: 560px) {
  .kan-help { position: static; }
  .kan-help__pop { position: static; width: 100%; max-width: none; margin-top: var(--space-2); }
}

/* --- 1.4 · a row is a link (decision 3) ----------------------------------- */
.kan-table tbody tr[data-href] { cursor: pointer; }
@media (hover: hover) {
  .kan-table tbody tr[data-href]:hover td { background: var(--surface-sunken); }
}
.kan-table__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  text-decoration: none;
}
.kan-table__link:hover { text-decoration: underline; }
.kan-table__link:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }

/* --- 1.5 · a row action is an icon (decision 4) --------------------------- */
/* 26. 9. 2026 (Matej): the cell stays a table cell — `display: flex` on a <td> took it out of the
   row, so its height and its dividing line drifted from the rest of the row in every list. The
   buttons sit inline instead; `font-size: 0` swallows the whitespace between them, the margin is
   the gap (the copied bubble sets its own size). */
.kan-table__actions--icons { vertical-align: middle; font-size: 0; }
.kan-table__actions--icons > * { vertical-align: middle; }
.kan-table__actions--icons > * + * { margin-left: 4px; }
.kan-table__actions .kan-iconbtn,
.kan-table__actions--icons .kan-iconbtn { width: var(--touch-min); height: var(--touch-min); }
.kan-iconbtn--danger { color: var(--text-muted); border-color: var(--border-default); }
.kan-iconbtn--danger:hover { color: var(--danger-text); border-color: var(--destructive-quiet-border); background: var(--destructive-quiet-bg-hover); }
/* Copied: the mask swaps to the check (admin.js) and the word appears in a bubble, so the
   button's accessible name never changes under the reader's hands. */
.kan-iconbtn.is-copied { color: var(--success-text); border-color: var(--success-border); }
.kan-iconbtn.is-copied::after {
  content: attr(data-copy-done);
  position: absolute;
  bottom: calc(100% + var(--space-1));
  right: 0;
  z-index: var(--z-sticky);
  padding: 2px var(--space-2);
  border-radius: var(--radius-badge);
  background: var(--surface-inverse);
  color: var(--text-on-dark);
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  pointer-events: none;
}
.kan-iconbtn { position: relative; }

/* --- 1.7 · the main page is a star (decision 5) --------------------------- */
.kan-star {
  display: inline-grid;
  place-items: center;
  width: var(--touch-min);
  height: var(--touch-min);
}
.kan-star.is-main { color: var(--gold-500); }
.kan-star__form { display: inline-flex; }
button.kan-star { border-color: transparent; color: var(--border-strong); }
button.kan-star:hover,
button.kan-star:focus-visible { color: var(--gold-600); background: transparent; border-color: transparent; }

/* --- 1.8 · a date field anywhere ------------------------------------------ */
.kan-date__native[hidden] { display: none; }
.kan-date__button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  text-align: left;
  cursor: pointer;
}
.kan-date__button[hidden] { display: none; }
.kan-date__button:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }

/* ============================================================
   SESSION-11F · stream anchors (File ownership, docs/handoff/SESSION-11F.md).
   A stream writes only between its own anchor and the next one.
   ============================================================ */

/* S11F · A · Stránky */
/* Decision 5: the star has a column of its own at the head of the row, so the titles under
   it all start on the same pixel whether a page is the main one or not. The cell is only as
   wide as the star, and it never pushes the row taller than the star itself. */
.kan-table__star-cell { width: 1%; padding-right: 0 !important; text-align: center; white-space: nowrap; }
/* Decision 4: the trash still posts a real form, but the form must not break the icon row. */
.kan-table__actionform { display: inline-flex; margin: 0; }
/* Decision 11: a card title that carries the „i" is a row, not a block. */
.kan-cardtitle { display: flex; align-items: center; gap: var(--space-2); }

/* S11F · B · Zbierky */

/* „Prechod na ďalší rok" is a procedure, not a warning: collapsed, and shaped like the admin
   cards around it (decision 11). Tokens only; the row is one control tall. */
.kan-details {
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-1);
  min-width: 0;
}
.kan-details__summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  padding: 0 var(--space-4);
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  cursor: pointer;
  list-style: none;
  border-radius: var(--radius-card);
}
.kan-details__summary::-webkit-details-marker { display: none; }
.kan-details__summary:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-details__chevron { color: var(--text-muted); transition: transform var(--dur-fast) var(--ease-standard); }
.kan-details[open] .kan-details__chevron { transform: rotate(90deg); }
.kan-details__body {
  margin: 0;
  padding: 0 var(--space-4) var(--space-4) calc(var(--space-4) + 16px + var(--space-2));
  font-size: var(--fs-legal);
  color: var(--text-muted);
}
@media (pointer: coarse) {
  .kan-details__summary { min-height: var(--touch-min); }
}

/* S11F · C · Osobné kampane */

/* §4 · The detail is a dashboard (decision 12). One card „Kampaň“: the author's photo on the
   left, the author's own editor, the same calendar and one save on the right. The card wraps
   to a column as soon as the editor would be narrower than it can be read.
   SESSION-11J §B: renamed from `.kan-fund-card` to `.kan-fund-panel` — that name collided
   with the donor's own personal-campaign card in the overview (B6 above), which this same
   rule used to reach by mistake (icons glued to the left there). `.kan-fund-form` was NOT
   the right rename either: the public giving form (`public/partials/fundraiser-form.blade.php`,
   `donor/fundraisers/details.blade.php`) already answers to it, above at line ~2549 — a
   second collision the task's own note did not know about. `__square`, `__square--empty`,
   `__file`, `__photo-actions` and `__shell` are gone with the rename: S11H's `x-photo-crop`
   replaced the photo widget they belonged to, and nothing in Blade or JS referenced them any
   more (grepped before deleting). */
.kan-fund-panel { display: flex; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap; }
.kan-fund-panel__photo { flex: 0 0 168px; max-width: 100%; }
.kan-fund-panel__main { flex: 1 1 280px; min-width: 0; display: flex; flex-direction: column; gap: var(--space-4); }

/* SESSION-11J §B · „Nová osobná kampaň“ (bod 3): the one POST form spans three cards (Darca,
   Zbierka, Kampaň) plus the actions row below it — `.kan-admin__main`'s own gap only reaches
   ITS direct children, so the form needs the same rhythm itself, or the row of cards inside
   it stack with none at all (the „glued“ publish button the client reported). */
.kan-fund-create-form { display: flex; flex-direction: column; gap: var(--admin-stack); }

/* Bod 1 · the „Darca“ combobox. No-JS floor: `.kan-donor-nojs` is the same on/off-under-
   `html.no-js` pattern as `.kan-photo-crop__nojs-submit` above — shown only without a script,
   on both the „Hľadať“ button and the server-rendered radio list beneath the field. */
.kan-donor-combobox { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-donor-combobox__row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.kan-donor-nojs { display: none; }
.no-js .kan-donor-nojs { display: block; }
.no-js button.kan-donor-nojs { display: inline-flex; }

/* The suggestions: an absolutely positioned listbox under the field (`.kan-search__wrap` is
   already `position: relative` for its icon), closed until a script opens it. */
.kan-donor-combobox__list {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  margin: 0;
  padding: var(--space-2);
  list-style: none;
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-raised);
  max-height: 280px;
  overflow-y: auto;
}
.kan-donor-combobox__option { padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); cursor: pointer; }
.kan-donor-combobox__option:hover,
.kan-donor-combobox__option[aria-selected="true"] { background: var(--accent-subtle); }
.kan-donor-combobox__option-name { display: block; font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-donor-combobox__option-email { display: block; font-size: var(--fs-small); color: var(--text-muted); }

/* The chosen donor, in place of the field once picked (name, e-mail, the „change“ icon). */
.kan-donor-combobox__selected {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  border: 1.5px solid var(--accent);
  background: var(--accent-subtle);
}
/* `display: flex` above would otherwise beat the `hidden` attribute. */
.kan-donor-combobox__selected[hidden],
.kan-donor-combobox__list[hidden],
.kan-donor-combobox [data-donor-combobox-search][hidden] { display: none; }

/* S11F · D · Pravidlá */

/* The translation state of the wording in force: one line with an icon, not a paragraph. */
.kan-rules__status {
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-legal);
  color: var(--success-text);
}
.kan-rules__status.is-missing { color: var(--warning-text); }

/* The language tabs and the „i" about the English wording share one underlined row. */
.kan-lang-tabs__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  border-bottom: 1px solid var(--border-default);
}
.kan-lang-tabs__head > .kan-help { margin-left: auto; }

/* The separators between the five toolbar groups: block · zoznam · písmo · odkaz · krok späť. */
.kan-editor__sep {
  flex: 0 0 auto;
  align-self: center;
  width: 1px;
  height: 60%;
  min-height: 16px;
  margin-inline: var(--space-1);
  background: var(--border-default);
}
/* The formatting note sits at the far end of the toolbar and opens leftwards, so the bubble
   never hangs off the card. */
.kan-editor__help { margin-left: auto; }
.kan-editor__help .kan-help__pop { left: auto; right: 0; }
@media (max-width: 560px) {
  .kan-editor__help .kan-help__pop { right: auto; }
}

/* ————————————————————————————————————————————————————————————————————————————
   SESSION-11H · kotvy prúdov (File ownership, docs/handoff/SESSION-11H.md). Každý prúd píše
   len medzi svoju kotvu a nasledujúcu — pred kotvami S11G, nikdy za nimi. */

/* S11H · A stránky */

/* S11H · B zbierky + 404 */

/* The 404's invitation (§3, bod 8): the section sits inside `.kan-result-col` (max 620px), so
   „grid at desktop" tops out at two narrow cards — auto-fit already collapses to one column on
   a phone without its own breakpoint. */
.kan-campaign-cards-section { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-campaign-cards__title {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
}
.kan-campaign-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-4); }

.kan-campaign-card {
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: var(--transition-shadow), var(--transition-colors);
}
.kan-campaign-card:hover { box-shadow: var(--shadow-card-hover); border-color: var(--border-strong); }
.kan-campaign-card:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }

.kan-campaign-card__photo { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--surface-sunken); }
.kan-campaign-card__photo--empty { display: grid; place-items: center; background: var(--surface-inverse); }
.kan-campaign-card__photo--empty img { width: 64px; height: auto; }

.kan-campaign-card__body { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); }
.kan-campaign-card__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: 1.125rem;
  line-height: 1.2;
  color: var(--text-heading);
}
.kan-campaign-card__meter-label { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-campaign-card__meter-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.kan-campaign-card__meter-current { font-family: var(--font-numeric); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; font-size: 1.125rem; color: var(--text-heading); }
.kan-campaign-card__meter-goal { font-family: var(--font-numeric); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-campaign-card__meter-track { height: 8px; border-radius: var(--radius-meter); background: var(--meter-track); overflow: hidden; }
.kan-campaign-card__meter-fill { height: 100%; border-radius: var(--radius-meter); background: var(--meter-fill); transition: var(--transition-meter); }
.kan-campaign-card__deadline { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); }

/* SESSION-11J §D · the same cards as rows, inside the ended personal campaign's white card:
   a small photo beside the name and the meter, one zbierka per line. */
.kan-campaign-cards--compact { grid-template-columns: 1fr; gap: var(--space-3); }
.kan-campaign-cards--compact .kan-campaign-card { flex-direction: row; align-items: stretch; box-shadow: none; }
.kan-campaign-cards--compact .kan-campaign-card:hover { box-shadow: var(--shadow-1); }
.kan-campaign-cards--compact .kan-campaign-card__photo { flex: 0 0 96px; width: 96px; aspect-ratio: auto; min-height: 96px; }
.kan-campaign-cards--compact .kan-campaign-card__body { flex: 1 1 auto; min-width: 0; gap: var(--space-1); padding: var(--space-3); }
.kan-campaign-cards--compact .kan-campaign-card__name { font-size: 1rem; }
.kan-campaign-cards--compact .kan-campaign-card__meter-current { font-size: 1rem; }
.kan-fund-ended-card .kan-campaign-cards-section { margin-top: var(--space-4); }

/* S11H · C osobné kampane admin */

/* Without JavaScript the crop dialog never opens, so the admin's photo form (bod 7) needs a
   plain submit button of its own; with a script the dialog's own fetch posts the moment a
   crop is confirmed, so the button only shows under html.no-js. The class sits on the
   button itself, not on x-photo-crop (stream D owns that component). */
.kan-photo-crop__nojs-submit { display: none; }
.no-js .kan-photo-crop__nojs-submit { display: grid; }

/* SESSION-11J §A (client feedback 17. 9. 2026): on desktop the dialog looked broken in the
   donor portal — `.kan-dialog__card` takes its padding from `--admin-dialog-pad`, which only
   exists inside `.kan-admin` (the old calendar dialog is gone, B19), so a donor's card had
   NONE. The crop dialog needs real room regardless of shell or pointer (the handles reach
   22 px past the selection — see `.kan-cropper--square .kan-cropper__handle--*` above), so it
   sets its own padding rather than relying on that token, on the admin too. 720 px gives a
   landscape or portrait photo more room than the default 560 px dialog. */
.kan-photo-crop-dialog { width: min(720px, 94vw); }
.kan-photo-crop-dialog .kan-dialog__card { padding: var(--space-6); }

/* S11H · D sprievodca */
/* Decision 7 / DoD 6: the shared crop dialog fills the screen on a phone, the same as the
   wizard's old inline cropper did — the square stage takes what is left once the head and
   foot are laid out, instead of the fixed 60vh cap `.kan-cropper--square` gives it on a wider
   screen (still respected by the admin, which never goes full height). */
@media (max-width: 719.98px) {
  .kan-photo-crop-dialog {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border-radius: 0;
  }
  .kan-photo-crop-dialog .kan-dialog__card {
    height: 100%;
    max-height: 100dvh;
    border-radius: 0;
    justify-content: space-between;
  }
  .kan-photo-crop-dialog .kan-cropper--square { flex: 1 1 auto; min-height: 0; }
  .kan-photo-crop-dialog .kan-cropper--square .kan-cropper__stage { max-height: none; flex: 1 1 auto; min-height: 0; }
}

/* ————————————————————————————————————————————————————————————————————————————
   SESSION-11G · kotvy prúdov (File ownership, docs/handoff/SESSION-11G.md). Každý prúd píše
   len medzi svoju kotvu a nasledujúcu. */

/* S11G · A portál */

/* The white mark at the top of the drawer (decision 1). The link is in the markup on every
   width; it is painted only where the drawer is — inside the narrow query, under
   `html:not(.no-js)`, like every dark rule of the drawer — so a wide screen keeps the one
   logo in the bar and a page without JavaScript keeps the light list without it. The wrapper's
   own gap is the space between the mark and the places. */
.kan-portal__drawer-logo { display: none; }
@media (max-width: 899px) {
  html:not(.no-js) .kan-portal__drawer-logo {
    display: flex;
    align-items: center;
    align-self: flex-start;
    min-height: var(--touch-min);
    padding: 0 var(--space-3);
  }
  html:not(.no-js) .kan-portal__drawer-logo img { height: 85px; width: auto; display: block; object-fit: contain; }
}

/* S11G · B sprievodca */

/* Bod 9: rám v kroku 3 je statický obrázok prvej obrazovky — na počítači aj na mobile. Nič
   v ňom neberie klik ani koliesko; `tabindex="-1"`, `scrolling="no"` a sandbox sú v šablóne,
   stránka vnútri si skryje vlastný overflow (`ram=1` v podpise). */
.kan-preview--flat .kan-preview__frame { pointer-events: none; }
/* SESSION-11J §C removed `.kan-preview__open` (and its now-dead `.kan-inline-link` styling)
   along with „Otvoriť v novom okne" itself; `.kan-fund-publish` moved up next to its other
   declaration. */

/* Bod 8: pod 480 px ostáva rad tlačidiel na jednom riadku — chevron 44 × 44 vľavo, CTA berie
   zvyšok šírky s výplňou `md`. Text v tlačidle sa nikdy nezalamuje (`.kan-btn` má
   `white-space: nowrap`); kratší text „Zverejňujem kampaň" sa tak zmestí aj na 360 px.
   Platí pre krok 2 aj 3 — na kroku 2 sa „Ďalej na náhľad" so šípkou len roztiahne. */
@media (max-width: 479.98px) {
  .kan-wizard-actions { flex-wrap: nowrap; }
  .kan-wizard-actions__cta { flex: 1 1 auto; min-width: 0; padding: 0 var(--space-6); }
}

/* S11G · C verejná stránka */
/* (The author's box as a phone grid lived here — gone with the box itself, Jeden box 18. 9. 2026:
   live and ended, the photo and the text now open the one white card as `kan-fund-box--intro`.) */

/* S11G · D admin */

/* S11G · E hover + telefón */
/* SESSION-11G §6, decision 17 · `tokens/base.css` says `a:hover { color: var(--text-link-hover) }`
   (0,1,1), which outweighs every single-class colour — so white text on a navy anchor turned
   navy on hover. Tokens are a verbatim copy (rule 9); each anchor that sets its own colour
   says it again for :hover and :active, in the colour it has at rest. Element + class only,
   nothing else changes on hover. */
a.kan-btn--primary:hover, a.kan-btn--primary:active { color: var(--on-accent); }
a.kan-btn--donate:hover, a.kan-btn--donate:active { color: var(--on-highlight); }
a.kan-btn--secondary:hover, a.kan-btn--secondary:active { color: var(--accent); }
a.kan-btn--destructive-quiet:hover, a.kan-btn--destructive-quiet:active { color: var(--destructive-quiet-text); }
a.kan-iconbtn:hover, a.kan-iconbtn:active { color: var(--accent); }
.kan-footer__link:hover, .kan-footer__link:active { color: var(--text-on-dark); }
.kan-footer__plain:hover, .kan-footer__plain:active { color: var(--text-on-dark); }
.kan-hero__manage:hover, .kan-hero__manage:active { color: var(--text-on-dark); }
.kan-skip-link:hover, .kan-skip-link:active { color: var(--on-accent); }

/* ============================================================
   ZDROJE AS A FUNNEL (17. 9. 2026) — tree left, funnel right.
   Source groups paint with existing tokens only; the connector
   between two steps is an SVG polygon stretched to the track.
   ============================================================ */
.kan-admin {
  --source-priamo: var(--navy-700);
  --source-nas-web: var(--navy-400);
  --source-email: var(--sky-600);
  --source-socialne-siete: var(--gold-500);
  --source-zdielanie: var(--gold-300);
  --source-sms: var(--gold-700);
  --source-vyhladavace: var(--green-600);
  --source-listy: var(--amber-600);
  --source-tlac: var(--warning-border);
  --source-ine: var(--ink-300);
}
.kan-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  color: var(--text-body);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-pill:hover { border-color: var(--border-strong); background: var(--surface-sunken); color: var(--text-heading); }
.kan-pill.is-on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.kan-pill.is-on:hover { background: var(--accent-hover); color: var(--on-accent); }
.kan-funnel-custom { position: relative; }
.kan-funnel-custom > summary { list-style: none; }
.kan-funnel-custom > summary::-webkit-details-marker { display: none; }
.kan-funnel-custom__form {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-2));
  z-index: 5;
  width: 320px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-2);
}

.kan-funnel-layout { display: grid; grid-template-columns: 272px minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.kan-funnel-main { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }
@media (max-width: 1100px) {
  .kan-funnel-layout { grid-template-columns: minmax(0, 1fr); }
}

/* The funnel card */
.kan-funnel { gap: var(--space-5); }
.kan-funnel__head { display: flex; flex-direction: column; gap: 6px; }
.kan-funnel__crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: var(--fs-overline); font-weight: var(--fw-semibold); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.kan-funnel__crumbs a { color: var(--text-link); text-underline-offset: 0.2em; display: inline-flex; align-items: center; min-height: 24px; }
.kan-funnel__title-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.kan-funnel__title { margin: 0; font-size: 1.375rem; font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-funnel__subtitle { margin: 0; font-size: var(--fs-small); color: var(--text-muted); }
.kan-funnel__chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.kan-funnel__swatch { flex: 0 0 auto; width: 10px; height: 10px; border-radius: var(--radius-pill); box-shadow: 0 0 0 1.5px var(--paper); }

.kan-funnel__steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.kan-funnel__row, .kan-funnel__conn { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: var(--space-6); align-items: center; }
.kan-funnel__label { margin: 0; display: flex; flex-direction: column; gap: 2px; }
.kan-funnel__name { font-size: var(--fs-overline); font-weight: var(--fw-semibold); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.kan-funnel__value { font-size: 1.75rem; font-weight: var(--fw-bold); line-height: 1.1; color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-funnel__sub { font-size: var(--fs-legal); color: var(--text-muted); }
.kan-funnel__track { height: 56px; display: flex; justify-content: center; }
.kan-funnel__bar { display: flex; height: 100%; border-radius: var(--radius-sm); overflow: hidden; background: var(--meter-track); }
.kan-funnel__seg { display: block; height: 100%; box-shadow: inset -1px 0 0 var(--paper); }
.kan-funnel__seg:last-child { box-shadow: none; }
.kan-funnel__conn-art { position: relative; display: block; height: 44px; }
.kan-funnel__conn-art svg { display: block; width: 100%; height: 100%; }
.kan-funnel__conn-art polygon { fill: var(--accent-subtle); }
.kan-funnel__conn-label { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: var(--fs-legal); font-weight: var(--fw-semibold); color: var(--navy-800); }

.kan-funnel__strip { margin: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); background: var(--surface-sunken); }
.kan-funnel__strip div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kan-funnel__strip dt { font-size: var(--fs-legal); color: var(--text-muted); }
.kan-funnel__strip dd { margin: 0; font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-funnel__how > summary { display: inline-flex; align-items: center; min-height: var(--touch-min); font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-link); cursor: pointer; }
.kan-funnel__how ul { margin: var(--space-2) 0 0; padding-left: var(--space-5); display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-small); line-height: 1.6; color: var(--text-body); max-width: 72ch; }

/* Parts and sources tables: eight columns in the right column, so the cells sit closer. */
.kan-funnel-table th, .kan-funnel-table td { padding-inline: var(--space-2); }
.kan-admin .kan-funnel-table td.kan-funnel-table__first { max-width: 210px; }
.kan-funnel-table__name > a:not(.kan-iconbtn), .kan-funnel-table__name > span:not([class*="__share"]):not([class*="__toggle"]):not(.kan-funnel__swatch) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kan-funnel-table th:first-child, .kan-funnel-table td:first-child { padding-left: var(--space-3); }
.kan-funnel-table__name { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.kan-funnel-table__share { flex: 0 0 auto; display: inline-block; height: 8px; border-radius: var(--radius-pill); background: var(--accent); }
.kan-funnel-table__kind { font-size: var(--fs-legal); color: var(--text-muted); font-weight: var(--fw-regular); }
.kan-funnel-table__toggle { flex: 0 0 auto; }
.kan-funnel-table__toggle .kan-icon { transition: transform var(--dur-fast) var(--ease-standard); }
.kan-funnel-table__toggle.is-open .kan-icon { transform: rotate(90deg); }
.kan-funnel-table__toggle-slot { flex: 0 0 auto; width: var(--touch-min); }
.kan-funnel-table tr.is-sel td { background: var(--accent-subtle); }
.kan-funnel-table__detail td { color: var(--text-muted); }
.kan-funnel-table__detail .kan-funnel-table__name { padding-left: calc(var(--touch-min) + var(--space-2)); }
.kan-funnel-table__utm { font-family: var(--font-mono); font-size: var(--fs-legal); color: var(--text-body); }

.kan-payfilter__field { min-width: 0; border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.kan-payfilter__field > legend { padding: 0; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-heading); }

.kan-payfilter__row { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.kan-payfilter__row > * { flex: 1 1 140px; min-width: 0; }
.kan-payfilter__checks { display: flex; flex-direction: column; gap: var(--space-1); }

.kan-payfilter__search { position: relative; }
.kan-payfilter__search .kan-icon { position: absolute; left: var(--space-2); top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; }
.kan-payfilter__search input {
  width: 100%;
  height: var(--control-h-sm);
  padding: 0 var(--space-2) 0 calc(var(--space-2) + 20px);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--surface-card);
  color: var(--text-body);
  font-size: var(--fs-small);
}
.kan-payfilter__search input:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-payfilter__none { margin: var(--space-2) 0 0; font-size: var(--fs-legal); color: var(--text-muted); }

.kan-export-mark { display: inline-flex; }
.kan-export-mark--not_exported { color: var(--text-muted); }
.kan-export-mark--exported { color: var(--success-text); }
.kan-export-mark--changed { color: var(--warning-text); }

/* SESSION-11I §7a point 1 · the table overflowed at 1440 px (nine columns, Stav and Akcie the
   widest): the Export mark became an icon-only cell like the pages list's star column, the
   „Spôsob" column moved inside the amount cell as a small icon (the word survives in `title`),
   and a long zbierka name gets an ellipsis instead of pushing the row wider (`title` carries
   the full name, as the reference column already did). */
.kan-table td.kan-table__export-cell, .kan-table th.kan-table__export-cell { width: 1%; padding-right: 0; text-align: center; white-space: nowrap; }
.kan-payments__method { display: inline-flex; margin-right: 4px; color: var(--text-muted); vertical-align: middle; }
.kan-table__campaign { max-width: 160px; overflow: hidden; }

/* SESSION-11M polish · the „Ročník" column and its own calendar action folded into this cell
   (`{zbierka} · {rok}`): the zbierka name is the part allowed to shrink and ellipsise, the
   year (its own link to the vintage screen) and the quiet manual-mark pencil never get cut. */
.kan-admin .kan-table td.kan-table__campaign { max-width: 184px; }
.kan-table__campaign-row { display: flex; align-items: baseline; gap: 0.25em; max-width: 160px; min-width: 0; }
.kan-table__campaign-name { min-width: 2ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kan-table__campaign-year { flex: 0 0 auto; display: inline-flex; align-items: baseline; gap: 0.25em; white-space: nowrap; }

/* SESSION-11N §1.2 fix · the zbierka detail's narrow „Ročník" column — same cell content as
   `.kan-table__campaign` minus the (redundant, on the detail) zbierka name, so it only needs
   to fit the year trigger and the silent pencil. */
.kan-table__vintage-narrow { width: 1%; white-space: nowrap; }

.kan-funnel-table__total td { font-weight: var(--fw-semibold); color: var(--text-heading); }

/* Jeden box · verejná osobná kampaň (17. 9. 2026) */
/* ONE white card on the live page. The sentence „{Meno} podporuje {zbierka}" is the H1 on the
   photo at both widths; the author's photo and text open the form's first step and fold away
   with it; the gold tag sits in the top bar beside „Moja podpora"; the meter previews the gift
   being chosen in gold. Tokens only — the one new value is how long the meter takes to move. */
:root { --dur-meter-preview: 600ms; }
@media (prefers-reduced-motion: reduce) {
  :root { --dur-meter-preview: 0ms; }
}

/* The gold tag sits right above the headline (Matej, 28. 9. 2026), close to its first word. */
.kan-fund-headline { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); }
.kan-fund-tag { white-space: nowrap; }

/* The H1 on the photo — the page's headline size would shout a whole sentence. */
.kan-fund-h1 { max-width: 640px; font-size: clamp(40px, 4.4vw, 60px); line-height: 1.04; }
.kan-fund-h1 a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.14em; }
.kan-fund-h1 a:hover { text-decoration-thickness: 2px; }

/* Ended: the campaign's own line stands quietly above „Kampaň sa skončila …". */
.kan-fund-ended-line {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-medium);
  line-height: 1.5;
  color: var(--text-on-dark);
  opacity: 0.86; /* as „Moja podpora" — the muted blue-grey gets lost on a bright photo */
  text-wrap: pretty;
}
.kan-fund-ended-line a { color: inherit; text-underline-offset: 0.18em; }
.kan-fund-page--ended .kan-hero__left { gap: var(--space-2); }

/* The author's opener inside step 1: no card of its own, the photo beside three lines of text
   whose last line ends level with the photo (4.5rem = 3 × 1.6 × 0.9375rem, so they scale
   together), „Zobraziť celý text" under the text. No line between it and the amounts. */
.kan-fund-box--intro {
  --kan-fund-lines: 3;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 14px;
  align-items: start;
  padding: var(--space-4) var(--space-4) var(--space-1);
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
.kan-fund-box--intro .kan-fund-box__photo {
  grid-column: 1;
  grid-row: 1;
  float: none;
  width: 4.5rem;
  height: 4.5rem;
  margin: 0;
}
.kan-fund-box--intro .kan-fund-box__text { grid-column: 2; font-size: var(--fs-body-sm); line-height: 1.6; }
.kan-fund-box--intro .kan-fund-box__more { grid-column: 2; justify-self: start; }
/* No photo: the text is the first child and takes the whole width, its control with it. */
.kan-fund-box--intro .kan-fund-box__text:first-child,
.kan-fund-box--intro .kan-fund-box__text:first-child ~ .kan-fund-box__more { grid-column: 1 / -1; }
/* Without JavaScript the text is whole: let it flow round the photo instead of beside it. */
.no-js .kan-fund-box--intro { display: flow-root; }
.no-js .kan-fund-box--intro .kan-fund-box__photo { float: left; margin: 0 14px 6px 0; }

/* Ended, the same opener tops the closing card, which brings its own padding. */
.kan-fund-ended-card .kan-fund-box--intro { padding: 0; }

.kan-fund-form__alert { padding: var(--space-4) var(--space-4) 0; }
/* Without JavaScript both steps are open and there is nowhere for „Ďalej" to go. */
.no-js .kan-fund-form .kan-acc__next { display: none; }

/* The meter's preview. Track → the gold stripe of the pending gift (under, grows from the
   left) → what is raised (over). On the photo the raised part is white, so the gold reads as
   the gift; under the band it is the navy it always was. Once the gift would reach the
   milestone the whole bar is gold. */
.kan-fund-meter--preview .kan-hero__meter-track,
.kan-fund-meter--preview .kan-mobile-meter__track { position: relative; }
.kan-fund-meter__pending {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: var(--radius-pill);
  background: var(--meter-marker);
  transition: width var(--dur-meter-preview) var(--ease-out);
}
.kan-fund-meter--preview .kan-hero__meter-fill,
.kan-fund-meter--preview .kan-mobile-meter__fill {
  position: relative;
  z-index: 1;
  transition: width var(--dur-meter-preview) var(--ease-out), background-color var(--dur-meter-preview) var(--ease-standard);
}
.kan-fund-meter--hero.kan-fund-meter--preview .kan-hero__meter-fill { background: var(--paper); }
.kan-fund-meter--preview.is-reached .kan-hero__meter-fill,
.kan-fund-meter--preview.is-reached .kan-mobile-meter__fill { background: var(--meter-marker); }

/* „+ 50 €" beside the sum — the tag's gold pill, so the stripe explains itself. */
.kan-fund-meter__plus {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--highlight);
  color: var(--on-highlight);
  font-size: var(--fs-legal);
  font-weight: var(--fw-bold);
  line-height: 1.4;
  white-space: nowrap;
  vertical-align: 0.12em;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-slow) var(--ease-standard), visibility 0s linear var(--dur-slow);
}
.kan-fund-meter__plus.is-on { opacity: 1; visibility: visible; transition-delay: 0s; }

/* On the photo the milestone line and the sentence share one cell and cross-fade. */
.kan-fund-meter__swap { display: grid; justify-items: end; }
.kan-fund-meter__swap > span {
  grid-area: 1 / 1;
  transition: opacity var(--dur-slow) var(--ease-standard), visibility 0s linear 0s;
}
.kan-fund-meter__swap-reached { color: var(--text-on-dark); font-weight: var(--fw-semibold); }
.kan-fund-meter__swap-reached,
.kan-fund-meter--preview.is-reached .kan-fund-meter__swap > [data-meter-goal] { opacity: 0; visibility: hidden; transition-delay: 0s, var(--dur-slow); }
.kan-fund-meter--preview.is-reached .kan-fund-meter__swap-reached { opacity: 1; visibility: visible; transition-delay: 0s; }

/* Under the band the sentence goes below the bar and may wrap to two lines on a narrow phone. */
.kan-fund-meter__reached {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  visibility: hidden;
  transition:
    max-height var(--dur-accordion) var(--ease-standard),
    opacity var(--dur-slow) var(--ease-standard),
    visibility 0s linear var(--dur-accordion);
}
.kan-fund-meter__reached p {
  margin: 0;
  padding-top: 2px;
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  line-height: 1.4;
  color: var(--text-heading);
  text-wrap: balance;
}
.kan-fund-meter--preview.is-reached .kan-fund-meter__reached { max-height: 4em; opacity: 1; visibility: visible; transition-delay: 0s; }

@media (max-width: 719.98px) {
  /* The H1 on the band, bottom left; the dots keep the bottom right corner. */
  .kan-fund-page .kan-hero__left { display: block; padding-right: 88px; }
  .kan-fund-h1 { max-width: none; font-size: 28px; line-height: 1.06; }
  .kan-fund-ended-line { margin-bottom: var(--space-1); font-size: var(--fs-legal); }
}

/* S11N-A · SESSION-11N §1 (detail zbierky) and §2 („Aktualizovať stav zbierky") — deliberately
   almost nothing new: year pills reuse `.kan-pill.is-on` (Zdroje's own
   period pills), the dialog reuses `.kan-dialog`, the goal-year selector reuses
   `.kan-payfilter__row`. Only the no-JS-fallback-button hide and the live-preview line's
   default-hidden state are genuinely new. */
html:not(.no-js) [data-goal-vintage-submit] { display: none; }
.kan-campaign-meter__facts { margin-top: var(--space-2); }

/* SESSION-11N §3.2, the client's popover-then-confirm flow (reverses the earlier one-dialog-
   with-a-select shape) — the shared year popover a payment's ročník link opens
   (`vintage-popover.blade.php`), built and positioned by `public/js/admin.js`. A native
   `[popover]` renders in the top layer, so it is never clipped by a table cell's own `overflow: hidden` under
   admin-density.css, or by `.kan-table-wrap`'s own scroll: no CSS trap to beat here.
   `position: fixed` plus the couple of inline styles the script sets from
   `getBoundingClientRect()` is all that is left to do — the UA stylesheet centres a bare
   `[popover]` in the viewport by default (`inset: 0; margin: auto`), so both need clearing
   first. A year button reuses `--touch-min` for its target size exactly like
   `.kan-table__actions .kan-iconbtn` above (28 px visual under `(pointer: fine)` in the
   admin per admin-density.css — past CLAUDE.md rule 12's 24 px floor there — 44 px
   everywhere else, coarse pointer included); the current year is not a button at all, so it
   is never in the tab order, and its background is the same `--accent-subtle` token the
   donor combobox's own selected option already uses (CLAUDE.md rule 9: no new hex/radius). */
.kan-vintage-pop {
  position: fixed;
  inset: auto;
  margin: 0;
  z-index: var(--z-modal);
  width: max-content;
  max-width: 200px;
  padding: var(--space-2);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
}
.kan-vintage-pop__list { display: flex; flex-direction: column; gap: 2px; }
.kan-vintage-pop__opt {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-min);
  padding: var(--space-1) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  width: 100%;
  font-family: var(--font-ui);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
  color: var(--text-heading);
}
button.kan-vintage-pop__opt { cursor: pointer; }
button.kan-vintage-pop__opt:hover { background: var(--accent-subtle); }
button.kan-vintage-pop__opt:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-vintage-pop__opt--current { background: var(--accent-subtle); font-weight: var(--fw-semibold); }

/* ── S11O-A (SESSION-11O stream A writes only between these two lines) ── */
/* SESSION-11O §2.7 · docs/design/formular/src/_mock.css moved in verbatim (tokens only,
   rule 9) — step 4 "Platba"'s recap and equal-weight payment pills, and the one spinner the
   app never had before (`kan-mock-spin` renamed `kan-spin` per the session brief). */

/* ── Krok 4 „Platba" — rekapitulácia nad tlačidlami spôsobu platby ─────────────────────── */
.kan-pay-recap {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-body);
  color: var(--text-heading);
  text-align: center;
}

/* 24. 9. 2026 (Matej) · the logo row that marks the step (x-pay-logos): Apple Pay, Google
   Pay, Visa and Mastercard, same visual height, grey while its accordion step is closed and
   in colour once open (the standalone Platba screen has no step to close, so it stays in
   colour — see .kan-pay-head below). Sizes match each brand's own proportions rather than a
   single height, as E5/E6 show them. */
.kan-pay-logos { display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto; }
.kan-pay-logos__wallets { display: inline-flex; align-items: center; gap: 7px; }
.kan-pay-logos__wallets[hidden] { display: none; }
.kan-pay-logos__mark { display: block; height: 20px; width: auto; }
.kan-pay-logos__mark--visa { height: 11px; }
.kan-pay-logos__mark--mastercard { height: 17px; }
.kan-acc__step:not(.is-open) .kan-pay-logos { filter: grayscale(1); opacity: 0.55; }
/* At 320 px the step head's dot + label + four logos are tight — shrink the marks and the
   gap rather than let anything wrap or overflow. */
@media (max-width: 359px) {
  .kan-pay-logos, .kan-pay-logos__wallets { gap: 5px; }
  .kan-pay-logos__mark { height: 17px; }
  .kan-pay-logos__mark--visa { height: 10px; }
  .kan-pay-logos__mark--mastercard { height: 15px; }
}
.kan-acc__pay-logos { flex-shrink: 0; }

/* The standalone „Vyberte spôsob platby" screen's own heading row (result/method.blade.php):
   „Platba" + the logos, in colour, like an open step head — but this screen is not an
   accordion step, so it gets its own small heading instead of `.kan-result-h1`. */
.kan-pay-head { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.kan-pay-head__title { margin: 0; font-family: var(--font-ui); font-size: var(--fs-h4); font-weight: var(--fw-semibold); color: var(--text-heading); }

/* ── Tlačidlá spôsobu platby — jedna plná pilulka „Podporiť Kolégium *", pod ňou menší
   textový odkaz „Bankový prevod *" / „Trvalý príkaz *" (24. 9. 2026, Matej — nahrádza
   rovnocenné pilulky „ako Signal"). Žiadne ikony vnútri: čo sa platí, hovoria logá v hlave
   kroku (x-pay-logos). ──────────────────────────────────────────────────────────────────── */
.kan-paymethod-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.kan-paymethod {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 56px;
  padding: var(--space-2) var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-button);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  color: var(--text-heading);
  cursor: pointer;
}
.kan-paymethod:hover:not(:disabled) { background: var(--accent-subtle); border-color: var(--accent); }
.kan-paymethod:active:not(:disabled) { background: var(--accent-subtle-hover); }
.kan-paymethod:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
/* Disabled = every OTHER method while one is redirecting, AND every pill before step 3
   answered (its URL is still "#"); dimmed by opacity only, never a new colour. The busy
   button itself (below) stays at full opacity. */
.kan-paymethod:disabled:not(.kan-paymethod--busy) { opacity: 0.5; cursor: default; }

.kan-paymethod__label {
  font-weight: var(--fw-semibold);
}

/* Kartou — plná farba --accent. */
.kan-paymethod--card { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.kan-paymethod--card:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }
.kan-paymethod--card:active:not(:disabled) { background: var(--accent-active); border-color: var(--accent-active); }

/* „Bankový prevod *" / „Trvalý príkaz *" under it — a small text button, not a pill: the
   legal-size token, medium weight, accent colour, no underline, no icon — still a real
   submit with a 44 px target and the system's own focus ring. */
.kan-paymethod--transfer {
  width: auto;
  align-self: center;
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  background: transparent;
  border-color: transparent;
  color: var(--accent);
  font-size: var(--fs-legal);
}
.kan-paymethod--transfer .kan-paymethod__label { font-weight: var(--fw-medium); }
.kan-paymethod--transfer:hover:not(:disabled) { background: transparent; border-color: transparent; color: var(--accent-hover); }
.kan-paymethod--transfer:active:not(:disabled) { background: transparent; color: var(--accent-active); }

/* No card (paused, the breaker, or an amount above the card limit): „Podporiť Kolégium *" is
   gone and the transfer becomes the primary pill, sized and coloured like the CTA it replaces. */
.kan-pay-methods--no-card .kan-paymethod--transfer {
  width: 100%;
  align-self: stretch;
  min-height: 56px;
  padding: var(--space-2) var(--space-4);
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-size: var(--fs-body);
}
.kan-pay-methods--no-card .kan-paymethod--transfer .kan-paymethod__label { font-weight: var(--fw-semibold); }
.kan-pay-methods--no-card .kan-paymethod--transfer:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--on-accent); }
.kan-pay-methods--no-card .kan-paymethod--transfer:active:not(:disabled) { background: var(--accent-active); border-color: var(--accent-active); color: var(--on-accent); }

/* Busy variant (P6 · presmerovanie): the clicked button keeps its place in the list but
   shows the spinner + a status text instead of its usual label. */
.kan-paymethod--busy .kan-paymethod__label { color: inherit; }

/* The footnote the asterisk points to (24. 9. 2026) — legal-size, medium weight, body
   colour, left-aligned like `x-pay-note` under it. */
.kan-paymethod-footnote { margin: 0; font-size: var(--fs-legal); font-weight: var(--fw-medium); color: var(--text-body); text-align: left; }

/* ── Malý točiaci sa indikátor (appka doteraz žiadny nemala) ─────────────────────────────── */
.kan-spin {
  display: inline-block;
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  border-radius: var(--radius-pill);
  border: 2px solid currentColor;
  border-top-color: transparent;
  opacity: 0.75;
  animation: kan-spin 800ms linear infinite;
}
.kan-btn .kan-spin { margin-right: var(--space-1); }
@keyframes kan-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .kan-spin { animation-duration: 2400ms; }
}
/* `hidden` must win over the pill's own `display: flex` — „Platba" hides above the card limit. */
.kan-paymethod[hidden] { display: none; }
/* Above the card limit (22. 9. 2026): one small line under the transfer pill, no box. */
.kan-paymethod-note { margin: var(--space-2) 0 0; font-size: var(--fs-legal); line-height: 1.5; color: var(--text-muted); text-align: center; text-wrap: pretty; }
.kan-paymethod-note[hidden] { display: none; }
/* ── /S11O-A ── */

/* ── S11O-B (SESSION-11O stream B writes only between these two lines) ── */
/* SESSION-11O §3.2/§2.7 · "Údaje na prevod" screen (docs/design/formular/src/_mock-prevod.css,
   moved into tokens verbatim — no new hex, no new radius, no new shadow, rule 9).
   Compact since 22. 9. 2026 (Matej): icon-only copy buttons (44 × 44 hit area, rule 12),
   no caption under the QR, tighter rows, QR beside the rows from 560 px. */

.kan-result-card--compact { gap: var(--space-4); }
.kan-result-card--compact .kan-result-head { gap: var(--space-2); }
.kan-result-card--compact .kan-result-h1 { font-size: clamp(26px, 4vw, 34px); }
.kan-result-card--compact .kan-result-amount { font-size: 1.5rem; }


/* One row = label + value + an icon-only copy button (copy icon, a check once copied). */
.kan-copyrows { margin: 0; display: flex; flex-direction: column; }
.kan-copyrow {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  min-height: var(--touch-min);
  padding: 2px 0;
  border-bottom: 1px solid var(--border-subtle);
}
.kan-copyrow:last-child { border-bottom: 0; }
.kan-copyrow__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kan-copyrow__text dt { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-copyrow__text dd {
  margin: 0;
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.kan-copyrow__btn {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: var(--touch-min);
  height: var(--touch-min);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.kan-copyrow__btn[hidden] { display: none; }
.kan-copyrow__btn:hover { background: var(--accent-subtle); color: var(--accent); }
.kan-copyrow__btn:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-copyrow__btn .kan-copyrow__ok { display: none; }
.kan-copyrow__btn.is-copied { color: var(--success); }
.kan-copyrow__btn.is-copied .kan-copyrow__idle { display: none; }
.kan-copyrow__btn.is-copied .kan-copyrow__ok { display: inline-block; }


/* Quiet centred links between/under the cards ("Posielate dar zo zahraničia?", "Chcem vybrať
   iný spôsob platby", "Posielam zo slovenskej banky"). */
.kan-prevod-switch { margin: 0; text-align: center; }
/* Failed / cancelled / resumed card payment (24. 9. 2026, Matej): these screens now share
   the giving form's own step „Platba" (`.kan-pay-head`, `.kan-pay-methods`, S11O-A above) —
   no card-specific rules left here. */
/* ── /S11O-B ── */

/* ── S11O-C (SESSION-11O stream C writes only between these two lines) ── */
/* ── /S11O-C ── */

/* ── S11O-D (SESSION-11O stream D writes only between these two lines) ── */
/* ── /S11O-D ── */

/* ── 22. 9. 2026 (Matej) · „donorskú komunikáciu" — a phrase of a consent label that opens
   its own explanation. A native <details>, so it works with no JavaScript; js/term.js only
   adds Esc and a click outside. Same bubble as `.kan-help__pop`, only wider. 24. 9. 2026:
   it floats ON TOP of what follows at every width (never pushes the form down), anchored on
   the whole checkbox row (`.kan-checkbox--term`), as wide as the row but never wider than
   the viewport minus a 16 px gutter on each side. ─────────────────────────────────────── */
/* The whole sentence is ONE flex item of `.kan-checkbox__text` (whose gap would otherwise
   push the phrase and the full stop apart), and inline inside itself, so it wraps as text. */
.kan-checkbox--term { position: relative; }
/* The accordion clips its panels (the height animation) and its rounded card; while a note
   is open inside the open panel, both let it float out over whatever follows. */
.kan-acc:has(.kan-term[open]),
.kan-acc__step.is-open > .kan-acc__body:has(.kan-term[open]) { overflow: visible; }
.kan-checkbox__sentence { min-width: 0; font-size: var(--fs-body-sm); line-height: 1.5; }
.kan-checkbox__sentence .kan-checkbox__label { display: inline; }
.kan-term {
  display: inline;
  position: static; /* the bubble is placed against the whole row, see above */
}
.kan-term__word {
  display: inline;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  list-style: none;
}
.kan-term__word::-webkit-details-marker { display: none; }
.kan-term__word::marker { content: ''; }
.kan-term__word:hover { color: var(--text-heading); }
.kan-term__word:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}
.kan-term__pop {
  position: absolute;
  top: calc(100% + var(--space-2));
  left: 0;
  z-index: var(--z-sticky);
  display: block;
  width: 100%;
  max-width: calc(100vw - 2 * var(--space-4));
  padding: var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  font-family: var(--font-ui);
  /* 25. 9. 2026 (Matej): 17 px, the site's body size — 13 px was too small to read. */
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: 1.5;
  text-align: left;
  color: var(--text-body);
}
/* On a phone the note takes the whole screen minus the 16 px gutter, not just the row: the
   giving forms' row sits centred in its card, so centring on the row centres on the screen. */
@media (max-width: 599px) {
  .kan-term__pop {
    left: 50%;
    transform: translateX(-50%);
    width: calc(100vw - 2 * var(--space-4));
  }
}
/* The title and the close button share one line; the button's 44 px target reaches into the
   padding, so its icon sits level with the title and in the corner. */
.kan-term__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.kan-term__title {
  display: block;
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-ui);
  color: var(--text-heading);
}
.kan-term__close {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--touch-min);
  height: var(--touch-min);
  margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) calc(var(--space-3) * -1) 0;
  border: 0;
  border-radius: var(--radius-button);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-term__close:hover { background: var(--bg-alt); color: var(--text-heading); }
.kan-term__close[hidden] { display: none; }
.kan-term__intro { display: block; }
.kan-term__list {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-6);
  list-style: disc;
}
.kan-term__list li + li { margin-top: var(--space-1); }
.kan-term__list li::marker { color: var(--text-muted); }

/* 23. 9. 2026 (Matej) · the marketing consent (`x-consent-marketing`) only: one line of the
   sentence is exactly as tall as the box (24 px), so the text's middle is the box's middle.
   Scoped to this component — multi-line checkbox labels elsewhere keep their top alignment,
   and an opened note still flows under the first line. */
.kan-consent-marketing .kan-checkbox__box { margin-top: 0; }
.kan-consent-marketing .kan-checkbox__sentence,
.kan-consent-marketing .kan-checkbox__label { line-height: var(--space-6); }
/* In the giving forms its 44 px row reaches into the column's gap instead of adding to it. */
.kan-acc__inner > .kan-consent-marketing { margin-block: calc(var(--space-2) * -1); }

/* ── P1 ▸ prihlásenie darcu a e-mail ── */
/* ── /P1 ── */

/* ── P2 ▸ administrácia a správcovia ── */
/* ── /P2 ── */

/* ── P3 ▸ karty a formulár ── */
/* K-2 (1) · the automatic card breaker's line on Prevádzka: the sentence and its „i" side by side. */
.kan-breaker__line { display: inline-flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.kan-breaker__form { margin-top: var(--space-3); }
/* ── /P3 ── */

/* ── P5 ▸ mesačná suma a karta ── */
/* S-9 · „Potvrdenie novej sumy": the old and the new amount, one row each, the new one a touch stronger. */
.kan-amount-confirm { display: grid; gap: var(--space-2); }
.kan-amount-confirm__new { border-color: var(--border-strong); }
.kan-amount-confirm__new .kan-current-row__value { font-size: var(--fs-body); }
/* ── /P5 ── */

/* ── P7 ▸ súkromie a GDPR ── */
/* ── /P7 ── */

/* ── P8 ▸ zneužitie funkcií ── */
/* Security audit V-9 · the calm line under a live personal campaign's form, outside its white
   card: on the photo (desktop) white like the rest of the hero's text, on the paper (phone)
   muted like the pay note. Small, never a box, never a colour of warning (rule 13). */
.kan-fund-safety {
  margin: var(--space-3) 0 0;
  padding: 0 var(--space-1);
  font-family: var(--font-ui);
  font-size: var(--fs-legal);
  line-height: 1.5;
  color: var(--text-muted);
  text-wrap: pretty;
}
.kan-hero__form .kan-fund-safety { color: var(--text-on-dark); }
/* ── /P8 ── */

/* ── Nastavenia → E-maily (23. 9. 2026) ──
   The screen itself is styled in the P4 block below (Upozornenia a e-maily, 25. 9. 2026 —
   the list-and-editor layout that stood here went with the text editor). The „Odosielanie"
   switch stays here: `.kan-switch`. */
/* „Odosielanie" · a switch that opens a confirmation (role="switch", aria-checked). */
.kan-switch {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--touch-min); min-height: var(--touch-min); padding: 0;
  border: 0; background: transparent; cursor: pointer; border-radius: var(--radius-pill);
}
.kan-switch__track {
  position: relative; display: block; width: 40px; height: 22px;
  border-radius: var(--radius-pill); background: var(--border-strong); transition: var(--transition-colors);
}
.kan-switch__thumb {
  position: absolute; top: 3px; left: 3px; width: 16px; height: 16px;
  border-radius: var(--radius-pill); background: var(--surface-card); transition: transform var(--dur-fast) var(--ease-standard);
}
.kan-switch[aria-checked="true"] .kan-switch__track { background: var(--success); }
.kan-switch[aria-checked="true"] .kan-switch__thumb { transform: translateX(18px); }
.kan-switch:disabled { cursor: not-allowed; }
.kan-switch:disabled .kan-switch__track { opacity: 0.55; }
/* ── /Nastavenia → E-maily ── */

/* ── Kanály súhlasu (24. 9. 2026, Matej) ──
   Moje údaje: „List" and „E-mail" under the marketing consent, indented to its text (the
   24 px box + the checkbox's own gap), side by side, the explanation under them. */
.kan-consent-prefs { display: flex; flex-direction: column; gap: var(--space-2); }
.kan-consent-channels { margin: 0; padding: 0 0 0 calc(var(--space-6) + var(--space-3)); border: 0; display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.kan-consent-channels[hidden] { display: none; }
.kan-consent-channels__options { display: flex; flex-wrap: wrap; column-gap: var(--space-6); }
/* The admin's donor detail: the same two channels in one row, the button beside them. */
.kan-consent-channels-admin { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--space-4); }
/* ── /Kanály súhlasu ── */

/* ── PODAKOVANIE-A (stream A writes only between these two lines) ── */
/* Poďakovanie (24. 9. 2026, board A1/M1/O1/P2) · the one shared thank-you screen. Classes
   taken from docs/design/podakovanie/src/_mock-podakovanie.css (.kan-thx*, .kan-post*,
   .kan-copyicon*, .kan-transfer-done) — tokens only, no new hex/radius/shadow. Additions
   beyond the mock are called out inline. The „Podporili ste" card (.kan-mini-impact*,
   .kan-minimeter*) is gone (Matej, 24. 9. 2026) — the main CTA is the „Zdieľať" button, a
   plain `x-button`, no CSS of its own beyond the shared `.kan-btn` and the global
   `.kan-btn[hidden]` rule. */

.kan-thx { max-width: 560px; margin-inline: auto; display: flex; flex-direction: column; gap: var(--space-4); }
.kan-result-col:has(.kan-thx) { max-width: 560px; }
.kan-result-main:has(.kan-thx) { padding-top: var(--space-5); }
.kan-thx__head { display: grid; grid-template-columns: auto 1fr; gap: 4px var(--space-3); align-items: center; }
.kan-thx__badge {
  width: 36px; height: 36px; border-radius: var(--radius-pill); background: var(--accent); color: var(--on-accent);
  display: grid; place-items: center;
}
.kan-thx__badge .kan-icon { width: 18px; height: 18px; }
.kan-thx__h1 {
  margin: 0; font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: 32px; line-height: 1.1;
  letter-spacing: var(--ls-display); color: var(--text-heading);
}
.kan-thx__sub { grid-column: 1 / -1; margin: 0; font-size: var(--fs-small); line-height: 1.5; color: var(--text-body); }
.kan-thx__sub a, .kan-thx__facts a { color: var(--text-link); font-weight: var(--fw-semibold); text-decoration: underline; text-underline-offset: 0.2em; }
.kan-thx__facts { grid-column: 1 / -1; margin: 0; font-size: var(--fs-small); color: var(--text-body); }
.kan-thx__card {
  background: var(--paper); border: 1px solid var(--border-default); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-1); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3);
}
.kan-thx__title { margin: 0; font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: 24px; line-height: 1.15; color: var(--text-heading); }
.kan-thx__text { margin: 0; font-family: var(--font-body); font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-body); text-wrap: pretty; }
.kan-thx__hint { margin: 0; font-size: var(--fs-small); color: var(--text-muted); line-height: 1.5; }
.kan-thx__back { display: flex; justify-content: center; }
/* Phone: a smaller H1 keeps the copy button above the 600 px fold (DoD). */
@media (max-width: 719px) {
  .kan-thx__h1 { font-size: 26px; }
  .kan-thx__card { gap: var(--space-3); }
}
/* Desktop has room to spare (Matej, 24. 9. 2026, after dropping `thanks.share_after`): more
   distance between the paragraph and the post preview, and the card breathes a bit more —
   never on the phone breakpoint above, which keeps the copy button above the 600 px fold. */
@media (min-width: 720px) {
  .kan-thx__card { padding: var(--space-6); gap: var(--space-5); }
}

/* Príspevok, ako ho uvidia priatelia (neutrálny rámec, nie dizajn konkrétnej siete). */
.kan-post { border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); background: var(--surface-card); overflow: hidden; }
.kan-post__head { position: relative; display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-3) 0; }
.kan-post__avatar {
  width: 36px; height: 36px; border-radius: var(--radius-pill); background: var(--navy-100); color: var(--navy-700);
  display: grid; place-items: center; font-size: var(--fs-legal); font-weight: var(--fw-bold); flex: 0 0 auto;
}
.kan-post__who { display: flex; flex-direction: column; min-width: 0; }
.kan-post__who b { font-size: var(--fs-small); color: var(--text-heading); overflow-wrap: anywhere; }
.kan-post__who span { font-size: var(--fs-legal); color: var(--text-muted); }
.kan-post__text {
  margin: 0; padding: var(--space-2) var(--space-3) var(--space-3); font-family: var(--font-body); font-size: 15px;
  line-height: 1.5; color: var(--text-heading); white-space: pre-line; overflow-wrap: anywhere;
}
/* The clamp only ever applies once this page has JavaScript (`html:not(.no-js)`, the class
   the base layout's head script removes) — without it the "more" control stays `hidden` and
   the visitor already sees the whole text, so nothing may clamp it away. Expanding it needs a
   selector at least as specific as the clamp rule itself (html + :not + two classes), or the
   clamp keeps winning even after `public/js/thanks.js` adds `--expanded` (browser pass). */
@media (max-width: 719px) {
  html:not(.no-js) .kan-post__text--clamp { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; padding-bottom: 0; }
  html:not(.no-js) .kan-post__text--clamp.kan-post__text--expanded { display: block; -webkit-line-clamp: unset; overflow: visible; padding-bottom: var(--space-3); }
}
.kan-post__text:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); border-radius: var(--radius-sm); }
.kan-post__more {
  display: flex; align-items: center; width: 100%; min-height: var(--touch-min); margin: 0;
  padding: 2px var(--space-3) var(--space-3); border: 0; background: none; cursor: pointer; text-align: left;
  font-family: var(--font-ui); font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-muted);
}
/* `[hidden]` needs its own rule — a class that sets `display` beats the attribute otherwise
   (the same S10 lesson `.kan-copyicon[hidden]` above already applies); the desktop rule below
   must come AFTER the base rule so it is the one that wins there (browser pass). */
.kan-post__more[hidden] { display: none; }
@media (min-width: 720px) { .kan-post__more { display: none; } }
.kan-post__more:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: -2px; }
.kan-post__link { border-top: 1px solid var(--border-subtle); background: var(--surface-sunken); }
.kan-post__img { display: block; width: 100%; aspect-ratio: 1.91 / 1; object-fit: cover; }
.kan-post__img--empty { background: var(--navy-100); }
.kan-post__meta { padding: var(--space-2) var(--space-3) var(--space-3); display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kan-post__domain { font-size: var(--fs-legal); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); overflow-wrap: anywhere; }
.kan-post__ltitle { font-size: var(--fs-small); font-weight: var(--fw-bold); color: var(--text-heading); overflow-wrap: anywhere; }
.kan-post__ldesc { font-size: var(--fs-legal); color: var(--text-muted); }
/* Phone: compact link preview — a square thumbnail beside the text, not the large 1.91:1 card. */
@media (max-width: 719px) {
  .kan-post__link--row-m { display: grid; grid-template-columns: 96px 1fr; align-items: center; }
  .kan-post__link--row-m .kan-post__img,
  .kan-post__link--row-m .kan-post__img--empty { aspect-ratio: 1 / 1; height: 100%; }
}

/* Kopírovacie tlačidlo v hlavičke príspevku: 44 px zlatý kruh; po skopírovaní fajka so
   „vyskočením", zelený kruh a bublina „Text je skopírovaný" (role=status) pod tlačidlom.
   Bez JavaScriptu je `hidden` — `.kan-copyicon` inak nesie vlastný `display`, ktorý by
   atribút `[hidden]` prebil (poučenie S10). */
.kan-copyicon-wrap { position: relative; margin-left: auto; display: inline-flex; align-items: center; }
.kan-copyicon {
  width: var(--touch-min); height: var(--touch-min); border-radius: var(--radius-pill); display: grid; place-items: center;
  border: 1px solid var(--highlight); background: var(--highlight); color: var(--on-highlight); cursor: pointer;
  box-shadow: var(--shadow-1); transition: background-color .25s ease, border-color .25s ease, color .25s ease;
}
.kan-copyicon[hidden] { display: none; }
.kan-copyicon:hover { background: var(--highlight-hover); }
.kan-copyicon:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-copyicon .kan-icon { width: 20px; height: 20px; }
.kan-copyicon__done-icon { display: none; }
.kan-copyicon.is-copied .kan-copyicon__idle { display: none; }
.kan-copyicon.is-copied .kan-copyicon__done-icon { display: inline-block; animation: kan-thx-pop .35s cubic-bezier(.2,.9,.3,1.4); }
.kan-copyicon.is-copied { background: var(--success-surface); border-color: var(--success-border); color: var(--success-text); }
.kan-copyicon__done {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 2; white-space: nowrap;
  font-size: var(--fs-legal); font-weight: var(--fw-semibold); color: var(--success-text); background: var(--success-surface);
  border: 1px solid var(--success-border); border-radius: var(--radius-pill); padding: 4px 10px; box-shadow: var(--shadow-1);
}
/* The bubble is a `role="status"` live region that stays in the DOM at all times (never
   `hidden`) — public/js/thanks.js only ever changes its text. Empty, it must take up no
   visible space at all (browser pass: it rendered as an empty green pill on load), and the
   fade-in only plays when `.is-on` is toggled on a real copy, never on page load. */
.kan-copyicon__done:empty { padding: 0; border: 0; box-shadow: none; }
.kan-copyicon__done.is-on { animation: kan-thx-fade .25s ease-out; }
@keyframes kan-thx-pop { 0% { transform: scale(.4); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
@keyframes kan-thx-fade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .kan-copyicon, .kan-copyicon.is-copied .kan-copyicon__done-icon, .kan-copyicon__done.is-on { transition: none; animation: none; }
}

/* Prevod: tlačidlo „Dar odoslaný" ako posledná časť karty s údajmi na obrazovke „Údaje na
   prevod" (Matej, 24. 9. 2026 — už nie vlastná karta). Oddelené od riadkov nad ním rovnako
   ako `.kan-transfer-block__facts` — vlastný `border-top`, medzera dodaná medzerou karty. */
.kan-transfer-done {
  display: flex; flex-direction: column; gap: var(--space-3); align-items: stretch; text-align: center;
  border-top: 1px solid var(--border-subtle); padding-top: var(--space-4);
}
.kan-transfer-done .kan-btn { width: 100%; justify-content: center; }
/* ── /PODAKOVANIE-A ── */

/* ── PODAKOVANIE-B (stream B writes only between these two lines) ── */
/* Ciele ročníkov (24. 9. 2026, boards B1–B3) · the zbierka detail's meter
   (`admin/campaigns/partials/meter.blade.php`): the „Ročník {rok}" button with its native
   popover, and the goal's pencil that swaps the amount for a small form in place. Every
   target reads --touch-min — 28 px on a fine pointer under admin-density.css (past rule 12's
   24 px floor), 44 px everywhere else. Without CSS anchor positioning the popover keeps the UA
   default (centred) until admin.js places it under the button; with it, CSS alone does. */
.kan-yearsel { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.kan-yearsel__note { font-size: var(--fs-small); color: var(--text-muted); }
.kan-yearbtn {
  display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--touch-min);
  padding: 0 var(--space-4); border-radius: var(--radius-pill); border: 1px solid var(--accent);
  background: var(--accent); color: var(--on-accent); font-family: var(--font-ui);
  font-size: var(--fs-small); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; cursor: pointer;
}
.kan-yearbtn:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.kan-yearbtn:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-yearbtn__label { font-weight: var(--fw-regular); }
.kan-yearpop {
  min-width: 220px; padding: var(--space-2);
  background: var(--surface-card); border: 1px solid var(--border-default);
  border-radius: var(--radius-md); box-shadow: var(--shadow-2);
}
@supports (anchor-name: --kan-yearbtn) {
  .kan-yearbtn { anchor-name: --kan-yearbtn; }
  .kan-yearpop { position-anchor: --kan-yearbtn; inset: auto; top: anchor(bottom); left: anchor(left); margin: var(--space-1) 0 0; }
}
.kan-yearpop__list { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.kan-yearpop__item {
  display: flex; align-items: center; gap: var(--space-2); min-height: var(--touch-min);
  padding: 0 var(--space-3); border-radius: var(--radius-sm); color: var(--text-heading);
  text-decoration: none; font-size: var(--fs-small); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums;
}
.kan-yearpop__item:hover { background: var(--accent-subtle); }
/* Etapy (25. 9. 2026) · a stage still waiting is listed but cannot be opened. */
.kan-yearpop__item.is-disabled { color: var(--text-muted); font-weight: var(--fw-regular); }
.kan-yearpop__item.is-disabled:hover { background: none; }
.kan-yearpop__item:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: -2px; }
.kan-yearpop__item.is-on { background: var(--accent-subtle); color: var(--accent); }
.kan-yearpop__note { font-weight: var(--fw-regular); color: var(--text-muted); }
.kan-yearpop__item .kan-icon { margin-left: auto; }

.kan-goalmeter { display: flex; flex-direction: column; gap: var(--space-3); }
.kan-yearsel + .kan-goalmeter { margin-top: var(--space-4); }
.kan-goalmeter__row { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.kan-goalmeter__raised {
  margin: 0; font-family: var(--font-numeric); font-weight: var(--fw-bold); font-size: 1.5rem; line-height: 1.05;
  letter-spacing: var(--ls-numeric); color: var(--text-heading); font-variant-numeric: tabular-nums;
}
.kan-goalmeter__goal { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); text-align: right; }
.kan-goalmeter__amount {
  margin: 0; display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-numeric); font-weight: var(--fw-semibold); font-size: 1.125rem; line-height: 1.05;
  color: var(--text-body); font-variant-numeric: tabular-nums;
}
.kan-goalmeter__amount[hidden], .kan-goaledit[hidden] { display: none; }
.kan-goalmeter__track { height: 12px; border-radius: var(--radius-meter); background: var(--meter-track); overflow: hidden; }
.kan-goalmeter__fill { height: 100%; border-radius: var(--radius-meter); background: var(--meter-fill); transition: var(--transition-meter); }
.kan-goalmeter__fill.is-complete { background: var(--meter-fill-complete); }
.kan-goaledit { display: flex; align-items: flex-start; justify-content: flex-end; gap: var(--space-2); flex-wrap: wrap; text-align: left; }
.kan-goaledit .kan-field { width: 13rem; }
.kan-goaledit .kan-input { text-align: right; }
.kan-goaledit__actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-height: var(--control-h); }
@media (max-width: 719px) {
  .kan-goalmeter__goal { align-items: flex-start; text-align: left; width: 100%; }
  .kan-goaledit { justify-content: flex-start; }
}
/* ── /PODAKOVANIE-B ── */

/* ── W0 ▸ x-segmented (upozornenia a e-maily, zadanie §0.8) ──
   The one look of every two-or-three-way switch is .kan-freq (above). x-segmented adds two
   variants on top of it: links (a switch through the address, works without JS) and icons
   (the preview width: monitor / smartphone, the label in aria-label + title). */
.kan-freq--links .kan-freq__option { text-decoration: none; }
.kan-freq--links .kan-freq__option:hover { color: var(--accent); }
.kan-freq--links .kan-freq__option[aria-current] {
  background: var(--paper);
  border-color: var(--accent);
  box-shadow: var(--shadow-1);
  color: var(--accent);
}
.kan-freq--links .kan-freq__option:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.kan-freq--icons { display: inline-block; }
.kan-freq--icons .kan-freq__track {
  display: inline-grid;
  grid-auto-flow: column;
  grid-template-columns: none;
  margin-top: 0;
}
.kan-freq--icons .kan-freq__option { min-width: 36px; min-height: 32px; padding: 0 var(--space-2); }
@media (pointer: coarse) {
  .kan-freq--icons .kan-freq__option { min-width: 44px; min-height: 38px; }
}
/* ── /W0 ── */

/* ── P1 ▸ upozornenia (P1 writes only between these two lines) ── */
/* ── /P1 ── */

/* ── P2 ▸ TEST (P2 writes only between these two lines) ── */
/* ── /P2 ── */

/* ── P3 ▸ sumáre (P3 writes only between these two lines) ── */
/* ── /P3 ── */

/* ── P4 ▸ Nastavenia → E-maily (P4 writes only between these two lines) ── */
/* Zadanie §5 (boards Admin-emaily, Admin-emaily-darcom, Admin-prijemcovia) · one tree on the
   left (native <details>, nested with a thin line, a coloured dot per alert level) and the
   selected item on the right: facts, the „only in the code" note, the toolbar (zbierka, test
   send, width switch) and the sandboxed preview (P6's .kan-emailpreview__frame,
   public/js/email-preview.js). P7 · „História odoslaných" is the first thing of the left
   column, above the tree card, the full width of that column — the tabs row is plain again.
   Tokens only; targets 44 px, 32 px on a fine pointer in the admin (S11B). */
.kan-mailbox { display: grid; grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); gap: var(--admin-card-gap); align-items: start; }
@media (max-width: 899px) { .kan-mailbox { grid-template-columns: minmax(0, 1fr); } }
.kan-mailbox [hidden] { display: none; }
.kan-mailbox__side { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.kan-mailbox__history { justify-content: center; }

.kan-mailtree__dot { flex: none; width: 9px; height: 9px; border-radius: var(--radius-pill); background: var(--text-muted); }
.kan-mailtree__dot--critical { background: var(--danger); }
.kan-mailtree__dot--warning { background: var(--warning-text); }
.kan-mailtree__dot--info { background: var(--info-text); }
.kan-mailtree__dot--digest { background: var(--surface-inverse); }

.kan-mailitem { min-width: 0; }
.kan-mailitem__level {
  display: inline-flex; align-items: center; padding: 2px var(--space-3);
  border-radius: var(--radius-pill); font-size: var(--fs-overline); font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--on-accent);
}
.kan-mailitem__level--critical { background: var(--danger); }
.kan-mailitem__level--warning { background: var(--warning-text); }
.kan-mailitem__level--info { background: var(--info-text); }
.kan-mailitem__facts dt { flex: 0 0 9rem; }
.kan-mailitem__facts dd { flex: 1 1 16rem; text-align: left; color: var(--text-heading); }
.kan-mailitem__facts .kan-inline-link { min-height: 0; }
/* P7 · „Odosielateľ" with its „i" beside the label; the value may wrap on a phone. */
.kan-mailitem__dt { display: inline-flex; align-items: center; gap: var(--space-1); }
.kan-mailitem__facts [data-mailitem-sender] dd { overflow-wrap: anywhere; }
.kan-mailitem__sending { display: inline-flex; align-items: center; gap: var(--space-2); }
.kan-mailitem__sending-state { color: var(--success-text); font-weight: var(--fw-semibold); }
.kan-mailitem__sending-state.is-stopped { color: var(--warning-text); }
.kan-mailitem__sending-since { display: block; color: var(--text-muted); }
.kan-mailitem__code {
  display: flex; align-items: center; gap: var(--space-3); margin: 0;
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-md);
  background: var(--surface-sunken); font-size: var(--fs-legal); color: var(--text-body);
}
.kan-mailitem__chip {
  flex: none; padding: 2px var(--space-2); border: 1px solid var(--accent-border); border-radius: var(--radius-sm);
  background: var(--surface-card); font-family: var(--font-mono); font-size: var(--fs-legal); font-weight: var(--fw-bold); color: var(--accent);
}
.kan-mailitem__preview { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.kan-mailitem__toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.kan-mailitem__campaign { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; }
.kan-mailitem__campaign .kan-field__label { margin: 0; }
.kan-mailitem__campaign .kan-select { width: auto; max-width: 100%; }
.kan-mailitem__test { margin: 0; }
.kan-mailitem__width { margin-left: auto; }
.kan-mailitem__add { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); }
.kan-mailitem__levels {
  list-style: none; margin: 0; padding: var(--space-4) 0 0; border-top: 1px solid var(--border-subtle);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: var(--space-3);
}
.kan-mailitem__levelcard { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3) var(--space-4); border: 1px solid var(--border-default); border-radius: var(--radius-md); }
.kan-mailitem__levelname { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--fs-legal); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-mailitem__levelnote { font-size: var(--fs-legal); color: var(--text-muted); }

/* Orchestrator, browser at 375 px: the long first-person label may wrap rather than push the card wider. */
.kan-mailitem__test { max-width: 100%; }
.kan-mailitem__test .kan-btn { white-space: normal; max-width: 100%; height: auto; min-height: var(--control-h-sm); text-align: center; }
/* ── /P4 ── */

/* ── P5 ▸ záznam e-mailov (P5 writes only between these two lines) ── */
/* ── /P5 ── */

/* ── P6 ▸ história e-mailov (P6 writes only between these two lines) ── */
/* Zadanie §6 · Nastavenia → E-maily → História odoslaných (list) and one e-mail's detail —
   design tokens only, the same spacing/border/radius scale as `.kan-payfilter`/`.kan-mailset`.
   Orchestrator review (browser, 1440 px) fixed the filter row, the table's overflow, the
   detail's two-column layout and the donor history's fit — see each rule's own note below. */
.kan-emailhistory__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-4); }

/* Review point 2 · ONE wrapping row (never a column — `.kan-search__wrap`'s own `flex: 0 1
   320px` sets its HEIGHT, not its width, inside a column flex container, which is what left
   huge empty bands above). */
.kan-emailhistory__filters { display: flex; flex-direction: row; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); margin-block: var(--space-3) var(--space-4); }

/* Status badges of the history: colours per CLAUDE.md's S11F rule — green live/sent, yellow
   inactive/stopped (an admin switch, not a failure), grey ended/suppressed (expected outside
   production), red failed/undeliverable. */
.kan-badge--history-sent { background: var(--success-surface); border-color: var(--success-border); color: var(--success-text); }
.kan-badge--history-stopped { background: var(--warning-surface); border-color: var(--warning-border); color: var(--warning-text); }
.kan-badge--history-suppressed { background: var(--status-paused-bg); border-color: var(--status-paused-bd); color: var(--status-paused-fg); }
.kan-badge--history-failed { background: var(--status-failed-bg); border-color: var(--status-failed-bd); color: var(--status-failed-fg); }
/* The "SPRÁVCOM" chip in the list's Komu column and the donor history's "upozornenie
   správcom" note — a neutral, not a status, colour. */
.kan-badge--to-admin { background: var(--surface-sunken); border-color: var(--border-default); color: var(--text-muted); }

.kan-table__truncate { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The level dot and the name on one line (orchestrator, browser): the name truncates, the dot stays. */
.kan-emailhistory__name { position: relative; }
.kan-emailhistory__name > .kan-emailhistory__level { position: absolute; top: 50%; margin-top: -4px; }
.kan-emailhistory__name > .kan-emailhistory__level ~ .kan-table__truncate { padding-inline-start: 16px; }
.kan-emailhistory__level { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-inline-end: var(--space-2); vertical-align: middle; }
.kan-emailhistory__level--critical { background: var(--status-failed-fg); }
.kan-emailhistory__level--warning { background: var(--warning-text); }
.kan-emailhistory__level--info { background: var(--info-text); }

/* The e-mail detail: two columns above ~1100 px (Presne tak preview | Údaje), one below it —
   review point 6. */
.kan-emaildetail { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: var(--space-5); align-items: start; }
@media (max-width: 1100px) {
  .kan-emaildetail { grid-template-columns: minmax(0, 1fr); }
}
.kan-emaildetail__head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

.kan-emailpreview__switch { display: flex; }
.kan-emailpreview__switch[hidden] { display: none; }
/* P7 · no stage box: the frame sits straight in its card, the full width of it — the e-mail
   centres itself at 600 px on its own background, the only surface around it. „Mobil" narrows
   it to 375 px, centred. email-preview.js sets the height to the e-mail's own (one scrollbar,
   the page's); without it the fixed height below scrolls inside the frame. */
.kan-emailpreview__frame { display: block; width: 100%; max-width: 100%; height: 720px; margin: 0 auto; border: 0; border-radius: var(--radius-md); background: var(--surface-sunken); transition: max-width var(--dur-base) var(--ease-out); }
.kan-emailpreview__frame--mobile { max-width: 375px; }
.kan-emailpreview > .kan-emailpreview__frame { margin-top: var(--space-3); }

/* Orchestrator, browser at 1440 px: the donor page's main column is ~590 px, too narrow for
   fixed widths — the table takes its natural layout, the details wrap, the date never does. */
.kan-table--donorhistory { table-layout: auto; }
.kan-table--donorhistory .kan-table__truncate { white-space: normal; overflow: visible; }
.kan-table--donorhistory td:first-child { white-space: nowrap; }
.kan-table--donorhistory td:nth-child(4) { overflow-wrap: anywhere; }
.kan-table--donorhistory td:last-child { width: 1%; white-space: nowrap; }
/* ── /P6 ── */

/* The detail's read-only „Text kampane" (the editor moved to „Upraviť"). */
.kan-fund-read { display: flex; gap: var(--space-4); align-items: flex-start; }
.kan-fund-read__photo { flex: 0 0 auto; width: 96px; height: 96px; border-radius: var(--radius-image); object-fit: cover; }
.kan-fund-read__body { margin: 0; color: var(--text-body); line-height: 1.55; overflow-wrap: anywhere; }
/* ── /Poistky kódom · C ── */

/* Denný limit e-mailov (25. 9. 2026) · Prehľad, the card „Odoslané e-maily" (admin/partials/mail-volume). */
.kan-mailvolume { margin-top: var(--admin-card-gap); }
.kan-mailvolume__today { display: flex; flex-direction: column; gap: var(--space-2); }
.kan-mailvolume__today .kan-overline { margin: 0; color: var(--text-muted); }
.kan-mailvolume__of { font-family: var(--font-sans); font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-muted); }
.kan-mailvolume__track { position: relative; height: 10px; border-radius: var(--radius-pill); background: var(--meter-track); }
.kan-mailvolume__fill { position: absolute; inset: 0 auto 0 0; border-radius: var(--radius-pill); background: var(--meter-fill); }
.kan-mailvolume__track.is-near .kan-mailvolume__fill { background: var(--warning); }
.kan-mailvolume__mark { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: var(--warning); }
.kan-mailvolume__strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 560px) { .kan-mailvolume__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kan-mailvolume__chart-wrap { display: flex; flex-direction: column; gap: var(--space-2); }
.kan-mailvolume__legend { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); font-size: var(--fs-legal); color: var(--text-muted); }
.kan-mailvolume__legend > span { display: inline-flex; align-items: center; gap: 6px; }
.kan-mailvolume__scale { margin-left: auto; }
.kan-mailvolume__swatch { width: 10px; height: 10px; border-radius: var(--radius-pill); }
.kan-mailvolume__swatch--donor, .kan-mailvolume__seg--donor { background: var(--meter-fill); }
.kan-mailvolume__swatch--admin, .kan-mailvolume__seg--admin { background: var(--navy-300); }
.kan-mailvolume__chart { position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 3px; height: 160px; margin-top: var(--space-4); border-bottom: 1px solid var(--border-default); }
.kan-mailvolume__day { position: relative; display: flex; flex-direction: column-reverse; justify-content: flex-start; min-width: 0; height: 100%; border-radius: 2px; }
/* 26. 9. 2026 (Matej) · hover: the whole column is tinted and its box shows at once. */
.kan-mailvolume__day:hover { background: var(--surface-sunken); }
.kan-mailvolume__tip {
  display: none;
  position: absolute; bottom: calc(100% + var(--space-1)); left: 50%; z-index: var(--z-sticky);
  transform: translateX(-50%);
  min-width: 11rem; padding: var(--space-2) var(--space-3);
  flex-direction: column; gap: 2px;
  background: var(--surface-inverse); color: var(--text-on-dark);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-2);
  font-size: var(--fs-legal); line-height: 1.4; white-space: nowrap; pointer-events: none;
}
.kan-mailvolume__tip.is-start { left: 0; transform: none; }
.kan-mailvolume__tip.is-end { left: auto; right: 0; transform: none; }
.kan-mailvolume__day:hover .kan-mailvolume__tip { display: flex; }
.kan-mailvolume__tip-date { color: var(--text-on-dark-muted); }
.kan-mailvolume__tip-row { display: flex; justify-content: space-between; gap: var(--space-4); font-variant-numeric: tabular-nums; }
.kan-mailvolume__tip-row > span:first-child { display: inline-flex; align-items: center; gap: 6px; }
.kan-mailvolume__tip-row--total { font-weight: var(--fw-semibold); }
.kan-mailvolume__seg { display: block; flex: 0 0 auto; }
.kan-mailvolume__seg--admin { border-radius: 2px 2px 0 0; }
.kan-mailvolume__line { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--warning); pointer-events: none; }
.kan-mailvolume__line-label { position: absolute; right: 0; bottom: 2px; font-size: var(--fs-legal); font-weight: var(--fw-semibold); line-height: 1.2; color: var(--warning-text); }
.kan-mailvolume__axis { display: flex; justify-content: space-between; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-mailvolume__num { text-align: right; font-variant-numeric: tabular-nums; }
.kan-table th.kan-mailvolume__num, .kan-table td.kan-mailvolume__num { text-align: right; }
/* On a phone the type names already say whom they go to; the count stays in view. */
@media (max-width: 560px) { .kan-mailvolume__to { display: none; } }

/* Zdroje → Kampane (26. 9. 2026) · the new-campaign form (its own narrow screen): one column;
   the short address in the list in the mono face. */
.kan-links-form { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); margin-top: var(--space-4); }
.kan-links-form .kan-field { margin: 0; }
/* The address column: the address, then its copy and (while unused) rename buttons beside it. */
.kan-links-address { display: inline-flex; align-items: center; gap: var(--space-1); }
.kan-links-url__base { color: var(--text-muted); }
.kan-links-url__slug { color: var(--text-heading); font-weight: var(--fw-bold); }
/* The whole campaign on top of its channels. */
.kan-table tr.kan-table__total > * { font-weight: var(--fw-semibold); color: var(--text-heading); background: var(--bg-alt); }
/* The check while typing, under its field. */
.kan-check { margin: var(--space-1) 0 0; min-height: 1.25em; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-check.is-ok { color: var(--success-text); }
.kan-check.is-error { color: var(--danger-text); }
/* „Pridať odkaz": one pill per channel, the social networks behind one pill with a menu. */
.kan-channels { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.kan-channels__btn { cursor: pointer; font-family: var(--font-ui); }
.kan-channels__count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.5em; padding: 0 var(--space-1);
  border-radius: var(--radius-pill); background: var(--bg-alt);
  font-size: var(--fs-legal); color: var(--text-muted);
}
.kan-channels__menu { position: relative; }
.kan-channels__menu > summary { list-style: none; cursor: pointer; }
.kan-channels__menu > summary::-webkit-details-marker { display: none; }
.kan-channels__sub {
  position: absolute; top: calc(100% + var(--space-1)); left: 0; z-index: var(--z-sticky);
  display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1);
  padding: var(--space-2); min-width: 16rem;
  background: var(--surface-card); border: 1px solid var(--border-default);
  border-radius: var(--radius-md); box-shadow: var(--shadow-2);
}
.kan-channels__sub .kan-channels__btn { justify-content: space-between; }
/* The question for a channel already in the campaign: three options, each a whole button. */
.kan-ask { display: grid; gap: var(--space-2); margin: var(--space-3) 0; }
.kan-ask__option {
  display: grid; gap: var(--space-1); width: 100%;
  min-height: var(--touch-min); padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default); border-radius: var(--radius-md);
  background: var(--surface-card); color: var(--text-body);
  font: inherit; text-align: left; text-decoration: none; cursor: pointer;
  transition: var(--transition-colors);
}
.kan-ask__option:hover { border-color: var(--border-strong); background: var(--surface-sunken); }
.kan-ask__option:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-ask__label { font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-ask__hint { font-size: var(--fs-legal); color: var(--text-muted); }
/* Without JavaScript the question is an open, non-modal dialog: it sits in the flow. */
dialog.kan-dialog[open]:not(:modal) { position: static; margin: var(--space-4) 0; }

/* Type-to-filter suggestions (`[data-combo]`, admin.js, 26. 9. 2026): the list hangs under the
   field in a card; the option under the arrow keys or the pointer is tinted. */
.kan-combo { position: relative; }
.kan-combo__list {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  right: 0;
  z-index: var(--z-sticky);
  margin: 0;
  padding: var(--space-1) 0;
  list-style: none;
  max-height: 18rem;
  overflow-y: auto;
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
}
.kan-combo__list[hidden] { display: none; }
.kan-combo__option {
  display: flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  font-size: var(--fs-small);
  color: var(--text-body);
  cursor: pointer;
}
.kan-combo__option:hover, .kan-combo__option.is-active { background: var(--bg-alt); color: var(--text-heading); }
.kan-combo__group, .kan-combo__none {
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-size: var(--fs-legal);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}
/* An „i" near the right edge opens its note towards the left (admin.js decides). */
@media (min-width: 561px) { .kan-help__pop--end { left: auto; right: 0; } }
.kan-combo__input { padding-right: calc(var(--space-3) + 24px); }
.kan-combo__chevron { position: absolute; top: 50%; right: var(--space-3); width: 16px; height: 16px; margin-top: -8px; color: var(--text-muted); pointer-events: none; }
/* 26. 9. 2026 · what Brevo counted beyond this app (the staging environment, anything else). */
.kan-mailvolume__swatch--other, .kan-mailvolume__seg--other { background: var(--gold-500); }
/* On the dark box a navy dot would vanish — each dot gets a light ring there. */
.kan-mailvolume__tip .kan-mailvolume__swatch { box-shadow: 0 0 0 1.5px var(--text-on-dark); }

/* ── P0 ▸ F2 #5 (K3) · Sivá kostra ──
   Len tam, kde sa niečo dopĺňa počas práce (C9, C22, C31–C37); inde stránku skladá server.
   Pulz medzi dvoma tokenmi, bez gradientu, bez kolieska; pri obmedzení pohybu stojí. */
@keyframes kan-skel-pulse { 0%, 100% { background-color: var(--skeleton-base); } 50% { background-color: var(--skeleton-shine); } }
.kan-skel { display: block; height: 12px; border-radius: var(--radius-xs); background-color: var(--skeleton-base); animation: kan-skel-pulse 1.6s var(--ease-in-out) infinite; }
.kan-skel--line-lg { height: 16px; }
.kan-skel--block { height: 40px; border-radius: var(--radius-sm); }
@media (prefers-reduced-motion: reduce) { .kan-skel { animation: none; } }
/* ── /P0 ▸ F2 #5 ── */

/* ── P0 ▸ F2 #14 · B19 · ONE calendar: the month grid of date-range, shared ───────────────────
   The month grid (title, week head, days) moved here from admin-ui.css: `x-date-field` (one
   day, `.kan-datepop`) and `x-admin.date-range` (two ends) draw it the same way through
   `window.KanMonth` (public/js/calendar.js). A day is `--touch-min` square: 28 px in the admin
   on a fine pointer, 44 px on a coarse pointer and in the public part. */
.kan-drange__month { display: flex; flex-direction: column; gap: var(--space-1); }
.kan-drange__title {
  display: block;
  line-height: var(--touch-min);
  margin: 0;
  text-align: center;
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  white-space: nowrap;
}
.kan-drange__title::first-letter { text-transform: uppercase; }
.kan-drange__grid { display: flex; flex-direction: column; gap: 2px; }
/* No gap across a week, so the band between the two ends reads as one. */
.kan-drange__row { display: grid; grid-template-columns: repeat(7, var(--touch-min)); }
.kan-drange__head { display: grid; place-items: center; min-height: 28px; font-size: var(--fs-legal); font-weight: var(--fw-medium); color: var(--text-muted); }
.kan-drange__day {
  display: grid;
  place-items: center;
  width: var(--touch-min);
  height: var(--touch-min);
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  font: inherit;
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
  color: var(--text-heading);
  cursor: pointer;
  transition: var(--transition-colors);
}
.kan-drange__day:hover { background: var(--accent-subtle-hover); }
.kan-drange__day:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: calc(-1 * var(--focus-ring-width)); position: relative; z-index: 1; }
.kan-drange__day--empty { cursor: default; }
.kan-drange__day--empty:hover { background: transparent; }
.kan-drange__day.is-today { border-color: var(--accent-border); font-weight: var(--fw-semibold); }

/* A day outside [min, max]: muted, no hover, no pointer; a preset button looks like its link sibling. */
.kan-drange__day[aria-disabled="true"],
.kan-drange__day[aria-disabled="true"]:hover { background: transparent; color: var(--text-disabled); cursor: not-allowed; }
.kan-drange__navbtn[aria-disabled="true"] { color: var(--text-disabled); cursor: not-allowed; }
.kan-drange__navbtn[aria-disabled="true"]:hover { background: transparent; color: var(--text-disabled); }
.kan-drange__quick button { padding: 0; border: 0; background: none; font: inherit; color: var(--text-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.18em; cursor: pointer; white-space: nowrap; }
.kan-drange__quick button:hover { color: var(--text-link-hover); }
.kan-drange__quick button:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: 2px; }
.kan-drange__quick button[aria-current] { color: var(--text-heading); font-weight: var(--fw-semibold); }

.kan-admin .kan-drange__day { font-size: 0.75rem; }
.kan-admin .kan-drange__head { min-height: 24px; font-size: 0.6875rem; }
.kan-drange__quick { padding-top: var(--space-2); border-top: 1px solid var(--border-subtle); }
.kan-drange__navbtn { width: var(--touch-min); height: var(--touch-min); min-width: 0; min-height: 0; display: inline-grid; place-items: center; }
.kan-drange__day.is-picked { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: var(--fw-semibold); }
.kan-drange__day.is-picked:hover { background: var(--accent-hover); }

/* The date field: the native input without a script; with it a button and a window under it. */
.kan-date__native[hidden] { display: none; }
.kan-date__button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  text-align: left;
  cursor: pointer;
}
.kan-date__button[hidden] { display: none; }
.kan-date__button:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-date__button .kan-icon { flex-shrink: 0; color: var(--text-muted); }
.kan-date__button-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kan-date__button--empty .kan-date__button-text { color: var(--text-muted); }
.kan-date .kan-input[aria-invalid="true"],
.kan-date__button[aria-invalid="true"] { border-color: var(--danger); }
/* The window: a native popover (Esc and a click outside close it), placed under the button by the script. */
.kan-datepop {
  position: fixed;
  inset: auto;
  margin: 0;
  width: max-content;
  max-width: calc(100vw - 2 * var(--space-4));
  padding: var(--space-3);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  color: var(--text-heading);
  overflow: visible;
}
.kan-datepop--public { padding: var(--space-4); border-radius: var(--radius-lg); }
.kan-datepop__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.kan-datepop__head .kan-drange__title { flex: 1 1 auto; }
.kan-datepop .kan-drange__quick { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); margin-top: var(--space-2); }
.kan-datepop .kan-drange__quick:empty { display: none; }
.kan-datepop .kan-drange__quick button { min-height: var(--touch-min); }
@media (pointer: coarse) { .kan-datepop .kan-drange__quick button { min-height: 44px; } }
/* ── /P0 ▸ F2 #14 ── */

/* ── P0 ▸ F3 #22 · B26 · the one transfer block (x-transfer-block) ─────────────────────────────
   The QR (144 px) beside the rows that copy (`.kan-copyrows`, below), optional facts without
   copying; under 560 px the QR stands centred above the rows. Replaces `.kan-transfer*` and
   `.kan-prevod-grid / -qr / -facts`. */
.kan-transfer-block { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.kan-transfer-block__head { display: flex; align-items: center; gap: 10px; margin: 0; font-size: var(--fs-body-sm); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-transfer-block__head .kan-icon { color: var(--accent); }
.kan-transfer-block__grid { display: flex; flex-direction: column; gap: var(--space-4); }
.kan-transfer-block__grid > .kan-copyrows { min-width: 0; }
.kan-transfer-block__qr { margin: 0; align-self: center; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
.kan-transfer-block__qr img { display: block; width: 144px; height: 144px; background: var(--paper); border: 1px solid var(--border-default); border-radius: var(--radius-sm); }
.kan-transfer-block__qr figcaption { max-width: 144px; font-size: var(--fs-overline); color: var(--text-muted); text-align: center; }
.kan-transfer-block__facts { margin: 0; display: flex; flex-direction: column; border-top: 1px solid var(--border-subtle); }
.kan-transfer-block__fact { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-1) var(--space-4); min-height: 40px; border-bottom: 1px solid var(--border-subtle); }
.kan-transfer-block__fact:last-child { border-bottom: 0; }
.kan-transfer-block__fact dt { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); }
.kan-transfer-block__fact dd { margin: 0; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-transfer-block__help { margin: 0; font-size: var(--fs-legal); line-height: 1.6; color: var(--text-body); text-wrap: pretty; }
@media (min-width: 560px) {
  .kan-transfer-block__grid { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-2) var(--space-5); align-items: start; }
  .kan-transfer-block__grid > .kan-transfer-block__qr { align-self: start; grid-row: 1 / span 2; }
  .kan-transfer-block__grid > .kan-transfer-block__facts { grid-column: 2; }
  /* No QR: the rows take the whole width. */
  .kan-transfer-block__grid:not(:has(.kan-transfer-block__qr)) { grid-template-columns: minmax(0, 1fr); }
  .kan-transfer-block__grid:not(:has(.kan-transfer-block__qr)) > .kan-transfer-block__facts { grid-column: 1; }
}
/* ── /P0 ▸ F3 #22 ── */

/* ═══ P8 ▸ Moje školné (C42, K18, K19) — moje.kolegium.org/skolne/{token}. Len tokeny; P8 píše len medzi týmito riadkami ═══ */
/* ---------------------------------------------------------------
   C42 · Moje školné — verejná stránka (public/tuition/show)
   → app.css. Kostra = x-result-shell :account="false" (K5: len logo).
   --------------------------------------------------------------- */
.kan-subheader__inner--logo-only { justify-content: flex-start; }
.kan-tuition-page { gap: var(--space-5); }
.kan-tuition-page__head { display: flex; flex-direction: column; gap: var(--space-2); }
.kan-tuition-page__overline { margin: 0; font-size: var(--fs-legal); font-weight: var(--fw-bold); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.kan-tuition-page__section { display: flex; flex-direction: column; gap: var(--space-3); padding-top: var(--space-5); border-top: 1px solid var(--border-subtle); }
.kan-tuition-page__h2 { margin: 0; font-family: var(--font-ui); font-size: var(--fs-h4); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-tuition-page__due { margin: 0; font-size: var(--fs-small); color: var(--text-body); font-variant-numeric: tabular-nums; }
.kan-tuition-page__due b { font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-tuition-page__note { margin: 0; font-size: var(--fs-legal); line-height: 1.5; color: var(--text-muted); text-wrap: pretty; }
.kan-tuition-page__paid { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.kan-tuition-page__paid li { display: flex; justify-content: space-between; gap: var(--space-3); padding: 10px 0; border-bottom: 1px solid var(--border-subtle); font-size: var(--fs-small); font-variant-numeric: tabular-nums; }
.kan-tuition-page__paid li:last-child { border-bottom: 0; }
.kan-tuition-page__paid b { font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-tuition-page__paid span { color: var(--text-muted); }
.kan-tuition-page__foot { margin: 0; font-size: var(--fs-legal); color: var(--text-muted); text-align: center; }
.kan-tuition-page__foot a { color: var(--text-link); }
/* pay-methods vo variante školného: bez hviezdičky, bez poznámky pod tlačidlom o daroch */
.kan-pay-methods--tuition .kan-paymethod-list { gap: 0; }

/* The calculation inside the „i" of a child (x-tuition.breakdown, variant public). Its base rules
   also live in admin-ui.css (loaded only in the admin) — the public page needs them here. */
.kan-tuition-breakdown { margin: 0; display: flex; flex-direction: column; }
.kan-tuition-breakdown__row {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--space-2);
  padding: 8px var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.kan-tuition-breakdown__row:last-child { border-bottom: 0; }
.kan-tuition-breakdown__row::before { content: ""; color: var(--text-muted); text-align: center; }
.kan-tuition-breakdown__row--eq::before { content: "=" / ""; }
.kan-tuition-breakdown__row dt { margin: 0; min-width: 0; color: var(--text-body); overflow-wrap: anywhere; }
.kan-tuition-breakdown__row dd { margin: 0; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--text-heading); }
.kan-tuition-breakdown__sub { display: block; margin-top: 2px; font-size: 0.75rem; font-weight: var(--fw-regular); line-height: 1.4; color: var(--text-muted); }
/* odpočet (zľava, štipendium, podpora, odpustené) */
.kan-tuition-breakdown__row--minus dd { color: var(--text-body); }
/* medzisúčet (= Školné po zľave) */
.kan-tuition-breakdown__row--subtotal dt,
.kan-tuition-breakdown__row--subtotal dd { font-weight: var(--fw-semibold); color: var(--text-heading); }
/* splátka (Záloha, = Doplatok) — so splatnosťou pod popisom */
.kan-tuition-breakdown__row--due dt,
.kan-tuition-breakdown__row--due dd { font-weight: var(--fw-semibold); color: var(--text-heading); }
/* súčtový riadok (D13 vzhľad: jemne modrý) — v rozpise je posledný, lebo rozpis je výpočet */
.kan-tuition-breakdown__row--total { background: var(--navy-50); }
.kan-tuition-breakdown__row--total dt,
.kan-tuition-breakdown__row--total dd { font-weight: var(--fw-semibold); color: var(--text-heading); }
/* zrážka, ktorá čaká na rozhodnutie (štipendium žiada) — suma „—“ */
.kan-tuition-breakdown__row--pending dt,
.kan-tuition-breakdown__row--pending dd { color: var(--text-muted); }
/* príznak preplatku voči predpisu (žltý pás pod súčtom) */
.kan-tuition-breakdown__flag {
  display: flex; align-items: flex-start; gap: var(--space-2);
  margin: 0; padding: 8px var(--space-4);
  background: var(--warning-surface); border-top: 1px solid var(--warning-border);
  color: var(--warning-text); font-size: 0.75rem; line-height: 1.4;
}
.kan-tuition-breakdown__flag .kan-icon { flex: none; margin-top: 1px; }
.kan-tuition-breakdown--public .kan-tuition-breakdown__row { padding: 11px 0; font-size: var(--fs-small); line-height: 1.45; }
.kan-tuition-breakdown--public .kan-tuition-breakdown__row--total { margin-inline: calc(-1 * var(--space-3)); padding-inline: var(--space-3); border-radius: var(--radius-sm); }
.kan-tuition-breakdown--public .kan-tuition-breakdown__flag { border-radius: var(--radius-sm); border: 1px solid var(--warning-border); }

/* C42 · Moje školné — harmonika detí, výber platieb a krok Platba (Matej 7. 10. 2026, K18). Len tokeny. */
.kan-tuition-page__lead { margin: 0; font-size: var(--fs-small); color: var(--text-body); }
.kan-tuition-select { container: tuition-select / inline-size; display: flex; flex-direction: column; gap: var(--space-4); }
.kan-tuition-kids { display: flex; flex-direction: column; gap: var(--space-3); }
/* dieťa = harmonika */
.kan-tuition-kid { border: 1px solid var(--border-default); border-radius: var(--radius-lg); background: var(--surface-card); }
.kan-tuition-kid[open] { border-color: var(--border-strong); box-shadow: var(--shadow-1); }
.kan-tuition-kid__sum { display: grid; grid-template-columns: minmax(0, 1fr) auto 20px; grid-template-areas: "who state chev" "who picked chev"; align-items: center; gap: 2px var(--space-3); min-height: 64px; padding: var(--space-3) var(--space-4); cursor: pointer; list-style: none; border-radius: var(--radius-lg); }
.kan-tuition-kid__sum::-webkit-details-marker { display: none; }
.kan-tuition-kid__sum:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-tuition-kid__who { grid-area: who; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kan-tuition-kid__name { font-size: var(--fs-body); font-weight: var(--fw-bold); color: var(--text-heading); }
.kan-tuition-kid__sub { font-size: var(--fs-legal); color: var(--text-muted); }
.kan-tuition-kid__state { grid-area: state; display: inline-flex; align-items: center; gap: 6px; justify-self: end; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-heading); font-variant-numeric: tabular-nums; white-space: nowrap; }
.kan-tuition-kid__state::before { content: ""; width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--info); }
.kan-tuition-kid__state--red { color: var(--danger-text); }
.kan-tuition-kid__state--red::before { background: var(--danger); }
.kan-tuition-kid__state--green::before { background: var(--success); }
.kan-tuition-kid__state--grey { color: var(--text-muted); font-weight: var(--fw-medium); }
.kan-tuition-kid__state--grey::before { background: var(--border-strong); }
.kan-tuition-kid__picked { grid-area: picked; justify-self: end; font-size: var(--fs-legal); font-weight: var(--fw-semibold); color: var(--accent); font-variant-numeric: tabular-nums; }
.kan-tuition-kid__chev { grid-area: chev; color: var(--text-muted); transition: transform var(--dur-fast) var(--ease-standard); }
.kan-tuition-kid[open] .kan-tuition-kid__chev { transform: rotate(180deg); }
.kan-tuition-kid__body { display: flex; flex-direction: column; gap: var(--space-2); padding: 0 var(--space-4) var(--space-4); }
.kan-tuition-kid__bar { display: flex; align-items: center; gap: var(--space-1); padding-top: var(--space-3); border-top: 1px solid var(--border-subtle); }
.kan-tuition-kid__label { font-size: var(--fs-legal); font-weight: var(--fw-bold); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.kan-tuition-kid__why .kan-help__pop { width: 320px; }
.kan-tuition-kid__why-title { display: block; margin-bottom: var(--space-2); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-tuition-kid__actions { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); }
@media (prefers-reduced-motion: reduce) { .kan-tuition-kid__chev { transition: none; } }
/* platba = dlaždica; zaškrtnutie zarovnané s prvým riadkom; od 520 px šírky formulára jeden riadok (container query) */
.kan-tuition-pays { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.kan-tuition-pay__row { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: 0 var(--space-3); min-height: 56px; padding: 10px var(--space-3); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface-card); cursor: pointer; }
.kan-tuition-pay--fixed .kan-tuition-pay__row { cursor: default; background: var(--bg-alt); }
.kan-tuition-pay__row:has(.kan-checkbox__input:checked) { border-color: var(--accent-border); background: var(--accent-subtle); }
.kan-tuition-pay__row:has(.kan-checkbox__input:focus-visible) { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: 2px; }
/* zaškrtnutie zarovnané so sumou (prvý riadok textu), nie na stred */
.kan-tuition-pay__check { align-self: start; width: 24px; height: 24px; margin: 0; }
.kan-tuition-pay__text { display: flex; flex-direction: column; min-width: 0; }
.kan-tuition-pay__amount { font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: 24px; color: var(--text-heading); font-variant-numeric: tabular-nums; }
.kan-tuition-pay__due { font-size: var(--fs-legal); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kan-tuition-pay__badge { justify-self: end; }
@container tuition-select (max-width: 520px) {
  .kan-tuition-kid__sum { grid-template-columns: minmax(0, 1fr) 20px; grid-template-areas: "who chev" "state chev" "picked chev"; }
  .kan-tuition-kid__state, .kan-tuition-kid__picked { justify-self: start; }
}
/* súčet a tlačidlo — pod deťmi, nikdy lepiaca lišta (pravidlo 13) */
.kan-tuition-select__bar { display: flex; flex-direction: column; gap: var(--space-3); }
/* hlavné tlačidlo s poznámkou (súčet vybraných) pod textom — Matej 7. 10. */
.kan-tuition-select__go { flex-direction: column; gap: 2px; width: 100%; min-height: var(--control-h-lg); padding-block: var(--space-2); }
.kan-tuition-select__go-main { display: inline-flex; align-items: center; gap: var(--space-2); }
.kan-tuition-select__go-note { font-size: var(--fs-legal); font-weight: var(--fw-medium); letter-spacing: 0; text-transform: none; opacity: 0.85; font-variant-numeric: tabular-nums; }
.kan-tuition-select__bar > .kan-alert { flex: 1 0 100%; }
/* krok Platba */
.kan-tuition-back { display: inline-flex; align-items: center; gap: var(--space-1); align-self: flex-start; min-height: var(--touch-min); font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-link); text-decoration: none; }
.kan-tuition-back:hover { text-decoration: underline; }
.kan-tuition-basket { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); border-radius: var(--radius-md); background: var(--bg-alt); font-variant-numeric: tabular-nums; }
.kan-tuition-basket__list, .kan-tuition-basket__list ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.kan-tuition-basket__list { gap: var(--space-3); }
.kan-tuition-basket__name { margin: 0 0 2px; font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-tuition-basket__list ul li { display: flex; justify-content: space-between; gap: var(--space-3); font-size: var(--fs-small); color: var(--text-body); }
.kan-tuition-basket__list ul b { font-weight: var(--fw-semibold); color: var(--text-heading); }
.kan-tuition-basket__total { display: flex; justify-content: space-between; margin: 0; padding-top: var(--space-2); border-top: 1px solid var(--border-subtle); font-size: var(--fs-body); color: var(--text-heading); }
.kan-tuition-basket__total b { font-weight: var(--fw-bold); }
.kan-tuition-pay-logos { display: flex; justify-content: center; margin-top: var(--space-2); }
/* na telefóne bez „do“ pred dátumom splatnosti (Matej 7. 10.) */
@media (max-width: 560px) { .kan-tuition-pay__do { display: none; } }
/* K19 (Matej 7. 10.): na telefóne je „Prejsť k platbe“ lepiace tlačidlo pri spodnom okraji, ukáže sa až po prvom zaškrtnutí.
   Vedomá výnimka z pravidla 13 len pre Moje školné. Bez JS ostáva v toku pod deťmi. */
@media (max-width: 560px) {
  html:not(.no-js) .kan-tuition-select__bar { position: sticky; bottom: 0; z-index: var(--z-sticky); margin-inline: calc(-1 * var(--space-4)); padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom)); border-top: 1px solid var(--border-subtle); background: var(--surface-card); box-shadow: var(--shadow-2); transition: transform 200ms var(--ease-standard), opacity 200ms var(--ease-standard); }
  html:not(.no-js) .kan-tuition-select__bar.is-empty { transform: translateY(110%); opacity: 0; visibility: hidden; pointer-events: none; transition: transform 200ms var(--ease-standard), opacity 200ms var(--ease-standard), visibility 0s 200ms; }
}
@media (max-width: 560px) and (prefers-reduced-motion: reduce) { html:not(.no-js) .kan-tuition-select__bar, html:not(.no-js) .kan-tuition-select__bar.is-empty { transition: none; } }
/* Bez JS sa „i" nedá otvoriť — výpočet je potom hneď pod nadpisom, ako blok. */
.no-js .kan-tuition-kid__why { display: block; width: 100%; }
.no-js .kan-tuition-kid__why .kan-help__btn { display: none; }
.no-js .kan-tuition-kid__why .kan-help__pop[hidden] { display: block; position: static; width: 100%; max-width: none; margin-top: var(--space-2); box-shadow: none; }
.no-js .kan-tuition-kid__bar { flex-wrap: wrap; }
/* ═══ ◂ P8 Moje školné ═══ */
/* ═══ P8 ▸ poznámka riadku „Neskôr" na telefóne: pilulka v prvom riadku, veta na celú šírku pod sumou ═══ */
@media (max-width: 560px) {
  .kan-tuition-pay--later .kan-tuition-pay__row { grid-template-columns: 24px minmax(0, 1fr) auto; grid-template-areas: "check amount badge" "note note note"; row-gap: var(--space-1); }
  .kan-tuition-pay--later .kan-tuition-pay__text { display: contents; }
  .kan-tuition-pay--later .kan-tuition-pay__check { grid-area: check; }
  .kan-tuition-pay--later .kan-tuition-pay__amount { grid-area: amount; }
  .kan-tuition-pay--later .kan-tuition-pay__badge { grid-area: badge; }
  .kan-tuition-pay--later .kan-tuition-pay__due { grid-area: note; }
}
/* ═══ ◂ P8 ═══ */

/* ═══ A2 ▸ Moje školné: prihlásenie kódom — the account menu in the slim header of x-tuition-shell
   (the donor portal's `.kan-account`, S11E §8d), centred on the header row, not on the portal bar's first line. ═══ */
.kan-tuition-shell .kan-account__summary { margin-top: 0; }
/* ═══ ◂ A2 ═══ */

/* ═══ Prevod odoslaný ▸ (8. 10. 2026) — tlačidlo pod QR a malé „Zaplatiť inak"; len tokeny ═══ */
.kan-tuition-page__announce { margin: var(--space-4) 0 0; display: flex; justify-content: flex-start; }
/* 15. 10. 2026 · what Moje školné is for, right under its title on the sign-in. */
.kan-tuition-signin__purpose { margin-top: calc(-1 * var(--space-2)); color: var(--text-heading); font-weight: var(--fw-semibold); }
/* Matej (14. 10. 2026) · the transfer details fold under a tertiary button below the card's logos. */
.kan-tuition-transfer { margin-top: var(--space-4); min-width: 0; }
.kan-tuition-transfer__toggle { display: flex; width: fit-content; margin-inline: auto; align-items: center; gap: var(--space-2); cursor: pointer; list-style: none; }
.kan-tuition-transfer__toggle::-webkit-details-marker { display: none; }
.kan-tuition-transfer__toggle:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-offset); }
.kan-tuition-transfer__chevron { transition: transform var(--dur-fast) var(--ease-standard); }
.kan-tuition-transfer[open] .kan-tuition-transfer__chevron { transform: rotate(180deg); }
.kan-tuition-transfer__body { margin-top: var(--space-4); }
@media (prefers-reduced-motion: reduce) { .kan-tuition-transfer__chevron { transition: none; } }
.kan-tuition-pay__otherwise { align-self: flex-start; }
/* ═══ ◂ Prevod odoslaný ═══ */
