/* ============================================================
   Kelas Sekejap — Component styles (Say it with confidence, v7)
   Every rule reads from tokens.css. Shared interaction model:
   rest → hover lifts up-left → pressed pushes into its own shadow.
   These classes back the React components in ../components.
   ============================================================ */
@import './tokens.css';

/* ---------- Button ---------- */
.ks-btn {
  min-height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ks-space-2);
  padding: 0 26px;
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  box-shadow: var(--ks-shadow-button);
  font-family: var(--ks-font-body);
  font-weight: var(--ks-weight-black);
  font-size: 16px;
  cursor: pointer;
  transition: transform var(--ks-dur-press) ease, box-shadow var(--ks-dur-press) ease;
}
.ks-btn:hover { transform: translate(-2px, -2px); box-shadow: var(--ks-shadow-hover); }
.ks-btn:active { transform: translate(var(--ks-press-offset), var(--ks-press-offset)); box-shadow: none; }
.ks-btn:focus-visible { outline: none; box-shadow: var(--ks-shadow-button), var(--ks-focus-ring); }
.ks-btn:disabled {
  background: var(--ks-disabled-fill);
  color: var(--ks-ink-45);
  border-color: var(--ks-ink-18);
  box-shadow: none;
  transform: none;
  cursor: not-allowed;
}
/* Decision A1 (2026-07): Flame carries INK text — white 16px on Flame is 3.89:1 (AA fail);
   ink is 4.88:1. White stays on Blue (5.4) and Ink. Icons on Flame may stay white (non-text, ≥3:1). */
.ks-btn--flame { background: var(--ks-flame); color: var(--ks-ink); }
.ks-btn--blue  { background: var(--ks-blue);  color: #fff; }
.ks-btn--paper { background: var(--ks-paper); color: var(--ks-ink); }
.ks-btn--haze  { background: var(--ks-haze);  color: var(--ks-ink); }
.ks-btn--block { width: 100%; }

/* ---------- Sticker tag ---------- */
.ks-tag {
  display: inline-flex;
  align-items: center;
  font-family: var(--ks-font-mono);
  font-size: 11px;
  font-weight: var(--ks-weight-extrabold);
  letter-spacing: var(--ks-mono-tracking);
  text-transform: uppercase;
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  padding: 8px 13px;
  box-shadow: var(--ks-shadow-button);
  /* rotation set per-instance, -2deg to +6deg, via inline style */
}
.ks-tag--flat { box-shadow: none; } /* inline chips inside dense UI */

/* ---------- Card ---------- */
.ks-card {
  background: var(--ks-paper);
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
/* Tones · the full palette is available as a surface, not just an accent.
   Text pairing follows decision A1: WHITE only on Blue and Ink. Every other
   brand colour carries Ink — white fails AA on them at body sizes. */
.ks-card--paper     { background: var(--ks-paper); }
.ks-card--peach     { background: var(--ks-peach); }
.ks-card--haze      { background: var(--ks-haze); }
.ks-card--ink       { background: var(--ks-ink);  color: #fff; }
.ks-card--blue      { background: var(--ks-blue); color: #fff; }
.ks-card--flame     { background: var(--ks-flame);     color: var(--ks-ink); }
.ks-card--sunflower { background: var(--ks-sunflower); color: var(--ks-ink); }
.ks-card--pulse     { background: var(--ks-pulse);     color: var(--ks-ink); }
.ks-card--moss      { background: var(--ks-moss);      color: var(--ks-ink); }
.ks-card--spark     { background: var(--ks-spark);     color: var(--ks-ink); }
/* Marketing / hero surface — the ONLY place blur is allowed */
.ks-card--hero {
  border-radius: var(--ks-radius-xl);
  box-shadow: var(--ks-shadow-soft);
  position: relative;
  overflow: hidden;
}

/* ---------- Eyebrow (mono label) ---------- */
.ks-eyebrow {
  font-family: var(--ks-font-mono);
  font-size: 11px;
  font-weight: var(--ks-weight-extrabold);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ks-ink-60); /* ink-50 fails AA at 11px (3.5:1); ink-60 passes (4.9:1) */
}

/* ---------- Section header ---------- */
.ks-section-head { display: flex; align-items: center; gap: var(--ks-space-4); }
.ks-section-num {
  font-family: var(--ks-font-display);
  font-size: 15px;
  background: var(--ks-ink); color: #fff;
  border: var(--ks-border); border-radius: var(--ks-radius-pill);
  padding: 7px 15px;
}
.ks-section-title {
  font-family: var(--ks-font-display);
  font-size: 56px; line-height: .82; letter-spacing: -.07em;
  text-transform: uppercase; margin: 0;
}

/* ---------- Display headline ---------- */
.ks-display {
  font-family: var(--ks-font-display);
  text-transform: uppercase;
  letter-spacing: var(--ks-display-tracking);
  line-height: var(--ks-display-leading);
  margin: 0;
}

/* ---------- Progress bar ---------- */
.ks-progress-track {
  height: 14px;
  background: var(--ks-haze);
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  overflow: hidden;
}
.ks-progress-fill {
  height: 100%;
  background: var(--ks-moss);
  border-right: var(--ks-border);
}

/* ---------- Step indicator (dots variant) ---------- */
.ks-step-dots { display: flex; gap: 6px; align-items: center; }
.ks-dot {
  width: 20px; height: 20px;
  border-radius: 50%;
  border: var(--ks-border);
  background: transparent;
}
.ks-dot--on { background: var(--ks-flame); }

/* ---------- Input ---------- */
.ks-input {
  width: 100%;
  background: var(--ks-haze);
  border: var(--ks-border);
  border-radius: var(--ks-radius-sm);
  padding: 13px 14px;
  font-family: var(--ks-font-body);
  font-size: 14px;
  font-weight: var(--ks-weight-bold);
  color: var(--ks-ink);
}
.ks-input::placeholder { color: var(--ks-ink-50); font-weight: var(--ks-weight-bold); }
.ks-input:focus {
  outline: none;
  background: var(--ks-paper);
  border-color: var(--ks-blue);
  box-shadow: 0 0 0 3px var(--ks-blue-tint);
}

/* ---------- Alert / error ---------- */
.ks-alert {
  display: flex; gap: 10px; align-items: center;
  border-radius: var(--ks-radius-sm);
  padding: 13px 14px;
  font-weight: var(--ks-weight-extrabold);
  font-size: 14px;
}
.ks-alert--error { background: var(--ks-flame-tint); border: 2px solid var(--ks-flame); color: var(--ks-ink); }
.ks-alert--warn  { background: color-mix(in srgb, var(--ks-spark) 18%, transparent); border: 2px solid var(--ks-spark); color: var(--ks-ink); }

/* ---------- Skeleton ---------- */
.ks-skeleton {
  height: 16px;
  background: var(--ks-haze);
  border: var(--ks-border);
  border-radius: 8px;
}

/* ---------- Organic blob (decoration) ---------- */
.ks-blob {
  border: var(--ks-border);
  border-radius: 60% 40% 55% 45% / 48% 52% 44% 56%;
}

/* ============================================================
   v8 additions — same sticker cut-out model, all token-driven.
   Contrast pairing (post-A1): white TEXT only on blue/ink;
   Ink text everywhere else, including flame & moss. White ICONS
   on flame/moss are fine (non-text, ≥3:1). Display-size (≥24px)
   white on flame/moss passes AA-large — marketing surfaces only.
   ============================================================ */

/* ---------- Badge (status pill) ---------- */
.ks-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 0 13px;
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  box-shadow: var(--ks-shadow-sm);
  font-family: var(--ks-font-body);
  font-size: 12px;
  font-weight: var(--ks-weight-black);
  white-space: nowrap;
  background: var(--ks-paper);
  color: var(--ks-ink);
}
.ks-badge--flat { box-shadow: none; }
.ks-badge--blue      { background: var(--ks-blue);      color: #fff; }
.ks-badge--flame     { background: var(--ks-flame);     color: var(--ks-ink); } /* A1: 12px text — white fails AA */
.ks-badge--moss      { background: var(--ks-moss);      color: var(--ks-ink); } /* white on moss 3.2 fails AA */
.ks-badge--ink       { background: var(--ks-ink);       color: #fff; }
.ks-badge--sunflower { background: var(--ks-sunflower); color: var(--ks-ink); }
.ks-badge--pulse     { background: var(--ks-pulse);     color: var(--ks-ink); }
.ks-badge--spark     { background: var(--ks-spark);     color: var(--ks-ink); }
.ks-badge--haze      { background: var(--ks-haze);      color: var(--ks-ink); }
.ks-badge--peach     { background: var(--ks-peach);     color: var(--ks-ink); }

/* ---------- Toggle (switch) ---------- */
.ks-toggle {
  position: relative;
  width: 58px;
  height: 34px;
  flex-shrink: 0;
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-haze);
  box-shadow: var(--ks-shadow-sm);
  cursor: pointer;
  padding: 0;
  transition: background var(--ks-dur-press) ease;
}
.ks-toggle--on { background: var(--ks-moss); }
.ks-toggle__knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border: var(--ks-border);
  border-radius: 50%;
  background: #fff;
  transition: transform var(--ks-dur-press) ease;
}
.ks-toggle--on .ks-toggle__knob { transform: translateX(24px); }
/* 58×34 is the visual size the switch wants, but FOUNDATIONS §07 needs a
   44×44 target — so the button grows a transparent 5px band above and below
   instead of getting taller. Width already clears 44. */
.ks-toggle::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 44px; /* centred, not inset — an inset would resolve against the
                   padding box and lose 2px a side to the Ink border */
}
.ks-toggle:focus-visible { outline: none; box-shadow: var(--ks-shadow-sm), var(--ks-focus-ring); }

/* ---------- TabBar (bottom navigation) ---------- */
.ks-tabbar {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--ks-space-2);
  padding: 10px;
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  background: var(--ks-haze);
}
.ks-tabitem {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-height: 58px;
  border: 2px solid transparent;
  border-radius: var(--ks-radius-md);
  background: transparent;
  color: var(--ks-ink);
  font-family: var(--ks-font-body);
  font-size: 11px;
  font-weight: var(--ks-weight-extrabold);
  cursor: pointer;
  transition: transform var(--ks-dur-press) ease;
}
.ks-tabitem:hover { transform: translateY(-2px); }
.ks-tabitem:focus-visible { outline: none; box-shadow: var(--ks-focus-ring); }
.ks-tabitem--active { background: var(--ks-blue); color: #fff; border: var(--ks-border); }

/* ---------- Overlay: Modal + Drawer ---------- */
.ks-modal-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--ks-space-5);
  background: rgba(16, 16, 20, 0.28);
}
.ks-modal {
  width: 100%;
  max-width: 420px;
  background: var(--ks-paper);
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  box-shadow: var(--ks-shadow-card);
  padding: var(--ks-space-6);
}
.ks-modal__title,
.ks-drawer__title,
.ks-empty__title,
.ks-complete__title,
.ks-player__title {
  font-family: var(--ks-font-body);
  font-size: 22px;
  font-weight: var(--ks-weight-black);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 12px 0 8px;
}
.ks-modal__body,
.ks-drawer__body {
  font-size: 15px;
  font-weight: var(--ks-weight-bold);
  line-height: 1.4;
  color: var(--ks-ink-60);
  margin: 0 0 var(--ks-space-5);
}
.ks-modal__actions,
.ks-drawer__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ks-space-3);
}

.ks-drawer-frame {
  position: relative;
  overflow: hidden;
  border: var(--ks-border);
  border-radius: var(--ks-radius-xl);
  background: var(--surface-base); /* it stands in for the app screen */
}
.ks-drawer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-top: var(--ks-border);
  border-radius: var(--ks-radius-lg) var(--ks-radius-lg) 0 0;
  background: var(--ks-paper);
  padding: var(--ks-space-6);
  box-shadow: 0 -8px 0 rgba(16, 16, 20, 0.05);
}
.ks-drawer__handle {
  width: 58px;
  height: 6px;
  margin: 0 auto var(--ks-space-4);
  border-radius: var(--ks-radius-pill);
  background: rgba(16, 16, 20, 0.28);
}

/* ---------- Toast / callout ---------- */
.ks-toast {
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: var(--ks-space-3);
  align-items: center;
  border: var(--ks-border);
  border-radius: var(--ks-radius-md);
  background: var(--ks-paper);
  padding: var(--ks-space-3);
  box-shadow: var(--ks-shadow-sm);
}
.ks-toast__icon {
  width: 46px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--ks-border);
  border-radius: var(--ks-radius-sm);
  background: var(--ks-sunflower);
  color: var(--ks-ink);
}
.ks-toast__icon--blue  { background: var(--ks-blue);  color: #fff; }
.ks-toast__icon--flame { background: var(--ks-flame); color: #fff; }
.ks-toast__icon--moss  { background: var(--ks-moss);  color: #fff; }
.ks-toast__icon--pulse { background: var(--ks-pulse); color: var(--ks-ink); }
.ks-toast__title { font-size: 15px; font-weight: var(--ks-weight-black); line-height: 1.2; }
.ks-toast__note  { display: block; font-size: 13px; font-weight: var(--ks-weight-bold); line-height: 1.3; color: var(--ks-ink-60); margin-top: 2px; }

/* ---------- Empty state ---------- */
.ks-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  background: var(--ks-paper);
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
.ks-empty__art { margin-bottom: var(--ks-space-5); }
.ks-empty__body { font-size: 15px; font-weight: var(--ks-weight-bold); line-height: 1.4; color: var(--ks-ink-60); margin: 0 0 var(--ks-space-5); }

/* ---------- Lesson tile / mode card ---------- */
.ks-tile {
  display: block;
  width: 100%;
  text-align: left;
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  background: var(--ks-paper);
  padding: var(--ks-space-5);
  box-shadow: var(--ks-shadow-sm);
  cursor: pointer;
  transition: transform var(--ks-dur-press) ease, box-shadow var(--ks-dur-press) ease;
  font-family: var(--ks-font-body);
  color: var(--ks-ink);
}
.ks-tile:hover  { transform: translate(-2px, -2px); box-shadow: var(--ks-shadow-hover); }
.ks-tile:active { transform: translate(var(--ks-press-offset), var(--ks-press-offset)); box-shadow: none; }
.ks-tile:focus-visible { outline: none; box-shadow: var(--ks-shadow-sm), var(--ks-focus-ring); }
.ks-tile__icon {
  width: 46px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--ks-border);
  border-radius: var(--ks-radius-sm);
  margin-bottom: var(--ks-space-4);
  background: var(--ks-sunflower);
  color: var(--ks-ink);
}
.ks-tile__icon--blue  { background: var(--ks-blue);  color: #fff; }
.ks-tile__icon--flame { background: var(--ks-flame); color: #fff; }
.ks-tile__icon--moss  { background: var(--ks-moss);  color: #fff; }
.ks-tile__icon--pulse { background: var(--ks-pulse); color: var(--ks-ink); }
.ks-tile__title { display: block; font-size: 18px; font-weight: var(--ks-weight-black); margin-bottom: 4px; }
.ks-tile__sub   { display: block; font-size: 13px; font-weight: var(--ks-weight-bold); line-height: 1.3; color: var(--ks-ink-60); }

/* ---------- Phrase card (Say it / more / better) ---------- */
.ks-phrase {
  display: grid;
  grid-template-columns: 38px 1fr auto;
  gap: var(--ks-space-4);
  align-items: center;
  border: var(--ks-border);
  border-radius: var(--ks-radius-md);
  background: var(--ks-paper);
  padding: var(--ks-space-4);
  box-shadow: var(--ks-shadow-sm);
}
.ks-phrase__num {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--ks-border);
  border-radius: 50%;
  background: var(--ks-sunflower);
  font-family: var(--ks-font-mono);
  font-size: 12px;
  font-weight: var(--ks-weight-black);
  color: var(--ks-ink);
}
.ks-phrase__num--more   { background: var(--ks-pulse); }
.ks-phrase__num--better { background: var(--ks-moss); color: #fff; }
.ks-phrase__label { display: block; font-size: 15px; font-weight: var(--ks-weight-black); }
.ks-phrase__text  { display: block; font-size: 13px; font-weight: var(--ks-weight-bold); color: var(--ks-ink-60); margin-top: 2px; }
.ks-phrase__action {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--ks-border);
  border-radius: 50%;
  background: var(--ks-flame);
  color: #fff;
  box-shadow: var(--ks-shadow-sm);
  cursor: pointer;
  transition: transform var(--ks-dur-press) ease, box-shadow var(--ks-dur-press) ease;
}
.ks-phrase__action:hover  { transform: translate(-2px, -2px); box-shadow: var(--ks-shadow-hover); }
.ks-phrase__action:active { transform: translate(var(--ks-press-offset), var(--ks-press-offset)); box-shadow: none; }
.ks-phrase__action:focus-visible { outline: none; box-shadow: var(--ks-shadow-sm), var(--ks-focus-ring); }

/* ---------- Completion card ---------- */
.ks-complete {
  position: relative;
  overflow: hidden;
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  background: var(--ks-paper);
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
.ks-complete--flame { background: var(--ks-flame); color: var(--ks-ink); } /* A1 */
.ks-complete--blue  { background: var(--ks-blue);  color: #fff; }
.ks-complete--moss  { background: var(--ks-moss);  color: var(--ks-ink); } /* 15px body — white fails AA */
.ks-complete__body { font-size: 15px; font-weight: var(--ks-weight-bold); line-height: 1.4; margin: 0; opacity: .9; }
.ks-complete__stat {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  margin-top: var(--ks-space-5);
  padding: 0 16px;
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-paper);
  color: var(--ks-ink);
  font-weight: var(--ks-weight-black);
  box-shadow: var(--ks-shadow-sm);
}
.ks-complete__blob {
  position: absolute;
  right: -26px;
  bottom: 16px;
  width: 150px;
  height: 84px;
  border: var(--ks-border);
  border-radius: 62% 38% 55% 45% / 52% 45% 55% 48%;
  background: var(--ks-sunflower);
  box-shadow: var(--ks-shadow-sm);
  transform: rotate(13deg);
}

/* ---------- Listening player ---------- */
/* Paper island: it can sit on any block, so it sets Ink rather than inheriting
   the block's on-colour text. Same contract as .ks-option. */
.ks-player {
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  background: var(--ks-paper);
  color: var(--ks-ink);
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
.ks-player__sub { font-size: 14px; font-weight: var(--ks-weight-bold); color: var(--ks-ink-60); margin: 0; }
.ks-player__row {
  display: grid;
  grid-template-columns: 48px 1fr auto;
  gap: var(--ks-space-4);
  align-items: center;
  margin-top: var(--ks-space-5);
  padding: var(--ks-space-4);
  border: var(--ks-border);
  border-radius: var(--ks-radius-md);
  background: var(--ks-haze);
}
.ks-player__play {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--ks-border);
  border-radius: 50%;
  background: var(--ks-blue);
  color: #fff;
  box-shadow: var(--ks-shadow-sm);
  cursor: pointer;
  transition: transform var(--ks-dur-press) ease, box-shadow var(--ks-dur-press) ease;
}
.ks-player__play:hover  { transform: translate(-2px, -2px); box-shadow: var(--ks-shadow-hover); }
.ks-player__play:active { transform: translate(var(--ks-press-offset), var(--ks-press-offset)); box-shadow: none; }
.ks-player__play:focus-visible { outline: none; box-shadow: var(--ks-shadow-sm), var(--ks-focus-ring); }
.ks-player__wave { display: flex; align-items: center; gap: 4px; height: 34px; }
.ks-player__wave i { display: block; width: 5px; border-radius: var(--ks-radius-pill); background: var(--ks-blue); }
.ks-player__time { font-family: var(--ks-font-mono); font-size: 12px; font-weight: var(--ks-weight-extrabold); }

/* ---------- SPM task card ---------- */
.ks-spm {
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  background: var(--ks-paper);
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
.ks-spm__row {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  gap: var(--ks-space-4);
  align-items: center;
  padding: var(--ks-space-4) 0;
  border-bottom: 2px solid var(--ks-ink-10);
}
.ks-spm__row:last-child { border-bottom: 0; }
.ks-spm__num {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--ks-border);
  border-radius: var(--ks-radius-sm);
  background: var(--ks-haze);
  font-weight: var(--ks-weight-black);
}
.ks-spm__title { font-size: 16px; font-weight: var(--ks-weight-black); }
.ks-spm__meta  { font-size: 13px; font-weight: var(--ks-weight-bold); color: var(--ks-ink-60); margin-top: 1px; }

/* ---------- Rubric summary ---------- */
.ks-rubric { display: grid; gap: var(--ks-space-3); }

/* ---------- Streak pill ---------- */
.ks-streak {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  padding: 0 18px;
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-flame);
  color: var(--ks-ink); /* A1: 16px text — white on flame fails AA */
  font-weight: var(--ks-weight-black);
  font-size: 16px;
  box-shadow: var(--ks-shadow-sm);
}

/* ---------- Quest card ---------- */
.ks-quest {
  position: relative;
  overflow: hidden;
  border: var(--ks-border);
  border-radius: var(--ks-radius-xl);
  background: var(--ks-sunflower);
  color: var(--ks-ink);
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
.ks-quest__blob {
  position: absolute;
  right: -20px;
  bottom: 20px;
  width: 150px;
  height: 84px;
  border: var(--ks-border);
  border-radius: 60% 40% 55% 45% / 50% 45% 55% 50%;
  background: var(--ks-pulse);
  box-shadow: var(--ks-shadow-sm);
  transform: rotate(14deg);
}

/* ---------- Reward card ---------- */
.ks-reward {
  border: var(--ks-border);
  border-radius: var(--ks-radius-xl);
  background: var(--ks-moss);
  color: var(--ks-ink); /* body copy at 15px — white on moss fails AA */
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
.ks-reward__voucher {
  display: block;
  margin-top: var(--ks-space-5);
  border: var(--ks-border);
  border-radius: var(--ks-radius-md);
  background: var(--ks-paper);
  color: var(--ks-ink);
  padding: var(--ks-space-4);
  font-weight: var(--ks-weight-black);
  box-shadow: var(--ks-shadow-sm);
}

/* ---------- Poster card (marketing) ---------- */
.ks-poster {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  border: var(--ks-border);
  border-radius: var(--ks-radius-xl);
  background: var(--ks-blue);
  color: #fff;
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
.ks-poster--pulse { background: var(--ks-pulse); color: var(--ks-ink); }
.ks-poster--flame { background: var(--ks-flame); color: #fff; } /* display-size headline only: 3.89 passes AA-large; captions ride on Paper chips */
.ks-poster--sunflower { background: var(--ks-sunflower); color: var(--ks-ink); }
.ks-poster--haze  { background: var(--ks-haze);  color: var(--ks-ink); }
.ks-poster__headline {
  position: relative;
  z-index: 2;
  font-family: var(--ks-font-display);
  text-transform: uppercase;
  letter-spacing: -0.065em;
  line-height: 0.82;
  font-size: clamp(40px, 4.5vw, 60px);
  margin: 0;
}
.ks-poster__caption {
  position: absolute;
  left: var(--ks-space-5);
  right: var(--ks-space-5);
  bottom: var(--ks-space-5);
  z-index: 3;
  border: var(--ks-border);
  border-radius: var(--ks-radius-sm);
  background: var(--ks-paper);
  color: var(--ks-ink);
  padding: 12px 14px;
  font-weight: var(--ks-weight-black);
  line-height: 1.2;
  box-shadow: var(--ks-shadow-sm);
  transform: rotate(-2deg);
}

/* ---------- Expression emoji (the branded expression layer) ---------- */
.ks-expr { display: inline-block; line-height: 0; }
.ks-expr svg { display: block; width: 100%; height: 100%; }
.ks-expr--framed {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: var(--ks-border);
  border-radius: var(--ks-radius-md);
  background: var(--ks-haze);
  box-shadow: var(--ks-shadow-sm);
  padding: 12px;
}

/* ============================================================
   Colour block · the full-bleed brand surface
   The primitive that carries Isaac's "energy comes from colour blocking".
   A screen picks ONE of these to go loud; interactive parts stay Paper.
   ============================================================ */
.ks-block {
  position: relative;
  overflow: hidden;
  background: var(--ks-haze);
  color: var(--ks-ink);
  border: var(--ks-border);
  border-radius: var(--ks-radius-lg);
  padding: var(--ks-space-6);
  box-shadow: var(--ks-shadow-card);
}
/* Text pairing follows A1 — white ONLY on Blue and Ink. */
.ks-block--paper     { background: var(--ks-paper); }
.ks-block--peach     { background: var(--ks-peach); }
.ks-block--haze      { background: var(--ks-haze); }
.ks-block--ink       { background: var(--ks-ink);  color: #fff; }
.ks-block--blue      { background: var(--ks-blue); color: #fff; }
.ks-block--flame     { background: var(--ks-flame);     color: var(--ks-ink); }
.ks-block--sunflower { background: var(--ks-sunflower); color: var(--ks-ink); }
.ks-block--pulse     { background: var(--ks-pulse);     color: var(--ks-ink); }
.ks-block--moss      { background: var(--ks-moss);      color: var(--ks-ink); }
.ks-block--spark     { background: var(--ks-spark);     color: var(--ks-ink); }

.ks-block--hero  { border-radius: var(--ks-radius-xl); }
/* Edge-to-edge screen surface — no outline or shadow to butt against the bezel. */
.ks-block--flush { border-radius: 0; border: none; box-shadow: none; }

/* The block IS the screen: fill the parent and lay content out as a column, so a
   bottom CTA can `margin-top: auto` against it. The content wrapper has to
   become the flex container too, otherwise it swallows the alignment. */
.ks-block--fill { height: 100%; display: flex; flex-direction: column; }
.ks-block--fill .ks-block__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0; /* let a long option list scroll instead of pushing the CTA off */
}

/* Phone is the primary surface — reclaim the side margins below 430px. */
@media (max-width: 430px) {
  .ks-block { padding: var(--ks-space-5); }
}

/* Decorative accent layer. Sits behind content, never catches a pointer. */
.ks-block__accent {
  position: absolute; inset: 0;
  pointer-events: none;
}
.ks-block__body { position: relative; }

/* A mono eyebrow needs lifting when the block goes dark. */
.ks-block--ink .ks-eyebrow,
.ks-block--blue .ks-eyebrow { color: rgba(255, 255, 255, 0.78); }
/* …except inside a Paper island, which keeps its own Ink type. */
.ks-block--ink .ks-player .ks-eyebrow,
.ks-block--blue .ks-player .ks-eyebrow { color: var(--ks-ink-60); }
/* ============================================================
   Option row · the Paper target that sits ON a colour block
   Shared base for RadioRow and any single selectable row.
   Flat (no offset shadow) — these are dense UI, and the block is the loud part.
   ============================================================ */
.ks-option {
  display: flex;
  align-items: center;
  gap: var(--ks-space-3);
  width: 100%;
  background: var(--surface-option);
  border: var(--ks-border);
  border-radius: var(--ks-radius-md);
  padding: 11px 14px;
  font-family: var(--ks-font-body);
  font-size: 14px;
  font-weight: var(--ks-weight-bold);
  color: var(--ks-ink);
  text-align: left;
  cursor: pointer;
  transition: background var(--ks-dur-fast) var(--ks-ease);
}
/* Accent pairs · set both the row tint and the mark colour that sits INSIDE the
   filled control. The mark is non-text UI, so it needs 3:1 against the fill —
   white clears that on Flame (3.89), Moss (3.2) and Blue (5.4) but NOT on the
   light accents (Sunflower 1.6, Pulse 2.0, Spark 2.3), which take Ink instead. */
.ks-option--acc-flame     { --ks-option-accent: var(--ks-flame);     --ks-option-tint: var(--ks-tint-flame);     --ks-option-mark: #fff; }
.ks-option--acc-blue      { --ks-option-accent: var(--ks-blue);      --ks-option-tint: var(--ks-tint-blue);      --ks-option-mark: #fff; }
.ks-option--acc-moss      { --ks-option-accent: var(--ks-moss);      --ks-option-tint: var(--ks-tint-moss);      --ks-option-mark: #fff; }
.ks-option--acc-sunflower { --ks-option-accent: var(--ks-sunflower); --ks-option-tint: var(--ks-tint-sunflower); --ks-option-mark: var(--ks-ink); }
.ks-option--acc-pulse     { --ks-option-accent: var(--ks-pulse);     --ks-option-tint: var(--ks-tint-pulse);     --ks-option-mark: var(--ks-ink); }
.ks-option--acc-spark     { --ks-option-accent: var(--ks-spark);     --ks-option-tint: var(--ks-tint-spark);     --ks-option-mark: var(--ks-ink); }

.ks-option--selected { background: var(--ks-option-tint, var(--surface-selected)); }
.ks-option:focus-within,
.ks-option:focus-visible {
  outline: none;
  box-shadow: var(--ks-focus-ring-on-color);
}
.ks-option[aria-disabled='true'],
.ks-option--disabled {
  cursor: not-allowed;
  background: var(--ks-disabled-fill);
  border-color: var(--ks-ink-18);
  color: var(--ks-ink-45);
}

/* The radio/check indicator. Empty = Ink ring on Paper; chosen = filled accent. */
.ks-option__control {
  flex: none;
  width: 22px; height: 22px;
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  background: var(--ks-paper);
  display: grid;
  place-items: center;
  color: transparent;
}
.ks-option--selected .ks-option__control {
  background: var(--ks-option-accent, var(--ks-blue));
  color: var(--ks-option-mark, #fff);
}
/* The inner dot for radio-style rows. */
.ks-option__dot {
  width: 8px; height: 8px;
  border-radius: var(--ks-radius-pill);
  background: currentColor;
}
/* The row's reading content, so it doesn't take the row's 14px chrome size:
   FOUNDATIONS §02/§07 put the mobile body floor at 16px, and option rows are
   primary reading in quiz and lesson flows. It tightens back to 14px from
   --ks-bp-sm up, where the row is no longer at thumb scale. */
.ks-option__label {
  flex: 1;
  min-width: 0;
  font-size: var(--ks-text-body-m);
  line-height: 1.5;
}
@media (min-width: 480px) { /* --ks-bp-sm */
  .ks-option__label { font-size: var(--ks-text-body-s); line-height: 1.45; }
}
.ks-option__meta {
  font-size: 12px;
  font-weight: var(--ks-weight-bold);
  color: var(--ks-ink-60);
}
/* Off-screen but still in the accessibility tree and still focusable. */
.ks-visually-hidden,
.ks-option__input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.ks-option-group { display: grid; gap: var(--ks-space-2); border: 0; padding: 0; margin: 0; }
.ks-option-group__legend {
  padding: 0;
  margin-bottom: var(--ks-space-3);
  font-family: var(--ks-font-body);
  font-size: 14px;
  font-weight: var(--ks-weight-extrabold);
  color: inherit;
}

/* ============================================================
   Pill select · multi-select chips
   Chosen = SOLID accent + a check, so selection survives colour-blindness
   and greyscale (FOUNDATIONS: every state needs a non-colour signal).
   ============================================================ */
.ks-pillset { display: flex; flex-wrap: wrap; gap: var(--ks-space-2); border: 0; padding: 0; margin: 0; }
.ks-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--ks-space-2);
  background: var(--surface-option);
  border: var(--ks-border);
  border-radius: var(--ks-radius-pill);
  padding: 9px 15px;
  font-family: var(--ks-font-body);
  font-size: 13px;
  font-weight: var(--ks-weight-black);
  color: var(--ks-ink);
  cursor: pointer;
  transition: background var(--ks-dur-fast) var(--ks-ease);
}
.ks-pill--selected { box-shadow: var(--ks-shadow-sm); }
/* A chosen pill fills SOLID, so this is real text on a brand colour — decision
   A1 applies in full: white only on Blue, Ink on every other accent. */
.ks-pill--sel-flame     { background: var(--ks-flame);     color: var(--ks-ink); }
.ks-pill--sel-blue      { background: var(--ks-blue);      color: #fff; }
.ks-pill--sel-moss      { background: var(--ks-moss);      color: var(--ks-ink); }
.ks-pill--sel-sunflower { background: var(--ks-sunflower); color: var(--ks-ink); }
.ks-pill--sel-pulse     { background: var(--ks-pulse);     color: var(--ks-ink); }
.ks-pill--sel-spark     { background: var(--ks-spark);     color: var(--ks-ink); }
.ks-pill:focus-within { outline: none; box-shadow: var(--ks-focus-ring-on-color); }
.ks-pill[aria-disabled='true'] {
  cursor: not-allowed;
  background: var(--ks-disabled-fill);
  border-color: var(--ks-ink-18);
  color: var(--ks-ink-45);
}
.ks-pill__check { display: none; }
.ks-pill--selected .ks-pill__check { display: block; }

/* ============================================================
   OTP input · one box per digit
   ============================================================ */
.ks-otp { display: flex; gap: var(--ks-space-2); }
.ks-otp__box {
  width: 48px; height: 56px;
  background: var(--surface-option);
  border: var(--ks-border);
  border-radius: var(--ks-radius-sm);
  font-family: var(--ks-font-body);
  font-size: 24px;
  font-weight: var(--ks-weight-black);
  color: var(--ks-ink);
  text-align: center;
  caret-color: var(--ks-ink);
}
.ks-otp--acc-flame     { --ks-otp-tint: var(--ks-tint-flame); }
.ks-otp--acc-blue      { --ks-otp-tint: var(--ks-tint-blue); }
.ks-otp--acc-moss      { --ks-otp-tint: var(--ks-tint-moss); }
.ks-otp--acc-sunflower { --ks-otp-tint: var(--ks-tint-sunflower); }
.ks-otp--acc-pulse     { --ks-otp-tint: var(--ks-tint-pulse); }
.ks-otp--acc-spark     { --ks-otp-tint: var(--ks-tint-spark); }
/* A typed digit tints its box — progress you can see without counting. */
.ks-otp__box--filled { background: var(--ks-otp-tint, var(--surface-selected)); }
.ks-otp__box:focus {
  outline: none;
  box-shadow: var(--ks-focus-ring-on-color);
}
.ks-otp--invalid .ks-otp__box {
  border-color: var(--ks-flame);
  background: var(--ks-tint-flame);
}
.ks-otp__box:disabled {
  background: var(--ks-disabled-fill);
  border-color: var(--ks-ink-18);
  color: var(--ks-ink-45);
}
/* Hide the number-spinner on the numeric boxes. */
.ks-otp__box::-webkit-outer-spin-button,
.ks-otp__box::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

@media (max-width: 380px) {
  .ks-otp { gap: var(--ks-space-1); }
  .ks-otp__box { width: 42px; height: 50px; font-size: 20px; }
}
