/* Mobile-first, light/dark via prefers-color-scheme. No build step. */

:root {
  color-scheme: light dark;
  --bg: #f2f2f7;
  --surface: #ffffff;
  --surface-2: #f7f7fa;
  --text: #1c1c1e;
  --muted: #6c6c72;
  --border: #e3e3e8;
  --accent: #0a63d1;
  --accent-text: #ffffff;
  --accent-soft: #e6effb;
  --good: #17733a;
  --good-bg: #e3f4e8;
  --warn: #9a4a00;
  --warn-bg: #fdf0dc;
  --info: #3f4a5a;
  --info-bg: #eceff4;
  --danger: #c4231b;
  --danger-bg: #fde8e6;
  --score-high: #1a7f3d;
  --score-mid: #a86400;
  --score-low: #6e6e76;
  --bar-bg: rgba(255, 255, 255, 0.86);
  --switch-off: #d9d9de;
  /* charts on the detail page: score factors, costs, image dots */
  --track: #e8e8ed;
  --chart-plus: #2e9d58;
  --chart-minus: #e0453a;
  --cost-base: #2f6fdb;
  --cost-service: #14968e;
  --cost-heating: #d4700a;
  --cost-other: #8a8a91;
  --dot: #9a9aa0;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 2px 10px rgba(0, 0, 0, 0.05);
  --radius: 14px;
  --gutter: 16px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --surface: #1c1c1e;
    --surface-2: #26262a;
    --text: #f2f2f7;
    --muted: #9a9aa1;
    --border: #333338;
    --accent: #4a9bff;
    --accent-text: #00152e;
    --accent-soft: #11294a;
    --good: #5ad685;
    --good-bg: #123320;
    --warn: #ffb44d;
    --warn-bg: #3a2810;
    --info: #c4cbd6;
    --info-bg: #2a2e35;
    --danger: #ff6b61;
    --danger-bg: #3d1513;
    --score-low: #5f5f66;
    --bar-bg: rgba(28, 28, 30, 0.86);
    --switch-off: #3a3a3e;
    --track: #303034;
    --chart-plus: #3fcf74;
    --chart-minus: #ff6b61;
    --cost-base: #5aa2ff;
    --cost-service: #2fc4b8;
    --cost-heating: #ffa94d;
    --cost-other: #7c7c84;
    --dot: #6a6a70;
    --shadow: none;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* the hidden attribute must win over display rules like .button's */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.45 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

a {
  color: var(--accent);
  text-decoration: none;
}

h1,
h2,
h3 {
  line-height: 1.25;
  margin: 0;
}

h1 {
  font-size: 1.45rem;
  font-weight: 700;
}

h2 {
  font-size: 1.05rem;
  font-weight: 650;
}

h3 {
  font-size: 0.95rem;
  font-weight: 650;
}

p {
  margin: 0;
}

img {
  display: block;
}

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

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* inline SVG icons (views/icons.tsx): sized with the text unless a rule says otherwise */
.icon {
  display: inline-block;
  flex-shrink: 0;
  width: 1.15em;
  height: 1.15em;
  vertical-align: -0.2em;
}

/* ---------- top bar ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bar-bg);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid var(--border);
  padding-top: env(safe-area-inset-top);
}

.topbar-inner {
  max-width: 760px;
  margin: 0 auto;
  height: 52px;
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--text);
}

.brand img {
  border-radius: 7px;
}

.back {
  font-size: 1.05rem;
  font-weight: 500;
  padding: 8px 0;
}

.topbar nav {
  display: flex;
  gap: 4px;
}

.topbar nav a {
  color: var(--muted);
  font-weight: 550;
  font-size: 0.95rem;
  padding: 6px 10px;
  border-radius: 8px;
}

.topbar nav a.active {
  color: var(--accent);
  background: var(--accent-soft);
}

/* ---------- layout ---------- */

.container {
  max-width: 760px;
  margin: 0 auto;
  padding: 16px var(--gutter) calc(32px + env(safe-area-inset-bottom));
}

/* room under the content for the detail page's action button (see "actions") */
.has-action-bar .container {
  padding-bottom: calc(88px + env(safe-area-inset-bottom));
}

.page-head {
  margin: 4px 0 16px;
}

.page-head .muted {
  margin-top: 4px;
}

.panel {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
  margin: 0 0 14px;
}

.panel > h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.hint {
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 10px;
}

.empty {
  text-align: center;
  color: var(--muted);
  padding: 48px 0;
}

/* ---------- notices ---------- */

.notice {
  border-radius: 10px;
  padding: 10px 12px;
  margin: 0 0 14px;
  font-size: 0.92rem;
  background: var(--info-bg);
  color: var(--info);
}

.notice-success {
  background: var(--good-bg);
  color: var(--good);
}

.notice-warn {
  background: var(--warn-bg);
  color: var(--warn);
}

.notice-error {
  background: var(--danger-bg);
  color: var(--danger);
}

/* an icon before the text */
.notice:has(> .icon) {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.notice > .icon {
  width: 20px;
  height: 20px;
  margin-top: 1px;
}

.detail-head .notice {
  margin: 12px 0 0;
}

/* "Nicht mehr online": first thing under the images */
.detail-head .notice-error {
  margin: 0 0 12px;
  padding: 12px 14px;
  font-size: 1rem;
}

/* ---------- buttons ---------- */

.button {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 0 18px;
  border-radius: 12px;
  border: 0;
  background: var(--surface-2);
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  text-align: center;
  touch-action: manipulation;
}

.button.primary {
  background: var(--accent);
  color: var(--accent-text);
}

.button.danger {
  color: var(--danger);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.button.block {
  display: flex;
  width: 100%;
}

.button:disabled {
  opacity: 0.45;
  cursor: default;
}

.button.done {
  background: var(--good-bg);
  color: var(--good);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.button-row .button {
  flex: 1 1 auto;
}

/* ---------- list ---------- */

/* heading and sorting on the first line; the filters and the "ausgeblendet" line below span the full width, in that
   order, so a filter stays under the finger when the line changes */
.list-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: 12px;
  margin: 4px 0 14px;
}

.list-head h1 {
  flex: 1 1 0;
  min-width: 0;
  font-size: 1.3rem;
}

.list-head .muted {
  flex-basis: 100%;
  font-size: 0.85rem;
  margin-top: 8px;
}

.segmented {
  display: inline-flex;
  flex-shrink: 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 2px;
}

.segmented a,
.filter-option {
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 6px 10px;
  border-radius: 8px;
}

/* The view filters' highlighted option follows the classes prefs.js sets on <html> before the first paint (not
   :checked, which app.js syncs only later); the cards and counts they hide are in the rule after this one. */
.segmented a.active,
html:not(.hide-tenants) [data-view-filter="hideTenants"] .filter-off,
.hide-tenants [data-view-filter="hideTenants"] .filter-on,
html:not(.hide-no-images) [data-view-filter="hideNoImages"] .filter-off,
.hide-no-images [data-view-filter="hideNoImages"] .filter-on {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

/* a filter that hides listings is on: in the accent colour, so a shorter list is explained at a glance */
.hide-tenants [data-view-filter="hideTenants"] .filter-on,
.hide-no-images [data-view-filter="hideNoImages"] .filter-on {
  color: var(--accent);
}

/* Anbieter: Alle | Gewerblich, Bilder: Bilder | (Auch) ohne Bilder (FilterControl in list.tsx). Side by side where
   they fit, else each on a line of its own and as wide as it, its options sharing it. */
.list-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  flex-basis: 100%;
  margin-top: 10px;
}

.filter-option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  white-space: nowrap;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

.filter-option .icon {
  width: 1.05em;
  height: 1.05em;
}

/* the radio itself is visually hidden: its label shows the focus */
.filter-option:has(:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

@media (max-width: 479px) {
  .list-filters .segmented {
    flex: 1 1 100%;
  }

  .filter-option {
    flex: 1 1 0;
  }
}

/* iPhone SE (1st gen) and narrower: a count of up to two digits stays on one line next to the sort – so the controls
   don't move when a filter changes it – and both halves of a filter fit */
@media (max-width: 359px) {
  .list-head {
    column-gap: 8px;
  }

  .list-head h1 {
    font-size: 1.1rem;
  }

  .segmented a,
  .filter-option {
    padding: 6px 8px;
    font-size: 0.8rem;
  }
}

/* What the view filters hide (html.hide-tenants, html.hide-no-images): the marked cards, and the count, hint and
   empty state rendered for the other combinations (ByFilters in list.tsx). Without JavaScript there are no filters. */
html:not(.js) .list-filters,
.hide-tenants [data-tenant],
.hide-no-images [data-no-images],
html:not(.hide-tenants) .when-hide-tenants,
.hide-tenants .unless-hide-tenants,
html:not(.hide-no-images) .when-hide-no-images,
.hide-no-images .unless-hide-no-images {
  display: none;
}

/* a checkbox as a switch (role="switch"), e.g. the profile's "Ich habe SuchenPlus" */
.switch {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  flex-shrink: 0;
  width: 40px;
  height: 24px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--switch-off);
  cursor: pointer;
  transition: background-color 0.2s;
}

.switch::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: transform 0.2s;
}

.switch:checked {
  background: var(--accent);
}

.switch:checked::before {
  transform: translateX(16px);
}

.switch:focus {
  outline: none;
}

.switch:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 16px;
}

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

.card {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.card-link {
  display: block;
  color: inherit;
}

/* Same layout on every card (see Card in list.tsx): status on the image corners – score top left, Plus top right,
   age bottom left, image count bottom right – then the three key facts in fixed columns, then the rest. */
.card-media {
  position: relative;
}

.card-body {
  padding: 12px 14px 14px;
}

/* Warmmiete · Wohnfläche · Zimmer: each value starts at the same place on every card – the rooms column is as wide
   as its label (the values are shorter), the other two share the rest */
.card-facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  column-gap: 12px;
  padding-bottom: 11px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--border);
}

.fact {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.fact + .fact {
  padding-left: 12px;
  border-left: 1px solid var(--border);
}

.fact-value {
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fact-missing {
  color: var(--muted);
  font-weight: 500;
}

.fact-label {
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 500;
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* "Kaltmiete": ImmoScout24 has no Warmmiete */
.fact-note .fact-label {
  color: var(--warn);
}

/* iPhone SE (1st gen) and narrower */
@media (max-width: 359px) {
  .card-facts {
    column-gap: 8px;
  }

  .fact + .fact {
    padding-left: 8px;
  }

  .fact-value {
    font-size: 1.12rem;
  }
}

.card-title {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

.card-location {
  color: var(--muted);
  font-size: 0.88rem;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card .tags {
  margin-top: 8px;
}

/* Marked as contacted on the detail page: a faded photo and lighter text, so the ones already written to recede while
   scanning – still readable, in their place and one link. The badges on the image and the marker stay clear. */
.card[data-contacted] .slides,
.card[data-contacted] .slide-placeholder {
  opacity: 0.6;
  filter: saturate(0.4);
}

.card[data-contacted] .card-facts,
.card[data-contacted] .card-title,
.card[data-contacted] .card-location,
.card[data-contacted] .tag:not(.tag-contacted) {
  opacity: 0.8;
}

/* ---------- districts (Stadtteile) ---------- */

/* A quarter as a tinted pill with a dot in its colour, the same on the cards and the detail page (District in
   views/district.tsx). src/web/districts.ts maps the name to a class: c1–c4 the four quarters of the default search,
   c5–c8 their neighbours, f1–f6 muted colours for other names. Each part has the same OKLCH lightness in every colour
   (with less chroma where sRGB has no room), so every name reads alike: 6.1:1 or more on its tint in light mode, 7.8:1
   or more in dark mode (WCAG AA asks for 4.5:1). */
.district {
  display: inline-block;
  max-width: 100%;
  padding: 0 8px 0 7px;
  border-radius: 999px;
  background: var(--district-bg);
  color: var(--district-ink);
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}

.district::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--district-dot);
  vertical-align: 1px;
}

.district-c1 {
  /* orange – Braunsfeld */
  --district-bg: #ffeadc;
  --district-ink: #834100;
  --district-dot: #d36c00;
}

.district-c2 {
  /* green – Lindenthal */
  --district-bg: #daf8df;
  --district-ink: #00672c;
  --district-dot: #17a750;
}

.district-c3 {
  /* blue – Sülz */
  --district-bg: #e4f0ff;
  --district-ink: #17559b;
  --district-dot: #388cf0;
}

.district-c4 {
  /* magenta – Neustadt-Süd */
  --district-bg: #ffe6f8;
  --district-ink: #7f3471;
  --district-dot: #c85eb4;
}

.district-c5 {
  /* red */
  --district-bg: #ffe9e6;
  --district-ink: #90302e;
  --district-dot: #e15955;
}

.district-c6 {
  /* gold */
  --district-bg: #f8efcd;
  --district-ink: #665400;
  --district-dot: #a58a00;
}

.district-c7 {
  /* teal */
  --district-bg: #ccf8fa;
  --district-ink: #006266;
  --district-dot: #00a0a6;
}

.district-c8 {
  /* violet */
  --district-bg: #efebff;
  --district-ink: #5c4295;
  --district-dot: #9572e7;
}

.district-f1 {
  /* sand */
  --district-bg: #f5ede2;
  --district-ink: #665136;
  --district-dot: #a38760;
}

.district-f2 {
  /* sage */
  --district-bg: #e5f2ec;
  --district-ink: #3a5e4e;
  --district-dot: #669982;
}

.district-f3 {
  /* slate */
  --district-bg: #e4f1f8;
  --district-ink: #375b6c;
  --district-dot: #6294ac;
}

.district-f4 {
  /* lavender */
  --district-bg: #ecedfa;
  --district-ink: #505271;
  --district-dot: #8488b3;
}

.district-f5 {
  /* mauve */
  --district-bg: #f8eaf0;
  --district-ink: #6b4a59;
  --district-dot: #ab7c92;
}

.district-f6 {
  /* olive */
  --district-bg: #edf0e4;
  --district-ink: #525a3a;
  --district-dot: #879266;
}

@media (prefers-color-scheme: dark) {
  .district-c1 {
    --district-bg: #502f17;
    --district-ink: #ffc7a1;
    --district-dot: #f28e42;
  }

  .district-c2 {
    --district-bg: #1f4127;
    --district-ink: #aae5b5;
    --district-dot: #5ac576;
  }

  .district-c3 {
    --district-bg: #223956;
    --district-ink: #b8d7ff;
    --district-dot: #6dadff;
  }

  .district-c4 {
    --district-bg: #4b2b44;
    --district-ink: #fabeec;
    --district-dot: #e484d0;
  }

  .district-c5 {
    --district-bg: #532b28;
    --district-ink: #ffc3bd;
    --district-dot: #fb817a;
  }

  .district-c6 {
    --district-bg: #42370d;
    --district-ink: #e7d48f;
    --district-dot: #c9a90c;
  }

  .district-c7 {
    --district-bg: #004144;
    --district-ink: #88e7ec;
    --district-dot: #00c2ca;
  }

  .district-c8 {
    --district-bg: #3a3154;
    --district-ink: #d7ccff;
    --district-dot: #b296ff;
  }

  .district-f1 {
    --district-bg: #3f362b;
    --district-ink: #e2d2bc;
    --district-dot: #c0a683;
  }

  .district-f2 {
    --district-bg: #2d3c35;
    --district-ink: #c0dccf;
    --district-dot: #89b7a2;
  }

  .district-f3 {
    --district-bg: #2c3a42;
    --district-ink: #bed9e7;
    --district-dot: #86b2c8;
  }

  .district-f4 {
    --district-bg: #353744;
    --district-ink: #cfd2eb;
    --district-dot: #a3a7cf;
  }

  .district-f5 {
    --district-bg: #41333a;
    --district-ink: #e7ccd7;
    --district-dot: #c89db0;
  }

  .district-f6 {
    --district-bg: #363a2d;
    --district-ink: #d1d8bf;
    --district-dot: #a6b188;
  }
}

/* ---------- badges over images: Plus, age ---------- */

.plus-badge,
.age {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  border-radius: 999px;
  line-height: 1;
  pointer-events: none;
}

.plus-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  max-width: calc(100% - 76px); /* never runs into the score */
  height: 28px;
  gap: 5px;
  padding: 0 10px 0 7px;
  font-size: 0.8rem;
  font-weight: 700;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.3);
}

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

.plus-when {
  overflow: hidden;
  text-overflow: ellipsis;
  padding-left: 6px;
  border-left: 1px solid currentColor;
  border-left-color: color-mix(in srgb, currentColor 35%, transparent);
  font-weight: 600;
}

/* Good news to act on (your Plus head start, a very fresh listing): a bright pill with a white ring, which sets it
   apart from any photo – also from yellow walls or green plants. */
.plus-ahead,
.age-strong {
  box-shadow: 0 0 0 2px #fff, 0 2px 10px rgba(0, 0, 0, 0.4);
}

/* with SuchenPlus: your head start */
.plus-ahead {
  background: #ffd60a;
  color: #2b2300;
}

/* without: you have to wait – muted, like ImmoScout's dark Plus pill */
.plus-wait {
  background: rgba(28, 28, 30, 0.8);
  color: #f2f2f7;
}

.plus-wait .plus-icon {
  color: #aeaeb2;
}

.plus-wait .plus-when {
  color: #d1d1d6;
  font-weight: 500;
}

.card-media .age,
.slider .age {
  position: absolute;
  left: 10px;
  bottom: 10px;
}

.age {
  gap: 6px;
  font-variant-numeric: tabular-nums;
}

/* older than FRESHNESS_HOURS.mild: calm, like the image counter */
.age-plain {
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 600;
}

.age-mild {
  height: 28px;
  padding: 0 11px 0 9px;
  background: rgba(28, 28, 30, 0.8);
  color: #fff;
  font-size: 0.88rem;
  font-weight: 700;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.3);
}

/* younger than FRESHNESS_HOURS.strong: big and bright */
.age-strong {
  height: 32px;
  padding: 0 13px 0 11px;
  background: #34c759;
  color: #002a0f;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}

.age-dot {
  position: relative;
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #34c759;
}

.age-strong .age-dot {
  background: #002a0f;
}

.age-strong .age-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: age-pulse 2s ease-out infinite;
}

@keyframes age-pulse {
  from {
    transform: scale(1);
    opacity: 0.6;
  }
  to {
    transform: scale(2.8);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .age-strong .age-dot::after {
    animation: none;
    display: none;
  }
}

/* ---------- slider ---------- */

.slider {
  position: relative;
  background: var(--surface-2);
}

.slides {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.slides::-webkit-scrollbar {
  display: none;
}

.slides img,
.slide-placeholder {
  flex: 0 0 100%;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  background: var(--surface-2);
}

.slide-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  color: var(--muted);
  font-size: 0.9rem;
}

.slide-placeholder .icon {
  width: 30px;
  height: 30px;
  stroke-width: 1.6;
}

/* app.js animates clicks and ←/→ itself; snapping would fight every step of it */
.slides.is-moving {
  scroll-snap-type: none;
}

/* the detail page's slider with its badges: edge to edge on phones */
.detail-media {
  position: relative;
  margin: -16px calc(-1 * var(--gutter)) 0;
}

.slider-large .slides img {
  aspect-ratio: 4 / 3;
  max-height: 64vh; /* desktop: the title and score stay in view */
}

/* no images: just room for the badges */
.slider-large .slide-placeholder {
  aspect-ratio: auto;
  height: 150px;
}

@media (min-width: 760px) {
  .detail-media {
    margin: 0 0 4px;
  }

  .detail-media .slider {
    border-radius: var(--radius);
    overflow: hidden;
  }
}

/* Previous/next over the image (detail page). On touch screens small and calm – swiping is the way there; with a
   mouse a tall hit area on each side whose button shows while the pointer is over the image. */
.slide-nav {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  top: 50%;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-top: -24px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  cursor: pointer;
  touch-action: manipulation;
}

.slide-prev {
  left: 2px;
}

.slide-next {
  right: 2px;
}

.slide-nav-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.36);
  transition: opacity 0.15s, transform 0.15s, background-color 0.15s;
}

.slide-nav .icon {
  width: 22px;
  height: 22px;
  stroke-width: 2.5;
}

.slide-nav:disabled {
  visibility: hidden;
}

.slide-nav:focus {
  outline: none;
}

.slide-nav:focus-visible .slide-nav-circle {
  opacity: 1;
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
  .slide-nav {
    top: 18%;
    bottom: 18%;
    width: 76px;
    height: auto;
    margin-top: 0;
    color: #1c1c1e;
  }

  .slide-prev {
    left: 0;
  }

  .slide-next {
    right: 0;
  }

  .slide-nav-circle {
    width: 44px;
    height: 44px;
    background: rgba(255, 255, 255, 0.92);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
    opacity: 0;
  }

  .slider:hover .slide-nav-circle {
    opacity: 1;
  }

  .slide-nav:hover .slide-nav-circle {
    background: #fff;
    transform: scale(1.08);
  }

  .slide-nav:active .slide-nav-circle {
    transform: scale(0.96);
  }
}

/* One dot per image below it; with many images a window of them follows the current one (app.js). */
.slide-dots {
  display: flex;
  justify-content: center;
  padding: 6px 0 0;
}

.slide-dots-track {
  display: flex;
  max-width: calc(9 * 20px);
  overflow: hidden;
  scroll-behavior: smooth;
}

.slide-dot {
  -webkit-appearance: none;
  appearance: none;
  flex: 0 0 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 24px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  touch-action: manipulation;
}

.slide-dot::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dot);
  transition: transform 0.15s, background-color 0.15s;
}

.slide-dot:hover::before {
  background: var(--muted);
}

.slide-dot[aria-current="true"]::before {
  background: var(--text);
  transform: scale(1.3);
}

/* at the edges of the window, when more images follow */
.slide-dot.is-far::before {
  transform: scale(0.6);
}

.slide-dot:focus {
  outline: none;
}

html:not(.js) .slide-nav,
html:not(.js) .slide-dots {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .slide-dots-track {
    scroll-behavior: auto;
  }

  .slide-nav-circle,
  .slide-dot::before {
    transition: none;
  }
}

.slide-count {
  position: absolute;
  right: 10px;
  bottom: 10px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  pointer-events: none;
}

/* ---------- score + tags ---------- */

.score {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  height: 28px;
  padding: 0 8px;
  border-radius: 999px;
  color: #fff;
  font-weight: 700;
  font-size: 0.92rem;
  font-variant-numeric: tabular-nums;
  background: var(--score-low);
}

.score-high {
  background: var(--score-high);
}

.score-mid {
  background: var(--score-mid);
}

.score-overlay {
  position: absolute;
  top: 10px;
  left: 10px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.3);
}

.score-large {
  min-width: 48px;
  height: 36px;
  font-size: 1.1rem;
  flex-shrink: 0;
}

.tags {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tag {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--info-bg);
  color: var(--info);
}

.tag-good {
  background: var(--good-bg);
  color: var(--good);
}

.tag-warn {
  background: var(--warn-bg);
  color: var(--warn);
}

/* "Angeschrieben", first on a contacted card: solid, so it isn't mistaken for one of the tags */
.tag-contacted {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--good);
  color: var(--surface);
}

.tag-contacted .icon {
  width: 14px;
  height: 14px;
}

/* ---------- detail ---------- */

.detail-head {
  padding: 14px 0 16px;
}

.detail-head h1 {
  font-size: 1.35rem;
  overflow-wrap: anywhere;
}

.detail-location,
.last-seen {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--muted);
}

.detail-location {
  margin-top: 6px;
  font-size: 0.95rem;
}

.detail-location .icon {
  width: 17px;
  height: 17px;
}

/* "Zuletzt bei ImmoScout gesehen": the dot sits where the pin is in the line above */
.last-seen {
  margin-top: 3px;
  font-size: 0.88rem;
}

.last-seen-dot {
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  margin: 0 4px;
  border-radius: 50%;
  background: var(--dot);
}

.last-seen-recent .last-seen-dot {
  background: #34c759;
  box-shadow: 0 0 0 3px color-mix(in srgb, #34c759 25%, transparent);
}

.last-seen-removed .last-seen-dot {
  background: var(--danger);
}

/* "Angeschrieben am …": below, its icon where the pin and the dot are */
.contacted-note {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 3px;
  color: var(--good);
  font-size: 0.88rem;
  font-weight: 600;
}

.contacted-note .icon {
  width: 17px;
  height: 17px;
}

.panel-title .icon {
  width: 20px;
  height: 20px;
  color: var(--accent);
}

/* --- score: the number, a meter, then one diverging bar per factor --- */

.score-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "big title"
    "big meter"
    "big sum";
  align-items: center;
  column-gap: 14px;
  row-gap: 5px;
}

.score-title {
  grid-area: title;
}

.score-big {
  grid-area: big;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 18px;
  color: #fff;
  font-size: 1.8rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* .score-high and .score-mid colour it like the badge */
.score-big.score-low {
  background: var(--score-low);
}

.score-meter {
  grid-area: meter;
  display: block;
}

.score-sum {
  grid-area: sum;
  color: var(--muted);
  font-size: 0.82rem;
}

.bar-track {
  fill: var(--track);
}

.meter-high {
  fill: var(--score-high);
}

.meter-mid {
  fill: var(--score-mid);
}

.meter-low {
  fill: var(--score-low);
}

.factors {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
}

/* phones: icon, label, bar and points on one line, the reason below */
.factor {
  display: grid;
  grid-template-columns: 20px minmax(0, 7.4em) minmax(0, 1fr) 2.7em;
  grid-template-areas:
    "icon label bar points"
    ". detail detail detail";
  align-items: center;
  column-gap: 10px;
  padding: 9px 0;
  border-top: 1px solid var(--border);
}

.factor-icon {
  grid-area: icon;
  width: 20px;
  height: 20px;
  color: var(--muted);
}

.factor-label {
  grid-area: label;
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.factor-bar {
  grid-area: bar;
  display: block;
}

.factor-points {
  grid-area: points;
  text-align: right;
  font-weight: 750;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--muted);
}

.factor-detail {
  grid-area: detail;
  margin-top: 2px;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.35;
}

.factor-plus .factor-icon,
.factor-plus .factor-points {
  color: var(--good);
}

.factor-minus .factor-icon,
.factor-minus .factor-points {
  color: var(--danger);
}

.bar-plus {
  fill: var(--chart-plus);
}

.bar-minus {
  fill: var(--chart-minus);
}

.bar-zero {
  stroke: var(--muted);
  stroke-width: 1.5;
}

/* wider: the reason between label and bar, so all bars line up on the right */
@media (min-width: 600px) {
  .factor {
    grid-template-columns: 20px 8.6em minmax(0, 1fr) minmax(110px, 32%) 2.7em;
    grid-template-areas: "icon label detail bar points";
  }

  .factor-detail {
    margin: 0;
  }
}

/* --- key facts: the card's three columns, bigger --- */

.key-facts {
  padding: 14px 16px;
}

.detail-facts {
  margin: 0;
  padding: 0;
  border: 0;
}

.detail-facts .fact-icon {
  width: 20px;
  height: 20px;
  margin-bottom: 6px;
  color: var(--accent);
}

.detail-facts .fact-value {
  font-size: 1.45rem;
}

.detail-facts .fact-label {
  font-size: 0.8rem;
}

@media (max-width: 359px) {
  .detail-facts .fact-value {
    font-size: 1.15rem;
  }
}

/* room enough: three equal columns */
@media (min-width: 600px) {
  .detail-facts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .detail-facts .fact-value {
    font-size: 1.6rem;
  }
}

/* --- costs: Kaltmiete + Nebenkosten + Heizkosten = Warmmiete --- */

.cost-bar {
  display: block;
  margin: 0 0 10px;
}

.seg {
  stroke: var(--surface);
  stroke-width: 2px;
}

.seg-base,
.cost-base .swatch {
  fill: var(--cost-base);
  background: var(--cost-base);
}

.seg-service,
.cost-service .swatch {
  fill: var(--cost-service);
  background: var(--cost-service);
}

.seg-heating,
.cost-heating .swatch {
  fill: var(--cost-heating);
  background: var(--cost-heating);
}

.seg-other,
.cost-other .swatch {
  fill: var(--cost-other);
  background: var(--cost-other);
}

.cost-sum {
  margin: 0;
}

.cost-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
}

.cost-row dt {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.cost-row dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  overflow-wrap: anywhere;
}

.swatch {
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  border-radius: 3px;
}

/* only a text, e.g. "in Nebenkosten enthalten": not part of the bar */
.cost-text .swatch {
  background: none;
  box-shadow: inset 0 0 0 2px var(--border);
}

.cost-text dd {
  color: var(--muted);
  font-weight: 500;
  font-size: 0.92rem;
}

.cost-total {
  margin-top: 4px;
  padding-top: 9px;
  border-top: 2px solid var(--text);
  font-size: 1.1rem;
  font-weight: 700;
}

.cost-total dd {
  font-weight: 750;
}

.cost-total dt::before {
  content: "=";
  width: 12px;
  text-align: center;
  font-weight: 700;
}

.cost-unknown dd {
  color: var(--warn);
}

.costs .info-list {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* per m²: one line under the sum */
.costs .info-list-compact {
  margin-top: 6px;
  padding-top: 0;
  border-top: 0;
}

/* wide: the sum on the left (values near their labels), deposit and parking on the right */
@media (min-width: 720px) {
  .costs {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    align-items: start;
    column-gap: 28px;
  }

  .costs > * {
    grid-column: 1;
  }

  .costs > .panel-title {
    grid-column: 1 / -1;
  }

  .costs > .info-list:not(.info-list-compact) {
    grid-column: 2;
    grid-row: 2 / span 3;
    grid-template-columns: minmax(0, 1fr);
    margin: 0;
    padding: 0 0 0 24px;
    border-top: 0;
    border-left: 1px solid var(--border);
  }
}

/* --- grouped facts --- */

/* two columns on wide screens; the panels flow top to bottom, then into the second column */
@media (min-width: 720px) {
  .detail-groups {
    columns: 2;
    column-gap: 14px;
    margin-bottom: 14px; /* the last panels' margins end at the column breaks */
  }

  .detail-groups > .panel {
    break-inside: avoid;
  }
}

.info-list {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 136px), 1fr));
  gap: 12px 16px;
}

.info {
  position: relative;
  min-width: 0;
  padding-left: 28px;
}

.info dt {
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.3;
}

.info dt .icon,
.info dt .plus-icon {
  position: absolute;
  left: 0;
  top: 3px;
  width: 19px;
  height: 19px;
  color: var(--muted);
}

.info dd {
  margin: 1px 0 0;
  font-weight: 550;
  overflow-wrap: anywhere;
}

.info-list-compact {
  gap: 8px 16px;
}

.info-list-wide {
  grid-template-columns: minmax(0, 1fr);
}

.info-list-compact .info {
  padding-left: 0;
}

.map-link {
  gap: 7px;
  min-height: 40px;
  margin-top: 14px;
  font-size: 0.92rem;
}

.map-link .icon {
  width: 18px;
  height: 18px;
}

/* Ausstattung: present, absent and unknown at a glance */
.features {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.feature {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 5px 10px 5px 9px;
  border: 1px solid transparent;
  border-radius: 10px;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.2;
}

.feature > .icon {
  width: 18px;
  height: 18px;
}

.feature-value {
  font-weight: 500;
}

.feature-value::before {
  content: "·";
  margin: 0 5px;
}

.feature-mark {
  width: 14px;
  height: 14px;
  stroke-width: 3;
  font-weight: 800;
  text-align: center;
  line-height: 14px;
}

.feature-yes {
  background: var(--good-bg);
  color: var(--good);
}

.feature-maybe {
  background: var(--warn-bg);
  color: var(--warn);
}

.feature-no {
  background: var(--surface-2);
  color: var(--muted);
}

.feature-no .feature-label {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.feature-unknown {
  color: var(--muted);
  border: 1px dashed color-mix(in srgb, var(--muted) 60%, transparent);
}

.feature-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 12px;
  color: var(--muted);
  font-size: 0.78rem;
}

.feature-legend span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: 0;
  color: inherit;
}

.feature-legend .feature-yes .feature-mark {
  color: var(--good);
}

/* energy label colours */
.energy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.4em;
  padding: 1px 8px;
  border-radius: 6px;
  font-weight: 800;
  color: #fff;
}

.energy-aplus {
  background: #0b6b2e;
}

.energy-a {
  background: #1e7f35;
}

.energy-b {
  background: #5aa531;
  color: #0b1a00;
}

.energy-c {
  background: #b3c823;
  color: #1a1d00;
}

.energy-d {
  background: #f3d41b;
  color: #2b2300;
}

.energy-e {
  background: #f6ad1a;
  color: #2b1a00;
}

.energy-f {
  background: #ec7a1f;
  color: #2b1000;
}

.energy-g {
  background: #c2361b;
}

.energy-h {
  background: #a51d1d;
}

.panel .notice {
  margin: 12px 0 0;
}

.description + .description {
  margin-top: 16px;
}

.description h3 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}

.description h3 .icon {
  width: 17px;
  height: 17px;
  color: var(--muted);
}

/* ImmoScout's AI summary, set apart from the landlord's texts */
.description-generated {
  background: var(--surface-2);
  border-left: 3px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
}

.description-generated .hint {
  margin-top: 6px;
}

.prose {
  max-width: 72ch; /* readable lines on wide screens */
  white-space: pre-line;
  overflow-wrap: anywhere;
}

textarea,
input,
select {
  font: inherit;
  font-size: 16px; /* no zoom on focus in iOS */
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  width: 100%;
}

textarea {
  padding: 12px;
  resize: vertical;
  line-height: 1.45;
}

textarea.message {
  min-height: 220px;
}

/* under the message: what the greeting rules chose (detail.tsx) */
.message-note {
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 8px;
}

input,
select {
  height: 46px;
  padding: 0 12px;
}

select {
  -webkit-appearance: none;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px;
}

textarea:focus,
input:focus,
select:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  border-color: transparent;
}

/* ---------- actions (detail page) ---------- */

/* One list of actions (detail.tsx). Phones and tablets: a round button at the bottom right opens it as a menu above
   it. Wide screens: a rail left of the content. Where popover isn't supported it stays a plain list at the end of the
   page – the base styles here, which also undo the popover's own (fixed, centred, framed). */
.actions {
  --action-hover: rgba(120, 120, 128, 0.12);
  --action-separator: rgba(60, 60, 67, 0.14);
  --action-backdrop: rgba(0, 0, 0, 0.12);
  --action-menu-bg: rgba(255, 255, 255, 0.94);
  --action-trigger-bg: var(--bar-bg);
  --action-switch-off: var(--switch-off);
  --action-menu-shadow: 0 12px 40px rgba(0, 0, 0, 0.16), 0 1px 4px rgba(0, 0, 0, 0.08);
}

@media (prefers-color-scheme: dark) {
  .actions {
    --action-hover: rgba(120, 120, 128, 0.26);
    --action-separator: rgba(84, 84, 88, 0.6);
    --action-backdrop: rgba(0, 0, 0, 0.4);
    --action-menu-bg: rgba(44, 44, 46, 0.94);
    --action-trigger-bg: rgba(44, 44, 46, 0.86);
    --action-switch-off: rgba(120, 120, 128, 0.4);
    --action-menu-shadow: 0 12px 40px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 255, 255, 0.06);
  }
}

.actions-trigger {
  display: none;
}

.action-menu {
  position: static;
  inset: auto;
  display: flex;
  flex-direction: column;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow);
}

.action-form {
  margin: 0;
}

/* a row: icon, name and hint, the toggle's switch */
.action {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 60px;
  margin: 0;
  padding: 9px 16px;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}

.action-menu > * + * {
  border-top: 1px solid var(--action-separator);
}

.action .icon {
  width: 22px;
  height: 22px;
}

/* the one that leaves the app, gently set apart */
.action-primary .icon {
  color: var(--accent);
}

.action-text {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
}

.action-label {
  font-size: 1rem;
  font-weight: 550;
  line-height: 1.25;
}

.action-label-short {
  display: none;
}

.action-hint {
  margin-top: 1px;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.3;
}

.action:active:not(:disabled) {
  background: var(--action-hover);
}

/* no template: the hint says why, so only the rest fades */
.action:disabled {
  cursor: default;
}

.action:disabled .icon,
.action:disabled .action-label {
  opacity: 0.4;
}

/* one icon per state: copied, and the toggle's two states */
.action .icon-done,
.action.done .icon-idle,
.action[aria-pressed="true"] .icon-off,
.action[aria-pressed="false"] .icon-on {
  display: none;
}

.action.done .icon-done {
  display: inline-block;
}

.action.done,
.action[aria-pressed="true"] .icon {
  color: var(--good);
}

/* "Angeschrieben": a switch, like the profile's */
.action-switch {
  position: relative;
  flex-shrink: 0;
  width: 40px;
  height: 24px;
  border-radius: 999px;
  background: var(--action-switch-off);
  transition: background-color 0.2s;
}

.action-switch::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: transform 0.2s;
}

.action[aria-pressed="true"] .action-switch {
  background: var(--good);
}

.action[aria-pressed="true"] .action-switch::before {
  transform: translateX(16px);
}

.action:focus,
.actions-trigger:focus {
  outline: none;
}

.action:focus-visible {
  border-radius: 10px;
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}

/* Phones and tablets: the trigger floats above the home indicator, the menu opens above it – tapping outside or Esc
   closes it (popover="auto"), the backdrop keeps that tap from reaching the page. The page's bottom padding
   (.has-action-bar) keeps the end of the content clear of the button. */
@supports selector(:popover-open) {
  @media (width < 1024px) {
    .actions {
      --trigger-size: 56px;
      --trigger-right: calc(16px + env(safe-area-inset-right));
      --trigger-bottom: max(16px, calc(env(safe-area-inset-bottom) + 4px));
    }

    .actions-trigger {
      -webkit-appearance: none;
      appearance: none;
      position: fixed;
      right: var(--trigger-right);
      bottom: var(--trigger-bottom);
      z-index: 10;
      display: flex;
      align-items: center;
      justify-content: center;
      width: var(--trigger-size);
      height: var(--trigger-size);
      padding: 0;
      border: 0;
      border-radius: 50%;
      background: var(--action-trigger-bg);
      -webkit-backdrop-filter: saturate(180%) blur(16px);
      backdrop-filter: saturate(180%) blur(16px);
      box-shadow: 0 0 0 1px var(--action-separator), 0 6px 20px rgba(0, 0, 0, 0.16);
      color: var(--accent);
      cursor: pointer;
      touch-action: manipulation;
      transition: transform 0.15s;
    }

    .actions-trigger .icon {
      width: 26px;
      height: 26px;
    }

    .actions-trigger:active {
      transform: scale(0.94);
    }

    .actions-trigger:focus-visible {
      outline: 2px solid var(--accent);
      outline-offset: 3px;
    }

    /* written to: the envelope gets its check */
    .actions-trigger .icon-on,
    .actions:has(.action[aria-pressed="true"]) .actions-trigger .icon-off {
      display: none;
    }

    .actions:has(.action[aria-pressed="true"]) .actions-trigger {
      color: var(--good);
    }

    .actions:has(.action[aria-pressed="true"]) .actions-trigger .icon-on {
      display: inline-block;
    }

    .action-menu {
      position: fixed;
      right: var(--trigger-right);
      bottom: calc(var(--trigger-bottom) + var(--trigger-size) + 10px);
      left: auto;
      top: auto;
      width: min(300px, 100vw - 32px - env(safe-area-inset-left) - env(safe-area-inset-right));
      max-height: calc(100dvh - var(--trigger-bottom) - var(--trigger-size) - 26px - env(safe-area-inset-top));
      overflow-y: auto;
      border-radius: 18px;
      background: var(--action-menu-bg);
      -webkit-backdrop-filter: saturate(180%) blur(24px);
      backdrop-filter: saturate(180%) blur(24px);
      box-shadow: var(--action-menu-shadow);
      transform-origin: calc(100% - var(--trigger-size) / 2) 100%;
      transition:
        opacity 0.16s,
        transform 0.16s,
        overlay 0.16s allow-discrete,
        display 0.16s allow-discrete;
    }

    .action-menu:not(:popover-open) {
      display: none;
      opacity: 0;
      transform: translateY(6px) scale(0.96);
    }

    @starting-style {
      .action-menu:popover-open {
        opacity: 0;
        transform: translateY(6px) scale(0.96);
      }
    }

    .action-menu::backdrop {
      background: var(--action-backdrop);
    }
  }

  @media (width < 1024px) and (prefers-reduced-motion: reduce) {
    .action-menu,
    .actions-trigger {
      transition: none;
    }
  }
}

/* Wide screens: a rail left of the content that stays in view while scrolling – icon left of a short label (the full
   one as tooltip), in the order of use. The content stays centred under the top bar: an empty column on the right
   balances the rail. */
@media (min-width: 1024px) {
  .detail-page .container {
    max-width: none;
    padding-bottom: calc(40px + env(safe-area-inset-bottom));
  }

  .detail-page .topbar-inner {
    max-width: min(912px, 100% - 384px); /* the content column plus its gutters */
  }

  .detail-head h1 {
    font-size: 1.6rem;
  }

  .detail {
    display: grid;
    grid-template-columns: 168px minmax(0, 880px) 168px;
    justify-content: center;
    column-gap: 24px;
  }

  .detail-main {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;
  }

  .actions {
    position: sticky;
    top: calc(52px + env(safe-area-inset-top) + 16px);
    grid-column: 1;
    grid-row: 1;
    align-self: start;
  }

  .action-menu {
    gap: 2px;
    padding: 6px;
  }

  .action-menu > * + * {
    border-top: 0;
  }

  .action {
    gap: 10px;
    min-height: 40px;
    padding: 8px 10px;
    border-radius: 9px;
  }

  .action .icon {
    width: 18px;
    height: 18px;
    color: var(--muted);
  }

  .action-primary .icon {
    color: var(--accent);
  }

  .action-label {
    font-size: 0.875rem;
  }

  .action-hint,
  .action-switch {
    display: none;
  }

  .action-label-short {
    display: inline;
  }

  /* still the button's name (like .visually-hidden) */
  .action-label-full {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .action:not(:disabled):not(.done):not([aria-pressed="true"]):hover {
    background: var(--action-hover);
  }

  /* copied, and written to: a calm green */
  .action.done,
  .action[aria-pressed="true"] {
    background: var(--good-bg);
    color: var(--good);
  }

  .action.done .icon,
  .action[aria-pressed="true"] .icon {
    color: inherit;
  }

  .action:focus-visible {
    border-radius: 9px;
    outline-offset: -2px;
  }
}

/* ---------- forms ---------- */

.field {
  display: block;
  min-width: 0;
}

.field + .field {
  margin-top: 12px;
}

.field-label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 4px;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.field-row + .field-row {
  margin-top: 12px;
}

.field-row .field + .field {
  margin-top: 0;
}

.input-unit {
  position: relative;
  display: block;
}

.input-unit input {
  display: block;
  padding-right: 40px;
}

.unit {
  position: absolute;
  right: 12px;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  color: var(--muted);
  font-size: 0.9rem;
  pointer-events: none;
}

.invalid input,
.invalid textarea {
  border-color: var(--danger);
}

.field-error {
  display: block;
  color: var(--danger);
  font-size: 0.82rem;
  margin-top: 4px;
}

.settings {
  margin-bottom: 20px;
}

/* a label with a switch on the right, e.g. "Ich habe SuchenPlus" */
.toggle-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

.toggle-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.toggle-label .plus-icon {
  width: 20px;
  height: 20px;
}

.toggle-field + .hint {
  margin-top: 4px;
}

/* the template syntax in the profile's hints */
.hint code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.95em;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0 4px;
}

.push-status {
  font-weight: 550;
}

.push-status.on {
  color: var(--good);
}

#push-hint {
  margin: 12px 0 0;
}

.devices {
  margin-top: 14px;
  font-size: 0.9rem;
}

.devices summary {
  cursor: pointer;
  color: var(--muted);
}

.devices ul {
  margin: 8px 0 0;
  padding-left: 18px;
}

.devices li + li {
  margin-top: 4px;
}

.logout {
  margin-top: 8px;
}

/* ---------- login ---------- */

.login-body .container {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: calc(24px + env(safe-area-inset-top));
}

.login {
  width: 100%;
  max-width: 380px;
  text-align: center;
}

.login-icon {
  margin: 0 auto 14px;
  border-radius: 16px;
  box-shadow: var(--shadow);
}

.login > .muted {
  margin: 4px 0 20px;
}

.login-form {
  text-align: left;
  margin-top: 4px;
}

.login-form .button {
  margin-top: 18px;
}
