/* ==========================================================================
   BUNKK COMPONENTS — v1.0 (Neo-Brutalism)
   Requires tokens.css. Plain CSS, no build step — drop into Flask /static.
   ========================================================================== */

/* ---- Base ---------------------------------------------------------------- */
* { box-sizing: border-box; }
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  margin: 0;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { line-height: var(--leading-tight); margin: 0 0 var(--sp-4); }
h1 { font-family: var(--font-display); font-size: var(--text-3xl); }
h2 { font-family: var(--font-display); font-size: var(--text-2xl); }
h3 { font-family: var(--font-body); font-weight: 800; font-size: var(--text-xl); }
a  { color: var(--ink); text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { background: var(--acc-yellow); }
.num, time, .mono { font-family: var(--font-mono); }

.eyebrow {
  font-family: var(--font-label);
  font-weight: 700;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

/* ---- Buttons ------------------------------------------------------------- */
/* Any `display` a component sets beats the UA's rule for the `hidden`
   attribute, which is how a hidden .btn stayed on screen. Nothing here wants
   that, so hidden wins everywhere. */
[hidden] { display: none !important; }

.btn {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-label); font-weight: 700;
  font-size: var(--text-sm); letter-spacing: var(--tracking-label);
  text-transform: uppercase; text-decoration: none;
  padding: var(--sp-3) var(--sp-5);
  background: var(--card); color: var(--ink);
  border: var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  cursor: pointer; user-select: none;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.btn:hover  { transform: translate(-2px, -2px); box-shadow: var(--shadow-lg); background: var(--card); }
.btn:active { transform: translate(4px, 4px); box-shadow: none; }
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 0.45; box-shadow: none; transform: none; cursor: not-allowed;
}
.btn--primary { background: var(--brand-primary); }
.btn--primary:hover { background: var(--brand-primary); }
.btn--accent  { background: var(--brand-accent); }
.btn--accent:hover  { background: var(--brand-accent); }
.btn--danger  { background: var(--danger-fill); }
.btn--danger:hover  { background: var(--danger-fill); }
.btn--ghost   { background: transparent; box-shadow: none; }
.btn--ghost:hover { background: var(--soft-yellow); box-shadow: var(--shadow-sm); }
.btn--sm   { padding: var(--sp-2) var(--sp-4); font-size: var(--text-xs); box-shadow: var(--shadow-sm); }
.btn--sm:hover { box-shadow: var(--shadow-md); }
.btn--lg   { padding: var(--sp-4) var(--sp-6); font-size: var(--text-base); }
.btn.is-loading { pointer-events: none; opacity: 0.7; }

/* ---- Cards ---------------------------------------------------------------- */
.card {
  background: var(--card);
  border: var(--border-heavy); border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--sp-5);
}
.card--yellow { background: var(--soft-yellow); }
.card--purple { background: var(--soft-purple); }
.card--cyan   { background: var(--soft-cyan); }
.card--clickable { cursor: pointer; transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.card--clickable:hover { transform: translate(-2px,-2px); box-shadow: var(--shadow-lg); }

/* ---- Status badges (never color alone — always text + dot) ---------------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-weight: 700; font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  padding: 3px 10px;
  border: var(--border); border-radius: var(--radius-pill);
  background: var(--card);
}
.badge::before { content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--ink); border: 1.5px solid var(--ink); }
.badge--safe    { background: var(--safe-fill); }
.badge--warn    { background: var(--warn-fill); }
.badge--danger  { background: var(--danger-fill); }
.badge--pending { background: var(--pending-soft); }
.badge--pending::before { background: var(--pending-fill); }
.badge--neutral { background: var(--soft-cyan); }
/* Lecture type is a fact about the subject, not a verdict on it, so it gets
   its own quiet palette rather than borrowing safe/warn/danger. */
.badge--type-theory    { background: var(--soft-cyan); }
.badge--type-practical { background: var(--soft-green); }
.badge--type-tutorial  { background: var(--soft-orange); }
.badge--type-unknown   { background: var(--paper); }

/* The GO/SKIP day strip lived here until the horizon outgrew a single row of
   chips; the plan page draws the same verdicts as month grids now, and its
   colours live with that grid in app.css. */

/* ---- Stat tiles ------------------------------------------------------------ */
.stat {
  background: var(--card); border: var(--border-heavy);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
  padding: var(--sp-4) var(--sp-5);
}
.stat__label { font-family: var(--font-label); font-size: var(--text-xs);
  font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label);
  margin-bottom: var(--sp-1); }
.stat__value { font-family: var(--font-display); font-size: var(--text-4xl); line-height: 1; }
.stat__value .unit { font-size: var(--text-xl); }
.stat__meta  { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink-muted); margin-top: var(--sp-1); }
.stat--safe   { background: var(--safe-soft); }
.stat--warn   { background: var(--warn-soft); }
.stat--danger { background: var(--danger-soft); }

/* ---- Attendance meter ------------------------------------------------------ */
.meter { position: relative; height: 22px;
  background: var(--card); border: var(--border); border-radius: var(--radius-pill);
  overflow: visible; }
.meter__fill { height: 100%; border-right: var(--border);
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
  background: var(--safe-fill); min-width: 8px; }
.meter--warn .meter__fill   { background: var(--warn-fill); }
.meter--danger .meter__fill { background: var(--danger-fill); }
.meter__limit { position: absolute; top: -5px; bottom: -5px; width: 0;
  border-left: 2px dashed var(--ink); }
.meter__limit::after { content: attr(data-label); position: absolute; top: -16px;
  left: 50%; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 10px; font-weight: 700; white-space: nowrap; }

/* ---- Subject table --------------------------------------------------------- */
.table-wrap { border: var(--border-heavy); border-radius: var(--radius-md);
  box-shadow: var(--shadow-md); overflow: hidden; background: var(--card); }
table.subjects { width: 100%; border-collapse: collapse; }
.subjects th {
  background: var(--ink); color: var(--ink-inverse);
  font-family: var(--font-label); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  text-align: left; padding: var(--sp-3) var(--sp-4);
}
.subjects td { padding: var(--sp-3) var(--sp-4); border-top: var(--bw) solid var(--ink);
  font-size: var(--text-sm); }
.subjects td.num { font-weight: 700; }
.subjects tr:nth-child(even) td { background: var(--paper); }
.subjects tr:hover td { background: var(--soft-yellow); cursor: pointer; }
.subjects .subj-code { font-family: var(--font-mono); font-weight: 700; }

/* ---- Banners (gap / staleness / diff nudges) ------------------------------- */
.banner {
  display: flex; align-items: center; gap: var(--sp-4);
  border: var(--border-heavy); border-radius: var(--radius-md);
  box-shadow: var(--shadow-md); padding: var(--sp-4) var(--sp-5);
  background: var(--warn-fill);
}
.banner--danger { background: var(--danger-fill); }
.banner--info   { background: var(--info-fill); }
.banner--success{ background: var(--safe-fill); }
.banner__body { flex: 1; }
.banner__title { font-family: var(--font-label); font-weight: 700;
  font-size: var(--text-sm); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.banner__text { font-size: var(--text-sm); margin-top: 2px; }
.banner__text .range { font-family: var(--font-mono); font-weight: 700;
  background: var(--card); border: var(--border); border-radius: var(--radius-sm);
  padding: 0 6px; white-space: nowrap; }

/* ---- Forms ------------------------------------------------------------------ */
.field { margin-bottom: var(--sp-4); }
.field > label { display: block; font-family: var(--font-label); font-weight: 700;
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-label); margin-bottom: var(--sp-2); }
.input, .select, textarea.input {
  width: 100%; font-family: var(--font-body); font-size: var(--text-base);
  padding: var(--sp-3) var(--sp-4);
  background: var(--card); color: var(--ink);
  border: var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.input:focus, .select:focus { outline: none; transform: translate(-2px,-2px); box-shadow: var(--shadow-md); }
.input::placeholder { color: var(--ink-muted); opacity: .7; }
.input.is-error { border-color: var(--danger-deep); border-width: var(--bw-heavy);
  box-shadow: 2px 2px 0 var(--danger-deep); }
.field__error { color: var(--danger-deep); font-size: var(--text-sm);
  font-weight: 700; margin-top: var(--sp-1); }
.field__hint  { color: var(--ink-muted);  font-size: var(--text-sm); margin-top: var(--sp-1); }
.input--mono { font-family: var(--font-mono); }

/* Checkbox */
.check { display: inline-flex; align-items: center; gap: var(--sp-3); cursor: pointer; }
.check input { appearance: none; width: 22px; height: 22px; margin: 0;
  background: var(--card); border: var(--border); border-radius: 6px;
  box-shadow: var(--shadow-sm); cursor: pointer; display: grid; place-content: center;
  transition: background var(--dur-fast); }
.check input:checked { background: var(--acc-green); }
.check input:checked::before { content: "✕"; font-weight: 900; font-size: 13px; }

/* Upload dropzone */
.dropzone {
  border: var(--bw-heavy) dashed var(--ink); border-radius: var(--radius-lg);
  background: var(--soft-cyan); padding: var(--sp-7) var(--sp-5);
  text-align: center; cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur);
}
.dropzone:hover, .dropzone.is-over { transform: translate(-2px,-2px);
  box-shadow: var(--shadow-lg); background: var(--acc-cyan); border-style: solid; }
.dropzone__title { font-family: var(--font-display); font-size: var(--text-xl); margin-top: var(--sp-2); }
.dropzone__hint { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink-muted); }

/* ---- Nav / tabs -------------------------------------------------------------- */
.nav {
  display: flex; align-items: center; gap: var(--sp-4);
  background: var(--card); border-bottom: var(--border-heavy);
  padding: var(--sp-3) var(--sp-5); position: sticky; top: 0; z-index: var(--z-nav);
}
.nav__logo { font-family: var(--font-display); font-size: var(--text-xl);
  background: var(--acc-yellow); border: var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm); padding: 2px 10px; }
.tabs { display: inline-flex; border: var(--border); border-radius: var(--radius-sm);
  overflow: hidden; background: var(--card); box-shadow: var(--shadow-sm); }
.tabs__tab { font-family: var(--font-label); font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--tracking-label);
  padding: var(--sp-2) var(--sp-4); cursor: pointer; background: transparent;
  border: none; border-right: var(--border); color: var(--ink); }
.tabs__tab:last-child { border-right: none; }
.tabs__tab[aria-selected="true"] { background: var(--ink); color: var(--ink-inverse); }
.tabs__tab:hover:not([aria-selected="true"]) { background: var(--soft-yellow); }

/* ---- Toast & modal ------------------------------------------------------------ */
.toast { display: inline-flex; align-items: center; gap: var(--sp-3);
  background: var(--ink); color: var(--ink-inverse);
  border: var(--border); border-radius: var(--radius-md);
  box-shadow: 4px 4px 0 var(--acc-purple);
  padding: var(--sp-3) var(--sp-5); font-weight: 700; font-size: var(--text-sm); }
.toast--danger { box-shadow: 4px 4px 0 var(--danger-fill); }
.toast__text { flex: 1; }
.toast__action { font-family: var(--font-label); font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  background: transparent; color: var(--ink-inverse); cursor: pointer;
  border: var(--bw) solid var(--ink-inverse); border-radius: var(--radius-sm);
  padding: var(--sp-1) var(--sp-3); }
.toast__action:hover:not(:disabled) { background: var(--ink-inverse); color: var(--ink); }
.toast__action:disabled { opacity: .5; cursor: default; }
.toast__action--undo { border-color: var(--acc-purple); color: var(--acc-purple); }
.toast__action--undo:hover:not(:disabled) { background: var(--acc-purple); color: var(--ink); }

/* Bottom-centred on mobile, bottom-left on desktop — never over the nav, and
   never over the primary action of a form the toast is reporting on. */
.toast-host { position: fixed; z-index: var(--z-toast);
  left: var(--sp-4); right: var(--sp-4); bottom: var(--sp-4);
  display: flex; flex-direction: column-reverse; align-items: stretch;
  gap: var(--sp-2); pointer-events: none; }
.toast-host > * { pointer-events: auto; }
@media (min-width: 640px) {
  .toast-host { right: auto; max-width: 420px; align-items: flex-start; }
}
.toast { animation: toast-in var(--dur) var(--ease); }
.toast.is-leaving { opacity: 0; transform: translate(0, 4px);
  transition: opacity var(--dur), transform var(--dur); }
@keyframes toast-in {
  from { opacity: 0; transform: translate(0, 8px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; }
  .toast.is-leaving { transition: none; }
}

.modal { background: var(--card); border: var(--border-heavy);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-xl);
  padding: var(--sp-6); max-width: 480px; }
.modal__title { font-family: var(--font-display); font-size: var(--text-2xl); margin-bottom: var(--sp-3); }

/* ---- Diff list (upload results) ------------------------------------------------ */
.diff-row { display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) 0; border-bottom: 1.5px dashed var(--ink);
  font-family: var(--font-mono); font-size: var(--text-sm); }
.diff-row:last-child { border-bottom: none; }
.diff-arrow { font-weight: 700; }

/* ---- Utilities ----------------------------------------------------------------- */
.text-muted { color: var(--ink-muted); }
.text-safe   { color: var(--safe-deep);   font-weight: 700; }
.text-danger { color: var(--danger-deep); font-weight: 700; }
.text-pending{ color: var(--pending-deep);font-weight: 700; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
