:root {
  color-scheme: dark light;

  --brand-red: #eb0a1e;

  --status-available: #2ecc71;
  --status-charging: #3b9dff;
  --status-busy: #f5a524;
  --status-faulted: #ff4d4f;
  --status-offline: #8a8f98;

  --bg: #0b0d10;
  --surface: #15181d;
  --surface-alt: #1c2127;
  --text: #f3f5f8;
  --text-dim: #a5adb8;
  --border: #262b32;

  --radius: 14px;
  --radius-sm: 8px;
  --shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 8px 24px rgba(0, 0, 0, 0.35);

  --gap: clamp(0.75rem, 1.2vw, 1.25rem);
  --pad: clamp(0.9rem, 1.4vw, 1.4rem);

  --fs-hero: clamp(2rem, 5.5vw, 3rem);
  --fs-lg: clamp(1.2rem, 2.4vw, 1.5rem);
  --fs-md: clamp(0.95rem, 1.5vw, 1.1rem);
  --fs-sm: clamp(0.8rem, 1.2vw, 0.9rem);
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #f3f5f8;
    --surface: #ffffff;
    --surface-alt: #eef1f5;
    --text: #0f1216;
    --text-dim: #5a6270;
    --border: #d9dee5;
    --shadow: 0 1px 0 rgba(255, 255, 255, 0.6) inset, 0 4px 16px rgba(13, 18, 26, 0.08);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, system-ui, sans-serif;
  font-size: var(--fs-md);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

/* Brand — lives in the footer, right-aligned */
.brand {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--text);
  font-size: var(--fs-sm);
  white-space: nowrap;
}
.brand-bar {
  display: inline-block;
  width: 3px;
  height: 1.05em;
  background: var(--brand-red);
  border-radius: 2px;
}
.brand-name {
  font-weight: 700;
  letter-spacing: 0.01em;
}
.brand-sub {
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
@media (max-width: 480px) {
  .brand-sub { display: none; }
}

/* Banner */
.banner {
  margin: var(--gap);
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--status-faulted) 20%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--status-faulted) 40%, var(--border));
  color: var(--text);
  font-size: var(--fs-sm);
}
.banner[hidden] { display: none; }

/* Grid */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--gap);
  padding: var(--gap);
  padding-bottom: 5rem;
}

/* Card */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  box-shadow: var(--shadow);
  position: relative;
  overflow: hidden;
  min-height: 44px;
}

.card-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.45rem;
}
.card-name {
  font-size: var(--fs-lg);
  font-weight: 600;
  margin: 0;
  overflow-wrap: break-word;
  line-height: 1.2;
  width: 100%;
}
.card-id {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* Status pill */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  white-space: nowrap;
}
.pill::before {
  content: "";
  width: 0.55em;
  height: 0.55em;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 25%, transparent);
}
.pill.available {
  color: var(--status-available);
  background: color-mix(in srgb, var(--status-available) 15%, var(--surface-alt));
  border-color: color-mix(in srgb, var(--status-available) 35%, transparent);
}
.pill.charging {
  color: var(--status-charging);
  background: color-mix(in srgb, var(--status-charging) 15%, var(--surface-alt));
  border-color: color-mix(in srgb, var(--status-charging) 35%, transparent);
}
/* Charging-but-not-drawing: session paused, handshake in progress, or no
   matching open session returned. Match Monta's "Busy Charging" label (pill
   still reads "Oplader") but shift the pill to the muted busy colour so staff
   can see at a glance which cars aren't actually drawing current. */
.card[data-status="charging"]:not([data-session-state="charging"]) .pill.charging {
  color: var(--status-busy);
  background: color-mix(in srgb, var(--status-busy) 14%, var(--surface-alt));
  border-color: color-mix(in srgb, var(--status-busy) 30%, transparent);
}
.card[data-status="charging"][data-session-state="paused"] .pill.charging::before {
  animation: pulse-pause 2s ease-in-out infinite;
}
@keyframes pulse-pause {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}
.pill.busy_idle {
  color: var(--status-busy);
  background: color-mix(in srgb, var(--status-busy) 18%, var(--surface-alt));
  border-color: color-mix(in srgb, var(--status-busy) 35%, transparent);
}
.pill.faulted {
  color: var(--status-faulted);
  background: color-mix(in srgb, var(--status-faulted) 18%, var(--surface-alt));
  border-color: color-mix(in srgb, var(--status-faulted) 35%, transparent);
}
.pill.offline {
  color: var(--status-offline);
  background: color-mix(in srgb, var(--status-offline) 18%, var(--surface-alt));
  border-color: color-mix(in srgb, var(--status-offline) 35%, transparent);
}

.card-detail {
  color: var(--text-dim);
  font-size: var(--fs-sm);
  min-height: 1.2em;
}
.card-detail strong {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.card-meta {
  display: flex;
  gap: 0.8rem;
  color: var(--text-dim);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

/* State-change flash */
.card.flash {
  animation: flash-bg 1.5s ease-out;
}
@keyframes flash-bg {
  0%   { box-shadow: 0 0 0 2px var(--flash-color, transparent), var(--shadow); }
  40%  { box-shadow: 0 0 0 4px var(--flash-color, transparent), var(--shadow); }
  100% { box-shadow: 0 0 0 0 transparent, var(--shadow); }
}
.card.flash-available  { --flash-color: color-mix(in srgb, var(--status-available) 60%, transparent); }
.card.flash-charging   { --flash-color: color-mix(in srgb, var(--status-charging) 60%, transparent); }
.card.flash-busy_idle  { --flash-color: color-mix(in srgb, var(--status-busy) 60%, transparent); }
.card.flash-faulted    { --flash-color: color-mix(in srgb, var(--status-faulted) 70%, transparent); }
.card.flash-offline    { --flash-color: color-mix(in srgb, var(--status-offline) 50%, transparent); }

/* Status bar (footer) */
.status-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 0.6rem 1rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: color-mix(in srgb, var(--surface) 85%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-top: 1px solid var(--border);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.pulse {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--status-available);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--status-available) 60%, transparent);
  animation: pulse 2.4s ease-in-out infinite;
}
.pulse.lost {
  background: var(--status-offline);
  animation: none;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--status-available) 60%, transparent); }
  50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--status-available) 0%, transparent); }
}
.freshness.stale { color: var(--status-busy); }
.freshness.dead  { color: var(--status-faulted); }

/* Empty state */
.empty {
  grid-column: 1 / -1;
  padding: 2rem;
  text-align: center;
  color: var(--text-dim);
}

/* TV mode — scale up for viewing across a workshop and pack all chargers
   into the viewport without scrolling (JS sets grid cols + rows). */
body.tv {
  --fs-lg: clamp(1.2rem, 2.1vw, 1.9rem);
  --fs-md: clamp(1rem, 1.5vw, 1.3rem);
  --fs-sm: clamp(0.9rem, 1.2vw, 1.1rem);
  --gap: clamp(0.7rem, 1vw, 1.1rem);
  --pad: clamp(0.9rem, 1.2vw, 1.3rem);

  height: 100vh;
  height: 100svh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
body.tv .banner,
body.tv .status-bar {
  flex: 0 0 auto;
}
body.tv .status-bar {
  position: static;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.tv .grid {
  flex: 1 1 auto;
  min-height: 0;
  padding: var(--gap);
  padding-bottom: var(--gap);
  /* grid-template-columns + grid-template-rows set by JS fitTvGrid() */
}
body.tv .card {
  min-height: 0;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  gap: 0.45rem;
  justify-content: flex-start;
}
body.tv .card-head { gap: 0.35rem; }
body.tv .card-name {
  font-size: var(--fs-lg);
  /* Cap name to two lines so taller content (charging detail) has room. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
body.tv .card-detail,
body.tv .card-meta {
  font-size: var(--fs-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Accessibility — respect reduced motion for the flash/pulse */
@media (prefers-reduced-motion: reduce) {
  .card.flash { animation: none; }
  .pulse { animation: none; }
}
