/* ── Self-hosted fonts ─────────────────────────────────────────────────────── */
@font-face {
    font-family: 'Inter';
    src: url('/fonts/inter-latin.woff2') format('woff2');
    font-weight: 400 600;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Manrope';
    src: url('/fonts/manrope-latin.woff2') format('woff2');
    font-weight: 500 700;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Design tokens ─────────────────────────────────────────────────────────── */
:root {
    /* Colours */
    --color-slate:          #3A4A5C;
    --color-terracotta:     #C4633F;
    --color-anthracite:     #1F2832;
    --color-background:     #F5F7FA;
    --color-warm-light:     #EFE3DC;
    --color-text-secondary: #5B6573;
    --color-text-light:     #8B95A3;
    --color-divider:        #EEF1F4;

    /* Left-rail exception marker (#699): the one red used by every left-edge accent bar,
       status or risk context alike — never a full traffic-light. Amber/grey are secondary
       Handlungsbedarf steps used only in the status context (see docs/design/components.md). */
    --color-rail-red:   #A32D2D;
    --color-rail-amber: #854F0B;
    --color-rail-grey:  #9CA3AF;

    /* Status palette (#574): the muted traffic light introduced with the GBU list in #668.
       Colour marks Handlungsbedarf, never achievement — "erledigt" is grey, never green.
       These are surface colours (dots, text); the louder --color-rail-* values stay reserved
       for the left-edge exception marker and the danger filter state. */
    --color-status-red-fg:      #7E4636;
    --color-status-red-dot:     #B0705E;
    --color-status-amber-dot:   #C2A566;
    --color-status-neutral-dot: #B9C1C9;
    --color-status-done-dot:    #D3D9DF;

    /* Typography */
    --font-headline: 'Manrope', sans-serif;
    --font-body:     'Inter', sans-serif;

    --font-weight-regular:  400;
    --font-weight-medium:   500;
    --font-weight-semibold: 600;
    --font-weight-bold:     700;

    --line-height-tight: 1.2;
    --line-height-body:  1.6;
}

/* ── Base ──────────────────────────────────────────────────────────────────── */
html, body {
    font-family: var(--font-body);
    font-size: 16px;
    line-height: var(--line-height-body);
    color: var(--color-text-secondary);
    background-color: var(--color-background);
    margin: 0;
    padding: 0;
    /* Clip horizontal overflow without creating a scroll container.
       overflow-x: hidden would make body the sticky ancestor, breaking
       position:sticky on .top-bar (top:0) and .sa-form-action-bar (bottom:0). */
    overflow-x: clip;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-headline);
    color: var(--color-anthracite);
    line-height: var(--line-height-tight);
}

h1 { font-size: 40px; font-weight: var(--font-weight-bold); letter-spacing: -0.8px; }
h2 { font-size: 26px; font-weight: var(--font-weight-bold); letter-spacing: -0.4px; }
h3 { font-size: 16px; font-weight: var(--font-weight-semibold); }

a, .btn-link {
    color: var(--color-terracotta);
}

/* ── SA table ──────────────────────────────────────────────────────────────── */
.sa-table {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    font-family: Inter, sans-serif;
    font-size: 0.9rem;
}
.sa-table td {
    padding: 10px 12px;
    border-bottom: 1px solid #F3F4F6;
    color: #1F2937;
}
.sa-table tbody tr:hover {
    background-color: #F9FAFB;
    cursor: pointer;
}

/* ── Row chevron affordance (clickable rows) ────────────────────────────────── */
.sa-row-chevron-cell {
    text-align: right;
    padding: 10px 12px !important;
    vertical-align: middle;
    color: #E5E7EB;
    pointer-events: none;
    white-space: nowrap;
}

.sa-row-chevron-cell .ti {
    font-size: 1rem;
    transition: color 0.12s;
}

.sa-table tbody tr:hover .sa-row-chevron-cell .ti {
    color: #9CA3AF;
}

/* ── SA table header ───────────────────────────────────────────────────────── */
.sa-table-header th {
    background-color: #3A4A5C !important;
    color: #ffffff !important;
    font-family: Inter, sans-serif;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 10px 12px;
    border: none !important;
    user-select: none;
}
.sa-table-header th:hover {
    background-color: #3A4A5C !important;
}
.sa-table-header th.sorted,
.sa-table-header th.sort-asc,
.sa-table-header th.sort-desc,
.sa-table-header th.ba-th-sort--active,
.sa-table-header th.kr-th-sort--active {
    background-color: #3A4A5C !important;
}

/* ── SA design-system buttons ──────────────────────────────────────────────── */
.btn-sa-primary {
    background-color: #C4633F;
    color: #ffffff;
    border: none;
    border-radius: 6px;
    padding: 6px 14px;
    font-family: Inter, sans-serif;
    font-size: 0.875rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    transition: opacity 0.15s;
    text-decoration: none;
}
.btn-sa-primary:hover { opacity: 0.9; color: #ffffff; background-color: #C4633F; }
.btn-sa-primary:disabled, .btn-sa-primary[disabled] { opacity: 0.6; cursor: not-allowed; }

.btn-sa-outline {
    background-color: #ffffff;
    color: #3A4A5C;
    border: 1px solid #3A4A5C;
    border-radius: 6px;
    padding: 6px 14px;
    font-family: Inter, sans-serif;
    font-size: 0.875rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    transition: background-color 0.15s;
    text-decoration: none;
}
.btn-sa-outline:hover { background-color: #F3F4F6; color: #3A4A5C; }
.btn-sa-outline:disabled, .btn-sa-outline[disabled] { opacity: 0.6; cursor: not-allowed; }

.btn-sa-danger {
    background-color: #ffffff;
    color: #A32D2D;
    border: 1px solid #A32D2D;
    border-radius: 6px;
    padding: 6px 14px;
    font-family: Inter, sans-serif;
    font-size: 0.875rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    text-decoration: none;
}
.btn-sa-danger:hover { background-color: #FCEBEB; color: #A32D2D; }
.btn-sa-danger:disabled, .btn-sa-danger[disabled] { opacity: 0.6; cursor: not-allowed; }

/* ── "Ergänzen" inline link (#696) ───────────────────────────────────────────
   Hoisted from SubstanceDetailPage.razor.css's .sd-ergaenzen (was local-only) so the GBU read
   view can reuse it without copying — small dashed-underline link next to a read-view gap,
   jumps straight into editing that spot instead of the page-top "Bearbeiten" button. */
.sa-ergaenzen {
    color: #9CA3AF;
    font-size: 0.8rem;
    text-decoration: none;
    border-bottom: 1px dashed #9CA3AF;
    white-space: nowrap;
}
.sa-ergaenzen:hover {
    color: #8B3A3A;
    border-bottom-color: #8B3A3A;
}
/* Gap modifier (#696): used where the link sits inline right after a value/sentence — Blazor
   collapses the markup whitespace between an @expression and an adjacent @if block, so the
   spacing has to come from CSS. Not needed on the Substance page, where the link only ever
   replaces an empty value and never sits beside text. */
.sa-ergaenzen--gap {
    margin-left: 0.4rem;
    /* Inline next to a value/sentence, so match the surrounding text size instead of the base
       0.8rem — in the GBU read view that context (.who-readonly) is 11.5px, and a fixed 0.8rem
       would render the edit link larger than the value it annotates (#696 Julia catch). */
    font-size: inherit;
}

.btn-sa-icon {
    background: none;
    border: 1px solid #3A4A5C;
    border-radius: 6px;
    padding: 6px 10px;
    color: #3A4A5C;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.875rem;
    text-decoration: none;
}
.btn-sa-icon:hover { background-color: #F3F4F6; color: #3A4A5C; }
.btn-sa-icon:disabled, .btn-sa-icon[disabled] { opacity: 0.6; cursor: not-allowed; }

/* ── "Was ist zu tun?" cell (#574) ───────────────────────────────────────────
   Hoisted from RiskAssessmentsListPage.razor.css's .gbu-todo (#668) so the Kataster list
   renders the identical cell instead of a second, drifting variant: one dot, the most urgent
   point in plain text, everything else as a quiet subline. Modifiers follow RiskMatrix's
   pill letters (r/a/g) so the GBU list can pass them straight through; --n is the Kataster's
   fourth step ("nicht prüfbar": an open point that carries no colour), --g the terminal
   "alles erledigt" step, which stays deliberately grey — green would reward exactly the rows
   that need no attention. */
.sa-todo { display: flex; gap: 10px; align-items: flex-start; }
.sa-todo-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; margin-top: 4px; }
.sa-todo--r .sa-todo-dot { background: var(--color-status-red-dot); }
.sa-todo--a .sa-todo-dot { background: var(--color-status-amber-dot); }
.sa-todo--n .sa-todo-dot { background: var(--color-status-neutral-dot); }
.sa-todo--g .sa-todo-dot { background: var(--color-status-done-dot); }
.sa-todo-txt { font-size: 13.5px; font-weight: 700; color: var(--color-anthracite); line-height: 1.3; }
.sa-todo--r .sa-todo-txt { color: var(--color-status-red-fg); }
.sa-todo--g .sa-todo-txt { font-weight: 600; color: var(--color-text-secondary); }
.sa-todo-sub { display: block; font-size: 11.5px; font-weight: 500; color: var(--color-text-light); margin-top: 2px; }
.sa-todo--g .sa-todo-sub { color: #A8B0B9; }

/* ── Status- und Prüfstands-Badges (#809) ────────────────────────────────────
   Hoisted from the list pages' scoped stylesheets (.ba-badge--*, .gbu-status-badge)
   for the same reason .sa-todo was hoisted in #574: the detail pages rendered a second,
   drifting variant — Bootstrap's .text-bg-success/-warning/-info — so one and the same
   Betriebsanweisung showed a soft green chip in the list and a loud solid one in its own
   header. Scoped CSS cannot cross component boundaries, so a shared definition has to be
   global; EntityMetaHeader's callers now pass these classes instead of Bootstrap's.

   Status is reference, not a signal (#745): it says what state the record is in, never that
   the user must act. Colour for Handlungsbedarf lives in .sa-review-badge below and in the
   left-rail marker, never here. */
.sa-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    border-radius: 10px;
    padding: 2px 9px;
    white-space: nowrap;
}
.sa-badge--neutral   { background-color: #F1F3F5; color: var(--color-text-secondary); }
.sa-badge--published { background-color: #E1F5EE; color: #0F6E56; }
.sa-badge--draft     { background-color: #FAEEDA; color: #854F0B; }
.sa-badge--archived  { background-color: var(--color-divider); color: var(--color-text-secondary); }

/* Prüfstand: the one place in this family where colour carries Handlungsbedarf.
   --changed is neutral on purpose — it names the cause, while --overdue/--soon carry the
   deadline itself and must stay the louder pair when both sit in the same cell. */
.sa-review-badge {
    display: inline-block;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
    width: fit-content;
}
.sa-review-badge--overdue { background-color: #FCEBEB; color: #A32D2D; }
.sa-review-badge--soon    { background-color: #FAEEDA; color: #854F0B; }
.sa-review-badge--changed { background-color: var(--color-divider); color: var(--color-slate); }

/* ── Buttons ───────────────────────────────────────────────────────────────── */
.btn-primary {
    background-color: var(--color-terracotta);
    border-color: var(--color-terracotta);
    color: #fff;
    font-family: var(--font-body);
    font-weight: var(--font-weight-medium);
    font-size: 15px;
}

.btn-primary:hover {
    background-color: #b05636;
    border-color: #b05636;
}

.btn-secondary {
    background-color: var(--color-slate);
    border-color: var(--color-slate);
    color: #fff;
    font-family: var(--font-body);
    font-weight: var(--font-weight-medium);
    font-size: 15px;
}

.btn-secondary:hover {
    background-color: #31404f;
    border-color: #31404f;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus,
.form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem var(--color-terracotta);
}

/* ── Content area ──────────────────────────────────────────────────────────── */
.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

/* ── Forms ─────────────────────────────────────────────────────────────────── */

/* Placeholder text: italic + lighter grey so it is visually distinct from actual input.
   "z. B." prefix + italic provide two additional cues beyond colour alone (WCAG). */
::placeholder {
    color: #B8C0C7 !important;
    font-style: italic;
    opacity: 1; /* Firefox lowers opacity by default */
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

/* ── Blazor error boundary ─────────────────────────────────────────────────── */
.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

/* ── Misc ───────────────────────────────────────────────────────────────────── */
.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder,
.form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder,
.form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Global form input font size. Was three identical copies of this rule stacked on top of each
   other; folded into one while #1025 was touching it. */
.form-control {
    font-size: 14px;
}

/* #1025: iOS Safari zooms the page in whenever a text field is focused whose font-size is below
   16px, and it does not zoom back out when the field is left. Every field in the app was 14px, so
   tapping the Kataster search box on an iPhone left the whole page zoomed - confirmed on a real
   device. 16px is the threshold, not a preference: at 16px the browser has no reason to zoom.

   Element selectors with !important, deliberately. A rule keyed on .form-control loses to the
   page-scoped stylesheets: Blazor compiles .kr-filter-bar__search into .kr-filter-bar__search[b-xxx],
   which outranks any plain class rule from here, and there are several such copies across the list
   pages. Enumerating them would leave the next new field unprotected. This is a functional floor
   that stops the browser zooming, not a style preference, so overriding whatever a page set is the
   intent rather than a side effect.

   Raising the floor only where a finger is in play, so the deliberately compact 14px desktop form
   design is untouched. Two conditions rather than the plain width query #1035 uses for tap targets:
   there, missing a device meant a slightly small button, here it means a page that zooms and stays
   zoomed, and an iPad in landscape sits above every width breakpoint we have. Fixing the viewport
   meta with maximum-scale would also stop the zoom, and is deliberately not done - it takes pinch
   zoom away from everyone who needs it.

   #1077: the width half is paired with `any-pointer: coarse`, because on its own it also caught a
   narrow window on a plain desktop - the app docked beside an editor - where nothing can zoom and
   the floor only made the fields look oversized next to the rest of the compact form. `any-pointer`
   rather than `pointer`: a touch laptop driven by its mouse reports a fine primary pointer but still
   has a finger available, and that is the case the floor exists for. A touch device keeps the floor
   at any width through the second condition, which is unchanged. */
@media (max-width: 1023px) and (any-pointer: coarse), (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]),
    select,
    textarea {
        font-size: 16px !important;
    }
}

/* Global alert font size */
.alert {
    font-size: 0.875rem;
}

/* ── Touch targets on small screens (#1028) ──────────────────────────────────
   Measured on the Kataster page at 390px before this rule: the SA buttons rendered 34-36px tall
   and the filter row 31px, against the 44px minimum both Apple and Google recommend for a finger.
   Only the height was short - the buttons are already comfortably wide - so a min-height is enough
   and nothing is repositioned.

   Width query rather than `pointer: coarse`: the whole stylesheet switches layouts on width, the
   card layouts and the drawer included, so a second, differently-triggered mechanism would make
   the breakpoints harder to reason about and harder to check in a desktop browser. A touch laptop
   at desktop width keeps the compact buttons; that is the accepted trade.

   The cut-off is 1023px, not the 640px this block originally shipped with. 640px is where the
   tables fold into cards, which says nothing about whether a finger is doing the tapping - the
   sidebar stays a hamburger drawer all the way up to 1023px, so anything in that band is a tablet
   or a narrow window on a touch screen. #1028 already used 1023px for the hamburger and the drawer
   toggles for exactly that reason and then failed to apply it here, which left buttons and filters
   at 31-36px across the whole 641-1023px band. 1024px up is where the fixed sidebar appears and a
   mouse can be assumed.

   The .kr-filter-* / .ba-filter-select / .cp-filter-select names belong to page-scoped stylesheets
   that each carry their own copy of the same declarations (four files for .kr-filter-btn alone).
   Blazor's scoped CSS cannot be shared, so the touch-target rule is hoisted here for the same
   reason .sa-todo and .sa-badge were - one definition instead of six. It only adds min-height and
   never competes with the scoped rules, which set padding and font-size. */
@media (max-width: 1023px) {
    .btn-sa-primary,
    .btn-sa-outline,
    .btn-sa-danger,
    .kr-filter-btn,
    .kr-filter-select,
    .ba-filter-select,
    .cp-filter-select {
        min-height: 44px;
    }
}
