/* =============================================================
   WebTec Energy Server — site chrome
   ============================================================= */

.wts {
  background: var(--wt-page);
  color: var(--wt-ink);
  font-family: var(--wt-font-sans);
  font-size: 14px;
  line-height: 1.5;
  width: 100%;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
}
.wts *, .wts *::before, .wts *::after { box-sizing: border-box; }
.wts h1, .wts h2, .wts h3, .wts h4 { margin: 0; font-weight: 700; letter-spacing: -0.015em; color: var(--wt-ink); }
.wts p { margin: 0; }
.wts a { color: var(--wt-brand-strong); text-decoration: none; }
.wts a:hover { text-decoration: underline; text-underline-offset: 3px; }
.wts code, .wts .mono { font-family: var(--wt-font-mono); }

/* Header --------------------------------------------------------*/
.wts-header {
  height: 64px;
  padding: 0 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--wt-border);
  background: var(--wt-surface);
  flex-shrink: 0;
}
.wts-brand {
  display: inline-flex; align-items: center; gap: 12px;
  font-weight: 800; letter-spacing: -0.02em;
  font-size: 20px; color: var(--wt-ink);
}
.wts-brand .logo {
  width: 36px; height: 36px;
  display: block; object-fit: contain;
  border-radius: var(--wt-r-md);
  flex-shrink: 0;
}
.wts-brand .name { line-height: 1.05; }
.wts-brand .name .sub {
  display: block; font-size: 10.5px; color: var(--wt-ink-muted);
  font-family: var(--wt-font-mono); font-weight: 500;
  letter-spacing: 0; margin-top: 4px; text-transform: uppercase;
}
.wts-nav { display: flex; gap: 6px; align-items: center; }
.wts-nav a {
  padding: 8px 14px; border-radius: var(--wt-r-md);
  font-size: 13.5px; font-weight: 500; color: var(--wt-ink-soft);
}
.wts-nav a:hover { background: var(--wt-surface-2); color: var(--wt-ink); text-decoration: none; }
.wts-nav a.is-active { color: var(--wt-ink); }
.wts-nav .nav-cta {
  margin-left: 6px;
  padding: 8px 16px; background: var(--wt-brand); color: var(--wt-ink-on-brand);
  border-radius: var(--wt-r-md); font-weight: 600;
}
.wts-nav .nav-cta:hover { background: var(--wt-brand-strong); text-decoration: none; }
.wts-nav .nav-user {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 6px; border-radius: var(--wt-r-full);
  background: var(--wt-surface-2); border: 1px solid var(--wt-border);
  font-size: 13px; color: var(--wt-ink);
}
.wts-nav .nav-user .avatar {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--wt-brand); color: var(--wt-ink-on-brand);
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700;
}

/* Footer --------------------------------------------------------*/
.wts-footer {
  margin-top: auto;
  padding: 24px 32px 20px;
  border-top: 1px solid var(--wt-border);
  background: var(--wt-surface);
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12.5px; color: var(--wt-ink-muted);
  flex-shrink: 0;
}
.wts-footer .links { display: flex; gap: 18px; }
.wts-footer .links a { color: var(--wt-ink-soft); font-weight: 500; }
/* Build identifier — present so a support call can name what it sees, quiet
   enough not to compete with the copyright line it sits next to. */
.wts-version { opacity: .55; font-variant-numeric: tabular-nums; margin-left: 6px; }

/* Settings sidebar ---------------------------------------------*/
.wts-shell { display: grid; grid-template-columns: 240px 1fr; flex: 1; min-height: 0; }
.wts-side {
  background: var(--wt-surface);
  border-right: 1px solid var(--wt-border);
  padding: 24px 16px;
  display: flex; flex-direction: column; gap: 4px;
}
.wts-side h4 {
  font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--wt-ink-muted); font-weight: 700;
  padding: 0 10px; margin-bottom: 8px;
}
.wts-side a {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--wt-r-md);
  font-size: 14px; color: var(--wt-ink-soft); font-weight: 500;
}
.wts-side a:hover { background: var(--wt-surface-2); color: var(--wt-ink); text-decoration: none; }
.wts-side a.is-active { background: var(--wt-brand-soft); color: var(--wt-brand-strong); }
.wts-side a .ic { width: 18px; height: 18px; flex-shrink: 0; }

/* Settings main area -------------------------------------------*/
.wts-main { padding: 32px 36px; overflow: hidden; min-width: 0; }
.wts-main h2.page-title { font-size: 26px; letter-spacing: -0.02em; }
.wts-main .page-sub { color: var(--wt-ink-soft); margin-top: 4px; font-size: 14px; }
.wts-toolbar {
  display: flex; align-items: center; gap: 12px; margin-top: 18px;
  padding: 12px 14px; background: var(--wt-surface); border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-md);
}

/* Dashboard hero ------------------------------------------------*/
.wts-hero {
  padding: 40px 32px 28px;
  display: grid; grid-template-columns: 1fr auto;
  gap: 32px; align-items: end;
  background: linear-gradient(180deg, var(--wt-surface) 0%, var(--wt-page) 100%);
  border-bottom: 1px solid var(--wt-border);
}
.wts-hero .eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--wt-brand-strong); margin-bottom: 8px;
}
.wts-hero h1 {
  font-size: 40px; line-height: 1.1; letter-spacing: -0.025em; font-weight: 800;
}
.wts-hero h1 .accent { color: var(--wt-brand-strong); }
.wts-hero p { color: var(--wt-ink-soft); font-size: 16px; max-width: 56ch; margin-top: 8px; }
.wts-hero .live-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 8px;
  background: var(--wt-success-soft); color: var(--wt-success);
  border-radius: var(--wt-r-full);
  font-size: 12.5px; font-weight: 600;
}
.wts-hero .live-pill .pulse {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--wt-success);
  box-shadow: 0 0 0 0 var(--wt-success);
  animation: wts-pulse 1.6s infinite;
}
@keyframes wts-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--wt-success) 60%, transparent); }
  70% { box-shadow: 0 0 0 10px color-mix(in oklab, var(--wt-success) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--wt-success) 0%, transparent); }
}

/* Tile row ------------------------------------------------------*/
.wts-tile-row {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
  padding: 24px 32px;
}
.wts-tile {
  background: var(--wt-surface);
  border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-xl);
  padding: 24px;
  display: flex; flex-direction: column; gap: 14px;
  min-height: 280px;
}
.wts-tile h3 {
  font-size: 13px; font-weight: 600; color: var(--wt-ink-muted);
  text-transform: uppercase; letter-spacing: 0.08em;
}
.wts-tile .figure { font-family: var(--wt-font-mono); font-size: 34px; font-weight: 700; letter-spacing: -0.025em; color: var(--wt-ink); }
.wts-tile .figure small { font-size: 18px; color: var(--wt-ink-muted); margin-left: 4px; font-weight: 500; }

.wts-stat-list { display: flex; flex-direction: column; gap: 14px; }
.wts-stat-list .row {
  display: flex; align-items: baseline; justify-content: space-between;
  padding-bottom: 14px; border-bottom: 1px dashed var(--wt-border);
}
.wts-stat-list .row:last-child { border-bottom: 0; padding-bottom: 0; }
.wts-stat-list .label {
  font-size: 13px; color: var(--wt-ink-soft);
  display: inline-flex; align-items: center; gap: 8px;
}
.wts-stat-list .label .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.wts-stat-list .value {
  font-family: var(--wt-font-mono); font-weight: 600; font-size: 19px;
  color: var(--wt-ink);
}
.wts-stat-list .value small { font-size: 12px; color: var(--wt-ink-muted); margin-left: 4px; font-weight: 500; }

/* Donut ---------------------------------------------------------*/
/* chart.js sizes its canvas from this box, so the box must be square and must
   be allowed to shrink - the 180px is a cap, not a width. */
.wts-donut { display: grid; place-items: center; min-width: 0; }
.wts-donut canvas { max-width: 100%; }
.wts-donut-legend {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 4px 8px;
  font-size: 12.5px; color: var(--wt-ink-muted); margin-top: 4px;
}
.wts-donut-legend > span { display: inline-flex; align-items: center; gap: 6px; }
/* JS recolours these from the same tokens the wedges use. */
.wts-donut-legend .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* Map -----------------------------------------------------------*/
/* The map only takes the wheel and the pointer once it has been clicked; until
   then the page scrolls straight over it. .is-active is set by setMapInteractive
   in index.js.

   The active state is deliberately quiet: the same 2px/--wt-border-medium the
   Stammdaten rows use, not a brand colour or a focus ring. The map is a large
   surface and a bright outline around it dominates the whole dashboard. What
   actually tells the user the map is live is the "Karte verlassen" button
   appearing and the cursor turning into a grab hand.
   The 1px the box gains is absorbed by the content, so nothing around it moves. */
.wts-map {
  margin: 0 32px 32px;
  border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-xl);
  background: var(--wt-surface);
  overflow: hidden;
  transition: border-color .15s ease;
}
.wts-map.is-active {
  border: 2px solid var(--wt-border-medium);
}
.wts-map-head-right { display: flex; align-items: center; gap: 12px; }

/* Exit control. Display is driven entirely by the parent's state class, so no
   [hidden] attribute to be overridden by this rule's own display. */
.wts-map-exit {
  display: none;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font: 600 12.5px var(--wt-font-sans);
  color: var(--wt-brand-strong);
  background: var(--wt-brand-soft);
  border: 1px solid var(--wt-brand);
  border-radius: var(--wt-r-full);
  cursor: pointer;
}
.wts-map.is-active .wts-map-exit { display: inline-flex; }

/* Same state-driven display as the exit button. */
.wts-map-toggle {
  display: none;
  align-items: center;
  gap: 6px;
  font: 600 12.5px var(--wt-font-sans);
  color: var(--wt-ink-soft);
  cursor: pointer;
  user-select: none;
}
.wts-map.is-active .wts-map-toggle { display: inline-flex; }
.wts-map-toggle input { accent-color: var(--wt-brand); cursor: pointer; margin: 0; }
/* The count spinner is only meaningful while min/max is on; it stays in the flow
   greyed out rather than disappearing, so the header does not reflow on toggle. */
.wts-map-count input[type="number"] {
  width: 52px;
  padding: 3px 6px;
  font: 600 12.5px var(--wt-font-mono);
  color: var(--wt-ink);
  background: var(--wt-surface);
  border: 1px solid var(--wt-border-medium);
  border-radius: var(--wt-r-sm);
}
.wts-map-count.is-disabled { opacity: .45; pointer-events: none; }
.wts-map-exit:hover { background: var(--wt-brand); color: var(--wt-ink-on-brand); }
.wts-map-exit:focus-visible { outline: 2px solid var(--wt-focus); outline-offset: 2px; }

/* Hint. pointer-events:none matters: this sits over the canvas, and if it took
   the click the map could never be activated by clicking the middle of it. */
.wts-map-hint {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  pointer-events: none;
  padding: 6px 14px;
  border-radius: var(--wt-r-full);
  background: var(--wt-overlay);
  color: #fff;
  font: 600 12.5px var(--wt-font-sans);
  opacity: 0;
  transition: opacity .15s ease;
}
.wts-map:not(.is-active) .wts-map-body:hover .wts-map-hint { opacity: 1; }
.wts-map:not(.is-active) #canvasMapData { cursor: zoom-in; }
.wts-map.is-active #canvasMapData { cursor: grab; touch-action: none; }
.wts-map.is-active #canvasMapData:active { cursor: grabbing; }

@media (prefers-reduced-motion: reduce) {
  .wts-map, .wts-map-hint { transition: none; }
}
.wts-map-header { padding: 14px 20px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--wt-border); }
.wts-map-header h3 { font-size: 15px; }
/* Holds the real map: the <img> sizes the box, the canvas draws over it.
   The redesign's mock dots and caption lived here - they sat on top of the
   actual map once one existed, so they are gone. */
.wts-map-body {
  background: var(--wt-surface-sunken);
  position: relative;
}

/* Content + rail split (profile page). Was an inline grid-template-columns,
   which no media query could reach - keep it a class so it can collapse. */
.wts-split { margin-top: 24px; display: grid; grid-template-columns: 1fr 280px; gap: 20px; }

/* Generic panel -------------------------------------------------*/
.wts-panel {
  background: var(--wt-surface); border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-lg);
  padding: 20px;
}
.wts-panel + .wts-panel { margin-top: 12px; }
.wts-panel .panel-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px;
}
.wts-panel .panel-head h4 { font-size: 15px; }

/* Form rows -----------------------------------------------------*/
.wts-field { display: flex; flex-direction: column; gap: 6px; }
.wts-field label { font-size: 13px; font-weight: 600; color: var(--wt-ink); }
.wts-field .help { font-size: 12px; color: var(--wt-ink-muted); }
.wts-input {
  height: 40px; padding: 0 14px;
  border: 1px solid var(--wt-border-strong); background: var(--wt-surface);
  border-radius: var(--wt-r-md);
  font: 500 14px var(--wt-font-sans);
  color: var(--wt-ink); width: 100%;
}
.wts-input:focus { outline: none; border-color: var(--wt-brand); box-shadow: 0 0 0 4px var(--wt-focus); }
.wts-input[readonly], .wts-input[disabled] { background: var(--wt-surface-sunken); color: var(--wt-ink-soft); }
textarea.wts-input { height: auto; min-height: 72px; padding: 10px 14px; line-height: 1.5; resize: vertical; font-family: var(--wt-font-mono); font-size: 12.5px; }
.wts-select { appearance: none; padding-right: 32px;
  background:
    linear-gradient(45deg, transparent 50%, var(--wt-ink-soft) 50%) no-repeat right 18px top 18px / 5px 5px,
    linear-gradient(135deg, var(--wt-ink-soft) 50%, transparent 50%) no-repeat right 13px top 18px / 5px 5px,
    var(--wt-surface);
}
.wts-input-group { display: flex; }
.wts-input-group .wts-input { border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: 0; }
.wts-input-group .wts-btn { border-top-left-radius: 0; border-bottom-left-radius: 0; }

.wts-btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 40px; padding: 0 16px;
  border-radius: var(--wt-r-md);
  font: 600 13.5px var(--wt-font-sans);
  border: 1px solid transparent; cursor: pointer;
  white-space: nowrap;
}
.wts-btn--primary { background: var(--wt-brand); color: var(--wt-ink-on-brand); }
.wts-btn--secondary { background: var(--wt-surface); color: var(--wt-ink); border-color: var(--wt-border-strong); }
.wts-btn--ghost { background: transparent; color: var(--wt-ink-soft); }
.wts-btn--ghost:hover { background: var(--wt-surface-2); color: var(--wt-ink); }
.wts-btn--danger { background: var(--wt-danger); color: white; }
.wts-btn--sm { height: 32px; padding: 0 12px; font-size: 12.5px; }
.wts-btn--icon {
  width: 36px; height: 36px; padding: 0; justify-content: center;
}
.wts-btn .ic { width: 16px; height: 16px; stroke-width: 1.75; }
/* A disabled button was indistinguishable from an enabled one - it kept the
   pointer cursor and the full contrast, and only did nothing when clicked. */
.wts-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.wts-btn--ghost:disabled:hover { background: transparent; color: var(--wt-ink-soft); }

/* Switches/checkboxes ------------------------------------------*/
.wts-switch { position: relative; width: 36px; height: 22px; flex-shrink: 0; }
.wts-switch input { opacity: 0; width: 0; height: 0; }
.wts-switch .track { position: absolute; inset: 0; background: var(--wt-border-strong); border-radius: var(--wt-r-full); transition: background 0.18s; }
.wts-switch .thumb { position: absolute; left: 3px; top: 3px; width: 16px; height: 16px; border-radius: 50%; background: white; box-shadow: var(--wt-shadow-sm); transition: transform 0.18s; }
.wts-switch input:checked + .track { background: var(--wt-brand); }
.wts-switch input:checked + .track .thumb { transform: translateX(14px); }

/* User accordion (Stammdaten / OCPP) ----------------------------*/
.wts-acc-list { display: flex; flex-direction: column; gap: 10px; }
.wts-acc {
  background: var(--wt-surface);
  border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-lg);
  overflow: hidden;
}
.wts-acc-head {
  display: grid;
  grid-template-columns: 28px 1fr auto auto auto;
  gap: 12px; padding: 12px 16px;
  align-items: center;
  cursor: pointer;
  background: var(--wt-surface);
}
.wts-acc[data-state="open"] .wts-acc-head { background: var(--wt-surface-2); border-bottom: 1px solid var(--wt-border); }
.wts-acc-head .caret {
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border-radius: 6px; color: var(--wt-ink-soft);
  background: transparent;
  transition: transform 0.16s ease;
}
/* .ic is sized per context (button, sidebar); the caret had no rule of its own,
   so its svg fell back to the 300x150 default of a replaced element. */
.wts-acc-head .caret .ic { width: 16px; height: 16px; }
.wts-acc[data-state="open"] .wts-acc-head .caret { transform: rotate(90deg); color: var(--wt-brand-strong); }
/* The open state was styled but the closed one never hid anything, so the
   component could not actually collapse. data-state is set by the page. */
.wts-acc:not([data-state="open"]) .wts-acc-body { display: none; }
.wts-acc-head .who { font-weight: 600; font-size: 14.5px; color: var(--wt-ink); }
.wts-acc-head .who .sub { font-size: 12.5px; color: var(--wt-ink-muted); font-weight: 500; margin-left: 6px; font-family: var(--wt-font-mono); }
.wts-acc-head .badge-set { display: flex; gap: 6px; }
.wts-acc-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 12px; }
.wts-form-row {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
}
.wts-form-row.col-2 { grid-template-columns: repeat(2, 1fr); }
.wts-form-row.col-3 { grid-template-columns: repeat(3, 1fr); }
.wts-form-row .field-h {
  display: flex; align-items: center; gap: 8px;
}
.wts-form-row .field-h label { font-size: 12.5px; color: var(--wt-ink-soft); font-weight: 500; flex-shrink: 0; }
.wts-form-row .field-h .wts-input { font-size: 13px; height: 36px; }
.wts-form-row .field-h.toggle-row { justify-content: space-between; background: var(--wt-surface-2); padding: 8px 12px; border-radius: var(--wt-r-md); }
.wts-divider { height: 1px; background: var(--wt-border); margin: 4px 0; }

/* Status badges -------------------------------------------------*/
.wts-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: var(--wt-r-full);
  font: 600 11px var(--wt-font-sans); letter-spacing: 0.02em;
  background: var(--wt-surface-2); color: var(--wt-ink-soft);
  border: 1px solid var(--wt-border);
}
.wts-badge .led { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.wts-badge--success { background: var(--wt-success-soft); color: var(--wt-success); border-color: transparent; }
.wts-badge--warning { background: var(--wt-warning-soft); color: var(--wt-accent-strong); border-color: transparent; }
.wts-badge--danger { background: var(--wt-danger-soft); color: var(--wt-danger); border-color: transparent; }
.wts-badge--info { background: var(--wt-info-soft); color: var(--wt-info); border-color: transparent; }
.wts-badge--brand { background: var(--wt-brand-soft); color: var(--wt-brand-strong); border-color: transparent; }

/* Server status row --------------------------------------------*/
.wts-srv-row {
  display: grid; grid-template-columns: 220px 1fr auto;
  gap: 18px; align-items: start;
  padding: 18px 20px;
  background: var(--wt-surface);
  border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-lg);
}
.wts-srv-row + .wts-srv-row { margin-top: 12px; }
.wts-srv-row .srv-label { display: flex; flex-direction: column; gap: 4px; }
.wts-srv-row .srv-label h4 { font-size: 14.5px; }
.wts-srv-row .srv-label .hint { font-size: 12px; color: var(--wt-ink-muted); }
.wts-srv-row textarea.wts-input { font-size: 12px; min-height: 70px; }

/* Auth card -----------------------------------------------------*/
.wts-auth-card {
  width: min(420px, 100%);
  background: var(--wt-surface);
  border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-xl);
  padding: 36px 32px;
  box-shadow: var(--wt-shadow-md);
}
.wts-auth-card .head {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  margin-bottom: 22px;
}
.wts-auth-card .head h2 { font-size: 22px; }
.wts-auth-card .head p { font-size: 13px; color: var(--wt-ink-muted); }

/* Legal pages ---------------------------------------------------*/
.wts-legal {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 40px;
  padding: 40px 48px 64px;
}
.wts-legal-toc {
  position: sticky; top: 24px; align-self: start;
  font-size: 13px;
}
.wts-legal-toc h4 {
  font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--wt-ink-muted); margin-bottom: 10px; font-weight: 700;
}
.wts-legal-toc ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 2px; }
.wts-legal-toc a {
  display: block; padding: 4px 10px; border-radius: 6px;
  color: var(--wt-ink-soft); font-size: 13px;
}
.wts-legal-toc a:hover { background: var(--wt-surface-2); text-decoration: none; }
.wts-legal-toc a.is-current { background: var(--wt-brand-soft); color: var(--wt-brand-strong); }

.wts-legal-body { max-width: 640px; }
.wts-legal-body h1 { font-size: 32px; letter-spacing: -0.025em; }
.wts-legal-body h2 { font-size: 18px; margin-top: 28px; }
.wts-legal-body h3 { font-size: 14.5px; margin-top: 22px; color: var(--wt-ink); }
.wts-legal-body p, .wts-legal-body li { color: var(--wt-ink-soft); font-size: 14px; line-height: 1.65; }
.wts-legal-body p + p { margin-top: 12px; }
.wts-legal-body ul { padding-left: 18px; }
.wts-legal-body .summary {
  background: var(--wt-brand-soft);
  border-left: 3px solid var(--wt-brand);
  padding: 14px 16px;
  border-radius: 0 var(--wt-r-md) var(--wt-r-md) 0;
  margin-top: 12px;
}
.wts-legal-body .summary strong { color: var(--wt-brand-strong); }
.wts-legal-body .meta-row {
  display: grid; grid-template-columns: 130px 1fr;
  font-size: 13px;
  padding: 6px 0;
  border-bottom: 1px dashed var(--wt-border);
}
.wts-legal-body .meta-row dt { color: var(--wt-ink-muted); }

/* Masks an admin-list password field without making it type="password" - see
   setPwdMaskedElement in indexBase.js for why those fields must stay text. */
.wts-pw-mask {
  -webkit-text-security: disc;
  text-security: disc;
}

/* Password show/hide eye ----------------------------------------
   Drawn in CSS, no icon font: a rounded lens rotated 45 degrees with a round
   pupil. It used to be styled in indexBase.css, which no template has loaded
   since the redesign, so the toggle rendered as an empty div. currentColor here
   so it takes the tint of whatever button it sits in, in either theme. */
.clsHideShowPwd {
  width: 13px; height: 13px;
  border: 1px solid currentColor;
  border-radius: 75% 15%;
  transform: rotate(45deg);
  position: relative;
  flex-shrink: 0;
}
.clsHideShowPwd::before {
  content: "";
  position: absolute;
  left: 3px; top: 3px;
  width: 5px; height: 5px;
  border: 1px solid currentColor;
  border-radius: 50%;
}

/* Helpers -------------------------------------------------------*/
.wts-row { display: flex; align-items: center; gap: 12px; }
.wts-spacer { flex: 1; }
.wts-text-muted { color: var(--wt-ink-muted); }
.wts-mono { font-family: var(--wt-font-mono); }

/* Search + filter bar ------------------------------------------*/
.wts-filterbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.wts-filterbar .search {
  display: flex; align-items: center; gap: 8px;
  background: var(--wt-surface); border: 1px solid var(--wt-border-strong);
  border-radius: var(--wt-r-md); padding: 0 12px;
  min-width: 240px; height: 38px;
}
.wts-filterbar .search input {
  border: 0; outline: 0; background: transparent; flex: 1;
  font: 500 13.5px var(--wt-font-sans); color: var(--wt-ink);
}
.wts-filterbar .search svg { width: 14px; height: 14px; color: var(--wt-ink-muted); }

/* Tables (used in some settings) -------------------------------*/
.wts-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.wts-table th, .wts-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--wt-border); }
.wts-table th { background: var(--wt-surface-2); color: var(--wt-ink-muted); font: 700 11px var(--wt-font-sans); letter-spacing: 0.06em; text-transform: uppercase; }

/* Responsive ----------------------------------------------------*/
/* The redesign shipped without a single media query, which is why every page
   scrolled sideways on a phone. Two causes, fixed separately below.

   1. Grid and flex children default to min-width:auto, so an item wider than
      its track (a mono figure, the map canvas, a long meter id) pushes the
      track past the viewport instead of shrinking. min-width:0 is what lets
      the 1fr tracks actually behave like 1fr.
   2. Rigid track counts and fixed gutters. Everything below only drops column
      counts and padding - no rule here may introduce a new fixed px width. */

.wts-shell, .wts-main, .wts-tile-row, .wts-tile, .wts-hero, .wts-legal,
.wts-srv-row, .wts-form-row, .wts-acc, .wts-acc-head, .wts-panel { min-width: 0; }
.wts-tile-row > *, .wts-hero > *, .wts-srv-row > *,
.wts-form-row > *, .wts-acc-head > *, .wts-shell > * { min-width: 0; }

/* German compounds in the hero and the legal pages are long enough to overflow
   on their own; the templates already carry soft hyphens, this is the backstop. */
.wts-hero h1, .wts-hero p, .wts-legal-body, .wts-tile h3 { overflow-wrap: break-word; }

/* The three dashboard tiles stay side by side at every width - the row is meant
   to be read as one comparison, so it compacts instead of stacking. Everything
   in it has to survive a ~90px column at 320px: hence the type ramp below, and
   the point where each stat label moves above its value instead of beside it. */
@media (max-width: 1100px) {
  .wts-form-row { grid-template-columns: repeat(2, 1fr); }
  .wts-legal { grid-template-columns: 1fr; gap: 24px; padding: 32px 24px 48px; }
  .wts-legal-toc { position: static; }
}

@media (max-width: 820px) {
  .wts-shell { grid-template-columns: 1fr; }
  .wts-side {
    border-right: 0; border-bottom: 1px solid var(--wt-border);
    flex-direction: row; flex-wrap: wrap; padding: 12px 16px;
  }
  .wts-side h4 { width: 100%; margin-bottom: 4px; padding: 0; }
  .wts-main { padding: 20px 16px; }

  .wts-hero {
    grid-template-columns: 1fr; gap: 16px;
    padding: 28px 20px 22px; align-items: start;
  }
  .wts-hero h1 { font-size: 30px; }
  .wts-hero p { font-size: 15px; }

  .wts-tile-row { gap: 10px; padding: 16px 16px; }
  .wts-tile { min-height: 0; padding: 16px 13px; gap: 11px; }
  .wts-tile h3 { font-size: 10.5px; letter-spacing: 0.05em; }
  .wts-stat-list { gap: 11px; }
  .wts-stat-list .row { padding-bottom: 11px; }
  .wts-stat-list .value { font-size: 16px; }
  .wts-donut-legend { font-size: 11px; }
  .wts-map { margin: 0 20px 20px; }

  .wts-split { grid-template-columns: 1fr; }
  .wts-srv-row { grid-template-columns: 1fr; gap: 12px; }
  /* Button rows are nowrap by default, so a 3-button toolbar runs off under
     .wts-main's overflow:hidden and the buttons become unreachable. The inner
     groups are inline display:flex, hence the child selector. */
  .wts-row, .wts-toolbar, .wts-filterbar { flex-wrap: wrap; }
  .wts-row > div { flex-wrap: wrap; }
  /* Let the badges wrap onto their own line instead of widening the head. */
  .wts-acc-head { grid-template-columns: 24px 1fr; row-gap: 8px; }
  .wts-acc-head .badge-set { grid-column: 1 / -1; flex-wrap: wrap; }
}

@media (max-width: 620px) {
  /* Below this a stat label and its value no longer fit on one line, and the
     three legend entries no longer fit across the donut. */
  .wts-stat-list .row { flex-direction: column; align-items: flex-start; gap: 3px; }
  .wts-stat-list .label { font-size: 11.5px; gap: 6px; }
  .wts-stat-list .value { font-size: 15px; }
  .wts-stat-list .value small { font-size: 10.5px; margin-left: 3px; }
  .wts-donut-legend { flex-direction: column; align-items: flex-start; gap: 4px; }
}

@media (max-width: 560px) {
  .wts-header {
    height: auto; padding: 10px 16px;
    flex-wrap: wrap; gap: 10px;
  }
  .wts-brand { font-size: 17px; }
  .wts-nav { flex-wrap: wrap; gap: 4px; }
  .wts-nav a { padding: 7px 10px; font-size: 13px; }
  .wts-nav .nav-cta { margin-left: 0; }

  .wts-footer {
    flex-direction: column; align-items: flex-start; gap: 10px;
    padding: 20px 16px 18px;
  }
  .wts-footer .links { flex-wrap: wrap; gap: 12px; }

  .wts-main { padding: 16px 12px; }
  .wts-tile-row { gap: 7px; padding: 12px 10px; }
  .wts-tile { padding: 13px 10px; gap: 9px; border-radius: var(--wt-r-lg); }
  .wts-tile h3 { font-size: 9.5px; letter-spacing: 0.03em; }
  .wts-stat-list .label { font-size: 10.5px; gap: 5px; }
  .wts-stat-list .value { font-size: 13.5px; }
  .wts-donut-legend { font-size: 10.5px; }
  .wts-map { margin: 0 12px 16px; }
  .wts-hero { padding: 24px 16px 20px; }
  .wts-hero h1 { font-size: 26px; }

  .wts-form-row,
  .wts-form-row.col-2,
  .wts-form-row.col-3 { grid-template-columns: 1fr; }
  /* The label sits above the input here - side by side there is no room. */
  .wts-form-row .field-h { flex-direction: column; align-items: stretch; gap: 4px; }
  .wts-form-row .field-h.toggle-row { flex-direction: row; align-items: center; }

  .wts-legal { padding: 24px 16px 40px; }
  .wts-legal-body h1 { font-size: 26px; }

  .wts-filterbar .search { min-width: 0; width: 100%; }
  .wts-auth-card { padding: 28px 20px; }
}

/* Floating scroll-to-top ------------------------------------------------
   Sits below bootstrap's modal layer (1055) on purpose, so an open dialog
   covers it instead of the button floating over the backdrop.
   Visibility is a class rather than the [hidden] attribute: this rule sets
   display:flex, which would win over [hidden]'s display:none, and a class
   also lets the appearance animate. Logic is wtsToTop* in indexBase.js. */
.wts-to-top {
  position: fixed;
  right: 20px;
  bottom: 20px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--wt-border);
  border-radius: var(--wt-r-full);
  background: var(--wt-surface);
  color: var(--wt-ink-soft);
  box-shadow: var(--wt-shadow-md);
  cursor: pointer;
  z-index: 1030;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s,
              background-color .15s ease, color .15s ease, border-color .15s ease;
}
.wts-to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.wts-to-top:hover {
  background: var(--wt-brand-soft);
  border-color: var(--wt-brand);
  color: var(--wt-brand-strong);
}
.wts-to-top:active { transform: translateY(1px); }
.wts-to-top:focus-visible { outline: 2px solid var(--wt-focus); outline-offset: 2px; }

@media (max-width: 620px) {
  /* Clear of the footer links and a thumb's reach on a phone. */
  .wts-to-top { right: 12px; bottom: 12px; width: 40px; height: 40px; }
}

@media (prefers-reduced-motion: reduce) {
  .wts-to-top { transition: opacity .01s, visibility .01s; transform: none; }
  .wts-to-top:active { transform: none; }
}
