/* hausannonce.de — base stylesheet.
   Identity: Design System v1.1 (immo/company/design/README.md) — slate, paper,
   one lit window. Layout/density tokens per ADR-0054 are untouched. */

@font-face{font-family:'Archivo';font-style:normal;font-weight:600 700;font-display:swap;
  src:url("fonts/archivo-latin.cd56e2ec63d7.woff2") format('woff2')}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:400 600;font-display:swap;
  src:url("fonts/source-sans-3-latin.30164609c163.woff2") format('woff2')}

:root{
  /* v1.1 palette by ROLE (README §3): Schiefer carries every primary action;
     Fensterlicht appears exactly twice site-wide (logo window + focus ring),
     never text; Bernstein is the text-level warm accent (links, prices, €);
     Patina/Ziegelrot mark state only. Cards are white panels on Papierweiß,
     separated by 1px Kalkgrau lines — no shadows, radius 2px ("Kante"). */
  --bg:#f4f5f6; --card:#ffffff; --text:#1c262e; --muted:#56626d; --border:#dde1e4;
  --accent:#2c3a47; --accent-soft:#e8ecef; --accent-text:#ffffff;
  --riss:#8f5c0f;   /* text accent (Bernstein). Name kept — ~40 call sites read the ROLE */
  --fokus:#e5a33d;  /* Fensterlicht: focus ring — its only appearance outside the logo */
  --chrome:#2c3a47; --chrome-text:#f4f5f6; --chrome-muted:#b9c2ca; --chrome-hover:#3a4956;
  --chrome-hover-bg:#ffffff; --chrome-hover-text:#1c262e;
  --ok:#3f6b54; --ok-soft:#e4efe9; --warn:#8f5c0f; --warn-soft:#f5eee1;
  --danger:#a3312c; --danger-soft:#f5e9e8; --info:#8f5c0f; --info-soft:#f5eee1;
  --shadow:none;
  --radius:2px;
  --r-pill:2px; --r-sm:2px;
  --mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
  --display:'Archivo',system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --body-font:'Source Sans 3',system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;

  --shell:88rem;    /* page-shell cap for grid/table/split/full content (T1b) */
  --measure:36rem;  /* prose column ≈ 70 characters at 16 px (C1) */
  --rail:20rem;     /* secondary column of the split archetype (T10) */
  --gutter:clamp(.85rem,2.2vw,1.4rem);
  --tap:24px;
  --sp-1:.25rem; --sp-2:.4rem; --sp-3:.6rem; --sp-4:.9rem; --sp-5:1.35rem; --sp-6:2rem;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
  --bg:#141a20; --card:#1c262e; --text:#f4f5f6; --muted:#9aa4ad; --border:#313c46;
  --accent:#3e5063; --accent-soft:#243039; --accent-text:#ffffff;
  --riss:#e5a33d; --fokus:#e5a33d;
  --chrome:#1c262e; --chrome-text:#f4f5f6; --chrome-muted:#8d97a0; --chrome-hover:#28343e;
  --chrome-hover-bg:#28343e; --chrome-hover-text:#f4f5f6;
  --ok:#6fae8c; --ok-soft:#1b2e24; --warn:#e5a33d; --warn-soft:#2b2415;
  --danger:#d4766f; --danger-soft:#391d1b; --info:#e5a33d; --info-soft:#2b2415;
  --shadow:none;
  }
}
:root[data-theme="dark"]{
  --bg:#141a20; --card:#1c262e; --text:#f4f5f6; --muted:#9aa4ad; --border:#313c46;
  --accent:#3e5063; --accent-soft:#243039; --accent-text:#ffffff;
  --riss:#e5a33d; --fokus:#e5a33d;
  --chrome:#1c262e; --chrome-text:#f4f5f6; --chrome-muted:#8d97a0; --chrome-hover:#28343e;
  --chrome-hover-bg:#28343e; --chrome-hover-text:#f4f5f6;
  --ok:#6fae8c; --ok-soft:#1b2e24; --warn:#e5a33d; --warn-soft:#2b2415;
  --danger:#d4766f; --danger-soft:#391d1b; --info:#e5a33d; --info-soft:#2b2415;
  --shadow:none;
}

*{box-sizing:border-box}
body{
  margin:0;background:var(--bg);color:var(--text);
  font:16px/1.55 var(--body-font);
  font-variant-numeric:tabular-nums;
}
h1,h2,h3{font-family:var(--display);letter-spacing:-.01em}
/* Links: Bernstein is the palette's text-safe accent ("Links, Preise") — the base
   rule catches content links that otherwise render browser-blue. Chrome, nav,
   footer and .button declare their own colours below and override it. */
a{color:var(--riss)}
::selection{background:var(--accent);color:var(--accent-text)}
:focus-visible{outline:2px solid var(--fokus);outline-offset:2px}
@media (prefers-reduced-motion: reduce){*{transition:none!important;animation:none!important}}

.skip-link{position:absolute;left:-9999px;top:0;background:var(--card);padding:.5rem 1rem;z-index:40}
.skip-link:focus{left:0}

/* Chrome compaction (T3): persistent chrome is paid on every screenful of every
   page, so it is the highest-leverage vertical pixel. Padding shrinks; the ≥24 px
   hit area does not — the links become inline-flex so min-height actually binds. */
.header{
  display:flex;justify-content:space-between;align-items:center;gap:1rem;
  padding:.5rem var(--gutter);background:var(--chrome);border-bottom:1px solid var(--chrome);
  position:sticky;top:0;z-index:30;
}
.brand{font-weight:700;font-size:1.15rem;color:var(--chrome-text);text-decoration:none;
  font-family:var(--display);display:inline-flex;align-items:center;gap:.5rem}
.brand span{color:var(--chrome-muted);font-weight:600}
/* Operator decision 2026-08-02: the word "annonce" carries Fensterlicht — the
   wordmark joins the logo's lit-window motif (brand lockup, not body text;
   5.2:1 on Schiefer). */
.brand b{color:var(--fokus);font-weight:inherit}
.brand:hover span{color:var(--chrome-hover-text)}
.brand:hover b{color:var(--riss)}
/* Monogramm: Striche erben die Chromfarbe (= „on dark"-Variante), das Fenster
   bleibt Fensterlicht — das einzige warme Element der Marke. Mindesthöhe 20px
   laut Zeichensatzregel; hier 22px. */
.brand svg{height:22px;width:auto;flex:none;color:var(--chrome-text)}
/* On the white hover ground the monogram strokes flip to ink (they follow
   currentColor); the Fensterlicht window keeps its hard fill. */
.brand:hover svg{color:var(--chrome-hover-text)}
/* Persistent primary-jobs nav (§5): Mieten · Kaufen · Inserieren · Preisüberblick */
.primary-nav{display:flex;gap:.15rem;align-items:center;flex-wrap:wrap}
.primary-nav a{color:var(--chrome-text);text-decoration:none;padding:.35rem .65rem;border-radius:var(--r-sm);
  font-weight:600;font-size:.95rem;display:inline-flex;align-items:center;min-height:var(--tap);
  position:relative}
.primary-nav a:hover{background:var(--chrome-hover-bg);color:var(--chrome-hover-text)}
/* Artefakt-Menülogik: die aktive Rubrik trägt eine Unterstreichung. Auf dem
   Schiefer-Chrom ist sie weiß — Fensterlicht wäre ihr dritter Auftritt. */
.primary-nav a[aria-current]::after{content:"";position:absolute;left:.65rem;right:.65rem;
  bottom:.15rem;height:2px;background:currentColor}
@media (max-width:640px){
  .header{flex-wrap:wrap}
  .primary-nav{order:3;flex-basis:100%;flex-wrap:nowrap;overflow-x:auto;
    gap:.1rem;padding-top:.4rem}
  .primary-nav a{white-space:nowrap}
}
.header>nav{display:flex;gap:.75rem;align-items:center}  /* legacy direct nav only */
.header a{color:var(--chrome-text);text-decoration:none;padding:.35rem .6rem;border-radius:var(--r-sm);
  display:inline-flex;align-items:center;min-height:var(--tap)}
.header a:hover{background:var(--chrome-hover-bg);color:var(--chrome-hover-text)}
/* The primary button in the chrome ("Registrieren") keeps its own hover — the
   white link-hover ground would collide with its !important white type. */
.header a.button:hover{background:var(--chrome-hover)}
.button{background:var(--accent);color:var(--accent-text)!important;border-radius:var(--r-pill);padding:.4rem 1rem}

/* ══════════════════════════════════════════════════════════════════════════
   Page archetypes (ADR-0054 / concept §4). Every page template declares one
   via {% block body_class %}; a page that declares none keeps the previous
   64 rem shell, so the rollout is monotone and a partial rollout cannot
   regress an unmigrated page.

     l-grid   card grids      → wide shell, extra width becomes extra columns
     l-table  rows of records → wide shell + dense rows
     l-split  one record      → wide shell, main column + secondary rail
     l-doc    prose           → measure-bound (widening it would be stretch waste)
     l-form   input           → measure + field pairing at ≥56 rem
     l-full   canvas (map)    → viewport-bleed
   ══════════════════════════════════════════════════════════════════════════ */
main{max-width:64rem;margin:0 auto;padding:var(--sp-4) var(--gutter)}
.l-grid main,.l-table main,.l-split main{max-width:var(--shell)}
.l-doc main{max-width:calc(var(--measure) + 8rem)}
.l-form main{max-width:calc(var(--measure) + 12rem)}
.l-full main{max-width:none}
/* Prose stays at the measure even where the shell is wider (C1). */
.l-doc .card>p,.l-doc .card>ul,.l-form .card>p{max-width:var(--measure)}

/* Split archetype (T10): the area gained by the wide shell carries the *next
   action* (booking / application / contact), not wider prose. The rail is a
   plain column on purpose (revision R3): a second sticky element would eat the
   fold the sticky action bar already protects, and a rail taller than the
   viewport would need a nested scroll container. Below the breakpoint the rail
   stacks in exactly the pre-existing section order — no reading-order change. */
.split{display:grid;gap:var(--sp-5)}
.split-main,.split-rail{min-width:0}
@media (min-width:64rem){
  .l-split .split{grid-template-columns:minmax(0,1fr) var(--rail);align-items:start}
  /* T4 (data-ink): with the contact card permanently visible in the rail, the
     sticky bar would repeat the same price + CTA. Kept in the DOM for print
     suppression rules and for narrow viewports. */
  .l-split .action-bar{display:none}
}

/* Form archetype (T13): pair *short generated* fields into two tracks; anything
   long or consequential (textarea, checkbox, a field showing errors) spans both,
   so the reading order stays row-major and no decision field gets cramped.
   Where :has() is unsupported every field simply spans one track. */
@media (min-width:56rem){
  .l-form .form-dense{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:0 var(--sp-5)}
  .l-form .form-dense>div{margin:.35rem 0}
  .l-form .form-dense>div:has(textarea),
  .l-form .form-dense>div:has(input[type=checkbox]),
  .l-form .form-dense>div:has(.errorlist),
  /* A field left alone right after a checkbox (e.g. Provisionsangabe below
     Provisionspflichtig) has no partner to pair with — span both tracks
     instead of leaving it half-width with a blank cell beside it. */
  .l-form .form-dense>div:has(input[type=checkbox])+div:last-child{grid-column:1/-1}
}

/* Energieausweis block (ADR-0065): one bordered fieldset holding the status
   question and the group its answer opens. `[hidden]` is set by the form page's
   progressive enhancement — without JS every group stays visible. */
.energy-block{
  border:1px solid var(--border);border-radius:var(--radius);
  padding:.6rem 1rem 1rem;margin:1rem 0;
}
.energy-block legend{padding:0 .4rem;font-weight:600}
.energy-block .alert{margin:.5rem 0}
.energy-group[hidden]{display:none}
.energy-group>.note{margin-top:.5rem}

.hero{text-align:center;padding:2.5rem 0 1.5rem}
.hero h1{margin:0 0 .25rem;font-size:1.9rem}
.subtitle{color:var(--muted);margin:0 0 1.25rem}
.searchbar{display:flex;gap:.5rem;max-width:34rem;margin:0 auto}
.searchbar input{
  flex:1;padding:.7rem 1rem;border:1px solid var(--border);border-radius:var(--r-pill);
  background:var(--card);color:var(--text);font-size:1rem;
}
.searchbar button{
  padding:.7rem 1.4rem;border:0;border-radius:var(--r-pill);background:var(--accent);
  color:var(--accent-text);font-size:1rem;cursor:pointer;
}
.searchbar :disabled{opacity:.55;cursor:not-allowed}
/* Same fixed row height as the filterbar, applied to the wrapper the
   places-autocomplete script puts around the <input> — see the .filterbar
   note above the equivalent rule. margin:0 strips the generic form>div{margin:
   .6rem 0} rule (form field wrapper spacing, meant for as_div-rendered forms)
   from leaking onto this unrelated div and pushing it out of line. */
.searchbar button,.searchbar>.ac-field{height:2.75rem;margin:0}
.note{color:var(--muted);font-size:.85rem;margin-top:1rem}
/* Hero: search-agent promise + price-atlas entry (§3.1) */
.hero-promise{margin:1rem 0 .25rem;font-size:.95rem}
.hero-promise a{color:var(--riss);font-weight:600}
.hero-links{margin:0}
.hero-links a{color:var(--muted);font-size:.9rem}
.price-atlas-link{margin-left:.4rem;white-space:nowrap}

/* T12: at minmax(14rem) + .8rem gap a 1392 px content column yields 5 columns
   instead of 4 — the extra width becomes extra results, not wider cards.
   auto-fit (not auto-fill) is deliberate: a result set smaller than one row
   still fills the width instead of hugging the left edge. */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:.8rem;
  margin-top:.8rem}
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:.75rem .95rem}
.card h2{margin:.2rem 0 .4rem;font-size:1.15rem}
.card p{margin:0;color:var(--muted)}
.narrow{max-width:44rem;margin:1rem auto}

.footer{border-top:1px solid var(--border);margin-top:2.5rem;
  padding:1.5rem var(--gutter) 2.5rem;color:var(--muted);font-size:.9rem}
.footer a{color:var(--muted)}
.footer a:hover{color:var(--text)}
.footer a{color:var(--muted)}

/* Alerts (Django messages) */
.alert{border-radius:var(--radius);padding:.6rem 1rem;border:1px solid var(--border)}
.alert.success{background:var(--ok-soft);color:var(--ok)}
.alert.error{background:var(--danger-soft);color:var(--danger)}
.alert.warning{background:var(--warn-soft);color:var(--warn)}
.alert.info{background:var(--info-soft);color:var(--info)}

/* Forms (as_div renderer → each field in a top-level <div>, a11y aria-describedby) */
form p,form>div{margin:.6rem 0}
form label{display:block;font-weight:600;margin-bottom:.15rem}
/* Required fields: a visible marker for sighted users (screen readers already
   get the `required` attribute); explained by the "* Pflichtfeld" legend. */
label.required::after{content:" *";color:var(--danger);font-weight:700}
input,select,textarea{
  width:100%;padding:.55rem .75rem;border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--card);color:var(--text);font:inherit;
}
input[type=checkbox]{width:auto;min-width:24px;min-height:24px}
/* Native form widgets (checkbox tick, radio dot, range, progress) otherwise
   paint browser-blue — accent-color pulls them into the palette and follows
   the theme via the token. */
input[type=checkbox],input[type=radio],input[type=range],progress{accent-color:var(--accent)}
/* Password reveal toggle (JS-enhanced in base.html) — button sits inside the field */
.pw-field{position:relative;display:block}
.pw-field>input{padding-right:2.75rem}
.pw-reveal{
  position:absolute;top:0;right:0;height:100%;width:2.75rem;
  display:flex;align-items:center;justify-content:center;
  background:none;border:0;padding:0;margin:0;color:var(--muted);cursor:pointer;
  border-radius:0 var(--r-sm) var(--r-sm) 0;
}
.pw-reveal:hover{color:var(--text)}
.pw-reveal:focus-visible{outline:2px solid currentColor;outline-offset:-3px}
.pw-reveal svg{width:1.2rem;height:1.2rem;display:block}
.helptext,.note{color:var(--muted);font-size:.85rem}
.errorlist{color:var(--danger);list-style:none;margin:.15rem 0;padding:0;font-size:.9rem}
.button-primary{
  display:inline-block;padding:.6rem 1.4rem;border:0;border-radius:var(--r-pill);
  background:var(--accent);color:var(--accent-text);font-size:1rem;cursor:pointer;
  text-decoration:none;
}

/* Assistant (ADR-0069). Every panel reads as an accessory to the real control
   next to it, never as the primary one: --accent-soft ground, no accent fill on
   its buttons, and the surrounding form/filter bar keeps the primary emphasis.
   Uses existing tokens only, so light/dark and the density budgets hold. */
.assistant-search,.assistant-qa,.assistant-expose,.assistant-reply{
  background:var(--accent-soft);border:1px solid var(--border);
  border-radius:var(--radius);padding:.6rem .8rem;margin:.6rem 0}
.assistant-search button,.assistant-qa button,
.assistant-expose button,.assistant-reply button{
  flex:0 0 auto;height:2.75rem;padding:.55rem 1.1rem;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--card);color:var(--text)}
/* M1: the free-text box sits on one row with its button, like the filter bar. */
.assistant-search{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}
.assistant-search label{flex:0 0 auto;font-size:.85rem;color:var(--muted)}
.assistant-search input{flex:2;min-width:14rem;height:2.75rem}
.assistant-search .note{flex:1 1 100%;margin:.2rem 0 0}
/* M2: quoted-back question above, answer below, with a left rule so the answer
   is visibly not the listing's own text. */
.assistant-question{margin:.6rem 0;padding:.1rem 0 .1rem .8rem;
  border-left:3px solid var(--border);color:var(--muted)}
.assistant-answer{margin:.6rem 0;padding:.6rem .8rem;
  background:var(--accent-soft);border-left:3px solid var(--accent);
  border-radius:var(--radius)}
.assistant-answer .note{margin:0 0 .35rem}
/* M3/M4: a single trigger button with its explanation beside it. */
.assistant-expose,.assistant-reply{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center}
.assistant-expose .note,.assistant-reply .note{margin:0;flex:1 1 12rem}
/* M5 (ADR-0070): the entry point is a single button, styled exactly like the
   other assistant triggers so the chat reads as one more accessory, not a new
   primary path. */
.assistant-chat-start{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center}
.assistant-chat-start .note{margin:0;flex:1 1 12rem}
/* M5 transcript: turns alternate by side rule and ground, never by colour alone
   (each also carries a visible role label, so the distinction survives a
   monochrome or high-contrast rendering — WCAG AA, CONCEPT-UI §1). */
.chat-turns{list-style:none;margin:.8rem 0;padding:0;display:flex;
  flex-direction:column;gap:.6rem}
.chat-turn{padding:.5rem .8rem;border-radius:var(--radius);border:1px solid var(--border)}
.chat-turn p{margin:.25rem 0}
.chat-role{font-size:.78rem;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted)}
.chat-turn-user{background:var(--card);border-left:3px solid var(--border)}
.chat-turn-assistant{background:var(--accent-soft);border-left:3px solid var(--accent)}
.chat-turn-empty{background:transparent;border-style:dashed;color:var(--muted)}

/* List filter bar */
.filterbar{display:flex;gap:.5rem;flex-wrap:wrap;margin:.6rem 0}
.filterbar input{flex:2;min-width:12rem}
.filterbar select{flex:1;min-width:10rem}
.filterbar button{flex:0;padding:.55rem 1.2rem;border:0;border-radius:var(--r-sm);
  background:var(--accent);color:var(--accent-text);cursor:pointer;white-space:nowrap}
.filterbar .amenities{flex:1 1 auto;display:flex;flex-wrap:wrap;gap:.75rem;
  align-items:center;border:1px solid var(--border);border-radius:var(--r-sm);
  padding:.3rem .7rem;margin:0;min-width:12rem}
.filterbar .amenities legend{font-size:.8rem;color:var(--muted);padding:0 .3rem}
.filterbar .amenities label{display:inline-flex;align-items:center;gap:.3rem;
  font-weight:400;white-space:nowrap}
.filterbar .amenities input{flex:0 0 auto;min-width:0}
/* One row height for every filterbar control (operator request): text inputs,
   selects, the submit button and the "Weitere Filter" toggle — across wrapped
   flex lines, where stretch alone can't equalise. Checkboxes keep their square.
   The matching min-height for .filter-more>summary lives at its own rule
   further down (it needs display:flex/gap too) rather than a second
   `.filter-more>summary{…}` block here — same selector, same specificity,
   so a second block would just be silently overruled by source order and do
   nothing (a real, previously-shipped instance of exactly that: see the fix
   at the later rule). */
.filterbar>input,.filterbar>select,.filterbar>button,
.filter-more-body>input,.filter-more-body>select{height:2.75rem}
/* The places-autocomplete script (base.html) wraps the search <input> in a
   .ac-field <div> on load, turning it from a direct child into a grandchild —
   the >input rule above stops matching it the moment that runs, so it falls
   back to unstretched intrinsic height and drifts short whenever it wraps
   onto its own flex line alone. Match the wrapper explicitly instead.
   margin:0 strips the generic form>div{margin:.6rem 0} rule (form field
   wrapper spacing, meant for as_div-rendered forms) that otherwise leaks onto
   this unrelated div and pushes it 9.6px out of line with its siblings. */
.filterbar>.ac-field{height:2.75rem;margin:0}
/* A wrapped multi-line "Ausstattung" checklist can legitimately grow past one
   row — floor it at the row height rather than force-clipping it. */
.filter-more-body .amenities{min-height:2.75rem}

/* Secondary filters behind a native <details> (T5): the fold belongs to the
   results, not to controls most visitors never touch. Safety rule — the block
   renders `open` whenever any control inside it is active, so an applied filter
   is never hidden from the person it applies to. */
/* Closed, the block is an ordinary item on the first bar row, so hiding the
   secondary controls costs no row at all; opened, it claims a row of its own. */
.filter-more{flex:0 1 auto;border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--card);padding:0 .6rem}
.filter-more[open]{flex:1 1 100%}
/* max() keeps both floors: the WCAG tap-target minimum (--tap) and the
   filterbar row height (2.75rem, minus the 2px .filter-more border) so the
   closed toggle lines up with its siblings instead of shrinking to its own
   unpadded content height. This rule previously duplicated the OTHER
   .filter-more>summary block above with a plain `min-height:var(--tap)`
   (24px) — same selector/specificity, so being the later declaration in the
   file, it silently won and undid that block's alignment fix. */
.filter-more>summary{display:flex;align-items:center;gap:.4rem;
  min-height:max(var(--tap),calc(2.75rem - 2px));
  padding:.35rem .2rem;cursor:pointer;font-size:.9rem;font-weight:600;color:var(--accent)}
.filter-more>summary::marker,.filter-more>summary::-webkit-details-marker{color:var(--muted)}
.filter-more[open]{padding-bottom:.5rem}
.filter-more-body{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}
.filter-more-body>input,.filter-more-body>select{flex:1 1 9rem;min-width:0}
.filter-more-body .amenities{flex:1 1 100%}

/* Saved-search form ("Suche speichern") */
.save-search-nudge{margin:.5rem 0 .1rem;font-weight:600;color:var(--accent)}
.save-search{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;margin:.25rem 0 .9rem}
.save-search label{font-weight:400;color:var(--muted);margin:0}
.save-search select{width:auto}
.save-search button{padding:.45rem 1rem;border:0;border-radius:var(--r-pill);
  background:var(--accent);color:var(--accent-text);cursor:pointer;width:auto}
/* Same row height as the filterbar above it (operator request) — select and
   button had no shared height at all before and only lined up by accident. */
.save-search select,.save-search button{height:2.75rem}

/* Facet chips (ch. 6) */
.facets{display:flex;gap:.4rem;flex-wrap:wrap;margin:.25rem 0 1rem}
.chip{
  display:inline-block;padding:.3rem .85rem;border-radius:var(--r-pill);min-height:24px;
  background:var(--card);border:1px solid var(--border);color:var(--text);
  text-decoration:none;font-size:.9rem;
}
.chip.active{background:var(--accent);color:var(--accent-text);border-color:var(--accent)}
.chip.empty{color:var(--muted);opacity:.6}

/* Removable active-filter chips (§3.2): one-click broadening of the search */
.filter-chips{align-items:center;gap:.4rem;margin:.25rem 0 .75rem}
.filter-chips-label{color:var(--muted);font-size:.85rem}
.chip.removable{background:var(--accent-soft);border-color:var(--accent-soft);color:var(--accent)}
.chip.removable span{opacity:.7;font-size:.8em}
.chip.removable:hover,.chip.removable:focus-visible{background:var(--danger-soft);
  border-color:var(--danger-soft);color:var(--danger)}

/* Per-card €/m² price signal (§3.2, ADR-0047) */
.per-sqm{color:var(--muted);font-size:.85rem;font-variant-numeric:tabular-nums;
  font-family:var(--mono);letter-spacing:.02em}
.per-sqm b,.per-sqm strong{color:var(--riss);font-weight:700}
.per-sqm .price-change{margin-left:.3rem}

/* Badges & tables */
.badges{margin:0 0 .25rem}
.badge{display:inline-block;background:var(--accent-soft);color:var(--accent);
  border-radius:var(--r-pill);padding:.15rem .7rem;font-size:.85rem}
.badge.status-active{background:var(--ok-soft);color:var(--ok)}
.badge.status-draft{background:var(--info-soft);color:var(--info)}
.badge.status-rejected,.badge.status-deleted{background:var(--danger-soft);color:var(--danger)}
.badge.status-review,.badge.status-expired{background:var(--warn-soft);color:var(--warn)}
/* Wide data tables scroll inside their card instead of bleeding past the box. */
.table-wrap{overflow-x:auto;margin:0 -.25rem}
.table{width:100%;border-collapse:collapse}
/* T4/T6: rows are separated by the existing hairline, so the padding that used
   to do the grouping can go — bounded by the --tap floor on the row actions. */
.table th,.table td{text-align:left;padding:.35rem .55rem;border-bottom:1px solid var(--border);
  vertical-align:top}
.actions{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center}
.actions form{display:inline}
.actions a{white-space:nowrap;padding:.3rem .7rem;border-radius:var(--r-pill);font-size:.9rem;
  border:1px solid var(--border);color:var(--text);
  display:inline-flex;align-items:center;min-height:var(--tap)}
.actions a:hover{background:var(--accent-soft)}
.actions button{width:auto;padding:.3rem .8rem;border:0;border-radius:var(--r-pill);font-size:.9rem;
  white-space:nowrap;background:var(--accent);color:var(--accent-text);cursor:pointer;
  min-height:var(--tap)}

/* Media */
.badge.status-ready{background:var(--ok-soft);color:var(--ok)}
.badge.status-uploaded{background:var(--info-soft);color:var(--info)}
.card-image{width:100%;height:10rem;object-fit:cover;border-radius:var(--r-sm);display:block;margin-bottom:.4rem}
.media-list .card-image{height:8rem}
.gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(11rem,1fr));gap:.6rem;margin:.75rem 0}
.gallery img{width:100%;height:9rem;object-fit:cover;border-radius:var(--r-sm);display:block}
.upload{display:grid;gap:.5rem;max-width:34rem}
.file-icon{font-size:2.2rem;margin:.4rem 0;text-align:center}

/* Account pages (allauth via templates/allauth/layouts/base.html) */
.account-card{max-width:26rem;margin:2rem auto;padding:1.5rem 1.75rem}
.account-card h1{font-size:1.4rem;margin:.25rem 0 1rem}
.account-card form{display:grid;gap:.7rem;margin:.75rem 0}
.account-card p{margin:.35rem 0}
.account-card label{font-weight:600}
.account-card input[type=checkbox]{min-height:0}
/* Colour scheme, now a setting instead of a header button (see WORKLOG
   2026-08-12). Laid out as a table so the three options align regardless of
   label width; the name is the row header, the control sits beside it, and the
   whole row keeps the 24 px hit area the rest of the chrome guarantees. */
.theme-choice{border:0;padding:0;margin:.5rem 0 1rem}
.theme-choice .table{width:auto}
.theme-choice th,.theme-choice td{vertical-align:middle;padding:.25rem .75rem .25rem 0}
.theme-choice th{font-weight:400}
.theme-choice label{display:inline-flex;align-items:center;min-height:var(--tap);cursor:pointer}
.theme-choice input[type=radio]{min-height:0;margin:0;cursor:pointer}
.theme-choice td.note{margin:0;white-space:nowrap}
@media (max-width:26rem){.theme-choice td.note{white-space:normal}}
.account-card button[type=submit]{
  padding:.65rem 1.4rem;border:0;border-radius:var(--r-pill);background:var(--accent);
  color:var(--accent-text);font-size:1rem;cursor:pointer;width:100%;margin-top:.25rem;
}
.account-card button[type=submit]:hover{opacity:.92}
.account-card a{color:var(--info)}
.account-card .helptext,.account-card ul{color:var(--muted);font-size:.85rem;margin:.15rem 0;padding-left:1.1rem}
.account-card h2{font-size:1.05rem;margin:1.2rem 0 .3rem}
.account-links{list-style:none;padding:0!important;font-size:1rem!important;color:var(--text)!important}
.account-links li{margin:.45rem 0}

/* Legal pages (imprint, privacy) */
.legal{margin:2rem auto;padding:1.5rem 1.75rem}
.legal h1{font-size:1.5rem;margin:.25rem 0 .5rem}
.legal h2{font-size:1.05rem;margin:1.4rem 0 .35rem}
.legal p{color:var(--text);margin:.4rem 0}
.legal .stand{color:var(--muted);font-size:.85rem}
.legal a{color:var(--info)}

/* Viewing slots */
.slot-list{list-style:none;margin:.5rem 0;padding:0}
.slot-list li{display:flex;gap:.75rem;align-items:center;flex-wrap:wrap;
  padding:.45rem 0;border-bottom:1px solid var(--border)}
.slot-list form{display:inline}
.slot-list button{width:auto;padding:.35rem .9rem;border:0;border-radius:var(--r-pill);
  background:var(--accent);color:var(--accent-text);cursor:pointer}

/* Inbox & conversations */
.hp-field{position:absolute!important;left:-9999px;top:-9999px}
/* Post-inquiry next-step panel (§3.4) */
.next-steps{background:var(--ok-soft);border:1px solid var(--ok-soft);border-radius:var(--radius);
  padding:.75rem 1.1rem;margin:.75rem 0 1rem}
.next-steps h2{margin:.1rem 0 .4rem;font-size:1.05rem;color:var(--ok)}
.next-steps ul{margin:0;padding-left:1.2rem}
.next-steps li{margin:.25rem 0}
.thread{display:flex;flex-direction:column;margin:1rem 0}
.message{max-width:75%;padding:.6rem .9rem;border-radius:var(--r-sm);background:var(--accent-soft);margin:.35rem 0}
.message.own{margin-left:auto;background:var(--info-soft)}
.message .meta{color:var(--muted);font-size:.8rem;margin:0 0 .25rem}
.message p{margin:0}

/* Detail page */
.views{color:var(--muted);font-variant-numeric:tabular-nums}

/* Sticky action bar (§3.3): the primary CTA (Anfragen/Merken/Besichtigung) is
   always one tap away on the long detail page. Pure CSS sticky, no JS; the
   buttons are on-page anchors + the merken POST, so it degrades gracefully. */
.action-bar{display:flex;justify-content:space-between;align-items:center;gap:.6rem;
  flex-wrap:wrap;background:var(--card);border:1px solid var(--border);
  border-radius:var(--r-pill);box-shadow:var(--shadow);padding:.5rem .6rem .5rem 1.1rem;
  margin:0 0 1rem;position:sticky;top:.5rem;z-index:20}
.action-bar-price{font-size:1.05rem;white-space:nowrap;font-variant-numeric:tabular-nums}
.action-bar-actions{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap}
.action-bar-actions form{margin:0}
.action-bar .save-favorite button{cursor:pointer}
.action-bar .button,.action-bar .button-primary{padding:.45rem 1.05rem;font-size:.95rem}
@media (max-width:520px){
  .action-bar{gap:.4rem;padding:.45rem .5rem}
  .action-bar .button,.action-bar .button-primary{padding:.45rem .8rem}
}

/* Property-question icon list (§3.3, ADR-0046): pets / barrier-free / WBS */
.question-list{display:flex;flex-wrap:wrap;gap:.4rem .9rem;list-style:none;
  margin:.5rem 0 0;padding:0}
.question-list li{background:var(--accent-soft);color:var(--text);border-radius:var(--r-pill);
  padding:.25rem .8rem;font-size:.9rem}
.facts{display:grid;grid-template-columns:max-content 1fr;gap:.25rem 1.25rem;margin:.75rem 0}
.facts dt{color:var(--muted)}
.facts dd{margin:0}
.pager{display:flex;gap:1rem;justify-content:center;align-items:center;margin:1.5rem 0}

/* ── Device layer (ADR-0057): the home page's design grammar, generalised to
   the component level so every page carries it. Section heads run out into a
   hairline (the dimension-line device); the €/m² figure is a measured tick;
   the search form is a framed "room" with corner marks. Palette-agnostic:
   only tokens are read. */
main > h2, main > section > h2, main > form > h2, .rule-head{
  display:flex;align-items:center;gap:1rem;font-size:1.25rem}
main > h2::after, main > section > h2::after, main > form > h2::after, .rule-head::after{
  content:"";flex:1;height:1px;background:var(--border);min-width:2rem}

.per-sqm{position:relative;display:flex;align-items:center;gap:.55rem;
  padding-top:.5rem;margin-top:.5rem;border-top:1px solid var(--border)}
.per-sqm::before,.per-sqm::after{content:"";position:absolute;top:-3px;width:1px;height:7px;
  background:var(--muted)}
.per-sqm::before{left:0}
.per-sqm::after{right:0}

.filterbar{position:relative;border:1.5px solid var(--text);border-radius:var(--radius);
  background:var(--card);padding:.5rem}
.filterbar::before,.filterbar::after{content:"";position:absolute;width:8px;height:8px;
  border:1.5px solid var(--riss)}
.filterbar::before{top:-1.5px;left:-1.5px;border-right:0;border-bottom:0}
.filterbar::after{bottom:-1.5px;right:-1.5px;border-left:0;border-top:0}

.facts dt{font-family:var(--mono);font-size:.82rem;letter-spacing:.02em;align-self:center}
.facts dd{font-variant-numeric:tabular-nums}

/* Verify-account nag banner + owner action bar (ADR-0035, edit affordance) */
.verify-banner{display:flex;flex-wrap:wrap;align-items:center;gap:.75rem}
.verify-banner form{margin:0}
.owner-actions{display:flex;flex-wrap:wrap;gap:.75rem;margin:1rem 0}
.boost-form{display:inline;margin:.25rem 0 0}

/* Photo categories: gallery caption + manage dropdown (media categorization) */
.gallery-item{margin:0;position:relative}
.gallery-item figcaption{font-size:.8rem;color:var(--muted);margin-top:.25rem}
.category-form{margin:.4rem 0 0;font-size:.85rem}
.category-form select{margin-left:.35rem}

/* Photo gallery: horizontal scroll strip + inline lightbox (no new window) */
.gallery-scroll{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
  gap:.6rem;padding-bottom:.5rem;-webkit-overflow-scrolling:touch}
.gallery-scroll .gallery-item{flex:0 0 auto;width:min(80%,18rem);scroll-snap-align:start}
.gallery-scroll .gallery-item img{height:12rem;cursor:zoom-in}
/* x/y counter pinned over the carousel (stays put while photos scroll under it) */
.gallery-wrap{position:relative}
.gallery-counter{position:absolute;top:.6rem;right:.6rem;z-index:2;margin:0;
  background:rgba(0,0,0,.6);color:#fff;padding:.2rem .6rem;border-radius:var(--r-pill);
  font-size:.85rem;font-variant-numeric:tabular-nums;pointer-events:none}
.gallery img{cursor:zoom-in}
.no-scroll{overflow:hidden}
.lightbox{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;
  justify-content:center;background:rgba(0,0,0,.92)}
.lightbox[hidden]{display:none}
.lightbox-img{max-width:92vw;max-height:86vh;object-fit:contain;border-radius:6px}
.lightbox-btn{position:absolute;background:rgba(255,255,255,.14);color:#fff;border:0;
  cursor:pointer;font-size:2rem;line-height:1;padding:.3rem .85rem;border-radius:var(--r-sm)}
.lightbox-btn:hover{background:rgba(255,255,255,.28)}
.lightbox-close{top:1rem;right:1rem}
.lightbox-prev{left:.6rem;top:50%;transform:translateY(-50%)}
.lightbox-next{right:.6rem;top:50%;transform:translateY(-50%)}
.lightbox-caption{position:absolute;bottom:1.2rem;color:#fff;background:rgba(0,0,0,.5);
  padding:.3rem .9rem;border-radius:var(--r-sm);font-size:.9rem}
.lightbox-count{position:absolute;top:1.35rem;right:4.7rem;margin:0;color:#fff;
  background:rgba(0,0,0,.55);padding:.3rem .75rem;border-radius:var(--r-pill);font-size:.95rem;
  font-variant-numeric:tabular-nums;pointer-events:none}

/* Merkliste comparison (§3.5): pick 2–3 and compare side by side */
.compare-bar{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;margin:0 0 1rem}
.compare-bar button{width:auto}
.compare-pick{margin:0 0 .4rem;font-size:.9rem}
.compare-pick label{display:inline-flex;align-items:center;gap:.4rem;font-weight:400}
.compare-pick input{width:auto;min-width:24px}
.compare-table th[scope=row]{color:var(--muted);white-space:nowrap}
.compare-table .price-change{margin-left:.3rem}

/* Provider run-a-letting hub (§4.2): inquiries + applications + viewings */
.hub-list{list-style:none;margin:.5rem 0;padding:0}
.hub-list li{display:flex;flex-wrap:wrap;gap:.5rem 1rem;align-items:center;
  justify-content:space-between;padding:.55rem 0;border-bottom:1px solid var(--border)}
.hub-application{gap:.5rem}
.hub-list .actions form{display:inline}

/* Create-listing wizard (§4.1): stepped progress + navigation */
.wizard-steps{display:flex;flex-wrap:wrap;gap:.4rem;list-style:none;margin:.5rem 0 1rem;padding:0;
  counter-reset:none}
.wizard-steps li{display:flex;align-items:center;gap:.35rem;color:var(--muted);font-size:.85rem}
.wizard-steps li:not(:last-child)::after{content:"›";margin-left:.4rem;color:var(--border)}
.wizard-step-num{display:inline-flex;align-items:center;justify-content:center;
  width:1.5rem;height:1.5rem;border-radius:var(--r-pill);background:var(--accent-soft);
  color:var(--accent);font-weight:700;font-size:.8rem}
.wizard-steps li.current{color:var(--text);font-weight:600}
.wizard-steps li.current .wizard-step-num{background:var(--accent);color:var(--accent-text)}
.wizard-steps li.done .wizard-step-num{background:var(--ok-soft);color:var(--ok)}
.wizard-nav{align-items:center;margin-top:1rem}
.wizard-nav form{margin:0}

/* Internal style & component reference (/stil/, §5) */
.swatches{list-style:none;margin:.5rem 0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:.5rem}
.swatches li{display:flex;align-items:center;gap:.5rem}
.swatch{width:1.6rem;height:1.6rem;border-radius:6px;border:1px solid var(--border);
  flex:0 0 auto}
.swatches code{font-size:.85rem}
.sg-form-demo{margin:.5rem 0}

/* Provider stats: summary + numeric table cells (Meine Inserate) */
.button-row{display:flex;flex-wrap:wrap;gap:.5rem;margin:0 0 1rem}
.stat-summary{display:flex;flex-wrap:wrap;gap:1.5rem;margin:0 0 1rem;padding:0}
.stat-summary div{margin:0}
.stat-summary dt{color:var(--muted);font-size:.85rem}
.stat-summary dd{margin:0;font-size:1.5rem;font-weight:700;font-variant-numeric:tabular-nums}
/* #1 visibility action per row (§4.2): turns the dashboard into a task list */
.vis-nudge{display:inline-block;margin-top:.2rem;font-size:.82rem;color:var(--accent);
  font-weight:600;text-decoration:none}
.vis-nudge:hover{text-decoration:underline}
td.num{text-align:right;font-variant-numeric:tabular-nums}

/* Right-side slide-in menu (hamburger → drawer) */
.site-menu{position:static}
.site-menu > summary{list-style:none;cursor:pointer;padding:.55rem;border-radius:var(--r-sm);
  display:inline-flex;align-items:center;justify-content:center;user-select:none}
.site-menu > summary::-webkit-details-marker{display:none}
.site-menu > summary:hover{background:var(--accent-soft)}
.menu-toggle-bars,.menu-toggle-bars::before,.menu-toggle-bars::after{
  display:block;width:22px;height:2px;background:var(--chrome-text);border-radius:2px;
  transition:transform .2s ease,opacity .2s ease}
.menu-toggle-bars{position:relative}
.menu-toggle-bars::before,.menu-toggle-bars::after{content:"";position:absolute;left:0}
.menu-toggle-bars::before{top:-7px}
.menu-toggle-bars::after{top:7px}
.site-menu[open] .menu-toggle-bars{background:transparent}
.site-menu[open] .menu-toggle-bars::before{top:0;transform:rotate(45deg)}
.site-menu[open] .menu-toggle-bars::after{top:0;transform:rotate(-45deg)}

.drawer-backdrop{position:fixed;inset:0;z-index:900;background:rgba(15,23,42,.45);
  opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s ease}
.site-menu[open] .drawer-backdrop{opacity:1;visibility:visible}

.drawer{position:fixed;top:0;right:0;height:100%;width:min(82vw,300px);z-index:1000;
  background:var(--card);box-shadow:var(--shadow);border-left:1px solid var(--border);
  display:flex;flex-direction:column;gap:.15rem;padding:3.5rem 1rem 1.25rem;
  overflow-y:auto;transform:translateX(100%);visibility:hidden;
  transition:transform .22s ease,visibility .22s ease}
.site-menu[open] .drawer{transform:translateX(0);visibility:visible}
.drawer a{display:block;color:var(--text);text-decoration:none;padding:.7rem .8rem;border-radius:var(--r-sm)}
.drawer a:hover{background:var(--accent-soft)}
.drawer .button{margin-top:.4rem;text-align:center}
.drawer .nav-aktion{font-weight:600}
body.menu-open{overflow:hidden}

/* Language switcher in the drawer */
.lang-switch{display:flex;gap:.4rem;margin-top:.75rem;padding-top:.75rem;border-top:1px solid var(--border)}
.lang-switch button{background:var(--accent-soft);border:0;color:var(--text);
  padding:.4rem .8rem;border-radius:var(--r-sm);cursor:pointer;font-weight:600}
.lang-switch button[aria-current]{background:var(--accent);color:var(--accent-text)}

/* Place autocomplete (PLZ + town suggestions below the field) */
.ac-field{position:relative;display:flex;flex:1 1 auto;min-width:0}
.searchbar .ac-field{flex:1}
.filterbar .ac-field{flex:2;min-width:12rem}
.ac-field>input{flex:1;min-width:0}
.ac-list{
  position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:50;
  margin:0;padding:.25rem;list-style:none;max-height:16rem;overflow-y:auto;
  background:var(--card);border:1px solid var(--border);border-radius:10px;
  box-shadow:var(--shadow);
}
.ac-list[hidden]{display:none}
.ac-option{
  display:flex;align-items:baseline;gap:.5rem;padding:.45rem .6rem;
  border-radius:7px;cursor:pointer;
}
.ac-option[aria-selected="true"],.ac-option:hover{background:var(--accent-soft)}
.ac-plz{font-variant-numeric:tabular-nums;font-weight:600;color:var(--text)}
.ac-ort{color:var(--text)}
.ac-region{margin-left:auto;color:var(--muted);font-size:.85rem;white-space:nowrap}

/* Price history note on the listing detail (#4) — a drop is good for seekers */
.price-change{display:inline-block;margin-left:.5rem;font-size:.9rem;font-weight:600;
  color:var(--warn)}
.price-change.down{color:var(--ok)}
.price-change .note{font-weight:400;color:var(--muted)}

/* ── Print: a clean, ink-saving exposé of the listing. Site chrome and
   interactive controls make no sense on paper, so they are removed; the photo
   carousel is unwrapped so every image prints; the transactional and
   "other listings" sections drop out (the latter tagged .no-print in the
   template, since their aria-labels are localized). ── */
@media print {
  *,*::before,*::after{background:transparent!important;box-shadow:none!important;color:#000!important}
  body{background:#fff}
  @page{margin:1.5cm}

  .header,.footer,.skip-link,#site-menu,.drawer,.drawer-backdrop,
  .searchbar,.save-search,.filterbar,.facets,.city-links,.pager,nav,
  button,.button,.button-primary,.actions,.alert,
  #lightbox,.gallery-counter,.lightbox-count,#push-toggle,
  .save-favorite,.no-print{display:none!important}

  /* Detail: drop the transactional (form) sections; keep facts/photos/energy */
  #besichtigung,#bewerben,#kontakt{display:none!important}

  /* Cards become plain document blocks */
  main,.card{border:none!important;border-radius:0!important;
    margin:0 0 1rem!important;padding:0!important;max-width:none!important}

  /* Photos: stack instead of horizontal-scroll so every image prints */
  .gallery,.gallery-scroll,.gallery-wrap{display:block!important;overflow:visible!important}
  .gallery-item,.gallery-link{display:inline-block!important;width:auto!important;
    margin:0 .3rem .3rem 0;vertical-align:top}
  .gallery img{max-width:48%!important;height:auto!important;page-break-inside:avoid}

  a[href]{text-decoration:none;color:#000!important}
  h1,h2{page-break-after:avoid}
  dl.facts{page-break-inside:avoid}
}

/* ══════════════════════════════════════════════════════════════════════════
   Home identity — "Grundriss" (ADR-0053). Scoped to body.home so no other
   page or global token is touched; rolls out page-by-page. Signature device:
   the dimension line (hairline + end-ticks + mono measurement) annotating real
   numbers — the nationwide count and each listing's €/m².
   ══════════════════════════════════════════════════════════════════════════ */
body.home{
  /* v1.1: the home names are aliases of the global tokens — one identity, one
     source. --riss keeps its ROLE (text/line accent) and resolves to Bernstein
     on light, Fensterlicht on dark; the CTA fill is Schiefer via --riss-ink. */
  --paper:var(--bg); --raise:var(--card); --ink:var(--text); --graphit:var(--muted);
  --linie:var(--border); --linie2:var(--border);
  --riss-ink:var(--accent); --on-riss:var(--accent-text); --frei:var(--ok);
  background:var(--paper); color:var(--ink);
}
.home main{max-width:var(--shell)}
.home .hp-mono,.home .hp-kicker,.home .hp-dim-label,.home .hp-go,.home .hp-loc,
.home .hp-price small,.home .hp-sqm .val,.home .hp-sqm .cmp,.home .hp-chip .n,
.home .hp-tag{font-family:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace}

/* hero */
.home .hp-hero{display:grid;grid-template-columns:1.1fr .9fr;gap:2rem;align-items:center;
  padding:clamp(1rem,3.4vw,2.3rem) 0 clamp(1rem,2.2vw,1.6rem)}
.home .hp-eyebrow{display:flex;align-items:center;gap:.7rem;margin:0 0 1.1rem;flex-wrap:wrap}
.home .hp-eyebrow .hp-rule{flex:0 1 3.5rem;height:1px;background:var(--linie)}
.home .hp-kicker{font-size:.75rem;line-height:1;letter-spacing:.04em;
  font-weight:600;color:var(--graphit)}
.home .hp-title{font-weight:800;font-size:clamp(2.1rem,5.4vw,3.55rem);line-height:.99;
  letter-spacing:-.02em;text-wrap:balance;margin:0}
.home .hp-sub{max-width:32rem;margin:1rem 0 1.5rem;font-size:1.05rem;color:var(--ink);opacity:.82}

/* search as a dimensioned room */
.home .hp-search{position:relative;display:flex;gap:.5rem;flex-wrap:wrap;align-items:stretch;
  max-width:38rem;padding:.5rem;background:var(--raise);border:1.5px solid var(--ink);border-radius:2px}
.home .hp-search::before,.home .hp-search::after{content:"";position:absolute;width:9px;height:9px;
  border:1.5px solid var(--riss)}
.home .hp-search::before{top:-1.5px;left:-1.5px;border-right:0;border-bottom:0}
.home .hp-search::after{right:-1.5px;bottom:-1.5px;border-left:0;border-top:0}
.home .hp-search input{flex:1 1 14rem;min-width:0;border:0;background:transparent;color:var(--ink);
  font:1rem/1.3 inherit;padding:.55rem .7rem}
.home .hp-search input:focus{outline:none}
.home .hp-search input::placeholder{color:var(--graphit)}
.home .hp-btn{font-weight:700;font-size:.95rem;border:1.5px solid var(--ink);background:transparent;
  color:var(--ink);border-radius:2px;padding:.6rem 1.15rem;cursor:pointer;white-space:nowrap}
.home .hp-btn:hover{background:var(--linie2)}
.home .hp-btn.primary{background:var(--riss-ink);border-color:var(--riss-ink);color:var(--on-riss)}
.home .hp-btn.primary:hover{filter:brightness(1.06)}
/* Same fixed row height as the filterbar/searchbar, applied to the wrapper
   the places-autocomplete script puts around the <input>; margin:0 strips the
   generic form>div{margin:.6rem 0} rule that otherwise pushes this div out of
   line with its siblings (see the .filterbar note for the same fix). */
.home .hp-btn,.home .hp-search>.ac-field{height:2.75rem;margin:0}

/* dimension line (the signature) */
.home .hp-dim{display:flex;align-items:center;gap:.7rem;max-width:38rem;margin:.9rem 0 0}
.home .hp-dim-rule{flex:1;height:1px;background:var(--linie)}
.home .hp-dim-tick{flex:none;width:1px;height:9px;background:var(--graphit)}
.home .hp-dim-label{font-size:.75rem;line-height:1;letter-spacing:.04em;
  font-weight:600;color:var(--graphit);white-space:nowrap;font-variant-numeric:tabular-nums}
.home .hp-dim-label b{color:var(--ink);font-weight:700}

/* hero secondary links (override global .hero-promise/.hero-links on home) */
.home .hero-promise{margin:1.3rem 0 .2rem;font-size:.95rem;color:var(--ink)}
.home .hero-promise a{color:var(--riss);font-weight:700;text-decoration:none}
.home .hero-promise a:hover{text-decoration:underline}
.home .hero-links{margin:0}
.home .hero-links a{color:var(--graphit);font-weight:600;font-size:.92rem;text-decoration:none}
.home .hero-links a:hover{color:var(--riss)}

/* floor-plan motif */
.home .hp-plan-wrap{align-self:center}
.home .hp-plan{display:block;width:100%;height:auto;max-width:26rem;margin-left:auto}
.home .hp-wall{fill:none;stroke:var(--ink);stroke-width:2}
.home .hp-thin{fill:none;stroke:var(--linie);stroke-width:1.25}
.home .hp-swing{fill:none;stroke:var(--graphit);stroke-width:1;stroke-dasharray:2 3}
.home .hp-measure{stroke:var(--riss);stroke-width:1}
.home .hp-glow{fill:var(--riss);opacity:.05}
.home .hp-mtext,.home .hp-rtext{fill:var(--graphit);font-size:9px;font-weight:600;
  font-family:ui-monospace,Menlo,monospace;letter-spacing:.08em}
.home .hp-rtext{opacity:.85}

/* intent tiles */
.home .hp-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--linie);
  border:1px solid var(--linie);border-radius:2px;overflow:hidden;
  margin:.4rem 0 clamp(1.4rem,3vw,2.2rem)}
.home .hp-tile{display:flex;flex-direction:column;gap:.4rem;min-height:9.5rem;padding:1.05rem 1.1rem;
  background:var(--raise);color:var(--ink);text-decoration:none;transition:background .15s}
.home .hp-tile:hover{background:var(--paper)}
.home .hp-glyph{display:block;color:var(--graphit)}
.home .hp-glyph svg{width:30px;height:30px}
.home .hp-tile:hover .hp-glyph{color:var(--riss)}
.home .hp-tile h2{margin:.3rem 0 0;font-weight:700;font-size:1.3rem;letter-spacing:-.01em}
.home .hp-tile p{margin:0;color:var(--ink);opacity:.72;font-size:.95rem}
.home .hp-go{margin-top:auto;font-size:.78rem;line-height:1;letter-spacing:.04em;
  font-weight:600;color:var(--graphit);display:inline-flex;align-items:center;gap:.4rem}
.home .hp-tile:hover .hp-go{color:var(--riss)}
.home .hp-go i{font-style:normal;transition:transform .15s}
.home .hp-tile:hover .hp-go i{transform:translateX(3px)}

/* section heads + chips */
.home .hp-section{margin:0 0 clamp(1.4rem,3vw,2.2rem)}
.home .hp-shead{display:flex;align-items:baseline;gap:1rem;margin:0 0 .8rem}
.home .hp-shead h2{margin:0;font-weight:800;font-size:1.4rem;letter-spacing:-.01em}
.home .hp-shead-rule{flex:1;height:1px;background:var(--linie);align-self:center}
.home .hp-chips{display:flex;flex-wrap:wrap;gap:.4rem;margin:0}
.home .hp-chip{display:inline-flex;align-items:center;gap:.4rem;padding:.42rem .8rem;background:var(--raise);
  border:1px solid var(--linie);border-radius:2px;color:var(--ink);text-decoration:none;
  font-weight:600;font-size:.85rem}
.home .hp-chip:hover{border-color:var(--riss);color:var(--riss)}
.home .hp-chip .n{color:var(--graphit);font-size:.8em;font-variant-numeric:tabular-nums}
.home .hp-chip:hover .n{color:var(--riss)}

/* vision section */
.home .hp-vision-lead{margin:0 0 1.1rem;font-size:1.05rem;color:var(--ink)}
.home .hp-vision-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
  gap:1rem 1.6rem;margin:0 0 1.1rem;padding:0;list-style:none}
.home .hp-vision-list li{display:flex;flex-direction:column;gap:.25rem}
.home .hp-vision-list strong{font-weight:700}
.home .hp-vision-list span{color:var(--ink);opacity:.72;font-size:.95rem}
.home .hp-vision-note{margin:0;font-size:.85rem;font-style:italic;color:var(--ink);opacity:.6}

/* listing cards + €/m² tick */
.home .hp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(14rem,1fr));gap:1rem}
.home .hp-listing{display:flex;flex-direction:column;background:var(--raise);border:1px solid var(--linie);
  border-radius:2px;overflow:hidden;color:var(--ink);text-decoration:none;
  transition:transform .15s,border-color .15s}
.home .hp-listing:hover{transform:translateY(-3px);border-color:var(--graphit)}
.home .hp-ph{position:relative;aspect-ratio:3/2;overflow:hidden;background:var(--linie2)}
.home .hp-ph img{width:100%;height:100%;object-fit:cover;display:block}
.home .hp-ph-plan{width:100%;height:100%;padding:1.2rem}
.home .hp-ph-plan path{fill:none;stroke:var(--graphit);stroke-width:2}
.home .hp-ph-plan line{stroke:var(--linie);stroke-width:2}
/* Operator decision 2026-08-02: every hp-tag ("Zur Miete"/"Zum Kauf") carries
   Patina — previously rent-only. */
.home .hp-tag{position:absolute;top:.6rem;left:.6rem;padding:.3rem .5rem;background:var(--paper);
  color:var(--frei);border:1px solid color-mix(in srgb,var(--frei) 40%,var(--linie));border-radius:2px;
  font-size:.7rem;line-height:1;letter-spacing:.03em;font-weight:600}
.home .hp-body{display:flex;flex-direction:column;gap:.45rem;flex:1;padding:.85rem 1rem 1rem}
.home .hp-body h3{margin:0;font-weight:700;font-size:1rem;line-height:1.25}
.home .hp-loc{margin:0;font-size:.8rem;line-height:1.2;color:var(--graphit);font-variant-numeric:tabular-nums}
.home .hp-price{margin:auto 0 0;font-weight:800;font-size:1.12rem;font-variant-numeric:tabular-nums}
.home .hp-price small{font-weight:600;font-size:.7rem;color:var(--graphit)}
.home .hp-sqm{display:flex;align-items:center;gap:.55rem;margin:0;padding-top:.55rem;
  border-top:1px solid var(--linie)}
.home .hp-sqm .rule{position:relative;flex:1;height:1px;background:var(--linie)}
.home .hp-sqm .rule::before,.home .hp-sqm .rule::after{content:"";position:absolute;top:-3px;
  width:1px;height:7px;background:var(--graphit)}
.home .hp-sqm .rule::before{left:0}
.home .hp-sqm .rule::after{right:0}
.home .hp-sqm .val{font-size:.8rem;font-weight:700;color:var(--riss);font-variant-numeric:tabular-nums}
.home .hp-sqm .cmp{font-size:.72rem;font-weight:500;color:var(--graphit);font-variant-numeric:tabular-nums}

/* responsive */
@media (max-width:820px){
  .home .hp-hero{grid-template-columns:1fr;gap:1.2rem}
  .home .hp-plan{max-width:18rem;margin:0 auto}
  .home .hp-tiles{grid-template-columns:1fr}
}
@media (max-width:520px){ .home .hp-plan-wrap{display:none} }

/* motion — gated so reduced-motion users keep the final (visible/drawn) state */
@media (prefers-reduced-motion:no-preference){
  .home .hp-fade{opacity:0;transform:translateY(12px);animation:hpFade .7s cubic-bezier(.2,.7,.2,1) both}
  .home .hp-d1{animation-delay:.08s}
  .home .hp-d2{animation-delay:.16s}
  .home .hp-d3{animation-delay:.24s}
  .home .hp-d4{animation-delay:.32s}
  .home .hp-wall{stroke-dasharray:920;stroke-dashoffset:920;animation:hpDash 1.4s ease .2s forwards}
  .home .hp-thin{stroke-dasharray:640;stroke-dashoffset:640;animation:hpDash 1.2s ease .5s forwards}
  .home .hp-measure{stroke-dasharray:340;stroke-dashoffset:340;animation:hpDash .9s ease 1s forwards}
  @keyframes hpFade{to{opacity:1;transform:none}}
  @keyframes hpDash{to{stroke-dashoffset:0}}
}
