/* ─── 1. TOKENS ──────────────────────────────────────────────────────────── */

/* Geist is a variable face, so one file per subset covers 300-700. IBM Plex
   Mono is not, so it ships 400 and 600 — without the 600 a parent's bold would
   be synthesised, and a faked-bold monospace identifier is how a charge point
   id becomes unreadable. latin-ext carries the Spanish accents and ¿ ¡. */

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/assets/geist-latin-d5790661.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/assets/geist-latin-ext-992fc5dd.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/ibm-plex-mono-latin-c6016505.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/ibm-plex-mono-latin-ext-4e909fb6.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/ibm-plex-mono-600-latin-59f54c34.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/ibm-plex-mono-600-latin-ext-d3cc04f3.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

:root {

  /* Values and names both come from RIVO.pen.

     They arrived in two passes on purpose. KEV-235 swapped the values and left
     the dark design's names in place, so the product turned light without a
     single view changing; KEV-263 renamed them once every screen had settled.
     Doing it the other way round would have left the product broken for the
     length of the project, because a name is only cheap to change while nothing
     outside this file knows it — and nothing outside this file ever does.

     A token is named for what it is for. None is named for a hue: that is how
     a token called --green came to render blue, and the spec now refuses it. */

  --background: #f5f4f0;
  --card: #fcfcfa;
  --card-raised: #ffffff;

  --border: #d2d6dd;
  --border-strong: #c2c7d1;

  --foreground: #253044;
  --muted-foreground: #576174;
  --subtle-foreground: #606772;

  --row-divider: #e4e6ea;
  --row-hover: #f0efe9;

  /* The lateral bar stays dark on a light product. */
  --sidebar: #202630;
  --sidebar-foreground: #e0e5ee;
  --sidebar-muted-foreground: #afbacb;
  /* The step above --sidebar-foreground: the mark, the current section and the
     signed-in manager's name, which the design sets in the page's own paper. */
  --sidebar-strong-foreground: #f5f4f0;
  /* The primary blue is unreadable on the slate panel, so the sign-in
     headline's accent has its own on-dark value. */
  --sidebar-accent: #b6c8ff;
  --sidebar-border: rgb(175 186 203 / 18%);
  /* Translucent white, the landing's own way of raising a surface on slate: the
     current section and the account's avatar, each with its edge a step up. */
  --sidebar-raised: rgb(255 255 255 / 8%);
  --sidebar-raised-edge: rgb(255 255 255 / 18%);

  /* --primary is the PRIMARY ACTION colour, not a status. Buttons, focus rings,
     the active nav item and links all resolve here. Success has its own tokens
     below, because a pill that means "working" must not render in the same
     colour as the button beside it. */
  --primary: #315ceb;
  --primary-hover: #2749c4;

  /* Status tones, from the design's three semantic pairs. Named for meaning
     rather than hue, because somebody reads one at a glance to decide whether to
     drive to the garage — and because the muted values the light design uses are
     no longer obviously green or red on their own. */
  --color-success: #004d1a;
  --color-success-tint: #dfe6e1;
  --color-success-edge: #c3d2c8;

  --color-warning: #804200;
  --color-warning-tint: #e9e3d8;
  --color-warning-edge: #d8cdb9;

  --color-error: #8c1c00;
  --color-error-tint: #e5dcda;
  --color-error-edge: #d3c2be;

  /* Neither a state nor an action: a pill with nothing to say. */
  --neutral-tint: rgb(103 116 138 / 8%);
  --neutral-edge: rgb(103 116 138 / 20%);

  /* The three steps of the band ramp on a resident's charge, from the cheapest
     third of a tariff's prices to the dearest (KEV-356). Named for the step and
     never for the band — `Valle`, `Llano` and `Punta` are a convention a manager
     is free not to follow, so a token called --tariff-band-valle would go
     uncoloured the first time somebody names their bands `Noche` and `Día`.
     Values from RIVO.pen; the middle step is --primary's own, which is the
     design's choice and not a reference, because the dot means "how dear" and
     not "the primary action". */
  --tariff-band-low: #b4c4f7;
  --tariff-band-mid: #315ceb;
  --tariff-band-high: #16286b;

  --radius: 4px;
  --radius-pill: 999px;

  --font: "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", "Roboto Mono", monospace;
}

/* ─── BASE ───────────────────────────────────────────────────────────────── */

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  color: var(--foreground);
  background: var(--background);
  font-family: var(--font);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

input,
button,
select,
textarea {
  font-family: inherit;
}

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: var(--radius);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--primary);
}

/* ─── 2. PRIMITIVES ──────────────────────────────────────────────────────── */

.card {
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.card--roomy {
  padding: 20px 24px;
}

.card--framed {
  padding: 0;
  overflow: hidden;
}

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}

.card__title {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
  color: var(--foreground);
}

.card__heading {
  display: flex;
  align-items: center;
  gap: 10px;
}

.card__icon {
  width: 15px;
  height: 15px;
  color: var(--primary);
  flex-shrink: 0;
}

.card__meta {
  font-size: 12px;
  color: var(--subtle-foreground);
}

.card__body {
  padding: 16px;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
}

/* Reading order on the page is value, then label, then detail — the number is
   the thing being read and the words explain it. The markup keeps label before
   value for screen readers, so the order is flipped visually. */
.stat__label {
  order: 2;
  font-size: 14px;
  font-weight: 600;
  color: var(--foreground);
}

.stat__value {
  order: 1;
  font-size: 44px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--foreground);
}

.stat__sub,
.stat__foot {
  order: 3;
}

/* The design tints no reading differently from its neighbours — on frame 01 all
   four are the same neutral. A blue figure beside three dark ones reads as a
   status the number does not carry. */
.stat__value--accent {
  color: var(--foreground);
}

.stat__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.stat__sub {
  font-size: 11px;
  color: var(--subtle-foreground);
}

.stat__delta {
  padding: 2px 7px;
  font-size: 11px;
  font-weight: 600;
  border-radius: var(--radius);
}

.stat__delta--up {
  color: var(--color-success);
  background: var(--color-success-tint);
}

.stat__delta--down {
  color: var(--color-error);
  background: var(--color-error-tint);
}

.table-scroll {
  overflow-x: auto;
}

.table {
  width: 100%;
  border-collapse: collapse;
}

.table th,
.table td {
  padding: 12px 16px;
  text-align: left;
  vertical-align: top;
}

.table thead th {
  padding-top: 10px;
  padding-bottom: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--subtle-foreground);
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
}

.table tbody tr {
  border-bottom: 1px solid var(--row-divider);
}

.table tbody tr:last-child {
  border-bottom: 0;
}

.table tbody tr:hover {
  background: var(--row-hover);
}

.table td {
  font-size: 13px;
  color: var(--muted-foreground);
}

.table__primary {
  font-size: 13px;
  font-weight: 500;
  color: var(--foreground);
  white-space: nowrap;
}

.table__value {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--foreground);
}

.table__id {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--subtle-foreground);
}

.table__sub {
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--subtle-foreground);
}

.table__actions {
  display: flex;
  gap: 6px;
  white-space: nowrap;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  font-size: 11.5px;
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
}

.pill--ok {
  color: var(--color-success);
  background: var(--color-success-tint);
  border-color: var(--color-success-edge);
}

.pill--neutral {
  color: var(--muted-foreground);
  background: var(--neutral-tint);
  border-color: var(--neutral-edge);
}

.pill--info {
  color: var(--foreground);
  background: #dce6ff;
  border-color: #dce6ff;
}

.pill--warn {
  color: var(--color-warning);
  background: var(--color-warning-tint);
  border-color: var(--color-warning-edge);
}

.pill--bad {
  color: var(--color-error);
  background: var(--color-error-tint);
  border-color: var(--color-error-edge);
}

.pill__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentcolor;
  flex-shrink: 0;
}

.pill__dot--live {
  animation: pill-pulse 2s infinite;
}

@keyframes pill-pulse {
  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0.4;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pill__dot--live {
    animation: none;
  }
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 18px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: #ffffff;
  text-decoration: none;
  background: var(--primary);
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s;
}

.button:hover {
  background: var(--primary-hover);
}

.button--secondary {
  font-weight: 500;
  color: var(--muted-foreground);
  background: transparent;
  border-color: var(--border);
  transition: color 0.15s, border-color 0.15s;
}

.button--secondary:hover {
  color: var(--foreground);
  background: transparent;
  border-color: var(--border-strong);
}

.button--icon {
  gap: 0;
  padding: 5px 8px;
  color: var(--subtle-foreground);
  background: transparent;
  border-color: var(--border);
  line-height: 1;
  transition: color 0.12s, border-color 0.12s;
}

.button--icon:hover {
  color: var(--foreground);
  background: transparent;
  border-color: var(--border-strong);
}

.button--danger {
  color: var(--muted-foreground);
  background: transparent;
  border-color: var(--border);
}

.button--danger:hover {
  color: var(--color-error);
  background: transparent;
  border-color: var(--color-error);
}

.button--link {
  padding: 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--primary);
  background: none;
  border: 0;
}

.button--link:hover {
  color: var(--primary-hover);
  background: none;
  text-decoration: underline;
}

.button--quiet {
  color: var(--foreground);
}

.button--quiet:hover {
  color: var(--muted-foreground);
}

.button--quiet.button--danger:hover {
  color: var(--color-error);
}

.button_to {
  display: inline-flex;
  margin: 0;
}

.button:disabled,
.button[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Frame 15. One label treatment: 12px, normal weight, in the text colour. The
   design does not uppercase labels, so .field--caps no longer changes anything —
   it stays declared because ten views still carry it, and their screen tickets
   drop it. */
.field {
  margin-bottom: 18px;
}

.field label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 400;
  color: var(--foreground);
}

.field input[type="email"],
.field input[type="password"],
.field input[type="text"],
.field input[type="number"],
.field input[type="tel"],
.field select,
.input {
  width: 100%;
  height: 38px;
  padding: 0 12px;
  font: inherit;
  font-size: 13px;
  color: var(--foreground);
  background: var(--background);
  border: 1px solid var(--border);
  border-radius: 4px;
  outline: none;
  transition: border-color 0.15s;
}

.field input:focus,
.field select:focus,
.input:focus {
  border-color: var(--primary);
}

/* A field that failed validation carries the error colour on its own border, so
   the eye lands on the control rather than only on the message under it. */
.field--invalid input,
.field--invalid select,
.field--invalid textarea {
  border-color: var(--color-error);
}

.field__error {
  margin: 6px 0 0;
  font-size: 11px;
  color: var(--color-error);
}

.field input::placeholder,
.input::placeholder {
  color: var(--subtle-foreground);
}

.field--adorned input,
.input--adorned {
  padding-right: 44px;
}

.field--inline {
  display: flex;
  align-items: center;
  gap: 10px;
}

.field--inline label {
  margin-bottom: 0;
  font-size: 13.5px;
}

.field--inline input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--primary);
}

/* Frame 04 draws the period control as three standalone chips, not as options inside a
   bordered well: the rule under the row is what groups them. The chosen one goes to ink, so
   the accent variant the old design needed no longer has a caller. */
.segmented {
  display: inline-flex;
  gap: 4px;
}

.segmented__option {
  padding: 11px 20px;
  font: inherit;
  font-size: 13px;
  color: var(--subtle-foreground);
  text-decoration: none;
  white-space: nowrap;
  background: transparent;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}

.segmented__option:hover {
  color: var(--foreground);
  background: var(--card);
}

.segmented__option[aria-pressed="true"],
.segmented__option[aria-current="true"] {
  color: var(--card-raised);
  background: var(--foreground);
}

/* Frames 05 and 06 both draw the search as a line, not a box: a glyph and a placeholder sitting
   on the rule that already separates the filter row from the list. */
.search {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.search__icon {
  flex: 0 0 15px;
  width: 15px;
  height: 15px;
  color: var(--subtle-foreground);
  pointer-events: none;
}

.search__input {
  flex: 1;
  min-width: 0;
  padding: 0;
  font-size: 13px;
  color: var(--foreground);
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.search__input::placeholder {
  color: var(--subtle-foreground);
}

.search__input:focus {
  outline: 0;
}

.search__input:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}

.pill-group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
}

.meter {
  height: 4px;
  overflow: hidden;
  background: var(--border);
  border-radius: 4px;
}

.meter__fill {
  height: 100%;
  border-radius: 4px;
  background: var(--color-success);
  transition: width 0.5s;
}

.meter__fill--warn {
  background: var(--color-warning);
}

.meter__fill--bad {
  background: var(--color-error);
}

@media (prefers-reduced-motion: reduce) {
  .meter__fill {
    transition: none;
  }
}

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  font-size: 11px;
  font-weight: 700;
  color: var(--background);
  background: var(--primary);
  border-radius: 50%;
  flex-shrink: 0;
}

.avatar--sm {
  width: 26px;
  height: 26px;
  font-size: 11px;
}

.avatar--lg {
  width: 32px;
  height: 32px;
}

.avatar--person {
  width: 52px;
  height: 52px;
  font-size: 16px;
  font-weight: 500;
  color: #435c87;
  background: #dde6fa;
}

/* Frame 10's profile avatar. */
.avatar--profile {
  width: 76px;
  height: 76px;
  font-size: 26px;
  font-weight: 500;
  color: var(--foreground);
  background: #dce6ff;
  letter-spacing: -0.02em;
}






/* ─── THE SIGNED-OUT SURFACE ─────────────────────────────────────────────── */

.auth {
  display: flex;
  min-height: 100vh;
  margin: 0;
  background: var(--background);
}

/* 530 of the design's 1272, not a half. The form column is centred in what is
   left, so a panel 53px too wide moves every field on the door with it. The
   design draws nothing behind this panel — no grid, no arcs — so the fill is
   the whole of it. */
.auth__brand-panel {
  display: none;
  position: relative;
  width: 41.67%;
  flex-direction: column;
  padding: 38px 40px 30px;
  overflow: hidden;
  background: var(--sidebar);
}

.auth__brand-content {
  display: flex;
  position: relative;
  z-index: 1;
  flex: 1;
  flex-direction: column;
}

/* The design hangs the mark on the panel's left edge, not down its middle, and
   the lockup is only as wide as itself. */
.auth__brand-content > .brand {
  align-self: flex-start;
}

.auth__pitch {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  gap: 32px;
}

.auth__headline-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.auth__headline {
  margin: 0;
  font-size: 46px;
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -1.7px;
  color: #f5f4f0;
}

.auth__headline--accent {
  color: var(--sidebar-accent);
}

/* The panel's own padding is the measure here — the design runs the blurb the
   full width of the content column rather than holding it short. */
.auth__blurb {
  margin: 0;
  font-size: 15px;
  line-height: 1.7;
  color: #bfc9d8;
}

/* The design rules the benefits off from the blurb above them. #445168 and
   #2c374b are the panel's own two steps up from the slate and have no token. */
.auth__features {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin: 0;
  padding: 28px 0 0;
  border-top: 1px solid #445168;
  list-style: none;
}

.auth__feature {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.auth__feature-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  color: var(--sidebar-accent);
  background: #2c374b;
  border: 1px solid #445168;
  border-radius: var(--radius);
}

.auth__feature-icon svg {
  width: 16px;
  height: 16px;
}

.auth__feature-title {
  display: block;
  margin-bottom: 6px;
  font-size: 14px;
  font-weight: 500;
  color: #f5f4f0;
}

.auth__feature-body {
  display: block;
  font-size: 13px;
  line-height: 1.6;
  color: var(--sidebar-muted-foreground);
}

.auth__legal {
  display: flex;
  gap: 14px;
  margin: 0;
  font-size: 11px;
  color: var(--sidebar-muted-foreground);
}

.auth__legal-link {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.auth__form-panel {
  display: flex;
  position: relative;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 38px 24px 30px;
}

.auth__locale {
  display: flex;
  position: absolute;
  top: 38px;
  right: 24px;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 7px 12px;
  font-size: 12px;
  color: var(--muted-foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.auth__locale-icon {
  width: 13px;
  height: 13px;
}

.auth__form {
  width: 100%;
  max-width: 404px;
}

.auth__compact-brand {
  margin-bottom: 40px;
}

.auth__heading {
  margin-bottom: 28px;
}

.auth__heading h1 {
  margin: 0 0 14px;
  font-size: 32px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -1.2px;
  color: var(--foreground);
}

.auth__heading p {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted-foreground);
}

.auth__fields {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.auth__fields .field {
  margin-bottom: 0;
}

/* Frame 07 labels the door's fields in mono caps at 10px, which is not how
   frame 15 labels a form — the two treatments are both current, so this one
   stays scoped to the signed-out surface rather than moving into `.field`.
   The design asks for 500 and IBM Plex Mono ships 400 and 600 only, so the
   browser resolves this to 400 until a 500 subset exists. */
.auth__fields .field label {
  margin-bottom: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.088em;
  text-transform: uppercase;
  color: var(--foreground);
}

/* The label row cancels that margin itself, but it does so in one class and
   the rule above carries two — so it has to be restated here or the label
   sits above the centre line of the link beside it. */
.auth__fields .field__label-row label {
  margin-bottom: 0;
}

/* The door's inputs are taller than the dashboard's and sit on a lighter fill
   with a darker edge. `#bfc8d7` has no token: it is one step darker than
   --border and exists only here. */
.auth__fields .field input {
  height: 52px;
  padding: 0 16px;
  font-size: 14px;
  background: var(--card);
  border-color: #bfc8d7;
}

/* Everything below restates a primitive the rule above outranks: two classes
   beat one, so the adorned gutter, the focus ring and the invalid edge would
   all lose to it silently. */
.auth__fields .field--adorned input {
  padding-right: 44px;
}

.auth__fields .field input:focus {
  border-color: var(--primary);
}

.auth__fields .field--invalid input {
  border-color: var(--color-error);
}

.auth__fields .field input::placeholder {
  color: var(--muted-foreground);
}

.auth__submit {
  justify-content: space-between;
  width: 100%;
  height: 52px;
  padding: 0 18px;
  font-size: 14px;
  font-weight: 600;
}

/* The same button with nothing beside it: frame 20's dead-link screen offers one way out. */
.auth__submit--solo {
  justify-content: center;
}

/* Frame 20 writes the reason a link failed in the error colour, not as a field error. */
.auth__heading p.auth__refusal {
  color: var(--color-error);
}

.auth__submit-icon {
  width: 16px;
  height: 16px;
}

.auth__link {
  font-size: 12px;
  color: var(--primary);
  text-decoration: none;
}

.auth__link:hover {
  text-decoration: underline;
}

.auth__links {
  display: flex;
  gap: 16px;
  margin-top: 24px;
}

.auth__errors {
  padding: 12px 14px;
  color: var(--color-error);
  background: var(--color-error-tint);
  border: 1px solid var(--color-error-edge);
  border-radius: var(--radius);
}

.auth__errors-title {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
}

.auth__errors ul {
  margin: 6px 0 0;
  padding-left: 1.1rem;
  font-size: 13px;
}

.auth__version {
  margin: 28px 0 0;
  font-size: 11.5px;
  text-align: center;
  color: var(--muted-foreground);
}

/* A wrong password never reaches the model, so it arrives as Devise's flash and
   not as `.auth__errors`. The inherited `.flash` is a full-bleed band, which
   inside a 404px column reads as a rendering fault; frame 20 draws an auth
   failure as a plain red line, so that is what this surface gets. */
.auth .flash {
  margin: 0 0 20px;
  padding: 0;
  font-size: 14px;
  background: none;
  border: 0;
}

/* Frame 17's confirmation screen says what happened in plain 14px --muted-foreground,
   so a notice on this surface reads as copy rather than as a banner. Without
   this it inherits --foreground and is indistinguishable from the heading beneath. */
.auth .flash--notice {
  color: var(--muted-foreground);
}

.field__control {
  position: relative;
}

.field__label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}

.field__label-row label {
  margin-bottom: 0;
}

.field__icon {
  position: absolute;
  top: 50%;
  right: 14px;
  width: 16px;
  height: 16px;
  transform: translateY(-50%);
  color: var(--subtle-foreground);
  pointer-events: none;
}

.field__adornment {
  display: flex;
  position: absolute;
  top: 50%;
  right: 12px;
  align-items: center;
  justify-content: center;
  padding: 4px;
  transform: translateY(-50%);
  color: var(--subtle-foreground);
  background: none;
  border: 0;
  cursor: pointer;
}

.field__adornment:hover {
  color: var(--muted-foreground);
}

.field__adornment svg {
  width: 16px;
  height: 16px;
}

.field__required {
  margin-left: 3px;
  color: var(--primary);
}

.field__label {
  display: block;
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 500;
  color: var(--muted-foreground);
}

.field--caps .field__label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.field__readonly {
  margin: 0;
  padding: 13px 0 0;
  font-size: 14px;
  color: var(--foreground);
}

.strength {
  margin-top: 8px;
}

.strength__bars {
  display: flex;
  gap: 4px;
  margin-bottom: 4px;
}

.strength__bar {
  flex: 1;
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  transition: background 0.2s;
}

.strength__label {
  font-size: 11.5px;
  font-weight: 500;
  color: currentcolor;
}

.strength[data-score="1"] {
  color: var(--color-error);
}

.strength[data-score="2"] {
  color: var(--color-warning);
}

.strength[data-score="3"] {
  color: var(--color-warning);
}

.strength[data-score="4"] {
  color: var(--color-success);
}

.strength__bar--on {
  background: currentcolor;
}

@media (prefers-reduced-motion: reduce) {
  .strength__bar {
    transition: none;
  }
}

.checkbox {
  display: flex;
  position: relative;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

.checkbox__input {
  position: absolute;
  width: 18px;
  height: 18px;
  margin: 0;
  opacity: 0;
}

/* Frame 07 draws the box on the input fill with a darker edge than --border,
   one step short of the input's own #bfc8d7. Neither has a token. Unscoped
   because devise/sessions/new is the only caller of .checkbox in the app. */
.checkbox__box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--background);
  background: var(--card);
  border: 1.5px solid #afbdd2;
  border-radius: 3px;
  transition: background 0.15s, border-color 0.15s;
}

.checkbox__box svg {
  width: 10px;
  height: 10px;
  opacity: 0;
}

.checkbox__input:checked + .checkbox__box {
  background: var(--primary);
  border-color: var(--primary);
}

.checkbox__input:checked + .checkbox__box svg {
  opacity: 1;
}

.checkbox__input:focus-visible + .checkbox__box {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.checkbox__label {
  font-size: 13.5px;
  color: var(--muted-foreground);
}

@media (min-width: 900px) {
  .auth__brand-panel {
    display: flex;
  }

  .auth__compact-brand {
    display: none;
  }

  .auth__form-panel {
    padding-inline: 54px;
  }

  .auth__locale {
    right: 54px;
  }
}

/* ─── THE MANAGER SHELL ──────────────────────────────────────────── */

.shell {
  display: flex;
  height: 100vh;
  margin: 0;
  overflow: hidden;
  background: var(--background);
}

.shell__main {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  background: var(--background);
}

.shell__scroll {
  display: flex;
  flex: 1;
  flex-direction: column;
  overflow-y: auto;
}

.shell__content {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 28px;
  padding: 26px 36px 24px;
}

/* Where the topbar used to be. 14px tall, scrolls with the content, and is the
   reason the lateral bar is now the only thing fixed to the frame (§3.3). */
.workspace-context {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.workspace-context__trail {
  display: flex;
  gap: 10px;
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--muted-foreground);
  text-transform: uppercase;
}

.workspace-context__link {
  font-size: 11px;
  color: var(--muted-foreground);
  text-decoration: none;
}

.workspace-context__link:hover {
  color: var(--foreground);
}

/* The lateral bar, at RIVO.pen's measurements. It does not collapse (KEV-234).
   The gradient is the landing's signature, moved onto the bar: a radial blue
   behind the mark that is gone by the time the menu starts. It is painted as a
   background rather than a node, so there is nothing new to read or tab past —
   460×400 at (-190, -170) in the design, which is a 230×200 ellipse centred
   just off the bar's top-left corner. The blue is --primary at 28%; a bare
   token cannot carry the alpha. */
.sidebar {
  display: flex;
  flex-direction: column;
  width: 224px;
  padding: 26px 14px 18px;
  flex-shrink: 0;
  overflow: hidden;
  background: radial-gradient(230px 200px at 40px 30px, rgb(49 92 235 / 28%), rgb(49 92 235 / 0%))
    var(--sidebar);
}

/* The mark sits on the menu's own left margin now, not down the bar's middle:
   one line, read against the glow behind it (frames 02 and 04). */
.sidebar__brand {
  display: flex;
  flex-shrink: 0;
  padding: 0 10px;
  margin-bottom: 24px;
}

.sidebar__brand-link {
  display: block;
  text-decoration: none;
}

/* Two pixels under the landing's lockup, so a 224px bar holds RIVO on one line
   with the menu's margins rather than its own. */
.sidebar__brand .brand__tile {
  width: 30px;
  height: 30px;
}

.sidebar__brand .brand__glyph {
  width: 17px;
  height: 17px;
}

.sidebar__brand .brand__name {
  font-size: 20px;
  letter-spacing: 0.1em;
}

.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

.sidebar__item {
  display: flex;
  align-items: center;
  gap: 11px;
  height: 38px;
  padding: 0 10px;
  font-size: 13px;
  color: var(--sidebar-foreground);
  text-decoration: none;
  white-space: nowrap;
  background: transparent;
  border-radius: var(--radius);
  transition: color 0.12s, background 0.12s;
}

.sidebar__item .sidebar__icon {
  color: var(--sidebar-muted-foreground);
}

.sidebar__item:hover {
  color: #ffffff;
  background: rgb(175 186 203 / 8%);
}

/* The current section used to be a block of pale blue. The design raises it the
   way the landing raises a control instead — white at 8% behind an edge at 18% —
   and the edge is `inset` rather than a border so the row keeps its 38px and the
   label does not shift a pixel when it becomes current. */
.sidebar__item--active,
.sidebar__item--active:hover {
  font-weight: 500;
  color: var(--sidebar-strong-foreground);
  background: var(--sidebar-raised);
  box-shadow: inset 0 0 0 1px var(--sidebar-raised-edge);
}

.sidebar__item--active .sidebar__icon {
  color: var(--sidebar-strong-foreground);
}

.sidebar__item--soon,
.sidebar__item--soon:hover {
  color: var(--sidebar-muted-foreground);
  background: transparent;
  cursor: default;
}

.sidebar__icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.sidebar__label {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Pushes the account to the foot of the bar. */
.sidebar__spacer {
  flex: 1;
}

/* The scope used to close the bar at its foot. Frame 04 chose it, out of five
   candidates, as what separates the mark from the menu: the air alone read as
   pegged, and a rule the full width of the bar cut the glow in half. The line
   under it is the one the account already had. */
.sidebar__scope {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 10px 18px;
  margin-bottom: 14px;
  font-size: 12px;
  color: var(--sidebar-foreground);
  border-bottom: 1px solid var(--sidebar-border);
}

/* The one mono label left in the chrome, now that the mark carries no
   descriptor — it reads as a machine label over a count, which is the point. */
.sidebar__scope-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--sidebar-muted-foreground);
  text-transform: uppercase;
}

/* A hairline, the account over it and the exit under that: the same close the
   design gives the bar, on the menu's own left margin. */
.sidebar__foot {
  display: flex;
  flex-direction: column;
  padding-top: 16px;
  border-top: 1px solid var(--sidebar-border);
}

.sidebar__account {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 10px 10px;
  overflow: hidden;
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius);
  transition: background 0.12s;
}

/* The bar's avatar is raised off the slate the way the current section is —
   translucent white behind an edge — rather than painted a solid step lighter. */
.sidebar__account .avatar {
  width: 32px;
  height: 32px;
  font-size: 11px;
  font-weight: 500;
  color: var(--sidebar-strong-foreground);
  background: var(--sidebar-raised);
  box-shadow: inset 0 0 0 1px var(--sidebar-raised-edge);
}

.sidebar__account:hover {
  background: rgb(175 186 203 / 12%);
}

.sidebar__account-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.sidebar__account-name {
  overflow: hidden;
  font-size: 13px;
  font-weight: 500;
  color: var(--sidebar-strong-foreground);
  text-overflow: ellipsis;
}

.sidebar__account-role {
  font-size: 11px;
  color: var(--sidebar-muted-foreground);
}

/* KEV-276 held sign-out here against a design that drew none. RIVO.pen has since
   come to draw it, and it draws it as the quietest row in the bar — no chip, no
   background, and no destructive treatment: ending a session is not deleting
   anything, so the row hovers into the slate ramp rather than red (KEV-300). */
.sidebar__action {
  display: flex;
  align-items: center;
  gap: 11px;
  height: 34px;
  padding: 0 10px;
  font-family: inherit;
  font-size: 12px;
  color: var(--sidebar-muted-foreground);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  background: transparent;
  border: 0;
  border-radius: var(--radius);
  transition: color 0.12s;
}

/* The bar's nav icons are 16px; the design draws this one a pixel smaller. */
.sidebar__action .sidebar__icon {
  width: 15px;
  height: 15px;
}

.sidebar__action:hover {
  color: var(--sidebar-foreground);
}

.sidebar__signout {
  margin: 0;
}

/* The mark is the design's "plaza" direction: a square blue mass with the
   connector tip inside it. There is one lockup now, the landing's — symbol
   beside wordmark, on one line, with no descriptor under it — and the app draws
   it on the lateral bar, both marks on the door and the resident's header. The
   stacked lockup and the two descriptors it carried went with the redesign: one
   product cannot say EV NETWORK on the door and ENERGÍA COMPARTIDA in the bar.

   Inline-flex, so the lockup is only as wide as itself; where it sits is the
   container's call, not the mark's. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.brand__tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  color: var(--background);
  background: var(--primary);
  border-radius: var(--radius);
}

.brand__glyph {
  width: 18px;
  height: 18px;
}

.brand__name {
  font-size: 22px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.09em;
  color: var(--sidebar-strong-foreground);
  white-space: nowrap;
}

/* The compact mark in the narrow auth form is the only one that sits on the
   page surface rather than on the slate chrome. The symbol does not change —
   the design draws one — but the type has to. */
.brand--on-light .brand__name {
  color: var(--foreground);
}

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  height: 60px;
  padding: 0 28px;
  flex-shrink: 0;
  background: var(--sidebar);
  border-bottom: 1px solid var(--sidebar-border);
}

.topbar__title {
  flex: 1;
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--sidebar-foreground);
}

.topbar__account {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 6px;
  color: inherit;
  text-decoration: none;
  border: 1px solid var(--sidebar-border);
  border-radius: var(--radius);
  transition: border-color 0.15s;
}

.topbar__account:hover,
.topbar__account[aria-current="page"] {
  border-color: var(--primary);
}

.topbar__account[aria-current="page"] .topbar__account-role {
  color: var(--primary);
}

.topbar__account-text {
  display: flex;
  flex-direction: column;
}

.topbar__account-name {
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--sidebar-foreground);
}

.topbar__account-role {
  font-size: 11px;
  color: var(--sidebar-muted-foreground);
}

@media (max-width: 900px) {
  .sidebar {
    width: 64px;
  }

  /* Scoped to the bar. Unscoped this also reached the auth panel's compact
     mark, which is the only mark on the page below 900px — the door showed a
     blue square and no wordmark. The scope line goes too: a mono label over a
     count has nothing to say in 36px, and it is the one row that would be
     clipped rather than hidden. */
  .sidebar__label,
  .sidebar__account-text,
  .sidebar__scope,
  .sidebar .brand__name {
    display: none;
  }

  /* 14 of bar padding plus the row's own 10 puts a 16px icon dead centre of a
     64px rail, so the rows keep the margin they have at full width. */
  .sidebar__brand {
    justify-content: center;
    padding-inline: 0;
  }

  .shell__content {
    padding: 20px 16px 0;
  }

  .shell__scroll > .site-footer {
    margin-top: 24px;
    padding: 14px 16px 20px;
  }

  .topbar {
    padding: 0 16px;
  }
}

/* ─── THE RESIDENT SHELL ─────────────────────────────────────────────────── */

.resident-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  margin: 0;
  overflow: hidden;
  background: var(--background);
}

.resident-shell__scroll {
  display: flex;
  flex: 1;
  flex-direction: column;
  overflow-y: auto;
}

.resident-shell__content {
  flex: 1;
  padding: 28px 32px 0;
}

.resident-topbar {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 80px;
  padding: 0 40px;
  flex-shrink: 0;
  background: var(--sidebar);
}

.resident-topbar__avatar {
  width: 38px;
  height: 38px;
  color: #e8edf5;
  background: #40506b;
}

.resident-topbar__screen {
  flex: 1;
  margin: 0;
  font-size: 14px;
  color: var(--sidebar-foreground);
}

.resident-topbar__brand {
  text-decoration: none;
}

/* The design ends the bar with one right-aligned identity block — the resident's
   name over `Ver perfil · Cerrar sesión` — and the avatar to its right. Both are
   words in a line, not controls: sign-out used to be `.button--danger`, whose
   `--muted-foreground` label and `--border` outline are light-surface values that read as a
   bright box around grey text once they land on the slate bar (KEV-300). */
.resident-topbar__identity {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  min-width: 0;
}

.resident-topbar__name {
  font-size: 13px;
  color: var(--sidebar-foreground);
}

.resident-topbar__links {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
}

.resident-topbar__link {
  padding: 0;
  font: inherit;
  color: var(--sidebar-foreground);
  text-decoration: none;
  cursor: pointer;
  background: transparent;
  border: 0;
  transition: color 0.12s;
}

.resident-topbar__link:hover {
  color: #ffffff;
  text-decoration: underline;
}

/* --primary is unreadable on the slate panel; the bar's own accent is the on-dark
   value of the same role. */
.resident-topbar__link[aria-current="page"] {
  color: var(--sidebar-accent);
}

.resident-topbar__link-sep {
  color: var(--sidebar-muted-foreground);
}

.resident-topbar__signout-form {
  display: inline-flex;
  margin: 0;
}

@media (max-width: 700px) {
  .resident-shell__content {
    padding: 20px 16px 0;
  }

  .resident-shell__scroll > .site-footer {
    margin-top: 24px;
    padding: 14px 16px 20px;
  }

  .resident-topbar {
    padding: 0 16px;
  }

  .resident-topbar__name {
    display: none;
  }
}

/* ─── THE PAGE FOOTER ────────────────────────────────────────────────────── */

.site-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
  flex-wrap: wrap;
  margin-top: 32px;
  padding: 16px 32px 24px;
  border-top: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--subtle-foreground);
}

.site-footer__legal {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0;
}

.site-footer__version {
  margin: 0;
}

/* ─── THE RESIDENT'S OWN PAGE (frame 09) ────────────────────────────────── */

/* Frame 09 uses rules where the manager surface does, not cards. The one card left on the screen
   is the unattached variant, which is a state rather than a section. */

.resident {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.resident__identity {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.resident__who {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.resident__eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted-foreground);
}

.resident__name {
  margin: 0;
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.025em;
  color: var(--foreground);
}

.resident__email {
  margin: 0;
  font-size: 13px;
  color: var(--muted-foreground);
}

.resident__stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

.figure {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 0 18px;
  border-bottom: 1px solid var(--border);
}

.figure__label {
  font-size: 12px;
  color: var(--muted-foreground);
}

.figure__value {
  font-size: 24px;
  font-weight: 500;
  line-height: 1.1;
  color: var(--foreground);
}

.figure__detail {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted-foreground);
}

.resident__panels {
  display: flex;
  align-items: stretch;
  gap: 20px;
}

.panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px 0 20px;
  border-bottom: 1px solid var(--border);
}

.panel--wide {
  flex: 1;
  min-width: 0;
}

.panel--side {
  flex: 0 0 432px;
}

.panel__title {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
  color: var(--foreground);
}

.panel__lead,
.panel__note {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

.panel__link {
  margin-top: auto;
  padding-top: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--foreground);
  text-decoration: none;
}

/* A bay this resident holds the deed to, and whatever stands on it. */
.deed {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 8px 0;
  border-top: 1px solid var(--border);
}

.deed__bay {
  font-size: 13px;
  font-weight: 500;
  color: var(--foreground);
}

.deed__charger {
  font-size: 12px;
  color: var(--muted-foreground);
}

.deed__link {
  color: inherit;
  text-decoration: none;
}

.deed__link:hover {
  color: var(--foreground);
}

/* The monthly bars: the figure above, the bar, the month under it. The current month is the one
   in the primary colour, which is the only colour on the panel. */
.chart {
  display: flex;
  align-items: flex-end;
  gap: 22px;
  height: 142px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chart__column {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  height: 100%;
  min-width: 0;
}

.chart__amount {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted-foreground);
}

.chart__bar {
  width: 100%;
  min-height: 2px;
  background: #dce6ff;
  border-radius: 4px 4px 0 0;
}

.chart__bar--current {
  background: var(--primary);
}

.chart__label {
  font-size: 11px;
  color: var(--muted-foreground);
}

/* The history: the same rule-separated ledger the manager's register uses, at the resident's
   smaller scale. */
.resident__history .page-header {
  margin-bottom: 4px;
}

.resident__history .page-header h2 {
  font-size: 18px;
}

.ledger th:first-child,
.ledger td:first-child {
  padding-left: 0;
}

.ledger th:last-child,
.ledger td:last-child {
  padding-right: 0;
}

.ledger thead th {
  height: 38px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

/* The padding is the frame's own (14px), and it is what keeps the `Tarifa` cell's three stacked
   lines from crushing the single-line cells beside them: the row's `height` below acts as a floor
   rather than a ceiling, so a tall cell grows its row (KEV-356). */
.ledger td,
.ledger tbody th {
  padding-block: 14px;
  font-size: 12px;
  color: var(--foreground);
  vertical-align: middle;
}

.ledger tbody tr {
  height: 38px;
  border-bottom: 1px solid var(--border);
}

.ledger tbody tr:hover {
  background: transparent;
}

/* Frame 09's date, duration and energy columns are monospaced; the names beside them are not. */
.ledger tbody th,
.ledger td:nth-child(5),
.ledger td:nth-child(6),
.ledger thead th:first-child,
.ledger thead th:nth-child(5),
.ledger thead th:nth-child(6) {
  font-family: var(--font-mono);
}

/* `Importe` is column 8 on both frames — 09 ends there and 13 carries `Cómo terminó` after it —
   which is what lets one rule serve two tables of different widths. It is a figure read by running
   an eye down the column, so it is monospaced and sits against the column's right edge. */
.ledger td:nth-child(8),
.ledger thead th:nth-child(8) {
  font-family: var(--font-mono);
  text-align: right;
}

/* Frame 14 reads at the resident's pace too: taller socket rows than the manager's supply cards,
   and a title one step down from a manager screen's. */
.sockets--roomy thead th,
.sockets--roomy tbody tr {
  height: 64px;
}

.sockets--roomy td,
.sockets--roomy tbody th {
  font-size: 13px;
}

.resident__title {
  margin: 0;
  font-size: 30px;
  font-weight: 500;
  letter-spacing: -0.027em;
  color: var(--foreground);
}

/* Frame 13's ledger is the same object at reading pace: taller rows, and the day stacked over
   the clock so the column stays narrow. */
.ledger--roomy thead th {
  height: 50px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.ledger--roomy tbody tr {
  height: 70px;
}

.ledger--roomy td,
.ledger--roomy tbody th {
  padding-block: 16px;
}

.ledger__day,
.ledger__clock {
  display: block;
  line-height: 1.5;
}

/* The `Tarifa` cell of frames 09 and 13: the bar is the charge read left to right as it ran, the
   lines under it are the arithmetic somebody checks a figure against, and the caption says which
   day the charge was billed under (KEV-356). */
.tariff-bands {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tariff-bands__bar {
  display: flex;
  gap: 2px;
  height: 6px;
}

/* No width of its own: the view sets each band's share inline, which is this repo's one way of
   expressing a server-computed proportion (`.chart__bar`). The minimum is so a band holding one
   per cent of the charge still draws something its dot can point at, rather than a sliver
   narrower than the gap beside it. */
.tariff-bands__segment {
  min-width: 4px;
  border-radius: 2px;
}

.tariff-bands__band {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: 12px;
  color: var(--foreground);
  white-space: nowrap;
}

/* `.pill__dot`'s shape without `.pill__dot`: this is not a pill, and the pill's classes are the
   design system's own — a screen that borrows one has borrowed the component's meaning with it. */
.tariff-bands__dot {
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

/* The surcharge line sits with the band lines and reads like one, indented to where a band's text
   starts so the two columns of figures line up under each other. No dot: it is not a share of the
   bar above, and a dot would claim it was. */
.tariff-bands__surcharge {
  margin: 0;
  padding-left: 13px;
  font-size: 12px;
  color: var(--foreground);
  white-space: nowrap;
}

.tariff-bands__day-type {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  color: var(--muted-foreground);
  text-transform: uppercase;
  white-space: nowrap;
}

.tariff-bands__segment--low,
.tariff-bands__dot--low {
  background: var(--tariff-band-low);
}

.tariff-bands__segment--mid,
.tariff-bands__dot--mid {
  background: var(--tariff-band-mid);
}

.tariff-bands__segment--high,
.tariff-bands__dot--high {
  background: var(--tariff-band-high);
}

.page-back {
  margin: 0;
  font-size: 13px;
  color: var(--muted-foreground);
}

.page-back a {
  color: inherit;
  text-decoration: none;
}

.page-back a::before {
  content: "← ";
}

.page-back a:hover {
  color: var(--foreground);
}

.resident__footnote {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted-foreground);
}

/* An account with no apartment yet: the one card frame 09 draws. */
.unattached {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px;
  background: var(--card);
  border-radius: var(--radius);
}

.unattached__icon {
  flex: 0 0 26px;
  width: 26px;
  height: 26px;
  color: var(--muted-foreground);
}

.unattached__body {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted-foreground);
}

@media (max-width: 900px) {
  .resident__panels {
    flex-direction: column;
  }

  .panel--side {
    flex: 1 1 auto;
  }

  .resident__stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

.profile {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 47.5rem;
}

.profile__title {
  margin: 0 0 18px;
  font-size: 30px;
  font-weight: 500;
  letter-spacing: -0.027em;
  color: var(--foreground);
}

.profile__identity {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px;
}

.profile__identity-name {
  margin: 0;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--foreground);
}

.profile__identity-email {
  margin: 5px 0 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

.profile__identity-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 0;
}

.profile__since {
  font-size: 11px;
  color: var(--muted-foreground);
}

.profile__panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin: 0;
  padding: 24px;
}

.profile__panel .field {
  margin-bottom: 0;
}

.profile__panel .field input {
  background: var(--card-raised);
}

.profile__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 16px;
}

.profile__lead {
  margin: 0;
  font-size: 12.5px;
  color: var(--muted-foreground);
}

.profile__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.profile__actions input[type="submit"] {
  min-width: 178px;
  justify-content: center;
}

.profile__note {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

@media (max-width: 700px) {
  .profile__grid {
    grid-template-columns: 1fr;
  }

  .profile__identity {
    gap: 16px;
    padding: 20px;
  }

  .profile__actions {
    flex-direction: column;
    align-items: flex-start;
  }
}

.stat__value--small {
  font-size: 17px;
}

/* ─── THE MANAGER DASHBOARD ──────────────────────────────────────────────── */

.dash {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.dash__greeting {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}

.dash__eyebrow {
  margin: 0 0 4px;
  font-size: 12.5px;
  color: var(--subtle-foreground);
}

.dash__name {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--foreground);
}

.dash__sub {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--subtle-foreground);
}

/* The readings band. The design gives it a bottom rule and no fill — the stats
   sit on the page rather than in boxes, which is why .stat has no border. */
/* Frame 01's attention band: the warning fill, no border, and it only appears
   when something needs attention. */
.attention {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin: 0;
  padding: 16px 18px;
  font-size: 12px;
  color: var(--color-warning);
  background: var(--color-warning-tint);
  border-radius: 4px;
}

.attention__icon {
  width: 20px;
  height: 20px;
  align-self: center;
  flex-shrink: 0;
}

.attention__message {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}

.attention__body {
  flex: 1;
}

.attention__action {
  font-weight: 600;
  color: inherit;
  white-space: nowrap;
}

.page-header__lead {
  margin: 0;
  font-size: 13px;
  color: var(--subtle-foreground);
}

.dash__stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 22px;
  padding: 6px 0 24px;
  border-bottom: 1px solid var(--border);
}

.dash__grid {
  display: grid;
  grid-template-columns: 310px 1fr;
  gap: 30px;
  align-items: start;
}

/* A panel is a heading and a stack of rows. The rule between rows is the only
   boundary the design draws — there is no card around any of this. */
.dash__panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.dash__panel-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  font-size: 21px;
  font-weight: 500;
  color: var(--foreground);
}

.dash__row {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px 0;
  border-bottom: 1px solid var(--border);
}

.dash__session {
  flex-direction: row;
  align-items: center;
  gap: 16px;
  padding: 16px 0;
}

.dash__session-identity {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.dash__session-station {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--foreground);
}

.dash__session-meta {
  display: flex;
  gap: 6px;
  font-size: 11.5px;
  color: var(--subtle-foreground);
}

.dash__session-figures {
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: right;
}

.dash__session-energy {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--foreground);
}

.dash__session-duration {
  font-size: 11.5px;
  color: var(--subtle-foreground);
}

.dash__buildings {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.dash__building-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.dash__building-name {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--foreground);
}

.dash__building-figures {
  display: flex;
  align-items: center;
  gap: 8px;
}

.dash__building-faults {
  font-size: 11px;
  color: var(--color-warning);
}

.dash__building-percentage {
  font-size: 11.5px;
  font-weight: 600;
}

.dash__building-percentage--ok {
  color: var(--color-success);
}

.dash__building-percentage--warn {
  color: var(--color-warning);
}

.dash__building-percentage--bad {
  color: var(--color-error);
}

.dash__building-sub {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--subtle-foreground);
}

@media (max-width: 1100px) {
  .dash__grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 860px) {
  .dash__stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 520px) {
  .dash__stats {
    grid-template-columns: 1fr;
  }
}

/* ─── THE MANAGER'S INDEX SCREENS ────────────────────────────────────────── */

.listing {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.listing__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}

.listing__title {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--foreground);
}

.listing__sub {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--subtle-foreground);
}

.listing__stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}

.listing__filters {
  flex-wrap: wrap;
  justify-content: flex-start;
}

.listing__table {
  min-width: 980px;
}

.person {
  display: flex;
  align-items: center;
  gap: 10px;
}

.listing__note {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--subtle-foreground);
}

@media (max-width: 860px) {
  .listing__stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 520px) {
  .listing__stats {
    grid-template-columns: 1fr;
  }
}

/* ─── THE MANAGER'S "USUARIOS" SCREEN ───────────────────────────────────── */

/* Frame 06. An entry per person: who they are, then what they can reach, then how the account
   is managed — three rows indented under one avatar. */

.directory {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.directory__intro {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 14px 0 24px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.directory__total {
  margin: 0;
  font-size: 48px;
  line-height: 1;
  letter-spacing: -0.042em;
  color: var(--foreground);
}

.directory__summary {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}

.directory__summary-title {
  margin: 0;
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -0.024em;
  color: var(--foreground);
}

.directory__summary-detail {
  margin: 0;
  font-size: 12px;
  color: var(--subtle-foreground);
}

.directory__scope select {
  font-family: inherit;
  font-size: 12px;
  color: var(--foreground);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.directory__search {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.directory__count {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--subtle-foreground);
}

.directory__entry {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 24px 0;
  border-top: 1px solid var(--border);
}

.directory__identity {
  display: flex;
  align-items: center;
  gap: 18px;
}

.directory__name-block {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.directory__name {
  margin: 0;
  font-size: 25px;
  font-weight: 500;
  letter-spacing: -0.024em;
  color: var(--foreground);
}

.directory__email {
  margin: 0;
  font-size: 12px;
  color: var(--subtle-foreground);
}

.directory__state {
  margin: 0;
  font-size: 11px;
  white-space: nowrap;
  color: #356cb2;
}

.directory__state--inactive {
  color: var(--subtle-foreground);
}

/* Indented to clear the avatar, so the three rows of an entry read as one column. */
.directory__access,
.directory__meta {
  padding-left: 70px;
}

.directory__access {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  margin: 0;
}

.directory__field {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.directory__field dt {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  color: var(--subtle-foreground);
}

.directory__field dd {
  margin: 0;
  font-size: 12px;
  color: var(--foreground);
}

.directory__field--apartment {
  flex: 0 0 190px;
}

.directory__field--sessions {
  flex: 0 0 85px;
}

.directory__field--energy {
  flex: 0 0 110px;
}

.directory__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-size: 11px;
  color: var(--subtle-foreground);
}

.directory__manage {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* An apartment with nobody in it is not an error, so this reads as an invitation rather than a
   warning — the neutral tint, not the amber one Departamentos uses for a missing bay. */
.invitation {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 20px;
  background: #e7ebf3;
}

.invitation__icon {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  color: var(--muted-foreground);
}

.invitation__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.invitation__heading {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--foreground);
}

.invitation__detail {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

.invitation__action {
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--foreground);
  text-decoration: none;
}

@media (max-width: 720px) {
  .directory__intro {
    flex-wrap: wrap;
  }

  .directory__access,
  .directory__meta {
    padding-left: 0;
  }
}

/* ─── THE CHARGER'S OWN PAGE (frame 12) ─────────────────────────────────── */

/* The live status gets a fixed column so the pill and its hint do not move when the CSMS pushes
   a longer word into it. */
.detail__field--live {
  flex: 0 0 220px;
}

.detail__hint {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  font-weight: 400;
  color: var(--subtle-foreground);
}

/* The charge point id, in mono because that is what --font-mono is on this screen for. */
.identifier {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 24px;
  margin: 24px 0 0;
}

.identifier__label {
  flex: 0 0 280px;
  font-size: 13px;
  color: var(--muted-foreground);
}

.identifier__value {
  overflow-wrap: anywhere;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--foreground);
}

/* Frame 12 prints the identifier plainly and warns beside it, rather than hiding it behind a
   reveal. The warning is the control the design chose, so it is always on the page. */
.credential-warning {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 18px;
  padding: 16px 18px;
  color: var(--color-warning);
  background: var(--color-warning-tint);
}

.credential-warning__icon {
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
}

.credential-warning__title {
  flex: 0 0 220px;
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.credential-warning__body {
  flex: 1;
  min-width: 260px;
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
}

/* One card per supply, each holding its own sockets. */
.supply {
  margin-top: 16px;
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.supply .page-header {
  margin-bottom: 12px;
}

.supply h3 {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
  color: var(--foreground);
}

.sockets th:first-child,
.sockets td:first-child {
  padding-left: 0;
}

.sockets th:last-child,
.sockets td:last-child {
  padding-right: 0;
}

.sockets thead th {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.sockets td,
.sockets tbody th {
  padding-top: 8px;
  padding-bottom: 8px;
  font-size: 13px;
  color: var(--muted-foreground);
  vertical-align: middle;
}

.sockets tbody tr {
  height: 40px;
  border-bottom: 1px solid var(--border);
}

.sockets tbody tr:hover {
  background: transparent;
}

/* ─── THE MANAGER'S "FACTURACIÓN" SCREEN (frame 08) ─────────────────────── */

/* A report, not an invoice. The one inverted panel is the month's total, because it is the one
   figure the whole screen exists to produce. */

.billing {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.billing__head {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.billing__eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  color: var(--muted-foreground);
}

.billing__title {
  margin: 0;
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -0.031em;
  color: var(--foreground);
}

.billing__filters {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.billing__filters input,
.billing__filters select {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--foreground);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.billing__summary {
  display: flex;
  align-items: stretch;
  gap: 20px;
}

.billing__total {
  display: flex;
  flex: 0 0 286px;
  flex-direction: column;
  gap: 10px;
  padding: 22px;
  color: var(--background);
  background: var(--sidebar);
  border-radius: var(--radius);
}

.billing__total-label {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
}

.billing__total-amount {
  margin: 0;
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.038em;
}

.billing__total-basis {
  margin: 0;
  font-size: 12px;
}

.billing__buildings {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
  padding: 22px;
  border-bottom: 1px solid var(--border);
}

.billing__buildings-title,
.billing__tariff-title {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
  color: var(--foreground);
}

.billing__building {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0;
}

.billing__building-name {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  color: var(--foreground);
}

.billing__building-energy {
  flex: 0 0 100px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted-foreground);
}

.billing__building-total {
  flex: 0 0 122px;
  font-family: var(--font-mono);
  font-size: 14px;
  text-align: right;
  color: var(--foreground);
}

.billing__tariff {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  border-bottom: 1px solid var(--border);
}

.billing__bands {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.billing__band {
  display: flex;
  flex: 1 1 160px;
  flex-direction: column;
  gap: 6px;
  margin: 0;
}

.billing__band-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--foreground);
}

.billing__band-hours {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted-foreground);
}

.billing__band-price {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--foreground);
}

.billing__apartments {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.billing__apartments-title {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
  color: var(--foreground);
}

.apartment-bills th:first-child,
.apartment-bills td:first-child {
  padding-left: 0;
}

.apartment-bills th:last-child,
.apartment-bills td:last-child {
  padding-right: 0;
  text-align: right;
}

.apartment-bills thead th {
  height: 44px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

.apartment-bills td,
.apartment-bills tbody th {
  padding-top: 0;
  padding-bottom: 0;
  font-size: 12px;
  color: var(--foreground);
  vertical-align: middle;
}

.apartment-bills tbody tr {
  height: 42px;
  border-bottom: 1px solid var(--border);
}

.apartment-bills tbody tr:hover {
  background: transparent;
}

/* Buildings and apartment names identify who is billed. Counts and money remain figures. */
.apartment-bills td:nth-child(3),
.apartment-bills td:nth-child(4),
.apartment-bills td:last-child,
.apartment-bills thead th:nth-child(3),
.apartment-bills thead th:nth-child(4),
.apartment-bills thead th:last-child {
  font-family: var(--font-mono);
}

/* Apartment invoices need room for the property identity, while the figures stay aligned. */
.apartment-bills th:nth-child(1) { width: 32%; }
.apartment-bills th:nth-child(2) { width: 18%; }
.apartment-bills th:nth-child(3) { width: 18%; }
.apartment-bills th:nth-child(4) { width: 16%; }
.apartment-bills th:nth-child(5) { width: 16%; }

.billing__note {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

@media (max-width: 860px) {
  .billing__summary {
    flex-direction: column;
  }

  .billing__total {
    flex: 1 1 auto;
  }
}

/* ─── THE MANAGER'S "TARIFAS" SCREEN (frame 19) ─────────────────────────── */

.tariffs {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.tariffs__scope select {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--foreground);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.tariffs__standing {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.tariffs__standing-title {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
  color: var(--foreground);
}

.tariffs__standing-since {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--foreground);
}

/* One table per day type, stacked. Each is a whole day on its own, so they are spaced further
   apart than the rows inside them are. */
.tariffs__schedules {
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.tariffs__schedule {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tariffs__schedule-title {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--foreground);
}

/* The bands table: hours and prices are figures, so they are monospaced and line up under each
   other; the band's own name is not, and frame 19 sets it in the muted ink at normal weight so the
   numbers are what the eye lands on. */
.schedule tbody th {
  font-weight: 400;
  color: var(--muted-foreground);
}

.schedule th:first-child,
.schedule td:first-child {
  padding-left: 0;
}

.schedule th:last-child,
.schedule td:last-child {
  padding-right: 0;
}

.schedule thead th {
  height: 46px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.schedule td,
.schedule tbody th {
  padding-top: 0;
  padding-bottom: 0;
  font-size: 13px;
  color: var(--foreground);
  vertical-align: middle;
}

.schedule tbody tr {
  height: 46px;
  border-bottom: 1px solid var(--border);
}

.schedule tbody tr:hover {
  background: transparent;
}

/* A `td` that is itself a flex container ignores `vertical-align`, so the row's own height is what
   centres its actions. */
.schedule td.table__actions {
  height: 46px;
  align-items: center;
  justify-content: flex-end;
}

.schedule td:nth-child(2),
.schedule td:nth-child(3) {
  font-family: var(--font-mono);
}

.tariffs__footnote {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted-foreground);
}

/* Frame 19's last row: the band editor and the version scheduler, side by side. The editor is the
   fixed one at 576px and the scheduler takes what is left, so the pair keeps its proportions as
   the window widens. */
.tariffs__editing {
  display: flex;
  gap: 24px;
  align-items: flex-start;
}

.tariffs__editor {
  flex: 0 0 576px;
}

.tariffs__version {
  flex: 1;
  min-width: 0;
}

.tariffs__editor-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.tariffs__editor-note {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

@media (max-width: 1100px) {
  .tariffs__editing {
    flex-direction: column;
  }

  .tariffs__editor {
    flex: 1 1 auto;
    width: 100%;
  }
}

/* The first tariff, the band editor and the version scheduler are the three forms on this screen,
   and the design gives all three the same card. */
.tariffs__first,
.tariffs__editor,
.tariffs__version {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.tariffs__first-title,
.tariffs__editor-title,
.tariffs__surcharge-title,
.tariffs__version-title {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
  color: var(--foreground);
}

.tariffs__first-lead,
.tariffs__surcharge-lead,
.tariffs__version-lead {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted-foreground);
}

.tariffs__surcharge-note,
.tariffs__version-note {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

/* The same card the version scheduler is, on its own row above the pair: it belongs with the
   prices rather than with the editing, and there is no second card to sit beside it. */
.tariffs__surcharge {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.tariffs__form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-start;
}

.tariffs__form input[type="submit"] {
  min-width: 178px;
  justify-content: center;
}

.tariffs__row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-self: stretch;
}

/* Frame 19 draws Nombre, Desde and Hasta as three equal fields on one line inside a 576px card,
   so the basis has to be small enough that three of them plus two 16px gaps still fit. */
.tariffs__row .field {
  flex: 1 1 0;
  min-width: 0;
}

.tariffs__band-title {
  margin: 0 0 18px;
  font-size: 30px;
  font-weight: 500;
  letter-spacing: -0.027em;
  color: var(--foreground);
}

.tariffs__prices-eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  color: var(--muted-foreground);
}

.tariffs__band-note {
  margin: 0;
  font-size: 11px;
  color: var(--muted-foreground);
}

/* ─── THE MANAGER'S "DEPARTAMENTOS" SCREEN ──────────────────────────────── */

/* Frame 05. One block per apartment under a building heading, separated by rules. The number
   plate inverts when somebody lives there, which is the fastest read on the screen. */

.apartments {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.apartments__filters {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 15px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.apartments__scope select {
  font-family: inherit;
  font-size: 12px;
  color: var(--foreground);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.apartments__group {
  display: flex;
  flex-direction: column;
}

.apartments__group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 4px;
}

.apartments__group-name {
  margin: 0;
  font-size: 23px;
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--foreground);
}

.apartments__group-counts {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  color: var(--subtle-foreground);
}

.apartments__unit {
  display: flex;
  gap: 24px;
  padding: 24px 0;
  border-top: 1px solid var(--border);
}

.apartments__plate {
  display: flex;
  flex: 0 0 102px;
  flex-direction: column;
  gap: 15px;
  align-self: flex-start;
  height: 124px;
  margin: 0;
  padding: 16px;
  background: #e6eaf1;
}

.apartments__plate-type {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  color: var(--subtle-foreground);
}

.apartments__plate-number {
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.038em;
  color: var(--foreground);
}

.apartments__plate--occupied {
  background: var(--foreground);
}

.apartments__plate--occupied .apartments__plate-type {
  color: #aebee0;
}

.apartments__plate--occupied .apartments__plate-number {
  color: var(--background);
}

.apartments__detail {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.apartments__title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.apartments__residents {
  margin: 0;
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.016em;
  color: var(--foreground);
}

.apartments__state {
  margin: 0;
  font-size: 11px;
  white-space: nowrap;
  color: #356cb2;
}

.apartments__state--inactive {
  color: var(--subtle-foreground);
}

.apartments__assignment {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

.apartments__assignment--pending {
  color: var(--color-warning);
}

.apartments__usage {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 6px 0;
}

.apartments__figure {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
}

.apartments__figure-label {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  color: var(--subtle-foreground);
}

.apartments__figure-value {
  font-size: 20px;
  color: var(--foreground);
}

.apartments__action {
  margin-left: auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--foreground);
  text-decoration: none;
}

.apartments__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-size: 11px;
  color: var(--subtle-foreground);
}

.apartments__manage {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* The apartments that cannot charge yet, and the one link that takes the manager to them. */
.pending {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  color: var(--color-warning);
  background: var(--color-warning-tint);
}

.pending__icon {
  flex: 0 0 21px;
  width: 21px;
  height: 21px;
}

.pending__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.pending__title {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
}

.pending__note {
  margin: 0;
  font-size: 12px;
}

.pending__action {
  font-size: 12px;
  font-weight: 600;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .apartments__unit {
    flex-direction: column;
  }

  .apartments__filters {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
}

/* ─── THE MANAGER'S "SESIONES" SCREEN ───────────────────────────────────── */

/* Frame 04. The screen is four stacked bands separated by rules — filters, the period's
   summary, the register, and the running session beside it — with no card anywhere. */

.sessions {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.sessions__filters {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border);
}

.sessions__building select {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--foreground);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.sessions__summary {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  padding: 12px 0 24px;
  border-bottom: 1px solid var(--border);
}

.sessions__record {
  display: flex;
  align-items: flex-start;
  gap: 32px;
  padding-top: 8px;
}

.sessions__period {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.sessions__eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--subtle-foreground);
}

.sessions__headline {
  margin: 0;
  font-size: 35px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--foreground);
}

.sessions__explanation {
  margin: 0;
  max-width: 62ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted-foreground);
}

.sessions__widen {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* The register's own scale: smaller than the shared table, and with the first column flush
   left so the rule under each row starts where the text does. */
.sessions__table th:first-child,
.sessions__table td:first-child {
  padding-left: 0;
}

.sessions__table th:last-child,
.sessions__table td:last-child {
  padding-right: 0;
}

.sessions__table thead th {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.08em;
}

.sessions__table td,
.sessions__table th {
  padding-top: 0;
  padding-bottom: 0;
  font-size: 11px;
  color: var(--foreground);
  vertical-align: middle;
}

.sessions__table tbody tr {
  height: 52px;
  border-bottom: 1px solid var(--border);
}

.sessions__table tbody tr:last-child {
  border-bottom: 1px solid var(--border);
}

.sessions__table tbody tr:hover {
  background: transparent;
}

/* A `td` that is itself a flex container ignores `vertical-align`, so the row's own height is what
   centres the write-off action — the same trap the bands table hit. */
.sessions__table td.table__actions {
  height: 52px;
  align-items: center;
  justify-content: flex-end;
}

.sessions__resident,
.sessions__bay {
  display: block;
  line-height: 1.5;
}

.sessions__bay {
  color: var(--muted-foreground);
}

.sessions__state--active {
  color: var(--primary);
}

.sessions__more {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  font-size: 11.5px;
  color: var(--muted-foreground);
}

.sessions__note {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--subtle-foreground);
}

/* The running session, on slate. It is the one place the admin surface inverts, because it is
   the one thing on the screen that is happening rather than recorded. */
.sessions__active {
  display: flex;
  flex: 0 0 290px;
  flex-direction: column;
  gap: 18px;
  padding: 24px;
  color: var(--sidebar-foreground);
  background: var(--foreground);
}

.sessions__active p {
  margin: 0;
}

.sessions__active-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--sidebar-accent);
}

.sessions__active-resident {
  font-size: 25px;
  font-weight: 500;
  letter-spacing: -0.024em;
  color: var(--background);
}

.sessions__active-location {
  font-size: 12px;
  line-height: 1.6;
  color: var(--sidebar-muted-foreground);
}

.sessions__active-energy {
  font-size: 35px;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--background);
}

.sessions__active-note {
  font-size: 11px;
  line-height: 1.5;
  color: var(--sidebar-muted-foreground);
}

@media (max-width: 900px) {
  .sessions__record {
    flex-direction: column;
  }

  .sessions__active {
    flex: 1 1 auto;
    align-self: stretch;
  }

  .sessions__summary {
    grid-template-columns: 1fr;
    gap: 20px;
  }
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  padding: 12px 16px;
  font-size: 11.5px;
  color: var(--muted-foreground);
  border-top: 1px solid var(--border);
}

.pagination__status {
  margin: 0;
}

.pagination__controls {
  display: flex;
  align-items: center;
  gap: 12px;
}

.pagination__position {
  color: var(--muted-foreground);
}

.pagination__step--off {
  color: var(--subtle-foreground);
}

@media (max-width: 860px) {
  .sessions__head {
    align-items: flex-start;
    flex-direction: column;
  }

  .sessions__stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 520px) {
  .sessions__stats {
    grid-template-columns: 1fr;
  }

  .sessions__pagination,
  .pagination {
    align-items: flex-start;
    flex-direction: column;
  }
}

/* ─── 3. INHERITED SCREENS ───────────────────────────────────────────────── */

.flash {
  margin: 0;
  padding: 0.75rem 1.5rem;
  color: var(--foreground);
  background: var(--card);
  border-bottom: 1px solid var(--border);
}

.flash--alert {
  color: var(--color-error);
}

/* Frame 01: the title with its sentence beneath it, and any actions pinned to
   the right of the title's own line. A CSS grid rather than a flex row, so the
   lead can sit under the title while the actions stay beside it. */
.page-header {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 10px 0.75rem;
  margin-bottom: 1rem;
}

.page-header h1,
.page-header h2 {
  grid-column: 1;
  margin: 0;
  font-size: 38px;
  font-weight: 500;
  line-height: 1.15;
  /* Every frame sets its title at 38/-1.5. */
  letter-spacing: -0.039em;
}

/* A section inside a page is titled, not headlined: frames 11 and 12 set one apart with an 18px
   line above the rules, which is a different job from the screen's own title. */
.section .page-header h2 {
  font-size: 18px;
  letter-spacing: -0.01em;
}

.page-header__lead {
  grid-column: 1;
}

.page-header__actions {
  display: flex;
  grid-column: 2;
  grid-row: 1;
  align-items: center;
  gap: 0.5rem;
}

.lead {
  max-width: 42rem;
  color: var(--muted-foreground);
}



/* Frames 11, 12 and 14 all open a detail page the same way: a band of equal columns between two
   rules, each a mono label over a 17px fact. */
.detail {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  margin: 0;
  padding: 18px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.detail__field {
  display: flex;
  flex: 1 1 180px;
  flex-direction: column;
  gap: 8px;
}

.detail dt {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}

.detail dd {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
  color: var(--foreground);
}

/* The rosters on a detail page: rules only, flush left, at the frame's own scale. */
.roster th:first-child,
.roster td:first-child {
  padding-left: 0;
}

.roster th:last-child,
.roster td:last-child {
  padding-right: 0;
}

.roster thead th {
  height: 52px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.roster td,
.roster tbody th {
  padding-top: 10px;
  padding-bottom: 10px;
  font-size: 13px;
  color: var(--muted-foreground);
  vertical-align: middle;
}

.roster tbody tr {
  border-bottom: 1px solid var(--border);
}

.roster tbody tr:last-child {
  border-bottom: 1px solid var(--border);
}

.roster tbody tr:hover {
  background: transparent;
}

.section {
  margin-top: 36px;
}

/* Frame 18. A state card, not a dashed placeholder: 24px padding, a 20px stack,
   on --card with a solid rule. The error variant inverts to the error pair
   because "we could not load this" must never be mistaken for "this is empty". */
.empty {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 24px;
  color: var(--foreground);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
}

.empty__headline {
  margin: 0;
  font-size: 30px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.empty__message {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
}

.empty__note {
  margin: 0;
  font-size: 13px;
  color: var(--muted-foreground);
}

.empty--error {
  color: var(--color-error);
  background: var(--color-error-tint);
  border-color: var(--color-error-edge);
}

.empty--error .empty__note {
  color: var(--color-error);
}

.muted {
  color: var(--muted-foreground);
}

.badge {
  padding: 3px 9px;
  font-size: 11.5px;
  font-weight: 500;
  border-radius: var(--radius-pill);
}

.badge--muted,
.badge--status {
  color: var(--muted-foreground);
  background: var(--neutral-tint);
}

.form {
  max-width: 34rem;
}

.form__group {
  margin: 0 0 1.5rem;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.form__group legend {
  padding: 0 0.35rem;
  color: var(--muted-foreground);
}

.field__hint {
  max-width: 34rem;
  margin: 0.3rem 0 0;
  font-size: 0.9rem;
  color: var(--muted-foreground);
}

.form__actions {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* The strip above a form that failed to save. Frame 15 gives it the error fill
   and no border — it is a band, like the attention strip, not a bordered card. */
.form__errors {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 24px;
  padding: 16px 18px;
  color: var(--color-error);
  background: var(--color-error-tint);
  border: 0;
  border-radius: 4px;
}

.form__errors-title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.form__errors-title {
  margin: 0 0 0.4rem;
  font-weight: 600;
}

.form__errors ul {
  margin: 0;
  padding-left: 1.2rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}





.card h3 {
  margin: 0;
  font-size: 1rem;
}


/* ─── EDIFICIOS (frame 02) ───────────────────────────────────────── */

/* The portfolio band: a count, a sentence, and a label, over a rule. */
.portfolio {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  padding: 18px 0 24px;
  border-bottom: 1px solid var(--border);
}

.portfolio__count {
  margin: 0;
  font-size: 58px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--foreground);
}

.portfolio__description {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 7px;
}

.portfolio__headline {
  margin: 0;
  font-size: 22px;
  font-weight: 500;
  color: var(--foreground);
}

.portfolio__totals {
  margin: 0;
  font-size: 13px;
  color: var(--subtle-foreground);
}

.portfolio__label {
  max-width: 7rem;
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--subtle-foreground);
  text-align: right;
}

/* One building: its identity on the left, its electrical supply on the right
   behind a rule. No card — the row's own bottom rule is the boundary. */
.property {
  display: flex;
  align-items: flex-start;
  gap: 28px;
  padding: 22px 0;
  border-bottom: 1px solid var(--border);
}

.property__index {
  margin: 0;
  font-size: 14px;
  color: var(--subtle-foreground);
}

.property__information {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.property__city {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--subtle-foreground);
  text-transform: uppercase;
}

.property__title {
  margin: 0;
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.property__title a {
  color: var(--foreground);
  text-decoration: none;
}

.property__address {
  margin: 0;
  font-size: 13px;
  color: var(--subtle-foreground);
}

.property__bays {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A bay reads as a chip: it is a physical thing with a label on it. */
.property__bay {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  font-size: 11px;
  color: var(--muted-foreground);
  background: #e8ebf1;
  border-radius: 3px;
}

.property__bay-icon {
  width: 13px;
  height: 13px;
  color: var(--muted-foreground);
}

.property__actions {
  display: flex;
  gap: 20px;
  margin: 0;
  font-size: 12px;
  font-weight: 500;
}

.property__actions a {
  color: var(--foreground);
  text-decoration: none;
}

.property__capacity {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 190px;
  padding: 4px 0 0 24px;
  border-left: 1px solid var(--border);
}

.property__supply {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--subtle-foreground);
  text-transform: uppercase;
}

.property__power {
  margin: 0;
  font-size: 27px;
  font-weight: 400;
  line-height: 1;
  color: var(--foreground);
}

.property__detail {
  margin: 0;
  font-size: 12px;
  color: var(--subtle-foreground);
}

.property__health {
  margin: 0;
  font-size: 11px;
}

.property__health--warn {
  color: var(--color-warning);
}

.property__health--ok {
  color: var(--color-success);
}

.property__note {
  margin: 0;
  font-size: 12px;
  color: var(--subtle-foreground);
}

/* ─── CARGADORES (frame 03) ──────────────────────────────────────── */

.equipment-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
}

.equipment-toolbar__filter select {
  height: auto;
  padding: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--foreground);
  background: transparent;
  border: 0;
}

.equipment-toolbar__totals {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--subtle-foreground);
  text-transform: uppercase;
}

/* The register beside the advisory. The design gives the advisory a fixed
   column and lets the register take the rest. */
.register-layout {
  display: grid;
  grid-template-columns: 1fr 250px;
  gap: 28px;
  align-items: start;
  margin-top: 24px;
}

.register {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.register__group {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.register__heading {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.register__city {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--subtle-foreground);
  text-transform: uppercase;
}

.register__building {
  margin: 0;
  font-size: 22px;
  font-weight: 500;
}

.register__building a {
  color: var(--foreground);
  text-decoration: none;
}

/* A charger is a row, not a table cell: the estate is grouped by building and
   the columns differ per group, so there is no shared grid to align to. */
.register__row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}

/* The bay reads as the plate on the wall the charger is bolted to. */
.register__bay {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 50px;
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
  background: #e6ebf5;
  border-radius: 3px;
  flex-shrink: 0;
}

.register__identity {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}

.register__serial {
  margin: 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--foreground);
}

.register__sockets {
  margin: 0;
  font-size: 11px;
  color: var(--subtle-foreground);
}

.register__reading {
  display: flex;
  flex-direction: column;
  gap: 7px;
  text-align: right;
}

.register__power {
  margin: 0;
  font-size: 17px;
  color: var(--foreground);
}

.register__state {
  margin: 0;
  font-size: 11px;
}

.register__open {
  font-size: 19px;
  color: var(--subtle-foreground);
  text-decoration: none;
}

/* Shown only while something is silent, like the dashboard's band. */
.advisory {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 24px;
  background: #e7ebf3;
  border-radius: 4px;
}

.advisory__icon {
  width: 28px;
  height: 28px;
  color: var(--muted-foreground);
}

.advisory__heading {
  margin: 0;
  font-size: 25px;
  font-weight: 500;
  line-height: 1.15;
  color: var(--foreground);
}

.advisory__body {
  margin: 0;
  font-size: 13px;
  color: var(--muted-foreground);
}

.advisory__footnote {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

/* The holiday calendar. No frame draws it — RIVO.pen prices holidays on Tarifas (frame 19) and
   never shows the list behind that column — so it is assembled from the vocabulary that screen
   already uses: the same filter row, the same rule-separated table, the same footnote. */
.holidays {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.holidays__filters {
  display: flex;
  gap: 18px;
  align-items: center;
}

.holidays__filters select {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--foreground);
  background: transparent;
  border: 0;
  cursor: pointer;
}

/* The tick is the point of the row, so it leads and takes only the width it needs. */
.calendar th:first-child,
.calendar td:first-child {
  width: 34px;
  padding-left: 0;
}

.calendar th:last-child,
.calendar td:last-child {
  padding-right: 0;
}

.calendar thead th {
  height: 46px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.calendar td,
.calendar tbody th {
  padding-top: 0;
  padding-bottom: 0;
  font-size: 13px;
  color: var(--foreground);
  vertical-align: middle;
}

.calendar tbody tr {
  height: 46px;
  border-bottom: 1px solid var(--border);
}

.calendar tbody th,
.calendar td:nth-child(3) {
  font-family: var(--font-mono);
}

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

.holidays__add {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-end;
/* Writing a charge off. No frame draws it — a write-off is an administrative act, and RIVO.pen
   draws the record of charging, not the decisions taken about it — so the form borrows the band
   editor's shape and the log borrows the table's rules. */
.write-off__title {
  margin: 0 0 6px;
  font-size: 26px;
  font-weight: 500;
  color: var(--foreground);
}

.write-off__charge {
  margin: 0 0 22px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted-foreground);
}

.write-off__form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 560px;
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.holidays__add-title {
  flex-basis: 100%;
  margin: 0;
  font-size: 17px;
.write-off__note {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted-foreground);
}

.write-off__log {
  margin-top: 28px;
  max-width: 560px;
}

.write-off__log-title {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 500;
  color: var(--foreground);
}

.holidays__error {
  margin: 0;
  font-size: 13px;
  color: var(--color-error);
}

.holidays__save {
  display: flex;
  justify-content: flex-end;
}

.holidays__footnote {
  margin: 0;
  font-size: 11px;
  line-height: 1.6;
.write-off__log-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.write-off__log-entry {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 2px 14px;
  padding: 12px 0;
  font-size: 13px;
  border-bottom: 1px solid var(--border);
}

.write-off__log-when {
  grid-row: span 2;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted-foreground);
}

.write-off__log-what {
  color: var(--foreground);
}

.write-off__log-why {
  color: var(--muted-foreground);
}

/* A charge the building chose not to collect. Neutral rather than an error tone: nothing went
   wrong, somebody decided something. */
.sessions__state--written-off {
  color: var(--subtle-foreground);
}

.billing__surcharge,
.billing__written-off {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

/* The export sits under the filters, quiet: it is a way out of the screen, not the point of it. */
.billing__export {
  margin: -6px 0 0;
}
