/* Box (box.postcss:5-11) */
/* `.stat` was `.box` minus the 1544 step: the same surface written twice,
   unintentionally deviating from CD box.postcss. One declaration serves both;
   the metric tile is a box carrying a number and label (see
   .stat__num/.stat__label below). */
.box, .stat { padding:var(--sp-4); background:var(--surface-bg-muted); border:0; border-radius:var(--radius-none); }
@media (min-width:480px) { .box, .stat { padding:var(--sp-5); } }
@media (min-width:1024px){ .box, .stat { padding:var(--sp-6); } }
@media (min-width:1544px){ .box, .stat { padding:var(--sp-8); } }
/* NO more `.box + .box { margin-top:1px }`: it was a fossil of the old 1px seam
   idea (the :has() exception had already gone because the seam did not hold on
   light backgrounds). At (0,2,0), however, the rule still beat the column
   rhythm `.vertical-spacing > *` (0,1,0): two boxes on the service landing page
   stuck together as ONE block while everything else had 3rem spacing (user
   finding 2026-08-04). Stacked boxes now get spacing from their context:
   `.vertical-spacing > *` (main column, 3/3.5rem), `.container__aside > *`
   (1.75/2rem), or `.detail-layout__aside .box + .box` (1.5rem). */
/* h2 included: the box title always looks the same regardless of outline level.
   The tenant-detail sidebar uses h2 because otherwise the page jumps directly
   from h1 to h3 (tab panels introduce no intermediate level). */
.box h2, .box h3 { font-size:var(--text-base); }

/* Stat figures — expressed on .box (no CD component) */
/* Column ramp from --gap-responsive: the private partial copy (1.25/2.25/2.5)
   omitted xs/xl/3xl and was the consolidated ramp's third clone
   (Design Review C3). */
.stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:var(--gap-responsive); }
.stat { box-shadow:var(--shadow-none); }
/* THE portal's large-number typography: text-3xl · fw-bold · lh-tight ·
   secondary-600 · tabular figures. Three surfaces consume it: .stat (box),
   .kpi (dashboard card), .kpi-strip (documented borderless strip). Previously
   the same element used three sizes, two colors and two label positions
   (Design Review C8). Surfaces remain modifiers. */
.stat__num, .kpi__value, .kpi-strip__value { font-size:var(--text-3xl); font-weight:var(--fw-bold);
  line-height:var(--lh-tight); color:var(--color-secondary-600); font-variant-numeric:tabular-nums; }
.stat__label { font-size:var(--text-sm); color:var(--color-text-muted); margin-top:var(--sp-1-5); }

/* Download items (download-item.postcss:5-57) */
.download-items { list-style:none; margin:0; padding:0; }
.download-item { display:flex; width:100%; padding:var(--sp-4) 0; text-align:left;
  border-bottom:var(--stroke-1) solid var(--color-secondary-200); text-decoration:none; color:inherit; }
.download-item:hover { text-decoration:none; }
.download-item:active { background:var(--color-secondary-50); }
.download-item:focus-visible { position:relative; z-index:var(--z-local-content);
  outline:var(--stroke-2) solid var(--color-focus-ring); outline-offset:calc(-1 * var(--stroke-2)); }
.download-item:is([aria-disabled="true"], .is-disabled) { cursor:not-allowed; opacity:.55; pointer-events:none; }
.download-item[aria-busy="true"] { cursor:progress; opacity:.7; }
.download-item[aria-invalid="true"] { color:var(--color-error-text); border-bottom-color:var(--color-error); }
.download-item[data-empty="true"] { cursor:default; color:var(--color-text-muted); }
/* On tinted surfaces use the darker divider (download-item.postcss:12-14
   `.bg--secondary-50 &`); secondary-200 would barely show there. */
.bg--secondary-50 .download-item, .box .download-item { border-bottom-color:var(--color-secondary-300); }
.download-item__icon { flex:none; width:var(--sp-7); height:var(--sp-7);
  margin:calc(-1 * var(--sp-1)) 0 calc(-1 * var(--sp-1)) calc(-1 * var(--sp-1)); padding-right:var(--sp-1); color:var(--color-primary-600); }
@media (min-width:768px){ .download-item__icon { width:var(--sp-8); height:var(--sp-8); padding-right:var(--sp-2); } }
@media (min-width:1024px){ .download-item__icon { width:var(--sp-9); height:var(--sp-9); } }
.download-item > div { min-width:0; }
.download-item__title { margin:0; font-size:var(--text-base); font-weight:var(--fw-bold);
  overflow-wrap:anywhere; transition:color var(--duration) var(--ease-in-out); }
.download-item:hover .download-item__title { color:var(--color-primary-600); }
.download-item__description { margin:0; color:var(--color-text); overflow-wrap:anywhere; }
.download-item__meta-info { padding-top:var(--sp-3); }

/* Meta info (meta-info.postcss:5-18) */
/* DELIBERATE DEVIATION: CD starts at text-gray-500 and darkens to text-600 only
   inside .box/.bg--secondary-50, but gray-500 measures only ~4.4:1 on
   secondary-50 (below AA), which is why CD switches there. ONE value
   (--color-text-muted = text-600, tokens.css) serves both surfaces. */
.meta-info { margin:0; color:var(--color-text-muted); font-size:var(--text-sm); }
.meta-info__item:not(:last-child)::after { content:"|"; padding:0 var(--sp-2); }
@media (min-width:1024px){ .meta-info__item:not(:last-child)::after { padding:0 var(--sp-3); } }  /* CD: px-2 lg:px-3 */

/* Separator (separator.postcss:5-53) */
.separator { display:block; height:auto; border:0; margin:0; background:none; }
.separator::before { content:""; display:block; width:100%; border-bottom:var(--stroke-1) solid var(--color-secondary-200); }
.box .separator::before { border-bottom-color:var(--color-secondary-300); }
/* (Dead rules removed in the 2026-08 code review, F-S30 — no emitter in any template.) */

/* Back to top: while scrolling, the button floats at bottom right and docks at
   the footer information's top-right corner at the page end (CD requirement).
   The rail hangs from the footer's top edge (#main-footer is position:relative)
   and extends upward as a full-width invisible strip. It contains a normal
   `.container`, using the same centered max width as the footer, so the button
   aligns with `.footer-information`'s right edge instead of sticking to the
   viewport gutter. When docked, the button's top-right corner sits
   `--btt-margin` inside the footer information's top-right corner. */
@media screen and (prefers-reduced-motion: no-preference){ html { scroll-behavior:smooth; } }
/* The docked white box in the footer is CD behavior and STAYS:
   back-to-top-btn.postcss:11-13 sets bottom:-3.5rem (−4rem lg, −5rem xl),
   exactly one button-height protrusion into the following band on a bg-white
   button. It also aligns to the content container rather than the viewport edge,
   so at 1440 it no longer covers the third card's open action.
   HOW EARLY the button appears is the rail's height, and 200vh was too short.
   CD anchors its wrapper at `top: 80vh` of the CONTENT and runs it to the end
   (back-to-top-btn.postcss:11-25), so the button exists for all but the first
   four fifths of a screen. Anchored to the footer instead — which is what makes
   the docking work — the equivalent is a rail as tall as the page. Measured
   before: on the home page at 375px (10.2 screens) the button first appeared
   after 5.6 screens of scrolling, past half the page, exactly where a long
   mobile page needs it most (user finding, 2026-08-12). 1000vh covers every
   route in the portal; on a short page the surplus simply hangs above the
   document, where an absolute, pointer-events:none strip costs nothing.
   The MapLibre overlap this height once caused is now handled at the map
   (.pf-map/.dash-map control padding below), not by shortening the rail. */
.back-to-top-rail { position:absolute; left:0; right:0; height:1000vh; pointer-events:none; z-index:var(--z-local-control);
  /* Dock: button bottom = (margin + button height) below the footer top edge,
     therefore button top = margin below it. */
  bottom:calc(100% - (var(--sp-4) + var(--target-min))); }
.back-to-top-track { padding-inline-end:var(--sp-3); }
@media (min-width:1280px){ .back-to-top-track { padding-inline-end:var(--sp-4); } }
/* Space below attribution keeps the sticky back-to-top button (bottom right,
   2.75–4rem tall) from covering it. 3.5rem was overly generous and visibly
   pushed attribution away from the map edge; with the button at `bottom:1.5rem`,
   ~1.5rem is enough. This applies only to large maps in page flow; the button
   never interferes with the hero map. */
.dash-map .maplibregl-ctrl-bottom-right,
.pf-map .maplibregl-ctrl-bottom-right { padding-bottom:var(--sp-6); }
@media (min-width:1024px){ .back-to-top-rail { bottom:calc(100% - (var(--sp-4) + var(--sp-12))); } }
@media (min-width:1920px){ .back-to-top-rail { bottom:calc(100% - (var(--sp-4) + var(--sp-16))); } }
.back-to-top-track { height:100%; display:flex; flex-direction:column;
  justify-content:flex-end; align-items:flex-end; pointer-events:none; }
.back-to-top-btn { position:sticky; bottom:var(--sp-6); pointer-events:all; margin-inline-end:0;
  width:var(--target-min); height:var(--target-min); flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--radius-sm); box-shadow:var(--shadow-lg); background:var(--color-bg);
  transition:box-shadow var(--duration-fast), border-color var(--duration-fast); }
@media (min-width:1024px){ .back-to-top-btn { width:var(--sp-12); height:var(--sp-12); } }
/* CD's xl:w-16 assumes placement in the side gutter, which applies only from
   1920; it takes effect THERE as well (back-to-top-btn.postcss:27-30). */
@media (min-width:1280px){ .back-to-top-btn { width:var(--sp-12); height:var(--sp-12); } }
@media (min-width:1920px){ .back-to-top-btn { width:var(--sp-16); height:var(--sp-16); } }
@media (hover:none), (max-width:767.98px){
  .back-to-top-btn { bottom:var(--sp-4); margin-inline-end:var(--sp-3); }
}
.back-to-top-btn:hover { box-shadow:var(--shadow-xl); }
.back-to-top-btn--outline { border:var(--stroke-1) solid var(--color-primary-600); }
.back-to-top-btn--outline:hover { border-color:var(--color-primary-700); }
.back-to-top-btn__icon { width:50%; height:100%; background-color:var(--color-primary-600); }   /* CD: w-1/2 h-full */
.back-to-top-btn--outline:hover .back-to-top-btn__icon { background-color:var(--color-primary-700); }
/* Hide while the mobile menu or document viewer is open. */
.body--mobile-menu-is-open .back-to-top-rail,
body.body--overlay-open .back-to-top-rail { display:none; }

/* Balance the divider spacing: the row gap plus sp-3 margin equals the sp-4
   padding on its far side. */
.view-switch { display:flex; align-items:center; gap:var(--sp-1);
  border-left:var(--stroke-1) solid var(--color-secondary-300);
  margin-left:var(--sp-3); padding-left:var(--sp-4); }
/* `text-decoration:none` because the news page renders these as LINKS (state
   in the URL) inside .site-main, where the content-link rule would otherwise
   underline them — the CD opts its components out the same way
   (card.postcss:336 no-underline). */
.view-switch__btn { display:inline-flex; align-items:center; justify-content:center;
  min-width:var(--target-min); min-height:var(--target-min); padding:0; background:none; border:0; border-radius:var(--radius-none);
  color:var(--color-secondary-500); text-decoration:none; cursor:pointer; transition:color var(--duration), background var(--duration); }
.view-switch__btn:hover { color:var(--color-primary-700); text-decoration:none; }
.view-switch__btn:active { background:var(--color-secondary-100); color:var(--color-primary-700); }
.view-switch__btn:focus-visible { position:relative; z-index:var(--z-local-content);
  outline:var(--stroke-2) solid var(--color-focus-ring); outline-offset:calc(-1 * var(--stroke-2)); }
.view-switch__btn:is(:disabled, [aria-disabled="true"]) { cursor:not-allowed; opacity:.55; }
.view-switch__btn[aria-busy="true"] { cursor:progress; opacity:.7; }
.view-switch__btn[aria-invalid="true"] { color:var(--color-error-text); }
.view-switch__btn[data-empty="true"] { cursor:default; color:var(--color-text-muted); }
/* Do not convey state by color alone (WCAG 1.4.1, P2-10): the surface alone did
   exactly that, and forced-colors removes it without replacement. The underline
   now conveys state through shape (Item 2.6). */
/* Retain an underline so pressed state survives forced-colors mode. */
/* `--active` is the marker on LINK toggles (news page): links carry
   aria-current, not aria-pressed, so the pressed style keys on both — the ONE
   active style for every view toggle in both portals (2026-08 unification). */
.view-switch__btn[aria-pressed="true"],
.view-switch__btn--active { color:var(--color-text); background:var(--color-secondary-100);
  box-shadow:inset 0 calc(-1 * var(--stroke-3)) 0 var(--color-text-light); }

/* Action-card rows (`C.actionCard`, js/ui/components/content.js). These lived in
   the lazily loaded `apps/floorplan.css`, which portfolio and the shop never
   load — both rendered the card unstyled. The component is shared, so its rule
   belongs beside the component, in the always-loaded layer. */
.fp-svc-list { display:flex; flex-direction:column; }

/* `min-height` is the WCAG 2.5.5 touch floor: a row carrying only a label (no
   description) measured ~36px, which the tenant portal's a11y sweep flagged.
   The rows are the primary controls of a detail page, so they take the same
   floor the buttons do. */
.fp-svc { display:grid; grid-template-columns:minmax(0,1fr) 1rem;
  align-items:center; width:100%; min-height:var(--target-min);
  column-gap:var(--sp-2-5); padding:var(--sp-2) var(--sp-0-5); text-align:left;
  background:transparent; border:0; border-bottom:var(--stroke-1) solid var(--color-secondary-100);
  color:var(--color-text); font-family:inherit; font-size:var(--text-sm); line-height:inherit; text-decoration:none; }
.fp-svc:last-child { border-bottom:0; }
.fp-svc:hover { color:var(--color-primary-700); }
.fp-svc:is(button) { cursor:pointer; }
.fp-svc__content { display:block; min-width:0; }
.fp-svc__label, .fp-svc__description { display:block; }
.fp-svc__description { margin-top:var(--sp-0-5); color:var(--color-text-muted); font-size:var(--text-xs); line-height:1.4; }
.fp-svc__go { justify-self:end; color:var(--color-text-muted); }
.fp-svc--disabled, .fp-svc--disabled:hover { color:var(--color-text-muted); cursor:not-allowed; }

/* Static tutorial preview (#/knowledge/guides). The generated bitmap owns only
   the scene; every label and YouTube-like control remains editable markup. The
   figure is intentionally not a link until a real video destination exists. */
.tutorial-video { position:relative; isolation:isolate; width:100%; aspect-ratio:16 / 9;
  overflow:hidden; margin:0; border-radius:var(--radius-lg); background:var(--color-bg-muted);
  box-shadow:var(--shadow-md); }
.tutorial-video::after { content:""; position:absolute; inset:0; z-index:var(--z-local-content);
  background:var(--scrim-gradient-top); pointer-events:none; }
.tutorial-video__image { position:relative; z-index:var(--z-local-base); display:block;
  width:100%; height:100%; object-fit:cover; }
.tutorial-video__brand { position:absolute; z-index:var(--z-local-control); top:var(--sp-3);
  left:var(--sp-3); right:var(--sp-3); display:flex; align-items:center; gap:var(--sp-2);
  width:max-content; max-width:calc(100% - (2 * var(--sp-3))); color:var(--color-text-negative); }
.tutorial-video__crest { display:grid; place-items:center; flex:none; width:var(--sp-9);
  height:var(--sp-9); border-radius:var(--radius-full); background:var(--color-bg);
  box-shadow:var(--shadow-overlay-control); }
.tutorial-video__crest img { display:block; width:var(--sp-6); height:auto; }
.tutorial-video__copy { display:flex; flex-direction:column; min-width:0; line-height:var(--lh-tight); }
.tutorial-video__portal { font-size:var(--text-sm); font-weight:var(--fw-bold); overflow-wrap:anywhere; }
.tutorial-video__title { margin-top:var(--sp-0-5); color:var(--color-text-negative);
  font-size:var(--text-xs); overflow-wrap:anywhere; }
.tutorial-video__play { position:absolute; z-index:var(--z-local-control); top:50%; left:50%;
  display:grid; place-items:center; width:var(--sp-16); height:var(--sp-10);
  border-radius:var(--radius-3xl); background:var(--color-federal-red); box-shadow:var(--shadow-xl);
  transform:translate(-50%,-50%); }
.tutorial-video__play::before { content:""; width:0; height:0; margin-left:var(--sp-1);
  border-top:var(--sp-2) solid transparent; border-bottom:var(--sp-2) solid transparent;
  border-left:var(--sp-3) solid var(--color-text-negative); }
.tutorial-video__provider { position:absolute; z-index:var(--z-local-control); right:var(--sp-3);
  bottom:var(--sp-3); display:inline-flex; align-items:center; gap:var(--sp-2);
  max-width:calc(100% - (2 * var(--sp-3))); padding:var(--sp-1-5) var(--sp-2-5);
  border-radius:var(--radius-full); background:var(--surface-lightbox-control);
  color:var(--color-text); box-shadow:var(--shadow-overlay-control); font-size:var(--text-xs);
  font-weight:var(--fw-bold); line-height:var(--lh-tight); white-space:nowrap; }
.tutorial-video__provider-mark { display:grid; place-items:center; flex:none; width:var(--sp-7);
  height:var(--sp-5); border-radius:var(--radius-xl); background:var(--color-federal-red); }
.tutorial-video__provider-mark::before { content:""; width:0; height:0; margin-left:var(--sp-0-5);
  border-top:var(--sp-1) solid transparent; border-bottom:var(--sp-1) solid transparent;
  border-left:var(--sp-1-5) solid var(--color-text-negative); }
@media (min-width:640px){
  .tutorial-video__brand { top:var(--sp-5); left:var(--sp-5); right:var(--sp-5); gap:var(--sp-3);
    max-width:calc(100% - (2 * var(--sp-5))); }
  .tutorial-video__crest { width:var(--sp-12); height:var(--sp-12); }
  .tutorial-video__crest img { width:var(--sp-8); }
  .tutorial-video__portal { font-size:var(--text-lg); }
  .tutorial-video__title { font-size:var(--text-sm); }
  .tutorial-video__play { width:var(--sp-24); height:var(--sp-16); }
  .tutorial-video__play::before { border-top-width:var(--sp-3); border-bottom-width:var(--sp-3);
    border-left-width:var(--sp-5); }
  .tutorial-video__provider { right:var(--sp-5); bottom:var(--sp-5); padding:var(--sp-2) var(--sp-4);
    max-width:calc(100% - (2 * var(--sp-5))); font-size:var(--text-base); }
}

/* Multispace equipment standard (#/knowledge/workspace). */
/* Module and example cards share the canonical card anatomy. */
.wsm-module-card__photo { aspect-ratio:16 / 9; }
.wsm-module-detail__photo { aspect-ratio:16 / 9; }
.wsm-module-detail__figure { margin:0; display:grid; gap:var(--sp-2); }
.wsm-module-detail__gallery { align-items:start; }

/* Planungsbeispiele: a place, its scope, and what it was built from. */
.wsm-example__photo { aspect-ratio:16 / 9; }
.wsm-references { margin:0; padding:0; list-style:none; }
.wsm-references li { display:grid; gap:var(--sp-1); padding:var(--sp-3) 0; border-bottom:var(--stroke-1) solid var(--color-secondary-200); }
.wsm-references li:first-child { border-top:var(--stroke-1) solid var(--color-secondary-200); }
.wsm-references__modules { display:flex; flex-wrap:wrap; gap:var(--sp-1-5); margin-top:var(--sp-1); }

/* Greeting strip — one line of personal context above the home case preview,
   ported from the tenant portal (alignment D44): quiet gray-50 field, no card
   chrome; the count is an inline link. Values byte-match the tenant's
   .greeting-strip (padding 24/32, 48px below, relaxed leading). */
.greeting-strip { margin:0 0 var(--sp-12); padding:var(--sp-6) var(--sp-8);
  background:var(--color-gray-50); color:var(--color-text);
  font-size:var(--text-base); line-height:var(--lh-relaxed); }
/* Underlined at rest like every content link (CD link.postcss:5-10; the
   foundations rule in elements.css already delivers it) — the former
   hover-only underline was a stray deviation (alignment D53). */
.greeting-strip a { color:var(--color-primary-600); }
.greeting-strip__count strong { font-weight:var(--fw-bold); }

/* ── «AKTUELL» NEWS CAROUSEL (home band) ─────────────────────────────────────
   Ported from the tenant portal byte-for-byte (2026-08 alignment D51; user
   decision) — the swisstopo «Aktuell» pattern on the CD carousel anatomy:
   arrows at the CD sizes (designsystem css/components/carousel.postcss:74-76,
   48px svg / 56 from lg), bullets per carousel.postcss:36-47 (16px ring,
   filled when active), three card--profile teasers per page. Token mapping
   tenant → here: space-md/lg/2xl → sp-4/6/12; text-body* → text-xs/sm/base;
   text-h3 → text-xl (same 20/22/26/32 ramp); shadow-card-hover → shadow-2xl
   (identical values). */
.news-section { background:var(--color-secondary-100); }
.news-section__viewport { position:relative; display:grid; grid-template-columns:1fr;
  gap:var(--sp-4); align-items:stretch; }
@media (min-width:768px){ .news-section__viewport { grid-template-columns:40px 1fr 40px; } }
.news-section__track { display:grid; grid-template-columns:1fr; gap:var(--sp-6); }
@media (min-width:768px)  { .news-section__track { grid-template-columns:repeat(2,1fr); } }
@media (min-width:1024px) { .news-section__track { grid-template-columns:repeat(3,1fr); } }
.news-section__nav { background:transparent; border:none; width:56px; height:100%; min-height:80px;
  display:flex; align-items:center; justify-content:center; color:var(--color-text-muted);
  cursor:pointer; transition:color var(--duration-fast); align-self:center; padding:0; }
.news-section__nav:hover:not([disabled]) { color:var(--color-primary-600); }
.news-section__nav[disabled] { opacity:.3; cursor:default; }
.news-section__nav .icon { width:48px; height:48px; }
@media (min-width:1024px) { .news-section__nav .icon { width:56px; height:56px; } }
@media (max-width:767.98px){ .news-section__nav { display:none; } }
.news-section__footer { display:flex; align-items:center; justify-content:space-between;
  margin-top:var(--sp-12); flex-wrap:wrap; gap:var(--sp-4); }
.news-section__dots { display:flex; gap:var(--sp-2); flex:1; justify-content:center; }
/* 16 × 16 visual, invisible 44 × 44 hit slop via ::before (WCAG 2.5.5). */
.news-section__dot { position:relative; width:16px; height:16px; border-radius:var(--radius-full);
  background:transparent; border:var(--stroke-1) solid var(--color-text-muted); padding:0;
  cursor:pointer; transition:background var(--duration-fast), border-color var(--duration-fast); }
.news-section__dot::before { content:''; position:absolute; inset:-14px; }
.news-section__dot:hover { background:var(--color-primary-600); border-color:var(--color-primary-600); }
.news-section__dot--active,
.news-section__dot--active:hover { background:var(--color-text); border-color:var(--color-text); cursor:default; }
.news-section__dot:focus-visible { outline:var(--stroke-2) solid var(--color-focus-ring); outline-offset:var(--stroke-2); }
.news-section__more { text-decoration:none; color:var(--color-text); font-size:var(--text-base);
  transition:color var(--duration-fast); margin-left:auto; }
.news-section__more:hover { color:var(--color-primary-600); text-decoration:none; }
.news-section__more .icon { transition:transform var(--duration-fast); margin-left:var(--sp-1);
  vertical-align:middle; }
.news-section__more:hover .icon { transform:translateX(4px); }

/* News teaser card — the tenant portal's .card--profile, same values. */
.card--profile { position:relative; background:var(--color-bg); color:var(--color-text);
  text-decoration:none; display:flex; flex-direction:column; min-height:360px; overflow:hidden;
  transition:box-shadow var(--duration-slow) var(--ease-in-out); }
/* CD cards lift via shadow only — no translate (DS card.postcss:27-29). */
.card--profile:hover { box-shadow:var(--shadow-2xl); text-decoration:none; }
.card--profile__image { display:block; width:100%; height:200px; object-fit:cover;
  background-color:var(--color-gray-200); }
.card--profile__body { padding:var(--sp-6); padding-bottom:var(--sp-20); /* clears the corner arrow */
  flex:1; display:flex; flex-direction:column; }
.card--profile__date { font-size:var(--text-xs); color:var(--color-text-muted); margin:0 0 var(--sp-2); }
.news-card .card--profile__date strong { color:var(--color-text); font-weight:var(--fw-bold); }
.card--profile__title { font-size:var(--text-xl); font-weight:var(--fw-bold); margin:0 0 var(--sp-2);
  color:var(--color-text); transition:color var(--duration); }
.card--profile:hover .card--profile__title { color:var(--color-primary-700); }
.card--profile__desc { font-size:var(--text-sm); color:var(--color-text-muted); margin:0;
  line-height:var(--lh-relaxed); }
.card--profile__arrow { position:absolute; bottom:var(--sp-6); right:var(--sp-6); }

/* ==========================================================================
   CASE VIEW — one anatomy for every process (docs/case-view-alignment.md)
   Shared, class for class, with the tenant portal's Vorgangsansicht.
   ========================================================================== */

/* --- Kopfbereich (CD Hero.vue:9-27: MetaInfo ABOVE the h1) --------------- */
/* The meta strip carries process, reference, object and date in ONE CD
   component instead of an uppercase kicker plus a lead plus a badge row. The
   actions column holds the status badge, so the state sits on the same optical
   line as the title rather than floating above it. */
.case-header { display:flex; flex-wrap:wrap; align-items:flex-start;
  justify-content:space-between; gap:var(--sp-4); }
.case-header__main { min-width:0; flex:1 1 28rem; }
.case-header__meta { margin:0 0 var(--sp-2); }
.case-header__title { margin:0; overflow-wrap:anywhere; }
/* `align-items:center` on the actions column, not on the header: the badge
   should sit against the title's first line, and a title wrapping to three
   lines must not drag it to the middle. */
.case-header__actions { display:flex; flex-wrap:wrap; align-items:center;
  gap:var(--sp-3); padding-top:var(--sp-1); }

/* --- Übersicht: reading column + action rail ----------------------------- */
/* The frame is `.detail-layout` (utilities.css) — the portal's established
   detail anatomy, as used by the property view. Only the Übersicht tab is two
   columns: the other three carry one full-width surface each (a table, a
   timeline, a comment list), and a 352px rail beside a table would take the
   width the table needs.
   Sections stack in the reading column and carry their own rhythm; the grid's
   gap separates the two COLUMNS, not the sections inside one. */
.case-overview__main { display:flex; flex-direction:column; gap:var(--stack-gap); min-width:0; }
/* ONE label column across every section, so the values line up down the whole
   panel. Each `.kv` sizes its own by default, which put «Referenz :» and
   «Wirtschaftseinheit (WE) :» at different x positions two sections apart.
   14rem clears the longest label the case view carries («Personen /
   Arbeitsplätze», «Wirtschaftseinheit (WE)») at the 16px body size. */
.case-overview__main .kv { --kv-label-col:14rem; }
@media (max-width:479.98px){ .case-overview__main .kv { --kv-label-col:auto; } }
@media (min-width:1024px){
  /* NOT `align-items:start` (which `.detail-layout` sets): a start-aligned grid
     item is only as tall as its own content and therefore its own sticky
     containing block, so the rail has zero travel and scrolls away. The item
     stretches to the row height and the sticky sits on the inner wrapper — the
     technique the tenant portal measured and documented on its property view.
     Scoped to the case view so the portfolio's rail is untouched. */
  .case-overview { align-items:stretch; }
  .case-overview > .detail-layout__aside { position:static; }
  .case-overview .detail-layout__aside-inner { position:sticky; top:var(--sp-4); }
}
@media (max-width:1023.98px){
  /* The rail carries the actions, so on one column it leads. A property is a
     thing you read about and its facts come first; a Vorgang is a thing you ACT
     on, and burying «Auflagen erfüllen» under six sections would hide the
     reason the page was opened. */
  .case-overview > .detail-layout__aside { order:-1; }
}
/* NO bottom rule. It was there to separate a title from its values while two
   sections sat side by side; stacked in one reading column the rules read as
   page-wide dividers and chop the panel into slices. The reference this layout
   follows — «Eckdaten» on the property view — has none either, and the section
   gap plus the bold title already do the separating. */
.case-section__title { margin:0 0 var(--sp-3);
  font-size:var(--text-lg); font-weight:var(--fw-bold); line-height:var(--lh-snug);
  overflow-wrap:anywhere; }
.case-section__icon { margin-right:var(--sp-2); color:var(--color-primary-600); }
/* The list sizes its own label column. A pinned width was right while four
   lists sat stacked and had to line up; side by side it only pushes short
   labels' values needlessly right (docs/case-view-alignment.md § 2.2). */
.case-section__list { margin:0; row-gap:var(--sp-2); }
.case-section__actions { margin:var(--sp-4) 0 0; }
.case-section__note { margin:0 0 var(--sp-3); }

/* --- Verlauf ------------------------------------------------------------- */
/* An <ol> with a rail: the dot marks position AND kind, so scanning the column
   distinguishes «approved» from «returned» without reading every line. */
.history-timeline { list-style:none; margin:0; padding:0; position:relative; }
.history-timeline::before { content:""; position:absolute; top:var(--sp-2); bottom:var(--sp-2);
  left:calc(var(--sp-1) + var(--stroke-1)); width:var(--stroke-2); background:var(--color-border); }
.history-timeline__item { position:relative; padding:0 0 var(--sp-6) var(--sp-8); }
.history-timeline__item:last-child { padding-bottom:0; }
.history-timeline__dot { position:absolute; left:0; top:var(--sp-1); width:var(--sp-3); height:var(--sp-3);
  border-radius:var(--radius-full); background:var(--color-gray-400);
  /* The ring is the page background, so the dot punches through the rail
     rather than sitting on top of a line that shows either side of it. */
  box-shadow:0 0 0 var(--stroke-2) var(--color-bg); }
.history-timeline__dot--info    { background:var(--color-info); }
.history-timeline__dot--success { background:var(--color-success-text); }
.history-timeline__dot--warning { background:var(--color-warning); }
.history-timeline__dot--neutral { background:var(--color-secondary-500); }
.history-timeline__time { display:block; font-size:var(--text-xs); color:var(--color-text-muted); }
.history-timeline__action { margin:var(--sp-0-5) 0 0; }
.history-timeline__note { margin:var(--sp-1) 0 0; font-size:var(--text-sm); color:var(--color-text-muted); }

/* --- Kommentare ---------------------------------------------------------- */
.case-comments { list-style:none; margin:0; padding:0; }
.case-comment { padding:var(--sp-4) 0; border-bottom:var(--stroke-1) solid var(--color-border); }
.case-comment:last-child { border-bottom:none; }
.case-comment:first-child { padding-top:0; }
.case-comment__meta { display:flex; flex-wrap:wrap; gap:var(--sp-3); margin:0 0 var(--sp-1);
  font-size:var(--text-sm); color:var(--color-text-muted); }
.case-comment__text { margin:0; line-height:var(--lh-relaxed); }

/* --- Leerzustand einer Registerkarte ------------------------------------- */
.case-empty { margin:0; padding:var(--sp-6) 0; }

/* --- Anhänge in der Tabelle ---------------------------------------------- */
/* The icon sits in the same cell as the name, so the column keeps ONE
   accessible name and the file type is legible before the «Typ» column is
   read. `vertical-align` is set on the mask span, which has no baseline. */
.attachment__icon { margin-right:var(--sp-2); color:var(--color-primary-600); vertical-align:-.2em; }
.attachment__name { overflow-wrap:anywhere; }

/* --- Kommentar erfassen -------------------------------------------------- */
/* The compose box under the comment list. Shared, value for value, with the
   tenant portal: a labelled full-width textarea and one primary button, with
   the gap above it coming from the list it follows. */
.case-comment-form { margin-top:var(--sp-6); max-width:42rem; }
.case-comment-form > label { display:block; margin-bottom:var(--sp-2); font-weight:var(--fw-bold); }
.case-comment-form textarea { display:block; width:100%; resize:vertical; }
.case-comment-form__actions { display:flex; flex-wrap:wrap; align-items:center;
  gap:var(--sp-4); margin:var(--sp-4) 0 0; }
