/* ==========================================================================
   Terapi Afasia - Components
   Every value comes from tokens.css. No raw colours or sizes here.
   ========================================================================== */

/* --- Icon ------------------------------------------------------------------
   SVG sprite symbols, injected by js/icons.js. Never emoji. */

.icon {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

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

/* --- Button ----------------------------------------------------------------
   Base is already at the secondary touch floor. Nothing smaller exists. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);

  min-height: var(--tap-secondary);
  min-width: var(--tap-secondary);
  padding: var(--s-3) var(--s-6);

  font-size: var(--t-body);
  font-weight: var(--fw-medium);
  text-align: center;
  text-decoration: none;

  border: 2px solid transparent;
  border-radius: var(--r-4);
  background: var(--c-surface-2);
  color: var(--c-ink);

  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              transform  var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}

/* Touch devices get no hover state. Feedback is the pressed state only,
   which is why every button has one. */
.btn:active { transform: scale(0.97); }

@media (hover: hover) {
  .btn:hover { background: var(--c-surface-3); }
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

.btn--primary {
  background: var(--c-primary);
  color: var(--c-on-primary);
  min-height: var(--tap-primary);
  font-size: var(--t-instruction);
  font-weight: var(--fw-bold);
  padding-inline: var(--s-8);
  box-shadow: var(--shadow);
}
.btn--primary:active { background: var(--c-primary-dark); box-shadow: var(--shadow-press); }
@media (hover: hover) { .btn--primary:hover { background: var(--c-primary-dark); } }

.btn--outline {
  background: var(--c-surface);
  border-color: var(--c-line-2);
}

.btn--ghost {
  background: transparent;
  color: var(--c-ink-2);
}

.btn--icon {
  padding: 0;
  width: var(--tap-secondary);
  height: var(--tap-secondary);
  border-radius: var(--r-full);
  font-size: 26px;
}

.btn--icon.btn--primary {
  width: var(--tap-primary);
  height: var(--tap-primary);
  font-size: 34px;
}

/* Chrome-only size, --tap-min. Permitted for caregiver controls in the top
   bar (end session, open dashboard) because neither is a therapy control the
   patient reaches for, and every row of chrome costs the phrase a row.
   Still well above the WCAG 44px minimum. Never use this in the control bar. */
.btn--chrome {
  width: var(--tap-min);
  height: var(--tap-min);
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  font-size: 24px;
}

.btn--block { width: 100%; }

/* --- Rating bar ------------------------------------------------------------
   The caregiver's only input during practice. Fixed position, fixed order,
   identical on every screen. Position is itself a memory aid.

   Colour is never the only signal: each button carries an icon and a word. */

.ratingbar {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--tap-gap);
  width: 100%;
}

.rating {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);

  min-height: var(--tap-rating);
  padding: var(--s-3) var(--s-2);

  font-size: var(--t-label);
  font-weight: var(--fw-bold);

  border: 2px solid transparent;
  border-radius: var(--r-4);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease),
              filter    var(--dur-fast) var(--ease);
}

.rating:active { transform: scale(0.97); }
.rating .icon  { font-size: 30px; stroke-width: 2.4; }

.rating--benar    { background: var(--c-benar);    color: #fff; }
.rating--sebagian { background: var(--c-sebagian); color: #fff; }
.rating--belum    { background: var(--c-belum);    color: #fff; }

/* Selected state is a ring plus a check, never colour alone. */
.rating[aria-pressed="true"] {
  outline: 4px solid var(--c-ink);
  outline-offset: 3px;
}

/* --- Card ------------------------------------------------------------------- */

.card {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-5);
  padding: var(--s-6);
  box-shadow: var(--shadow);
}

.card--flat { box-shadow: none; }
.card--soft { background: var(--c-surface-2); border-color: transparent; box-shadow: none; }

/* --- Phrase display ---------------------------------------------------------
   Three modes, chosen by the reading result in the onboarding screener.
   The mode is set once on a wrapper and every phrase respects it.

     .is-teks       reading intact        text carries the interface
     .is-teks-ikon  partial reading       text plus icon plus audio
     .is-ikon       reading impaired      icon leads, text is secondary
   ---------------------------------------------------------------------------- */

.phrase {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--practice-gap);
  text-align: center;
  width: 100%;
}

/* Icon and text sit side by side in landscape. Stacking them costs vertical
   space the 768px-tall tablet does not have, and landscape has width to
   spare. Portrait stacks them again below. */
.phrase__main {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-5);
  width: 100%;
}

.phrase__icon {
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--phrase-icon);
  height: var(--phrase-icon);
  border-radius: var(--r-5);
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-size: calc(var(--phrase-icon) * 0.6);
  flex: none;
}

.phrase__icon .icon { stroke-width: 1.6; }

.phrase__text {
  font-size: var(--t-phrase);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  color: var(--c-ink);
  text-wrap: balance;
}

.phrase__hint {
  font-size: var(--t-caption);
  color: var(--c-ink-2);
}

/* mode: teks + ikon */
.is-teks-ikon .phrase__icon { display: flex; }

/* mode: ikon first. Icon leads and grows, text drops to a caption. */
.is-ikon .phrase__main  { flex-direction: column; }
.is-ikon .phrase__icon  { display: flex; width: calc(var(--phrase-icon) * 1.25); height: calc(var(--phrase-icon) * 1.25); }
.is-ikon .phrase__text  { font-size: var(--t-instruction); color: var(--c-ink-2); font-weight: var(--fw-medium); }
.is-ikon .syllables     { display: none; }

@media (orientation: portrait) {
  .phrase__main { flex-direction: column; }
}

/* --- Syllable pitch notation ------------------------------------------------
   MIT is two pitches, one note per syllable. Height carries the pitch,
   colour only reinforces it. A visible high/low guide keeps the contour
   readable even when the tablet is muted. */

.syllables {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--s-3);
  padding-block: calc(var(--pitch-offset) + var(--s-2));
  position: relative;
}

/* Two guide lines mark the high and low registers, so the contour stays
   readable even on a muted tablet. */
.syllables::before,
.syllables::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 1px;
  background: var(--c-line);
}
.syllables::before { top: var(--s-2); }
.syllables::after  { bottom: var(--s-2); }

.syl {
  font-size: var(--t-syllable);
  font-weight: var(--fw-bold);
  line-height: 1;
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-3);
  background: var(--c-surface-2);
  color: var(--c-ink-2);
  transition: transform var(--dur-base) var(--ease),
              background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}

.syl--hi { transform: translateY(calc(var(--pitch-offset) * -1)); color: var(--c-pitch-hi); }
.syl--lo { transform: translateY(var(--pitch-offset));            color: var(--c-pitch-lo); }

.syl.is-active {
  background: var(--c-primary);
  color: var(--c-on-primary);
}
.syl--hi.is-active { transform: translateY(calc(var(--pitch-offset) * -1)) scale(1.12); }
.syl--lo.is-active { transform: translateY(var(--pitch-offset)) scale(1.12); }

/* --- Practice surface -------------------------------------------------------
   The entire practice area is the tap target. One tap per syllable, in time
   with the melody.

   Merging the tap pad into the phrase area was a fix, not a shortcut: a
   separate pad cost 120px of height the 768px tablet does not have, and a
   full-area target is easier to hit with an impaired hand than a strip.

   A missed tap never fails an item. This is feedback, not a scored control. */

.practice {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--practice-gap);

  width: 100%;
  padding: var(--practice-pad) var(--s-5);

  border: 3px dashed var(--c-line-2);
  border-radius: var(--r-5);
  background: var(--c-surface);
  color: inherit;
  font: inherit;
  text-align: center;
  cursor: pointer;

  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}

.practice:active,
.practice.is-hit {
  background: var(--c-primary-soft);
  border-color: var(--c-primary);
  border-style: solid;
}

.practice.is-beat::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: var(--r-5);
  border: 3px solid var(--c-primary);
  pointer-events: none;
  animation: beat var(--dur-slow) var(--ease);
}

.practice__hint {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-caption);
  font-weight: var(--fw-medium);
  color: var(--c-ink-2);
}

@keyframes beat {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(1.03); }
}

/* --- Session chrome ---------------------------------------------------------
   Top bar carries orientation, bottom bar carries controls. Neither ever
   moves between screens. */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: clamp(4px, 1.2vh, 14px) var(--s-5);
  border-bottom: 1px solid var(--c-line);
  background: var(--c-surface);
  flex: none;
}

/* Padding tightens on short screens so the 96px primary control and the
   88px rating buttons never have to shrink. Those two are PRD floors. */
.controlbar {
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.6vh, 16px);
  padding: clamp(10px, 2vh, 24px) var(--s-5);
  padding-bottom: max(clamp(10px, 2vh, 24px), env(safe-area-inset-bottom));
  border-top: 1px solid var(--c-line);
  background: var(--c-surface);
  flex: none;
}

.controlbar__label {
  font-size: clamp(13px, 1.9vh, 16px);
  line-height: 1.3;
  color: var(--c-ink-2);
  text-align: center;
  margin-bottom: var(--s-1);
}

/* Below the 768px design floor the label is the first thing to go. The three
   rating buttons carry their own words and the group has an accessible name,
   so nothing is lost but a reminder. */
@media (max-height: 700px) {
  .controlbar__label { display: none; }
}

/* --- Step ladder indicator (MIT 1..5) ---------------------------------------
   Shows where this phrase sits, and is labelled. Never a bare dot row. */

.steps {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.step {
  width: 44px;
  height: 10px;
  border-radius: var(--r-full);
  background: var(--c-surface-3);
}

.step.is-done    { background: var(--c-primary); }
.step.is-current { background: var(--c-primary); box-shadow: 0 0 0 4px var(--c-primary-soft); }

/* --- Dose meter -------------------------------------------------------------- */

.dose {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.dose__track {
  position: relative;
  height: 24px;
  border-radius: var(--r-full);
  background: var(--c-surface-2);
  overflow: hidden;
}

.dose__fill {
  height: 100%;
  border-radius: var(--r-full);
  background: var(--c-primary);
  transition: width var(--dur-slow) var(--ease);
}

.dose__target {
  position: absolute;
  top: -6px;
  bottom: -6px;
  width: 3px;
  background: var(--c-ink);
  border-radius: var(--r-full);
}

/* --- Pills and status --------------------------------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-full);
  font-size: var(--t-caption);
  font-weight: var(--fw-medium);
  background: var(--c-surface-2);
  color: var(--c-ink-2);
}

.pill--ok   { background: var(--c-benar-soft);    color: var(--c-benar); }
.pill--warn { background: var(--c-sebagian-soft); color: var(--c-sebagian); }
.pill--info { background: var(--c-primary-soft);  color: var(--c-primary); }

/* --- Notice ------------------------------------------------------------------ */

.notice {
  display: flex;
  gap: var(--s-4);
  padding: var(--s-5);
  border-radius: var(--r-4);
  background: var(--c-primary-soft);
  color: var(--c-ink);
  font-size: var(--t-label);
  line-height: var(--lh-loose);
}

.notice .icon { font-size: 28px; color: var(--c-primary); }
.notice--warn { background: var(--c-sebagian-soft); }
.notice--warn .icon { color: var(--c-sebagian); }
