.kalender__tag:hover:not(:disabled),
.kalender__tag:focus-visible {
  background: var(--surface-2);
}

/* Today is ringed, the chosen day is filled: one is where the reader stands,
   the other is the answer. */
.kalender__tag.is-heute {
  box-shadow: inset 0 0 0 1px var(--line-strong);
}

.kalender__tag.is-gewaehlt,
.kalender__tag.is-gewaehlt:hover {
  background: var(--brass);
  color: #fff;
  box-shadow: none;
}

.kalender__tag:disabled {
  color: var(--text-faint);
  opacity: 0.45;
  cursor: default;
}

/* Eighty-six years, opened at the one in the field. */
.kalender__jahre {
  display: grid;
  grid-template-columns: repeat(4, 4.6rem);
  gap: 0.2rem;
  max-height: 17.5rem;
  overflow-y: auto;
}

.kalender__jahr {
  height: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: 1.25rem;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 120ms ease;
}

.kalender__jahr:hover,
.kalender__jahr:focus-visible {
  background: var(--surface-2);
}

.kalender__jahr.is-gewaehlt,
.kalender__jahr.is-gewaehlt:hover {
  background: var(--brass);
  color: #fff;
}

/* Said at the field rather than on submit: the entry is wrong while the reader
   is still looking at it, and a date that silently became empty is what this
   whole change exists to stop. */
.field > .field__error {
  font-size: 0.78rem;
  color: var(--neg);
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

/* --- A select you can type into ---
   The list overlays what follows rather than pushing it down: a picker that
   reflows the form under it moves the button somebody was about to click.

   `.combo` carries no rule of its own. It was the list's positioning parent
   until #240 took the list out to the window; it stays as the element that
   holds the box and the list together, and as the hook the script reads. */

/* Wider than its field when the entries need it, and placed against the window
   rather than inside the form. A picker in the detail sheet gets 432 px and the
   longest Mietverhältnis it offers —
   `Augustine Emmanuel, Maureen Emmanuel · 018 · Bramfelder Chaussee 252` —
   needs 526. Tying the list to the column would abbreviate all 60 of them.

   `fixed`, not `absolute`, because `.sheet__body` scrolls: anything positioned
   inside it is clipped by it, and a list anchored either way lost 95 px to that
   edge. Which is the same reason the list used to be cut off below. `platziere`
   sets top and left; the cap only guards against pathological content, since
   `max-content` already gives an entry exactly the room it asks for. */
.combo__list {
  position: fixed;
  z-index: 20;
  width: max-content;
  max-width: min(40rem, calc(100vw - 2rem));
  max-height: 16rem;
  overflow-y: auto;
  padding: 0.25rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: 0 10px 30px rgb(0 0 0 / 18%);
}

/* Abbreviated against the list, which is as wide as its entries; not against a
   fixed width of its own. `max-width: 7rem` stood here and cut every entry at
   112 px inside a list that measured 1041 — 12 of 19 tenant names, and every
   single Sachkonto and Mietverhältnis on offer. It arrived with the sidebar
   truncation in #223, where 7 rem is right, and reached this rule because it
   also carries `text-overflow`. See #240. */
.combo__option {
  padding: 0.4rem 0.55rem;
  border-radius: var(--r-sm);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.combo__option:hover,
.combo__option.is-marked {
  background: var(
    --surface-2,
    color-mix(in srgb, var(--focus) 12%, transparent)
  );
}

.combo__empty,
.combo__more {
  padding: 0.4rem 0.55rem;
  font-size: 0.85rem;
  color: var(--text-faint);
}

.combo__more {
  border-top: 1px solid var(--line);
  margin-top: 0.25rem;
}

/* --- One button, every command of the screen behind it ---
   A toolbar that grows a button per feature is a toolbar nobody reads, and the
   two most dangerous commands end up beside the two most common. */
.menu {
  position: relative;
}

/* The record head's slot for the open tab's commands. It stays in the layout
   while empty so the heading does not shift as the reader moves between tabs. */
.record__menu {
  display: flex;
  align-items: center;
  min-height: 2.25rem;
}

.menu__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.menu__chev {
  display: inline-flex;
  transition: transform 150ms ease;
}

.menu__trigger[aria-expanded="true"] .menu__chev {
  transform: rotate(180deg);
}

/* `fixed`, not `absolute`, for the reason `.combo__list` carries: `.sheet__body`
   scrolls, so anything positioned inside it is clipped by it — and the supply
   point's menu sits at the foot of that sheet. `platziereMenue` sets top and
   left. */
.menu__pop {
  position: fixed;
  z-index: 40;
  display: grid;
  gap: 0.1rem;
  min-width: 13rem;
  padding: 0.25rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--shadow-md);
}

.menu__pop[hidden] {
  display: none;
}

.menu__item {
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.88rem;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.menu__item:hover,
.menu__item:focus-visible {
  background: var(--surface-2);
}

.menu__item--danger {
  color: var(--neg);
}

.menu__item--danger:hover {
  background: var(--neg-soft);
}

/* A refusal is a sentence, not a label, and it takes the place of one.

   The four the Hauspost refuses with run to 117 characters; on one nowrap line
   551 of those pixels sat outside the popup, so the reader was told the command
   failed and not why — which is the whole of what the refusal is for (#599). */
.menu__item--refused {
  max-width: 28rem;
  white-space: normal;
}

/* Armed, not fired: the second click is the one that removes something. */
.menu__item--armed {
  background: var(--neg-soft);
  font-weight: 550;
}

/* --- An explanation you ask for --- */

/* The label carries what is needed to act. A term that has to be learned once —
   what a Gewicht is measured in, why an empty row is the mechanism — sits behind
   a mark, where it is read in the first week and passed over after.

   No `position` of its own: the bubble is fixed and placed against the window,
   so there is nothing here for it to be positioned against. */
.hint {
  display: inline-flex;
  margin-left: 0.35rem;
  vertical-align: middle;
}

/* The glyph is centred by the box, not by its baseline. A `?` set on the text
   baseline inside a fixed circle sits low and slightly left, and at 17px that
   reads as a rendering fault rather than a mark. */
.hint__mark {
  display: grid;
  place-items: center;
  width: 1.05rem;
  height: 1.05rem;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-faint);
  font: inherit;
  font-size: 0.7rem;
  line-height: 1;
  text-indent: 0;
  text-transform: none;
  letter-spacing: 0;
  cursor: help;
}

.hint__mark:hover,
.hint__mark:focus-visible {
  border-color: var(--brass);
  color: var(--brass);
}

/* Fixed and placed by `platziereUeberlagerung`, like the combo list and the
   calendar. Absolute was right beside a form label and wrong everywhere else: a
   `.panel` hides its overflow and a `.panel__scroll` scrolls on both axes, so a
   bubble opening from a column heading was cut off at the panel's edge and drawn
   over the first row of figures it was explaining. Fixed is outside both, and
   the shared placement clamps it into the window. */
.hint__bubble {
  position: fixed;
  z-index: 20;
  width: max-content;
  max-width: min(24rem, 80vw);
  /* `.ledger th` sets `nowrap` and the bubble inherited it, so the sentence ran
     out of the panel on one line and was cut mid-word. A bubble is prose. */
  white-space: normal;
  overflow-wrap: anywhere;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
  color: var(--text-dim);
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  text-transform: none;
  letter-spacing: 0;
  /* The open/closed state, and the script's alone since the bubble became a
     placed overlay: `platziereUeberlagerung` measures the box, and a box set to
     `visibility: hidden` would measure right but a `display: none` one measures
     nothing — so it is shown first and placed second. */
  display: none;
}

/* --- A command with work waiting behind it (#470) --- */

/* The count sits at the right edge of its own line rather than inside the name.
   Written as "Adressen prüfen · 4" it reads as part of what the command is
   called; a badge saying "4 offen" reads as how much is behind it. */
.menu__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
}

.menu__count {
  flex: none;
}

/* And a dot on the closed trigger, because a menu hides its own reason to be
   opened. It says only *open me*; the badge inside says how much. */
.menu__dot {
  width: 0.4rem;
  height: 0.4rem;
  margin-left: 0.1rem;
  border-radius: 999px;
  background: currentcolor;
}
