/* ============================================================
   COMPONENTS — the small vocabulary this app is built from.
   Class names are `ssb-` prefixed so nothing collides with anything
   a browser extension injects into a kiosk page.
   ============================================================ */

/* ---------- Buttons ---------------------------------------- */

.ssb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text-body);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.ssb-btn:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--ink-400); }
.ssb-btn:active:not(:disabled) { transform: translateY(1px); }
.ssb-btn:disabled { opacity: 0.45; cursor: not-allowed; }

.ssb-btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.ssb-btn--primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }

.ssb-btn--danger { color: var(--danger-text); border-color: var(--danger-line); }
.ssb-btn--danger:hover:not(:disabled) { background: var(--danger-fill); }

.ssb-btn--ghost { border-color: transparent; background: transparent; }
.ssb-btn--ghost:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--line); }

.ssb-btn--block { width: 100%; }
.ssb-btn--lg { min-height: var(--touch-kiosk); font-size: var(--text-lg); padding: var(--space-3) var(--space-5); }

/* ---------- Segmented control (Day / Week / Month) --------- */

.ssb-segmented {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--surface-sunk);
  border-radius: var(--radius);
}
.ssb-segmented button {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  padding: var(--space-2) var(--space-4);
  min-height: 36px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
}
.ssb-segmented button[aria-pressed="true"] {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.08);
}

/* ---------- Slot row (the resident day view) ---------------
   One line per window: time leads, window name second, state right.
   Time is tabular so the column reads straight down. */

.ssb-slots { border-top: 1px solid var(--line); }

.ssb-slot {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-min);
  padding: var(--space-3);
  border: 0;
  border-bottom: 1px solid var(--line);
  border-left: 3px solid transparent;
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.ssb-slot:hover { background: var(--surface-hover); }
.ssb-slot[disabled] { cursor: default; }

.ssb-slot__time {
  min-width: 6.5rem;
  font-size: var(--text-md);
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.ssb-slot__name { flex: 1; font-size: var(--text-sm); color: var(--text-muted); }
.ssb-slot__state { display: flex; align-items: center; gap: var(--space-2); }

.ssb-slot--past { opacity: 0.5; }
.ssb-slot--past .ssb-slot__state { color: var(--text-faint); font-size: var(--text-xs); }

/* The resident's own booking. A left bar rather than a full outline:
   it marks the row without boxing it in, so a week of your own slots
   doesn't turn into a wall of rectangles. */
.ssb-slot--mine {
  border-left-color: var(--mine-line);
  background: var(--mine-fill);
}
.ssb-slot--mine .ssb-slot__time { color: var(--mine-text); font-weight: var(--fw-medium); }
.ssb-slot--mine .ssb-slot__name { color: var(--mine-text); }

.ssb-slot--closed { background: var(--closed-fill); }
.ssb-slot--closed .ssb-slot__state { color: var(--closed-text); font-size: var(--text-xs); }

/* ---------- Apartment label --------------------------------
   The one thing anyone learns about another household. */
.ssb-apt {
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}

.ssb-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  border: 1px solid transparent;
}
.ssb-badge--free   { background: var(--free-fill);   color: var(--free-text);   border-color: var(--free-line); }
.ssb-badge--mine   { background: var(--mine-fill);   color: var(--mine-text);   border-color: var(--mine-line); }
.ssb-badge--closed { background: var(--closed-fill); color: var(--closed-text); border-color: var(--closed-line); }
.ssb-badge--taken  { background: var(--taken-fill);  color: var(--taken-text);  border-color: var(--taken-line); }

/* ---------- Slot cell (the grid tile) -----------------------
   Shared by the resident week view and the wall screen, so it lives
   here rather than in kiosk.css. The kiosk only overrides its sizing.
   State is carried by fill, by border AND by the word printed on it —
   never by hue alone, because this gets read at three metres, under a
   fluorescent tube, by people who may not distinguish green from grey. */

.ssb-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: center;
  cursor: pointer;
  min-height: var(--touch-min);
}
.ssb-cell[disabled] { cursor: default; }
.ssb-cell__time  { font-size: var(--text-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ssb-cell__state { font-size: var(--text-sm); font-weight: var(--fw-bold); line-height: var(--lh-tight); }

.ssb-cell--free   { background: var(--free-fill);   border-color: var(--free-line); }
.ssb-cell--free .ssb-cell__state { color: var(--free-text); }

.ssb-cell--taken  { background: var(--taken-fill);  border-color: var(--taken-line); }
.ssb-cell--taken .ssb-cell__state { color: var(--taken-text); }

.ssb-cell--mine   { background: var(--mine-fill);   border-color: var(--mine-line); border-width: 2px; }
.ssb-cell--mine .ssb-cell__state { color: var(--mine-text); }

.ssb-cell--closed { background: var(--closed-fill); border-color: var(--closed-line); }
.ssb-cell--closed .ssb-cell__state { color: var(--closed-text); font-size: var(--text-xs); }

.ssb-cell--past   { opacity: 0.4; }

/* ---------- Cards, sheets ----------------------------------- */

.ssb-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

.ssb-sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 0.4);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 50;
  animation: ssb-rise var(--dur-base) var(--ease);
}
@media (min-width: 640px) { .ssb-sheet-backdrop { align-items: center; } }

.ssb-sheet {
  width: 100%;
  max-width: 32rem;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: var(--space-4) var(--space-4) var(--space-5);
}
@media (min-width: 640px) { .ssb-sheet { border-radius: var(--radius-lg); } }

.ssb-sheet__grip {
  width: 40px; height: 4px;
  margin: 0 auto var(--space-4);
  border-radius: 2px;
  background: var(--line-strong);
}

.ssb-kv {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--line);
  font-size: var(--text-sm);
}
.ssb-kv dt { color: var(--text-muted); }
.ssb-kv dd { margin: 0; color: var(--text-strong); font-weight: var(--fw-medium); text-align: right; }

/* ---------- Notices — how a rule explains itself ------------ */

.ssb-notice {
  padding: var(--space-3);
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface-sunk);
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
}
.ssb-notice--error   { background: var(--danger-fill); border-color: var(--danger-line); color: var(--danger-text); }
.ssb-notice--success { background: var(--free-fill);   border-color: var(--free-line);   color: var(--free-text); }
.ssb-notice--warn    { background: var(--closed-fill); border-color: var(--closed-line); color: var(--closed-text); }

/* ---------- Month density grid ------------------------------
   Four segments per day, filled for free slots. Reads as a bar chart
   of availability across the month, which is the question the month
   view exists to answer. */

.ssb-month {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-1);
}
.ssb-month__dow {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-faint);
  padding-bottom: var(--space-1);
}
.ssb-month__day {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-1);
  min-height: 52px;
  padding: var(--space-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.ssb-month__day:hover { background: var(--surface-hover); }
.ssb-month__day--empty { border: 0; cursor: default; pointer-events: none; }
.ssb-month__day--outside { opacity: 0.35; cursor: default; }
/* Finished days: still legible and still tappable, but visibly behind you,
   so the eye goes straight to the part of the month you can still book. */
.ssb-month__day--done { opacity: 0.45; border-style: dashed; }
.ssb-month__day--today { border-color: var(--ink-500); border-width: 2px; }

.ssb-month__num {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.ssb-month__mine {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--mine-line);
}
.ssb-month__meter { display: flex; gap: 1px; height: 5px; }
.ssb-month__seg { flex: 1; border-radius: 1px; background: var(--taken-line); }
.ssb-month__seg--free { background: var(--free-line); }
.ssb-month__closed { font-size: var(--text-xs); color: var(--closed-text); }

/* ---------- Loading ----------------------------------------- */

.ssb-skeleton {
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-sunk) 25%, var(--line) 37%, var(--surface-sunk) 63%);
  background-size: 200% 100%;
  animation: ssb-shimmer 1.4s ease-in-out infinite;
}

.ssb-spinner {
  width: 18px; height: 18px;
  border: 2px solid var(--line-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: ssb-spin 0.7s linear infinite;
}

.ssb-empty {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* ---------- Toast ------------------------------------------- */

.ssb-toasts {
  position: fixed;
  left: 50%;
  bottom: var(--space-4);
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: min(24rem, calc(100vw - 2 * var(--space-4)));
}
.ssb-toast {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  background: var(--ink-900);
  color: var(--ink-0);
  font-size: var(--text-sm);
  animation: ssb-rise var(--dur-base) var(--ease);
}
.ssb-toast--error { background: var(--danger-text); }
