/* ══════════════════════════════════════════════════════════════════
   BUTTONS — one vocabulary. Same shape, same states, everywhere.
   Every variant has: default · hover · focus · active · disabled.
   ══════════════════════════════════════════════════════════════════ */

.primary-btn,
.google-btn,
.small-btn,
.danger-btn,
.addbtn,
.modal-actions button {
  font: inherit;
  font-weight: 600;
  border-radius: var(--r-md);
  cursor: pointer;
  transition:
    background-color var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out),
    color var(--dur-1) var(--ease-out);
}

.primary-btn:disabled,
.google-btn:disabled,
.small-btn:disabled,
.addbtn:disabled,
.danger-btn:disabled,
.modal-actions button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
/* ⚠️ .danger-btn was missing from that list until 2026-08-13, which is a real
   gap and not a cosmetic one: every other button variant said when it was off,
   so a disabled destructive button was the ONE control in the app that looked
   fully live while doing nothing. Big caught it on the Waiting List's bulk bin —
   "มันกดได้ทั้งที่ยังไม่ได้เลือกอะไรเลย" — the button was genuinely disabled the whole
   time, it just never said so.
   Dimming alone is not enough here either. A destructive button is RED, and a
   washed-out red still reads as a warning; grey is what reads as "not now"
   (Big: "อาจจะทำเป็นสีเทาไว้ก็ได้"). So a disabled danger button drops its red
   entirely and stops answering hover — a red flash under the cursor is a promise
   the button cannot keep. */
.danger-btn:disabled,
.modal-actions .delete:disabled {
  color: var(--muted);
  border-color: var(--line);
  background: var(--surface);
}
.danger-btn:disabled:hover,
.modal-actions .delete:disabled:hover {
  background: var(--surface);
}

/* Primary — the app's own action. Ink, not a language colour. */
.primary-btn,
.modal-actions .save {
  background: var(--accent);
  color: var(--accent-ink);
  border: 1px solid var(--accent);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-md);
}
.primary-btn:hover,
.modal-actions .save:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}
.primary-btn:active,
.modal-actions .save:active {
  background: var(--ink);
}

/* Secondary — bordered surface. */
.google-btn,
.modal-actions .cancel {
  background: var(--surface);
  color: var(--ink-2);
  border: 1px solid var(--line-strong);
}
.google-btn:hover,
.modal-actions .cancel:hover {
  background: var(--surface-2);
  border-color: var(--muted);
}
.google-btn:active,
.modal-actions .cancel:active {
  background: var(--surface-3);
}

/* Quiet — inline actions inside panels and cards. */
.small-btn,
.addbtn {
  background: var(--surface-2);
  color: var(--ink-2);
  border: 1px solid var(--line);
  font-size: var(--fs-sm);
  padding: var(--sp-1) var(--sp-3);
}
.small-btn:hover,
.addbtn:hover {
  background: var(--surface-3);
  border-color: var(--line-strong);
  color: var(--ink);
}

/* Destructive. */
.danger-btn,
.modal-actions .delete {
  background: var(--surface);
  color: var(--danger);
  border: 1px solid var(--chi-ring);
  font-size: var(--fs-sm);
  padding: var(--sp-1) var(--sp-3);
}
.danger-btn:hover,
.modal-actions .delete:hover {
  background: var(--danger-bg);
}

/* Row remove ✕ — always present so it is discoverable, but grey until
   you reach for it. A column of red crosses is noise, not information. */
.rmbtn {
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1;
  color: var(--muted);
  background: none;
  border: none;
  border-radius: var(--r-sm);
  padding: var(--sp-1);
  cursor: pointer;
  opacity: 0.55;
  transition:
    opacity var(--dur-1) var(--ease-out),
    color var(--dur-1) var(--ease-out),
    background-color var(--dur-1) var(--ease-out);
}
.mcard li:hover .rmbtn,
.rmbtn:focus-visible {
  opacity: 1;
}
.rmbtn:hover {
  opacity: 1;
  color: var(--danger);
  background: var(--danger-bg);
}

/* ══════════════════════════════════════════════════════════════════
   FORM CONTROLS
   ══════════════════════════════════════════════════════════════════ */

input,
select,
textarea {
  font: inherit;
  color: var(--ink-2);
}

::placeholder {
  color: var(--muted); /* 7:1 — not the washed-out default */
  opacity: 1;
}

input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}

input[type="text"].name-input {
  border: 1px solid transparent;
  background: transparent;
  border-radius: var(--r-sm);
  font-size: var(--fs-base);
  width: 100%;
  padding: var(--sp-1) var(--sp-2);
  transition:
    background-color var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out);
}
input[type="text"].name-input:hover {
  border-color: var(--line);
  background: var(--surface-2);
}
input[type="text"].name-input:focus {
  border-color: var(--line-strong);
  background: var(--surface);
}

select.classpick {
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-md);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-out);
}
select.classpick:hover {
  border-color: var(--muted);
}

/* ══════════════════════════════════════════════════════════════════
   THE PAGE ACTION — solid green, one per page, maximum.
   In Class Planner this was bound to specific button ids; here it is a
   class so any project can use it. Put it on the ONE thing a page
   exists to do ("Add booking", "Publish"). A second green button on
   the same screen makes both of them mean nothing.
   .ok-btn is a .small-btn underneath — it only repaints it.
   ══════════════════════════════════════════════════════════════════ */
.ok-btn {
  background: var(--ok-solid);
  color: var(--ok-ink);
  border-color: var(--ok-solid);
}
.ok-btn:hover {
  background: var(--ok-solid-hover);
  border-color: var(--ok-solid-hover);
  color: var(--ok-ink);
}
/* Nothing to do right now: drop the green rather than fade it. Green means
   "this needs doing" — left on permanently it says nothing at all.
   opacity is pinned back to 1 because the shared .small-btn:disabled 0.5
   stacked on this grey reads as broken, not as off. */
.ok-btn.is-idle,
.ok-btn.is-idle:hover,
.ok-btn.is-idle:disabled:hover {
  background: var(--surface-2);
  border-color: var(--line-strong);
  color: var(--muted);
}
.ok-btn.is-idle:disabled {
  opacity: 1;
}

/* ══════════════════════════════════════════════════════════════════
   ICON BUTTON — square, neutral chrome. Header controls, toolbars.
   Always give it an aria-label: an icon with no text is invisible to a
   screen reader, and the tooltip does not count.
   ══════════════════════════════════════════════════════════════════ */
.hdr-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  cursor: pointer;
  transition:
    background-color var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out),
    color var(--dur-1) var(--ease-out),
    opacity var(--dur-1) var(--ease-out);
}
.hdr-icon-btn svg {
  width: 17px;
  height: 17px;
}
.hdr-icon-btn:hover:not(:disabled) {
  background: var(--surface-2);
  border-color: var(--muted);
  color: var(--ink);
}
.hdr-icon-btn:disabled {
  opacity: 0.4;
  cursor: default;
}
/* display:inline-flex would otherwise beat the browser's own [hidden] rule,
   so hiding one with the hidden attribute would silently do nothing. */
.hdr-icon-btn[hidden] {
  display: none;
}
