/* Total row (tfoot) in detail tables */
/* CD tfoot (table.postcss:45-67): 2px borders at BOTH top and bottom in text-300,
   no surface tint, and bold only on th — td remains regular. The .table__total
   class in the markup is therefore purely semantic, with no styling of its own. */
.table tfoot { border-top:var(--stroke-2) solid var(--color-border-strong); border-bottom:var(--stroke-2) solid var(--color-border-strong); }
.table tfoot th { font-weight:var(--fw-bold); color:var(--color-gray-800); }

/* ---- Accessibility (Design Review Stage 2) ------------------------------- */
/* Surface-only components retain a visible border in Windows High Contrast /
   forced-colors; otherwise their fill is removed and their boundaries disappear:
   badges, notifications (including toasts — both host a .notification), and the
   default gray tag pill. */
@media (forced-colors:active){
  .badge, .notification, .tag-item__inner { border:var(--stroke-1) solid currentColor; }
}
/* Apply hover accents only to true pointers; otherwise the color sticks on touch. */
/* On touch, :hover remains after a tap until another target is tapped. The guard
   previously covered only color changes, not transforms and shadows (Item 2.25). */
@media (hover:none){
  .accordion__button:hover { color:inherit; }
  .tab__control:hover:not(.tab__control--active) { color:inherit; }
  .tab__control:hover:not(.tab__control--active)::after { background:transparent; }
  .card--clickable:hover .card__title { color:inherit; }
  .card--clickable:hover { box-shadow:var(--shadow-lg); }
  .card--clickable:hover::after { border-color:transparent; }
  .card--clickable:hover .domain-tile__icon { color:var(--color-primary-600); }
  /* `.quick-tile:hover` used to be here, but the component is defined farther
     below and won the cascade, so sticky hover remained on touch. Its override
     now follows the component. */
  .back-to-top-btn:hover { box-shadow:var(--shadow-lg); }
}
/* Less common input types (CD parity) */
input[type="color"] { height:var(--sp-12); padding:var(--sp-1); }
input[type="range"] { border:0; box-shadow:none; padding:0; }

/* ---- CD alignment (Design Review Stage 5/6) ------------------------------ */
/* Separator (separator.postcss): vertical rule + spacing/negative variants */
.separator--vertical { display:inline-block; align-self:stretch; width:0; border-right:var(--stroke-1) solid var(--color-secondary-400); margin-inline:var(--sp-4); }
/* (Dead rules removed in the 2026-08 code review, F-S30 — no emitter in any template.) */
/* Right-aligned pagination below results lists (CD) */
.pagination-wrap--right { justify-content:flex-end; }

/* Misc utility */
.row { display:flex; align-items:center; gap:var(--sp-3); flex-wrap:wrap; }
/* `.row > * { min-width:0 }` lets flex children shrink — icons must not, or a
   long label next to one squashes it to a sliver. */
.row > * { min-width:0; }
.row > .icon { flex:none; }
.break-all { overflow-wrap:anywhere; word-break:break-word; }


/* ===================== Home page (workspace) ===================== */
/* CD section heading and action (section.postcss:55,89 · ServicesSection.vue):
   title at the top, “View all …” link at the bottom right. */
/* Use pb rather than mb, as CD does (section.postcss:53-56 pb-10): padding does
   not collapse with the margin-top of a following block (.grid + .grid and
   mt-* utilities). */
.section__title { font-weight:var(--fw-bold); font-size:var(--text-2xl); margin:0; padding-bottom:var(--sp-10); }
/* CD section.postcss:89-97 gives the section CTA `relative; top-6 lg:top-8
   3xl:top-12`, pulling the action into the band's bottom padding. Without it,
   measurements on home-1440 show 50px before and 97px after the link. */
.section__action { display:flex; justify-content:flex-end; padding-top:var(--sp-4);
  position:relative; top:var(--sp-6); }
@media (min-width:1024px){ .section__action { top:var(--sp-8); } }
@media (min-width:1920px){ .section__action { top:var(--sp-12); } }

/* CD section.postcss:80-87 — the canonical way to divide a section into two
   named card groups (currently achieved with an `mt-8`). */

/* Home-page hero = the ACTUAL CD hero--main-image (hero.postcss:73-90). It
   replaces the former parallel .home-hero implementation (custom grid, 900px
   breakpoint outside the CD scale, 4:3 image); only the search row remains a
   portal class. `height:auto` is required on the image: otherwise the `height`
   attribute acts as a presentational hint and defeats aspect-ratio. */
.hero__image figure > img { display:block; width:100%; height:auto; background:var(--color-secondary-50); }
/* nowrap overrides flex-wrap:wrap from the .hero__cta base class: the field has
   width:100% (the global input rule) and would otherwise push the button to a
   second row. Field and “Search” remain on one row; below 640px, the rule below
   still stacks them deliberately. */
/* The hero CTA slot, here holding the search row PLUS the source selection. It
   caps both at the same width and makes them a single child of .hero__content —
   as two children each picked up that column's gap, so the line describing the
   field stood a paragraph away from it. */
.hero__search { max-width:40rem; }
.home-search { display:flex; flex-wrap:nowrap; gap:var(--sp-2); align-items:stretch; max-width:40rem; }
/* The field's own box: it takes the growing share of the row, and the suggestion
   popup is positioned against it rather than against the row (the anchor is the
   input's parent — js/search/search-suggest.js). A popup as wide as field plus
   «Suchen» claimed a control it has nothing to do with. */
.home-search__field { flex:1 1 auto; min-width:0; display:flex; }
.home-search input { flex:1 1 auto; min-width:0; min-height:var(--input-h); font-size:var(--text-base); }
/* The button must NOT shrink: `.btn__text` carries CD's `overflow-wrap:anywhere`
   (btn.postcss:133-137), reducing min-content width to one character. As a flex
   item beside the growing field, this wrapped “Search” across the word. The
   field grows while the button retains its intrinsic width. */
.home-search .btn { flex:0 0 auto; }
@media (max-width:639.98px){ .home-search { flex-direction:column; } }

/* Quick links — text before image: the destination matters more than illustration.
   Since the 2026-08 alignment (D41) the HOME band uses the shared white
   `.card--quick` (components/card.css); `.quick-tile` remains the compact icon
   tile of the my-cases bookmark band, which sits on a TINTED section where the
   white surface + shadow below is the intended rendering. */
/* Use min(20rem,100%) rather than 20rem as the minimum column size: below a
   320px viewport, a fixed 20rem minimum would make the tile wider than the
   screen and cause horizontal page scrolling. */
.quick-tile { display:flex; gap:var(--sp-4); align-items:flex-start; padding:var(--sp-5);
  background:var(--color-bg); color:inherit; text-decoration:none;
  border-left:var(--stroke-3) solid transparent; box-shadow:var(--shadow-lg);
  /* Shadow lift follows the card timing (CD card.postcss:17 duration-300
     ease-in-out), so both lifting home-page components move alike. */
  transition:box-shadow var(--duration-slow) var(--ease-in-out), border-color var(--duration); }
.quick-tile:hover, .quick-tile:focus-visible { box-shadow:var(--shadow-2xl);
  border-left-color:var(--color-primary-600); }
.quick-tile:active { background:var(--color-secondary-100); border-left-color:var(--color-primary-700); }
.quick-tile:focus-visible { outline:var(--stroke-2) solid var(--color-focus-ring); outline-offset:var(--stroke-2); }
.quick-tile:is([aria-disabled="true"], .is-disabled) { cursor:not-allowed; opacity:.55; pointer-events:none; }
.quick-tile[aria-busy="true"] { cursor:progress; opacity:.7; }
.quick-tile[aria-invalid="true"] { color:var(--color-error-text); border-left-color:var(--color-error); }
.quick-tile[data-empty="true"] { cursor:default; color:var(--color-text-muted); }
.quick-tile > .icon { flex:none; color:var(--color-primary-600); margin-top:var(--sp-0-5); }
/* The text wrapper is a flex child: without min-width:0 it cannot shrink below
   its intrinsic minimum width, and long compound words overflow the tile. */
.quick-tile__text { min-width:0; }
/* The label is an <h3>; its size and spacing come from the tile, not the heading scale. */
.quick-tile__label { margin:0; display:block; font-size:var(--text-base);
  font-weight:var(--fw-bold); line-height:var(--lh-snug); overflow-wrap:anywhere; }
.quick-tile:hover .quick-tile__label { color:var(--color-primary-700); }
.quick-tile__meta { display:block; margin-top:var(--sp-0-5); font-size:var(--text-sm); color:var(--color-text-muted); overflow-wrap:anywhere; }
/* (The former white-section TINT variant is gone with its only consumer —
   the home band, now `.card--quick` per D41. Bookmark tiles live on tinted
   bands, where the white surface above is the rendering.) */
/* Without a pointer, hover otherwise persists after a touch. This must follow
   the hover rules above: specificity is equal, so the later rule wins. */
@media (hover:none){
  .quick-tile:hover { box-shadow:var(--shadow-lg); border-left-color:transparent; }
}
.gap-sm { gap:var(--sp-2); }
.py-1-5 { padding-block:var(--sp-1-5); }   /* Row link in the services aside box, replacing an inline style */
.mt-2 { margin-top:var(--sp-2); } .mt-3 { margin-top:var(--sp-3); } .mt-4 { margin-top:var(--sp-4); } .mt-6 { margin-top:var(--sp-6); }
.mt-8 { margin-top:var(--sp-8); }
.mb-4 { margin-bottom:var(--sp-4); }
.m-0 { margin:0; } .mb-0 { margin-bottom:0; } .mt-0 { margin-top:0; } .mb-3 { margin-bottom:var(--sp-3); }
/* Map placeholder fills its frame, replacing four `style="height:100%"` instances. */
.h-full { height:100%; }
/* ---- Detail-page layout: content column + STICKY aside --------------------
   Deliberately NOT the container's 12-column grid: there, the aside is a
   separate grid child in the SAME row as the first main-column block, so it can
   remain sticky only within that row and disappears after the first section.
   Here there are exactly two children; the aside spans the full height of all
   sections and remains in view while scrolling. This is the same anatomy as the
   tenant-portal prototype (`.property-layout`). Use `minmax(0,1fr)` instead of
   `1fr`; otherwise a wide table in the main column pushes the track beyond the
   container. */
.detail-layout { display:grid; grid-template-columns:minmax(0,1fr); gap:var(--gap-responsive); }
.detail-layout > * { min-width:0; }
@media (min-width:1024px){
  .detail-layout { grid-template-columns:minmax(0,1fr) 22rem; align-items:start; }
  .detail-layout__aside { position:sticky; top:var(--sp-4); }
}
/* Catalogue records already sit beside an 18rem hierarchy rail. At the first
   desktop breakpoint, splitting their remaining pane again would leave roughly
   14rem for the description and key/value grid. Keep the contact below the
   facts through that transition; from xl onward it becomes the same sticky
   right rail used by portfolio details. */
@media (min-width:1024px) and (max-width:1279.98px){
  .mc-layout--detail .pf-main > .tab__container > .detail-layout,
  .pd-detail-tabs > .tab__container > .detail-layout { grid-template-columns:minmax(0,1fr); }
  .mc-layout--detail .pf-main > .tab__container > .detail-layout > .detail-layout__aside,
  .pd-detail-tabs > .tab__container > .detail-layout > .detail-layout__aside { position:static; }
}
/* Spacing between aside cards. `.box + .box` would otherwise join them with a
   1px seam into ONE surface. That is correct for stacked boxes in flowing text,
   but wrong here: adjacent detail cards are separate offerings, not sections
   of one surface. */
.detail-layout__aside .box + .box { margin-top:var(--sp-6); }

/* KPI row above contract details: four large figures, small labels, and a rule
   above and below. It answers “how large, how expensive” at a glance before the
   property list provides detail. There is no card border; type scale alone
   creates the contrast. */
.kpi-strip { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--sp-4);
  margin:0 0 var(--sp-6); padding:var(--sp-4) 0;
  border-top:var(--stroke-1) solid var(--color-secondary-100); border-bottom:var(--stroke-1) solid var(--color-secondary-100); }
@media (min-width:768px){ .kpi-strip { grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--sp-6); } }
.kpi-strip__item { display:flex; flex-direction:column; gap:var(--sp-0-5); }
.kpi-strip__label { font-size:var(--text-sm); color:var(--color-text-muted); }
/* Typography follows the shared large-number recipe (.stat__num); the strip
   remains borderless (a documented surface decision). */
.kpi-strip__value small { font-size:var(--text-sm); font-weight:var(--fw-regular); color:var(--color-text-muted); }

/* Eyebrow above the page heading: identifiers users scan for (lease number,
   business entity, EGID) rather than read as body text. Tracking .06em and
   8px bottom — the shared cross-portal kicker recipe (tenant .overtitle;
   2026-08 alignment D20). */
.eyebrow { margin:0 0 var(--sp-2); font-size:var(--text-xs); text-transform:uppercase;
  letter-spacing:.06em; color:var(--color-text-muted); }

/* Reading-width caps. Five different `style="max-width:…"` values served this
   purpose in js/; classes make them named, reusable, and discoverable here. */
/* measure-* = PARENT cap for surfaces OUTSIDE the grid (article wrappers and
   tile rows); inside the grid, the column itself establishes the measure (C25).
   measure-lg (50rem) was removed: its only consumer (the workspace success
   panel) now uses the siblings' 46rem form column. */
.measure-sm { max-width:34rem; } .measure    { max-width:42rem; }
.measure-xl { max-width:60rem; }
.pill-row { display:flex; flex-wrap:wrap; gap:var(--sp-2); }
/* Property list (label · value), including the “Overview” tab in all detail
   views. The label column is deliberately WIDER than its longest entry: with
   `max-content`, the value touched the longest label (“Business entity (BE)”),
   and because one track governs every row, the value edge moved with the
   longest word instead of staying visually stable. An extra 2rem clearly
   separates the columns; the 18rem cap prevents one long label from taking
   space away from the value. */
/* `--kv-label-col` lets a surface PIN the label column. Left unset the column
   is `fit-content`, which is right for a single list (it takes what its longest
   label needs). It is wrong for a stack of several lists, where each one sizes
   itself and the values then start at a different x in every section. */
.kv { display:grid; grid-template-columns:var(--kv-label-col, fit-content(18rem)) minmax(0,1fr);
  gap:var(--sp-2) var(--sp-8); font-size:var(--text-sm); }
.kv dt { color:var(--color-text-muted); }
/* Add the colon in CSS, not in strings: it belongs to list presentation, so all
   nine consumers receive it consistently without every JS label carrying it.
   The requested preceding space uses non-breaking \00A0 rather than an ordinary
   space; otherwise the colon could land alone on the next line when a label wraps. */
.kv dt::after { content:"\00A0:"; }
/* FORCE a single column — the same form produced by the container query below
   for narrow boxes, but independent of measured width. This supports values
   that do not fit beside their label even in a 411px aside; an email address
   would otherwise break in the middle of the name. */
.kv--stack { grid-template-columns:minmax(0,1fr); gap:0; }
.kv--stack dt::after { content:none; }
.kv--stack dt { margin-top:var(--sp-4); }
.kv--stack dt:first-of-type { margin-top:0; }
/* Do not indent the value: in the aside, label and value align to the same edge
   as the card heading above. A half-centimeter offset in every block made the
   column look unsettled. */
.kv--stack dd { padding-left:0; }
/* Use break-word rather than anywhere: long URLs may wrap, but ordinary words
   must not break in the middle. */
.kv dd { margin:0; overflow-wrap:break-word; }
/* Technical identifiers keep their semantic <code> markup, but a property grid
   uses one visual text style for every value. */
.kv code { font:inherit; overflow-wrap:anywhere; }
/* Ruled variant — retains the row separators from the former .data-rows
   (data-catalogue metadata and long distribution lists): one implementation,
   two surfaces (Design Review C7). */
.kv--ruled { row-gap:0; }
.kv--ruled dt, .kv--ruled dd { padding:var(--sp-2) 0; border-bottom:var(--stroke-1) solid var(--color-border); margin:0; }
/* The narrow aside cannot accommodate two columns; stack the label above the
   value there instead of breaking words. */
.box { container-type:inline-size; }
@container (max-width:22rem){
  .kv { grid-template-columns:minmax(0,1fr); gap:0; }
  .kv dt { margin-top:var(--sp-2-5); }
  .kv dt:first-of-type { margin-top:0; }
}
@media (max-width:639.98px){ .kv { grid-template-columns:minmax(0,1fr); gap:var(--sp-0-5) 0; } .kv dt { margin-top:var(--sp-2); } }
/* ============================== MOTION ============================== */
@media (prefers-reduced-motion: reduce) {
  /* Accessibility override: author animations and transitions must not outrank
     the user's OS-level reduced-motion preference. */
  *, *::before, *::after {
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
}

/* ============================== PRINT (print.postcss) ============================== */
@media print {
  /* Print is a terminal cascade boundary. These declarations intentionally
     override screen components whose selectors are more specific. */
  html { font-size:13px !important; max-width:80% !important; margin:var(--sp-8) auto !important; }
  body { display:block; }
  .top-bar, .desktop-menu, .desktop-menu__overlay, .mobile-menu, .burger,
  .top-header__right, .breadcrumb, .site-footer,
  .search--main, .skip-to-content, .demo-chip, .card__image, .card__footer,
  /* btn--back + notification-banner: CD print.postcss:62,72 hides both. This was
     missing here, so every printed detail page included the back button (Review C19). */
  .btn--back, .back-link-row, .notification-banner,
  .pf-map, video, audio, object, iframe, .tutorial-video { display:none !important; }
  .top-header { border:0 !important; padding:0 0 var(--sp-4) !important; }
  .logo { align-items:flex-start !important; }
  .logo__name { display:block !important; }
  .grid, .stats, .container--grid { display:block !important; }
  p, img, ul, ol, .card, .notification, .box, .table { position:relative; display:block; break-inside:avoid; }
  .table { display:table; }
  .card { margin-bottom:2em; box-shadow:none !important; border:var(--stroke-1) solid var(--color-border-strong); }
  .stat, .notification, .table { box-shadow:none !important; }
  a { color:var(--color-print) !important; text-decoration:underline; }
  .site-main a[href^="http"]::after { content:" (" attr(href) ")"; font-size:.85em; }
  /* Print dataset sheets and FAQs completely: reveal collapsed accordion panels
     (the global [hidden]{display:none} otherwise suppresses them) and omit the
     expand/collapse arrows; otherwise the printed output lacks content. */
  .accordion__drawer[hidden] { display:block !important; }
  .accordion__button .icon, .accordion__arrow { display:none !important; }
}
