/*
 * Web Pilot custom CSS.
 *
 * Bootstrap 5 utility classes are strongly preferred everywhere. This file
 * exists ONLY for the two declared spacing tokens that have no native
 * Bootstrap utility equivalent (see 01-UI-SPEC.md "Design System" spacing
 * scale), the accent-colour variable set (05-UI-SPEC.md "Color"), and the
 * Open Sans typeface override below (07-UI-SPEC.md "Typography"). Do not
 * add general-purpose overrides here without a documented reason.
 */

/*
 * Open Sans typeface override (07-UI-SPEC.md "Typography"): the single
 * source of truth for switching app text from the browser's system font
 * stack to the self-hosted Open Sans webfont (vendored at
 * assets/fonts/open-sans-v40-latin/, linked in includes/header.php and
 * render_403() in includes/functions.php).
 *
 * Deliberately targets the narrower per-element custom property below
 * rather than the broader sans-serif stack variable it derives its default
 * value from in bootstrap.min.css — this keeps monospace-based elements
 * untouched.
 *
 * bootstrap.min.css declares no equivalent custom property scoped to
 * headings at all, so h1 through h6 inherit through the normal cascade;
 * a separate heading-scoped rule would be dead weight and must not be
 * added.
 */
:root {
    --bs-body-font-family: 'Open Sans', -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/*
 * Bold-element weight correction (07-03 checkpoint finding): two unrelated
 * sources push rendered text to weight 700, which the vendored Open Sans
 * kit only ships a real weight file for as an unused variant (07-UI-SPEC.md
 * "Only two weights render anywhere in the app: 400 and 600") —
 * bootstrap.min.css hardcodes --bs-badge-font-weight: 700 on .badge (the
 * navbar role badges), and every browser's default UA stylesheet renders
 * <th> as bold. Left unaddressed, both silently pull a third .woff2 over
 * the network on every page that has a badge or a table, contradicting the
 * "only regular + 600 fetched" FONT-01 verification contract. Pinning both
 * to the same 600 weight already used for headings keeps the visual weight
 * close to their bold default without the extra weight variant.
 */
.badge {
    --bs-badge-font-weight: 600;
}

th {
    font-weight: 600;
}

/*
 * Custom accent colour (05-UI-SPEC.md "Color"): replaces Bootstrap's stock
 * default blue accent with a teal accent, in both light (:root) and dark
 * ([data-bs-theme="dark"]) variants. A `--bs-primary` override alone does
 * NOT retint `.btn-primary` hover/active states or the focus ring, because
 * Bootstrap 5.3 bakes `--bs-btn-hover-bg`/`--bs-btn-active-bg`/
 * `--bs-btn-focus-shadow-rgb` at Sass compile time — they do not re-derive
 * from `--bs-primary` at runtime (research/PITFALLS.md Pitfall 5). The
 * hand-precomputed hover/active/focus values below were derived from the
 * same Tailwind teal scale as `--bs-primary` for visual consistency.
 * Scope is deliberately limited to the components this app actually
 * renders: `.btn-primary` (login button, "Neu…" buttons), `.nav-link.active`
 * (current-page nav indicator), plain `<a>` hyperlinks, and Bootstrap's
 * default `:focus-visible` ring — not every theoretical Bootstrap component.
 *
 * IMPORTANT — custom-property inheritance vs. direct declaration: Bootstrap's
 * compiled `.btn-primary` and `.navbar` rules each declare their own
 * `--bs-btn-*` / `--bs-navbar-active-color` custom properties directly on
 * the element (e.g. `.btn-primary{--bs-btn-hover-bg:#0b5ed7;...}`). A custom
 * property declared directly on an element always wins over one merely
 * inherited from `:root`, regardless of stylesheet load order or selector
 * specificity — inheritance is only a fallback for properties with no
 * direct declaration on that element. So overriding these on `:root` alone
 * is silently ignored by `.btn-primary`/`.navbar`; the override must target
 * those selectors directly too (confirmed via manual QA in 05-05, item B7).
 */
:root {
    --bs-primary: #0F766E;
    --bs-primary-rgb: 15, 118, 110;
    --bs-primary-text-emphasis: #115E56;
    --bs-primary-bg-subtle: #CCFBF1;
    --bs-primary-border-subtle: #5EEAD4;
    --bs-link-color: #0F766E;
    --bs-link-color-rgb: 15, 118, 110;
    --bs-link-hover-color: #115E56;
    --bs-link-hover-color-rgb: 17, 94, 86;
}

[data-bs-theme="dark"] {
    --bs-primary: #2DD4BF;
    --bs-primary-rgb: 45, 212, 191;
    --bs-primary-text-emphasis: #99F6E4;
    --bs-primary-bg-subtle: #134E4A;
    --bs-primary-border-subtle: #0F766E;
    --bs-link-color: #2DD4BF;
    --bs-link-color-rgb: 45, 212, 191;
    --bs-link-hover-color: #5EEAD4;
    --bs-link-hover-color-rgb: 94, 234, 212;
}

/* .btn-primary re-declares --bs-btn-* locally (see note above) — override
   must target the class directly, not just :root, to actually take effect. */
.btn-primary {
    --bs-btn-bg: #0F766E;
    --bs-btn-border-color: #0F766E;
    --bs-btn-hover-bg: #115E56;
    --bs-btn-hover-border-color: #115E56;
    --bs-btn-active-bg: #134E4A;
    --bs-btn-active-border-color: #134E4A;
    --bs-btn-focus-shadow-rgb: 15, 118, 110;
    --bs-btn-disabled-bg: #0F766E;
    --bs-btn-disabled-border-color: #0F766E;
}

/* Dark-mode button background (#2DD4BF) is itself a LIGHT colour, so
   Bootstrap's default white --bs-btn-*-color (5.47:1 in light mode) drops
   to 1.86:1 here — badly failing AA. Text colour must switch to the page's
   dark body colour instead (8.29:1 against the resting background, 10.4+:1
   against the lighter hover/active backgrounds — confirmed via manual QA
   in 05-05, item B8). */
[data-bs-theme="dark"] .btn-primary {
    --bs-btn-bg: #2DD4BF;
    --bs-btn-border-color: #2DD4BF;
    --bs-btn-color: #212529;
    --bs-btn-hover-bg: #5EEAD4;
    --bs-btn-hover-border-color: #5EEAD4;
    --bs-btn-hover-color: #212529;
    --bs-btn-active-bg: #99F6E4;
    --bs-btn-active-border-color: #99F6E4;
    --bs-btn-active-color: #212529;
    --bs-btn-focus-shadow-rgb: 45, 212, 191;
    --bs-btn-disabled-bg: #2DD4BF;
    --bs-btn-disabled-border-color: #2DD4BF;
    --bs-btn-disabled-color: #212529;
}

/* .navbar re-declares --bs-navbar-active-color locally (see note above) —
   same direct-declaration-beats-inheritance issue as .btn-primary. */
.navbar {
    --bs-navbar-active-color: #0F766E;
}

[data-bs-theme="dark"] .navbar {
    --bs-navbar-active-color: #2DD4BF;
}

/* .dropdown-menu re-declares --bs-dropdown-link-active-bg locally (see note
   above) — same direct-declaration-beats-inheritance issue as .btn-primary
   and .navbar, newly exposed by quick task 260805-fzr's Administration
   dropdown (the active-page highlight on its items was rendering Bootstrap's
   stock default blue instead of the teal accent). Dark mode additionally
   needs the same text-colour fix as .btn-primary's dark variant above: the
   dark-mode background (#2DD4BF) is itself light, so Bootstrap's default
   white --bs-dropdown-link-active-color drops to the same ~1.86:1 AA
   failure already documented for .btn-primary in 05-05 item B8. */
.dropdown-menu {
    --bs-dropdown-link-active-bg: #0F766E;
}

[data-bs-theme="dark"] .dropdown-menu {
    --bs-dropdown-link-active-bg: #2DD4BF;
    --bs-dropdown-link-active-color: #212529;
}

/*
 * Table-header dark-mode override (quick task 260805-h3b): the fourth
 * occurrence of the same "direct declaration beats inheritance" pattern
 * already documented above for .btn-primary/.navbar/.dropdown-menu. The
 * vendored Bootstrap stylesheet declares .table-light's three colour
 * custom properties with fixed light-mode values and ships no
 * [data-bs-theme=dark] variant for them, so the table head stays visibly
 * light even after the page switches to dark mode. Re-pointing the same
 * three properties at Bootstrap's own already theme-adaptive tokens keeps
 * the header exactly one step removed from the page background in either
 * theme, with no newly invented colour values of any kind.
 */
[data-bs-theme="dark"] .table-light {
    --bs-table-color: var(--bs-body-color);
    --bs-table-bg: var(--bs-tertiary-bg);
    --bs-table-border-color: var(--bs-border-color);
}

/*
 * Theme-toggle dropdown-item row (05-UI-SPEC.md "Spacing Scale" exceptions,
 * updated for quick task 260805-fzr): the toggle moved from a standalone
 * icon-only square button into the account dropdown menu as a full-width
 * item row (icon + visible text label), so it no longer centers its
 * content — width and left alignment now come from Bootstrap's own
 * .dropdown-item. The 44x44px minimum hit-area exception carries over
 * unchanged from the same rule already established for
 * .wp-toggle/.wp-project-edit/.wp-project-delete above — pad the row,
 * never the icon glyph itself.
 */
.wp-theme-toggle {
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    gap: .5rem;
}

/*
 * Theme-toggle transition (THEME-03): fires only when a background/text/
 * border colour actually changes inside a still-mounted DOM — i.e. exactly
 * the toggle-click case. A fresh server-rendered page load has no "previous
 * state" to transition from, so this never fires on ordinary navigation; do
 * not add a page-load fade/animation of any kind.
 */
body,
.navbar,
.card,
.table {
    transition: background-color .15s ease-in-out, color .15s ease-in-out, border-color .15s ease-in-out;
}

.p-xl {
    padding: 2rem;
}

.p-3xl {
    padding: 4rem;
}

/*
 * Expand/collapse row toggle (01-04, D-05): a minimum 44x44px hit area for
 * touch/click accessibility, achieved by padding the button wrapper, never
 * the small chevron SVG itself (see 01-UI-SPEC.md "Spacing Scale"
 * exceptions).
 *
 * Button-like chrome (quick task 260805-ike): .btn-link sets its border
 * color trio to transparent, so a plain `border` shorthand here would look
 * right at rest but vanish again on hover/active/focus — those states are
 * declared at higher specificity than this single-class selector and read
 * the same custom properties, not a shorthand. Overriding the three
 * properties directly survives every state instead. Width and radius are
 * already correct from Bootstrap's own button base rule, so they are
 * deliberately not duplicated here. var(--bs-border-color) is already
 * theme-adaptive, so no separate dark-mode rule is needed. The underline
 * comes from .btn-link too (not just on hover) and is neutralised the same
 * way — the accent color stays untouched, sourced from .btn-link as before;
 * switching to an outline-button variant instead was intentionally ruled
 * out for that reason.
 */
.wp-toggle {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    --bs-btn-border-color: var(--bs-border-color);
    --bs-btn-hover-border-color: var(--bs-border-color);
    --bs-btn-active-border-color: var(--bs-border-color);
    text-decoration: none;
    transition: color 0.3s ease-in-out, border-color 0.3s ease-in-out;
}

.wp-chevron {
    transition: transform 0.15s ease-in-out;
}

[aria-expanded="true"] .wp-chevron {
    transform: rotate(90deg);
}

/*
 * Row-level edit/delete icon buttons (02-03, 02-UI-SPEC.md "Interaction
 * Notes") reuse the same 44x44px minimum hit-area rule as .wp-toggle above
 * — pad the button wrapper, never the small SVG icon itself.
 */
.wp-project-edit,
.wp-project-delete {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/*
 * Maintenance-log free-text rendering (01-06, T-06-01): preserve newlines
 * via CSS instead of nl2br()/`.html()` on the AJAX side, so the entry
 * content is always inserted with jQuery's `.text()` only.
 */
.wp-entry-content {
    white-space: pre-wrap;
    word-break: break-word;
}

/*
 * Rendered markdown entry text: unlike
 * .wp-entry-content above, this class holds real block-level HTML from
 * render_entry_content() (a <p>/<h2>/<ul> tree), so `white-space: pre-wrap`
 * must NOT be applied here — it would additionally render the newlines
 * Parsedown puts between block tags as visible blank lines, doubling every
 * paragraph gap. h1..h6 is capped down from Bootstrap's default heading
 * scale so a "##" in an entry reads as an in-entry sub-heading, not a
 * 2rem headline that dwarfs the rest of the Historie row; the last-child
 * margin reset removes Bootstrap's own trailing <p> margin so the entry
 * doesn't end with extra blank space before the byline below it.
 */
.wp-entry-markdown {
    word-break: break-word;
}

.wp-entry-markdown h1,
.wp-entry-markdown h2,
.wp-entry-markdown h3,
.wp-entry-markdown h4,
.wp-entry-markdown h5,
.wp-entry-markdown h6 {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: .25rem;
}

.wp-entry-markdown > :last-child {
    margin-bottom: 0;
}

/*
 * #entryModal's Vorschau pane: a fixed minimum
 * height matching the 6-row Schreiben textarea it sits next to, so
 * switching between the Schreiben/Vorschau tabs doesn't visibly resize the
 * modal.
 */
.wp-entry-preview {
    min-height: 9rem;
}

/*
 * Panel-section indent (quick task 260805-si0): the three panel wrappers
 * (Technische Details, Historie list, empty state) previously carried
 * Bootstrap's p-3, which starts their content flush with the table's left
 * edge — under the empty chevron column, not aligned with the Domain
 * column. Bootstrap's p-3 sets its padding with !important, so a plain
 * padding-left override at equal specificity could never win against it;
 * this class replaces p-3 outright instead of layering on top of it, so no
 * !important is needed here either. The 5.5rem left value is a manually
 * tuned visual offset (not derived from a column-width formula) — adjust it
 * directly if the desired indent changes. The remaining 1rem on every other
 * side matches Bootstrap's own p-3 exactly.
 */
.wp-panel-section {
    padding: 1rem 1rem 1rem 5.5rem;
}

/*
 * Row-hover accent scoped to the chevron button only (quick task
 * 260806-s53, revised): the `#wp-projects` table no longer carries
 * Bootstrap's `.table-hover` class, so a project row has no hover state of
 * its own — and hovering elsewhere in the row must not trigger this accent
 * either. The rule below fires only on `:hover` of `.wp-toggle` itself,
 * the chevron button, which is the row's actual click target. The 0.3s
 * transition above (on the base `.wp-toggle` rule, not here) animates both
 * the hover-in and hover-out so the accent fades rather than snapping.
 *
 * Both values below are existing theme-adaptive accent tokens already
 * declared for `:root` and `[data-bs-theme="dark"]` at the top of this
 * file, so no separate dark-mode rule may be added here and no new hex
 * value is introduced (same discipline as the 260805-h3b `.table-light`
 * override).
 *
 * Bootstrap's `.btn:hover` reads the *hover* custom properties
 * (`--bs-btn-hover-color`, `--bs-btn-hover-border-color`), not the plain
 * `--bs-btn-color`/`--bs-btn-border-color` ones — those only apply at
 * rest. Since this selector already only matches while `.wp-toggle` itself
 * is hovered, only the hover-prefixed properties need overriding here.
 *
 * `--bs-btn-active-border-color` is deliberately left at `.wp-toggle`'s
 * neutral value — it applies only during the transient press, and the
 * 260805-ike contract ("the border survives active/focus") stays intact.
 */
.wp-toggle:hover {
    --bs-btn-hover-color: var(--bs-link-hover-color);
    --bs-btn-hover-border-color: var(--bs-primary);
}

/*
 * Wartung column colour interpolation (quick task 260806-srs): the inline
 * --wp-maintenance-urgency custom property is a 0..1 ratio computed
 * server-side (maintenance_urgency() in includes/maintenance.php), 0 at 30
 * or more remaining days and 1 at zero or fewer, so CSS interpolates and
 * PHP owns the curve.
 *
 * Both endpoints below are theme-adaptive custom properties, so NO
 * [data-bs-theme="dark"] variant of .wp-maintenance itself may be added —
 * same discipline as the 260805-h3b .table-light and 260806-s53
 * .wp-toggle:hover overrides.
 *
 * DD-8 finding: Bootstrap 5.3 declares --bs-danger / --bs-danger-rgb only
 * once, at :root, and does NOT re-declare them under [data-bs-theme=dark]
 * (verified in the vendored bootstrap.min.css). The theme-adaptive red is
 * --bs-danger-text-emphasis (#58151c / #ea868f), which is why the dark
 * alias below points there. No new hex literal is introduced: both values
 * are Bootstrap's own reds.
 */
:root {
    --wp-maintenance-due-color: var(--bs-danger);
}

[data-bs-theme="dark"] {
    --wp-maintenance-due-color: var(--bs-danger-text-emphasis);
}

/*
 * The duplicated `color` declaration below is a deliberate
 * progressive-enhancement fallback, not a leftover: a browser that cannot
 * parse color-mix() drops the second declaration and renders the plain
 * accent colour. The wrench glyph is a child <i> and inherits `color`, so
 * it needs no rule of its own.
 */
.wp-maintenance {
    --wp-maintenance-urgency: 0;
    white-space: nowrap;
    color: var(--bs-primary);
    color: color-mix(in srgb, var(--wp-maintenance-due-color) calc(var(--wp-maintenance-urgency) * 100%), var(--bs-primary));
}

/*
 * Live-search filter class (Quick task 260806-vcn): the only CSS this
 * feature adds, because the search bar's entire look is built from existing
 * Bootstrap utilities. Deliberately NOT d-none, even though it does the
 * same thing, because .wp-entries-row already uses d-none as its own
 * expand/collapse state (managed by assets/js/entries.js) — sharing one
 * class between the two states would mean clearing the search re-opens
 * panels the user had deliberately collapsed. !important is required to win
 * against Bootstrap's own table display rules on <tr>, and is safe here
 * because this class is set exclusively by applyProjectSearch() in
 * assets/js/projects.js. There is no dark-mode variant, and must not be
 * one — this rule never touches colour.
 */
.wp-search-hidden {
    display: none !important;
}

/*
 * "Wichtige Notiz" marker: the note icon next to a
 * project's domain. --bs-warning-text-emphasis is already theme-adaptive in
 * Bootstrap 5.3 (#664d03 light / #ffda6a dark), so — same discipline as
 * .wp-maintenance above — NO [data-bs-theme="dark"] variant of
 * .wp-project-note itself may be added.
 */
.wp-project-note {
    color: var(--bs-warning-text-emphasis);
    cursor: help;
}

/*
 * Preserves line breaks in a multi-line note's tooltip text instead of
 * collapsing it to one line — Bootstrap tooltips default to plain-text
 * rendering (data-bs-title, never html: true), so this only affects
 * whitespace handling, not what markup is allowed inside. Scoped via
 * data-bs-custom-class so no other tooltip in the app is affected.
 */
.wp-note-tooltip .tooltip-inner {
    white-space: pre-line;
    text-align: left;
}

/*
 * Content-preview marker: the icon next to the type
 * badge in the Papierkorb "Gelöschte Einträge" rows. Deliberately neutral
 * grey rather than the note icon's warning colour above — this icon
 * surfaces a plain piece of information (the deleted entry's text), not a
 * warning. --bs-secondary-color is already theme-adaptive in Bootstrap 5.3
 * (rgba(33,37,41,.75) light / rgba(222,226,230,.75) dark), so — same
 * discipline as .wp-maintenance/.wp-project-note above — NO
 * [data-bs-theme="dark"] variant of .wp-entry-text itself may be added.
 *
 * .wp-preview-tooltip widens Bootstrap's default 200px tooltip so a
 * ~200-character preview doesn't render as a tall, narrow column; it is
 * scoped via data-bs-custom-class, so no other tooltip in the app is
 * affected.
 *
 * #wp-confirm-modal's rule makes the '\n\n' separator assets/js/trash.js
 * appends to the restore-confirmation message (below) render as a visible
 * paragraph break, without confirmDialog() ever inserting markup (Pitfall
 * 4). It is a no-op for the existing single-line project-restore message.
 */
.wp-entry-text {
    color: var(--bs-secondary-color);
    cursor: help;
}

/*
 * "Erstellt von" and "Zuletzt geändert von" byline icon markers (entry
 * history panel). Both now share the app's teal brand colour for visual
 * consistency between the two byline markers. --bs-primary is already
 * theme-adaptive via this file's own :root/[data-bs-theme="dark"] blocks
 * above, so — same discipline as .wp-maintenance/.wp-project-note/
 * .wp-entry-text above — NO [data-bs-theme="dark"] variant of this
 * selector may be added.
 */
.wp-byline-created-icon, .wp-byline-updated-icon {
    color: var(--bs-primary);
}

.wp-preview-tooltip .tooltip-inner {
    max-width: 320px;
    text-align: left;
}

#wp-confirm-modal .modal-body p {
    white-space: pre-line;
}

/*
 * Project offcanvas width: Bootstrap's own default
 * is 400px; this override goes through Bootstrap's own CSS variable rather
 * than a hard width declaration, so the offcanvas keeps all of its own
 * behaviour (slide animation, backdrop, max-width:100% fallback on narrow
 * screens) untouched. Scoped tightly to #projectModal so a future second
 * offcanvas in this app is unaffected. #projectModal's background already
 * follows --bs-body-bg via Bootstrap's own --bs-offcanvas-bg, so — same
 * discipline as .wp-maintenance and .wp-project-note above — no
 * [data-bs-theme="dark"] variant is needed here either.
 *
 * The value is back to Bootstrap's own default
 * (400px). The rule stays in place regardless — it is the documented
 * location of this decision and pins the value against a future change of
 * the vendored default.
 */
#projectModal {
    --bs-offcanvas-width: 400px;
}

/*
 * Inactive-project row dimming. The locked
 * CONTEXT.md decision is dimming the ENTIRE row, so opacity sits on the
 * <tr> itself rather than on individual <td>s.
 *
 * Why exactly .7: body text (#212529 on white) lands at ~5.9:1 and stays
 * AA-compliant; .55 would drop to only ~3.7:1. .7 is the strongest dim
 * value that leaves readability intact, and sits close to the app's
 * already-established --bs-secondary-color (a .75 alpha). The actual
 * eye-catcher is the "Inaktiv" badge (index.php), not the opacity — the
 * same division of labour CONTEXT.md specifies.
 *
 * opacity is hue-free and renders identically in both themes, so there is
 * deliberately NO [data-bs-theme="dark"] counterpart here (same discipline
 * as .wp-search-hidden).
 *
 * The selector is deliberately .wp-project-inactive alone, not
 * .wp-project-row.wp-project-inactive — the row class is already unique
 * enough, and the leaner selector keeps the existing .wp-project-row
 * count-based gates in tests/entries_test.php untouched.
 *
 * No transition: the class only ever flips on an AJAX row rebuild, never
 * as a hover/interaction state.
 */
.wp-project-inactive {
    opacity: .7;
}

/*
 * Static help-icon marker: the info glyph next to a
 * label in #projectModal whose Bootstrap tooltip carries the field's former
 * form-text hint. --bs-secondary-color is already theme-adaptive in
 * Bootstrap 5.3 — same discipline as .wp-maintenance/.wp-project-note/
 * .wp-entry-text above — so NO [data-bs-theme="dark"] variant is needed.
 * Deliberately the same neutral grey as .wp-entry-text (plain information),
 * not .wp-project-note's warning colour. cursor: help is the only reason
 * this rule exists at all: Bootstrap 5.3 has no cursor utility class; the
 * colour could be a utility on its own, but logically belongs to the same
 * one-element rule.
 *
 * .wp-help-tooltip is scoped via data-bs-custom-class and affects no other
 * tooltip in the app. max-width: 260px (wider than Bootstrap's default
 * 200px) because the longest of the four help texts would otherwise render
 * as a tall, narrow column inside the 400px offcanvas; text-align: left for
 * the same reason. No white-space: pre-line like .wp-note-tooltip — these
 * texts are single-line paragraphs with no line breaks.
 */
.wp-help {
    color: var(--bs-secondary-color);
    cursor: help;
}

.wp-help-tooltip .tooltip-inner {
    max-width: 260px;
    text-align: left;
}
