/* I-Transact — base styles. Plain CSS, no build step, so it works unmodified
   on any host including plain FTP/cPanel deploys. */

/* ---------------------------------------------------------------------
   I-COMPANY BRAND PALETTE (2026-08-20)

   The six colours below are the real brand colours sampled from the
   I-Transact logo — the site had been running on an approximation
   (#2e4c6d / var(--accent)) that never matched the logo or the brochure.

   Two of them can't be used as-is for text, so each has a derived
   companion. This isn't a licence to invent new brand colours; it's
   what WCAG contrast requires:

     Teal #00A4BD on white is 2.98:1 — well under the 4.5:1 needed for
     text. So the pure teal is used for DECORATION (rules, icons, active
     indicators, marks on navy, where it reads at 5.22:1), and link text
     uses --teal-ink #00707F (5.79:1 on white). Teal button fills use
     --teal-deep #007487, which carries white text at 5.46:1.

     Gold #F8B420 on white is 1.82:1 — decorative only. It is always a
     BACKGROUND, carrying --brand-dark text at 9.98:1, never text itself.

   --muted also moved from #66737f (4.44:1 on the page background, just
   under AA) to #5A6B7C (5.01:1), fixing an accessibility issue that had
   been sitting in every page's secondary text.
--------------------------------------------------------------------- */
:root {
    /* Brand, as sampled from the logo */
    --brand: #002252;            /* Deep Navy  — primary, headings, navigation */
    --brand-dark: #00133B;       /* Dark Navy  — footer, dark backgrounds, hover */
    --brand-mid: #164971;        /* Mid Blue   — secondary panels, supporting elements */
    --teal: #00A4BD;             /* Teal       — DECORATIVE only: rules, icons, active marks */
    --accent: #F8B420;           /* Gold       — highlights and notifications; background only */
    --soft-white: #FBFBFB;       /* Soft White — text on dark brand colours */

    /* Accessible derivations of the two that can't carry text */
    --teal-ink: #00707F;         /* teal as link/label text on light (5.79:1) */
    --teal-deep: #007487;        /* teal as a fill under white text (5.46:1) */
    --accent-deep: #D89400;      /* gold pressed/hover state */
    /* Teal as TEXT on the navy chrome — the mirror of --teal-ink, which
       exists because #00A4BD cannot carry text on white (2.98:1). On navy
       the problem is the opposite one: #00A4BD manages 5.22:1 there, but
       it is DARKER than the white it replaces, so a hovered item reads as
       dimmed rather than lit. This tint is 9.2:1 on the header and 9.8:1
       on the member quick-nav band, so hovering brightens. Added
       2026-08-28 when Henk pointed out the header had no visible hover
       state at all. */
    --teal-bright: #7FD4E3;

    --bg: #F2F5F8;
    --card-bg: #ffffff;
    --text: #1E2C3F;
    --muted: #5A6B7C;
    --border: #DCE3EB;
    --success-bg: #e7f6ec;
    --success-text: #1f7a3f;
    --error-bg: #fdecea;
    --error-text: #b3261e;
    --warn-bg: #FFF4DC;
    --warn-text: #8a6100;
    --radius: 8px;

    /* Asymmetry, expressed as numbers so every split on the site is the
       SAME split rather than a pile of one-off percentages. 62/38 is
       close enough to the golden ratio to feel deliberate and far enough
       from 50/50 to never read as a failed attempt at symmetry. */
    --split-major: 62fr;
    --split-minor: 38fr;
    --rail: 340px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.5;
}

.container {
    max-width: 980px;
    margin: 0 auto;
    padding: 0 20px;
}

/* Opt-in wider content column for data-dense, desktop-first screens (the
   accounting grid pages) — set $wideContainer = true before including
   includes/header.php to use it. Deliberately NOT the default: every other
   admin page reads better at the standard 980px measure, and this is only
   worth the extra width when a page has a wide table to show, like the
   accounting grids' inline-editable rows, which is why those pages
   specifically opt in rather than this being the header's default. */
main.container.wide { max-width: 1680px; }

/* Header */
.site-header {
    background: var(--brand);
    color: #fff;
}
.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    flex-wrap: wrap;
    gap: 10px;
}
.site-header .brand {
    display: inline-flex;
    align-items: center;
    color: #fff;
    font-weight: 700;
    font-size: 1.3rem;
    text-decoration: none;
    letter-spacing: 0.3px;
}
.brand-icon { height: 30px; width: auto; margin-right: 8px; }
.site-header nav a {
    color: #fff;
    text-decoration: none;
    margin-left: 18px;
    font-size: 0.95rem;
    opacity: 0.92;
}
.site-header nav a:hover { opacity: 1; text-decoration: underline; }
.nav-user { color: var(--accent); margin-left: 18px; font-size: 0.9rem; }
.site-header nav .lang-switcher { display: inline-flex; margin-left: 18px; vertical-align: middle; }

/* Accounting section sub-nav (includes/accounting_nav.php) — a second menu
   bar under the main site header, shown only on accounting-*.php + team.php
   pages. Styled as a light "tab strip" card (not a second dark bar) so it
   reads as a distinct, lower-emphasis navigation layer under the header —
   an underlined accent tab marks the active section, matching the rest of
   the app's card-based look rather than looking like a second copy of the
   header. The multi-item menus (Customers, Items, Banking, Company) are
   plain <details>/<summary> — no JS needed, identical behaviour on touch
   and mouse. A shared name="" attribute on all four <details> makes them
   act as an exclusive group (opening one closes the others), same trick
   browsers use for radio-style <details> groups. Customers additionally
   nests a second, INDEPENDENT <details> (.accounting-nav-submenu, no
   shared name) for "Transactions" (Customer Invoice / Customer Receipts /
   Allocate Receipts) — it expands inline/indented within the Customers
   panel (an accordion), not as a second floating flyout, deliberately
   avoiding a second layer of position:absolute that would risk the same
   clipping bug a plain nested flyout hit earlier. Deliberately NOT
   overflow-x:auto for
   horizontal scrolling on narrow screens — that would establish a scroll
   container and, per the CSS overflow spec, an element with overflow-x set
   to anything but visible gets overflow-y:auto too, which clips the
   dropdown menus' absolute-positioned panels below the bar. flex-wrap onto
   a second line is the trade-off that keeps the dropdowns working. */
.accounting-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 2px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 1px 3px rgba(20, 30, 45, 0.06);
    padding: 0 6px;
    margin-bottom: 24px;
    position: relative;
    z-index: 40;
}
.accounting-nav-link,
.accounting-nav-dropdown > summary {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--muted);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.88rem;
    padding: 13px 14px;
    border-bottom: 3px solid transparent;
    margin-bottom: -1px;
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.accounting-nav-dropdown > summary::-webkit-details-marker { display: none; }
.accounting-nav-dropdown > summary::after {
    content: '';
    display: inline-block;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    opacity: 0.6;
    margin-left: 1px;
}
.accounting-nav-link:hover,
.accounting-nav-dropdown > summary:hover {
    color: var(--brand-dark);
}
.accounting-nav-link.active,
.accounting-nav-dropdown > summary.active {
    color: var(--brand-dark);
    border-bottom-color: var(--accent);
}
.accounting-nav-dropdown { position: relative; }
.accounting-nav-dropdown[open] > summary {
    color: var(--brand-dark);
}
.accounting-nav-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(20, 30, 45, 0.16);
    min-width: 230px;
    padding: 6px;
    z-index: 41;
}
.accounting-nav-menu a {
    display: block;
    padding: 9px 12px;
    border-radius: 6px;
    color: var(--text);
    text-decoration: none;
    font-size: 0.9rem;
}
.accounting-nav-menu a:hover { background: var(--bg); }

/* Nested "Transactions" accordion under the Customers dropdown — see the
   comment at the top of this section for why this is inline/indented
   rather than a second flyout panel. */
.accounting-nav-submenu { margin: 2px 0; }
.accounting-nav-submenu > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 9px 12px;
    border-radius: 6px;
    color: var(--text);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}
.accounting-nav-submenu > summary::-webkit-details-marker { display: none; }
.accounting-nav-submenu > summary::after {
    content: '';
    flex: none;
    width: 0;
    height: 0;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 5px solid currentColor;
    opacity: 0.5;
    transition: transform 0.15s ease;
}
.accounting-nav-submenu[open] > summary::after { transform: rotate(90deg); }
.accounting-nav-submenu > summary:hover,
.accounting-nav-submenu > summary.active { background: var(--bg); }
.accounting-nav-submenu-list {
    margin: 2px 0 2px 10px;
    padding-left: 10px;
    border-left: 2px solid var(--border);
}
.accounting-nav-submenu-list a {
    display: block;
    padding: 8px 10px;
    border-radius: 6px;
    color: var(--text);
    text-decoration: none;
    font-size: 0.87rem;
}
.accounting-nav-submenu-list a:hover { background: var(--bg); }

@media (max-width: 600px) {
    .accounting-nav-link, .accounting-nav-dropdown > summary { font-size: 0.82rem; padding: 11px 10px; }
}

/* Main */
main.container { padding: 32px 20px 60px; }

h1 { font-size: 1.8rem; margin: 0 0 6px; color: var(--brand-dark); }
h2 { font-size: 1.3rem; color: var(--brand-dark); margin-top: 0; }
.subtitle { color: var(--muted); margin-bottom: 28px; }

/* Cards */
.card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 24px;
    margin-bottom: 24px;
    box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04);
}
.card + .card { margin-top: 20px; }

/* Forms */
label { display: block; font-weight: 600; margin: 16px 0 6px; font-size: 0.92rem; }
label.inline { display: inline-block; font-weight: 500; margin: 0; }
.hint { color: var(--muted); font-size: 0.83rem; margin-top: 4px; }
/* input[type=search] added 2026-08-21: the register's search box was the
   app's only one, and it had been missing from this list since the
   beginning — so it rendered with the browser's own 2px padding and hairline
   border, visibly shorter and flatter than the select and button beside
   it. Listing the type here rather than restyling that one box keeps the
   next search field anyone adds consistent by default. */
/* input[type=time] added 2026-09-14 (the home cell form's meeting time was the app's only one and rendered with the browser's own look). */
input[type=text], input[type=email], input[type=password], input[type=tel], input[type=date], input[type=time], input[type=search], input[type=number], select, textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.97rem;
    font-family: inherit;
    background: #fff;
    color: var(--text);
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(46, 76, 109, 0.12);
}
.password-field { position: relative; }
.password-field input[type=password], .password-field input[type=text] { padding-right: 42px; }
.password-toggle {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    background: none;
    border: none;
    border-radius: 6px;
    color: var(--muted);
    cursor: pointer;
}
.password-toggle:hover { color: var(--text); }
.password-toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.password-toggle .icon-eye-off { display: none; }
.password-toggle[aria-pressed="true"] .icon-eye { display: none; }
.password-toggle[aria-pressed="true"] .icon-eye-off { display: block; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius); margin: 20px 0; padding: 16px 20px; }
legend { font-weight: 700; color: var(--brand-dark); padding: 0 8px; }
.field-error { color: var(--error-text); font-size: 0.85rem; margin-top: 4px; }
.row { display: flex; gap: 16px; flex-wrap: wrap; }
/* An equal-width column inside a .row.
   This used to be written as an inline style="flex:1" on each of 65
   elements — which quietly broke the phone layout, because an inline
   declaration outranks the `.row > * { flex-basis: 100% }` rule further
   down that is supposed to stack these at <=600px. Two form fields then
   stayed side by side on a 5-inch screen, each about 145px wide, and
   Afrikaans labels like "Rekenmeester" were clipped mid-word. As a class
   the media query can win. */
.row-col { flex: 1; min-width: 0; }
.row > * { flex: 1 1 220px; }
.checkbox-row { display: flex; align-items: flex-start; gap: 10px; margin: 18px 0; }
/* flex: 0 0 auto + min sizes added 2026-09-07: iOS Safari lets a checkbox
   shrink below its intrinsic size inside a flex row, so next to the long
   POPIA consent sentence on register-member.php it collapsed to 0px —
   invisible and untappable on iPhones. Same fix .statement-check uses. */
.checkbox-row input { width: auto; flex: 0 0 auto; min-width: 18px; min-height: 18px; margin-top: 3px; }
.checkbox-row label.inline { min-width: 0; }

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 46px;
    background: var(--brand);
    color: #fff;
    border: none;
    padding: 11px 22px;
    border-radius: 6px;
    font-size: 0.97rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    margin-top: 20px;
}
/* BUTTON HOVER (rebuilt 2026-08-29). Henk: "Fix mouse over on all the
   buttons ... on mouse over the letters should turn into white letters."

   Two of the four variants had no usable hover at all:

     .btn-secondary  — white fill, navy text — had NO :hover rule whatever,
                       so the most common button on the dashboard did
                       nothing when you pointed at it.
     .btn-accent     — gold fill, navy text — darkened its gold slightly
                       and kept the dark letters, which on a light fill is
                       nearly invisible movement.

   Every button now resolves to the same idea on hover: a dark fill and
   white letters. That is what was asked for, and it makes the whole app
   answer the cursor the same way.

   WHY THE GOLD BUTTON TURNS NAVY RATHER THAN DARKER GOLD
   White letters need a dark enough fill to be readable. White on the gold
   is 1.82:1 and on the darkened gold 2.57:1 — both unreadable. The
   darkest gold that carries white at all is a muddy bronze (#9A6800,
   4.82:1) that no longer looks like the brand. Navy carries white at
   15.5:1 and is already the app's other button colour, so a gold button
   inverting to navy reads as deliberate rather than broken.

   :not(:disabled) on every rule, so a disabled button stays inert — it
   used to be handed `background: var(--brand)` on hover further down this
   file, which filled a disabled SECONDARY button navy on the way past. */
.btn { transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease; }
.btn:hover:not(:disabled):not([disabled]),
.btn:focus-visible:not(:disabled):not([disabled]) {
    background: var(--brand-dark);
    color: #fff;
}
.btn-accent { background: var(--accent); color: var(--brand-dark); }
.btn-accent:hover:not(:disabled):not([disabled]),
.btn-accent:focus-visible:not(:disabled):not([disabled]) {
    background: var(--brand-dark);
    color: #fff;
}
.btn-danger { background: var(--error-text); }
.btn-danger:hover:not(:disabled):not([disabled]),
.btn-danger:focus-visible:not(:disabled):not([disabled]) {
    background: #8f1e18;
    color: #fff;
}
.btn-small { padding: 6px 14px; min-height: 38px; font-size: 0.85rem; margin-top: 0; }
.btn-secondary { background: #fff; color: var(--brand); border: 1px solid var(--brand); }
.btn-secondary:hover:not(:disabled):not([disabled]),
.btn-secondary:focus-visible:not(:disabled):not([disabled]) {
    background: var(--brand);
    color: #fff;
    border-color: var(--brand);
}
.btn-block { display: flex; width: 100%; }

/* Alerts */
.alert { padding: 12px 16px; border-radius: 6px; margin-bottom: 20px; font-size: 0.93rem; }
.alert-success { background: var(--success-bg); color: var(--success-text); }
.alert-error { background: var(--error-bg); color: var(--error-text); }
.alert-warning { background: var(--warn-bg); color: var(--warn-text); }

/* Demo mode banner — shown on every page while logged into the shared
   demo company (see includes/demo.php). Deliberately a different colour
   from the trial/warning alerts above so it reads as "this whole account
   is a sandbox", not just another status message. */
.demo-banner {
    background: #5b2a9e;
    color: #ffffff;
    padding: 10px 16px;
    border-radius: 6px;
    margin-bottom: 20px;
    font-size: 0.88rem;
    font-weight: 600;
    text-align: center;
}

/* Tables */
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); font-size: 0.92rem; vertical-align: top; }
th { color: var(--muted); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.4px; }
.badge { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 0.76rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px; }
.badge-pending { background: var(--warn-bg); color: var(--warn-text); }
.badge-approved { background: var(--success-bg); color: var(--success-text); }
.badge-rejected { background: var(--error-bg); color: var(--error-text); }
.badge-invalid { background: var(--error-bg); color: var(--error-text); }
.badge-valid { background: var(--success-bg); color: var(--success-text); }

/* Four-step severity ramp for the dashboard's inactive-members badge
   (1+ week -> 1+ month) — reuses .badge-pending (mild) and .badge-rejected
   (most severe) at the two ends, with two intermediate amber/orange steps
   defined here so the ramp reads as one continuous scale rather than
   jumping straight from "mild" to "severe". */
.badge-inactive-2 { background: #ffe9c7; color: #8a5300; }
.badge-inactive-3 { background: #ffdcc7; color: #9c4200; }
/* A member marked inactive (left the company) — neutral grey, not a warning
   colour: it's a status on file, not a problem to fix. */
.badge-inactive { background: #e3e8ef; color: #475569; }

/* Two-tab switcher (New Transactions / Reviewed Transactions) on
   accounting-transactions.php — plain underline-style tabs, switched via
   JS with no page reload (see itransactAccountingSwitchTab() on that page). */
.tx-tabs-nav { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--border); margin: 4px 0 16px; }
.tx-tab-btn {
    background: none; border: none; border-bottom: 2px solid transparent;
    padding: 10px 4px; margin-right: 20px; font-size: 0.95rem; font-weight: 600;
    color: var(--muted); cursor: pointer;
}
.tx-tab-btn:hover { color: var(--brand); }
.tx-tab-btn.active { color: var(--brand); border-bottom-color: var(--brand); }

/* Numbered pagination nav under each Transactions tab's table — plain GET
   links (a real page reload), not JS, so a page number is a normal
   bookmarkable/shareable URL. */
.tx-pagination { display: flex; align-items: center; gap: 6px; margin-top: 14px; flex-wrap: wrap; }
.tx-page-link {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 32px; height: 32px; padding: 0 8px; border-radius: var(--radius);
    border: 1px solid var(--border); color: var(--text); text-decoration: none; font-size: 0.9rem;
}
a.tx-page-link:hover { border-color: var(--brand); color: var(--brand); }
.tx-page-current { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.tx-page-ellipsis { color: var(--muted); padding: 0 2px; }
/* Dashboard member tabs (Approved / Inactive), paged 10 at a time by JS
   (2026-09-08). Prev/Next are <button>s, so the page never reloads; the
   disabled one at either end goes faint instead of vanishing. */
.dash-pager .tx-page-link { background: var(--card-bg); font: inherit; font-size: 0.9rem; cursor: pointer; }
.dash-pager .tx-page-link:disabled { opacity: 0.45; cursor: default; }
.dash-pager .tx-page-link:not(:disabled):hover { border-color: var(--brand); color: var(--brand); }
.dash-page-of { padding: 0 8px; color: var(--muted); font-size: 0.9rem; }

/* Neutral pill for plain informational tags (e.g. the departments a member
   belongs to) — deliberately not a .badge color, since those imply a
   status/outcome (pending/approved/rejected) and a department name isn't one. */
.chip {
    display: inline-block;
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    background: rgba(46, 76, 109, 0.08);
    color: var(--brand-dark);
    border: 1px solid var(--border);
}

/* Reusable collapsible "dropdown" — a <details> whose <summary> shows a
   small rotating twisty, used wherever a list should collapse to save
   space instead of always dumping everything on the page (member-profile.php
   "My departments", member-company-life.php FAQs). */
details.dropdown > summary {
    cursor: pointer;
    font-weight: 700;
    color: var(--brand-dark);
    list-style: none;
    display: flex;
    align-items: center;
    gap: 6px;
}
details.dropdown > summary::-webkit-details-marker { display: none; }
details.dropdown > summary::before {
    content: '';
    display: inline-block;
    width: 0;
    height: 0;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-left: 6px solid var(--brand);
    transition: transform 0.15s;
}
details.dropdown[open] > summary::before { transform: rotate(90deg); }
.dept-chip-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

/* Hero / landing */
.hero { text-align: center; padding: 60px 0 40px; }
.hero h1 { font-size: 2.3rem; }
.hero p { color: var(--muted); font-size: 1.1rem; max-width: 640px; margin: 12px auto 28px; }
.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; margin-top: 30px; }
.feature-grid .card { margin-bottom: 0; }
.feature-grid h3 { margin: 0 0 8px; color: var(--brand-dark); font-size: 1.05rem; }
.feature-grid p { color: var(--muted); font-size: 0.9rem; margin: 0; }

/* Two-up card grid (demo.php's admin/member login options) — a proper
   grid rather than the .row flex helper (which is meant for pairs of
   form fields, not full cards): stretches both cards to equal height and
   resets the .card + .card { margin-top: 20px } rule below, which would
   otherwise nudge the second card down out of alignment with the first. */
/* The HTML `hidden` attribute is display:none in the UA stylesheet, which
   any later display:flex / display:grid rule silently overrides — so a
   .row marked hidden stayed visible. Every conditional block in this app
   uses `hidden`, so it's stated once here rather than worked around per
   component. */
[hidden] { display: none !important; }

.demo-options-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; align-items: stretch; }
.demo-options-grid .card { margin: 0; display: flex; flex-direction: column; }
/* The three blurbs are different lengths, which left the three "Log in"
   buttons at three different heights — a ragged row of the one element on
   the page a visitor is actually meant to click. The blurb absorbs the
   slack instead, so the buttons line up. */
.demo-options-grid .card > p:first-of-type { flex: 1 0 auto; }

/* =====================================================================
   ASYMMETRICAL LAYOUT SYSTEM (2026-08-20 redesign)

   Henk: "Design Asymmetrical — User experience is very important."

   The site used to be built almost entirely from centred text and grids
   of equal-width cards. That's symmetrical by default and it reads as
   flat: every element claims the same importance, so the eye has nowhere
   to land and no route through the page.

   This replaces it with one consistent asymmetric split — --split-major /
   --split-minor, 62/38, close enough to the golden ratio to feel
   deliberate and far enough from 50/50 never to read as a failed attempt
   at symmetry. Everything below is a variation on that one ratio, which
   is what keeps an asymmetric layout looking designed rather than
   accidental:

     .hero-split   heading and CTAs left, supporting panel right
     .split-row    alternating feature rows (--reverse flips the sides)
     .bento        feature grid where the lead card is deliberately larger
     .section-head left-aligned with a teal rule, never centred
     .cta-split    closing CTA: the ask left, the buttons right

   Every one of them collapses to a single column below 860px, in reading
   order, because on a phone there is no "beside" — asymmetry there is
   vertical rhythm and hierarchy, not columns.
===================================================================== */

/* --- Hero -----------------------------------------------------------
   The old hero centred everything in a full-width navy slab. This puts
   the words on the left where reading starts, and gives the right side a
   raised panel that carries the proof points — so the eye goes headline →
   CTA → proof instead of bouncing off a centred wall of text. */
.hero-split {
    display: grid;
    grid-template-columns: var(--split-major) var(--split-minor);
    gap: 44px;
    align-items: center;
    background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%);
    color: var(--soft-white);
    border-radius: 20px;
    padding: 60px 48px;
    margin: 12px 0 48px;
    position: relative;
    overflow: hidden;
}
/* A teal arc bleeding off the top-right corner. Decorative, and the one
   place the pure brand teal can be used at full strength — it carries no
   text, so its 2.98:1 contrast doesn't matter here. */
.hero-split::after {
    content: "";
    position: absolute;
    top: -140px;
    right: -120px;
    width: 380px;
    height: 380px;
    border-radius: 50%;
    background: radial-gradient(circle at 30% 30%, rgba(0, 164, 189, 0.38), rgba(0, 164, 189, 0) 68%);
    pointer-events: none;
}
.hero-split > * { position: relative; z-index: 1; }

.hero-eyebrow {
    display: inline-block;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    font-size: 0.74rem;
    font-weight: 700;
    color: var(--accent);
    margin-bottom: 18px;
}
.hero-split h1 {
    color: var(--soft-white);
    font-size: 2.7rem;
    line-height: 1.12;
    margin: 0 0 16px;
    max-width: 15ch;          /* a short measure makes the headline a shape, not a paragraph */
    letter-spacing: -0.4px;
}
.hero-split .hero-lead {
    color: rgba(251, 251, 251, 0.84);
    font-size: 1.1rem;
    max-width: 46ch;
    margin: 0 0 30px;
}
.hero-cta-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 28px; }
.hero-split .btn-secondary { background: transparent; color: var(--soft-white); border-color: rgba(251, 251, 251, 0.5); }
/* These two sit on dark panels, where an outlined button is the right
   look and filling it navy would erase it. They must therefore out-rank
   the global .btn-secondary hover, which carries (0,4,0) because :not()
   contributes its argument’s specificity — hence the matching chain.
   Noticed 2026-08-29 while giving every button a white-letter hover. */
.hero-split .btn-secondary:hover:not(:disabled):not([disabled]) { background: rgba(251, 251, 251, 0.14); border-color: var(--soft-white); }

.trust-row {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
    font-size: 0.85rem;
    color: rgba(251, 251, 251, 0.76);
    margin: 0;
    padding: 0;
    list-style: none;
}
.trust-row li { display: inline-flex; align-items: center; gap: 7px; }
.trust-row svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--teal); }

/* The hero's right-hand panel. Lighter than the slab behind it so it
   reads as sitting on top, and deliberately narrower than the text — it
   supports the headline, it doesn't compete with it. */
.hero-aside {
    background: rgba(251, 251, 251, 0.07);
    border: 1px solid rgba(251, 251, 251, 0.16);
    border-radius: 14px;
    padding: 26px 24px;
    backdrop-filter: blur(2px);
}
.hero-aside-label {
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--teal);
    margin-bottom: 14px;
}
.hero-aside ul { margin: 0; padding: 0; list-style: none; }
.hero-aside li {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 11px 0;
    border-bottom: 1px solid rgba(251, 251, 251, 0.1);
    font-size: 0.9rem;
    color: rgba(251, 251, 251, 0.88);
    line-height: 1.4;
}
.hero-aside li:last-child { border-bottom: none; padding-bottom: 0; }
.hero-aside li::before { content: "\2713"; color: var(--teal); font-weight: 800; flex: 0 0 auto; }

/* --- Stats ----------------------------------------------------------
   Not four equal boxes. The first stat is the one worth remembering, so
   it gets its own gold-ruled panel at roughly twice the width, and the
   rest sit beside it as a quieter row. */
.stats-strip {
    display: grid;
    grid-template-columns: var(--split-minor) var(--split-major);
    gap: 24px;
    align-items: stretch;
    margin: 0 0 52px;
}
.stat-lead {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 5px solid var(--accent);
    border-radius: var(--radius);
    padding: 26px 28px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.stat-lead .stat-number { font-size: 3.2rem; }
.stat-rest { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 20px; align-items: center; }
.stat-box { padding: 4px 2px; }
.stat-number { font-size: 2rem; font-weight: 800; color: var(--brand); line-height: 1.05; letter-spacing: -1px; }
.stat-label { color: var(--muted); font-size: 0.84rem; margin-top: 6px; }

/* --- Section headings ------------------------------------------------
   Left-aligned, with a short teal rule above. A centred heading over a
   left-aligned grid is the single most common way a page ends up looking
   symmetrical by accident. */
.section-head { margin: 0 0 26px; max-width: 60ch; }
.section-head::before {
    content: "";
    display: block;
    width: 44px;
    height: 3px;
    background: var(--teal);
    border-radius: 2px;
    margin-bottom: 14px;
}
.section-head h2 { font-size: 1.7rem; margin: 0 0 8px; letter-spacing: -0.3px; }
.section-head p { color: var(--muted); margin: 0; font-size: 1rem; }
/* Kept for pricing.php's plainer banner, which is centred on purpose —
   it's a single column of cards with nothing to align against. */
.section-heading { text-align: center; margin: 0 0 30px; }
.section-heading h2 { font-size: 1.55rem; margin: 0 0 8px; }
.section-heading p { color: var(--muted); margin: 0; }

/* --- Alternating feature rows ---------------------------------------
   The workhorse of the redesign: text on one side, a supporting panel on
   the other, sides swapping row to row so the page has a rhythm instead
   of a column. */
.split-row {
    display: grid;
    grid-template-columns: var(--split-major) var(--split-minor);
    gap: 40px;
    align-items: center;
    margin-bottom: 52px;
}
.split-row.split-row-reverse { grid-template-columns: var(--split-minor) var(--split-major); }
.split-row.split-row-reverse .split-row-text { order: 2; }
.split-row.split-row-reverse .split-row-aside { order: 1; }
.split-row-text h2 { font-size: 1.6rem; margin: 0 0 12px; letter-spacing: -0.3px; }
.split-row-text p { color: var(--muted); margin: 0 0 16px; max-width: 54ch; }
.split-row-list { margin: 0; padding: 0; list-style: none; }
.split-row-list li {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 7px 0;
    color: var(--text);
    font-size: 0.94rem;
}
.split-row-list li::before { content: "\2713"; color: var(--teal-ink); font-weight: 800; flex: 0 0 auto; }
.split-row-aside {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 28px 26px;
    box-shadow: 0 10px 30px rgba(0, 34, 82, 0.06);
}
.split-row-aside-mid { background: var(--brand-mid); color: var(--soft-white); border-color: var(--brand-mid); }
.split-row-aside-mid h3 { color: var(--soft-white); }
.split-row-aside-mid p { color: rgba(251, 251, 251, 0.82); }

/* --- Bento feature grid ---------------------------------------------
   Twelve columns, and the lead card takes half of them and both rows.
   Every card the same size says every feature matters equally, which is
   never true — this says which one to read first. */
/* Twelve columns that must TILE, not merely fit: the lead takes 6 and two
   rows, the two cards beside it take the other 6 one row each, and the
   remaining four sit below at 3 apiece. Spans that don't add to 12 leave
   ragged holes down the right-hand side, which reads as a broken grid
   rather than as deliberate asymmetry. */
.bento { display: grid; grid-template-columns: repeat(12, 1fr); gap: 18px; margin-bottom: 52px; }
.bento .card { margin: 0; grid-column: span 3; }
.bento .bento-side { grid-column: span 6; }
.bento .bento-lead {
    grid-column: span 6;
    grid-row: span 2;
    background: linear-gradient(160deg, var(--brand) 0%, var(--brand-dark) 100%);
    color: var(--soft-white);
    border-color: var(--brand);
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.bento .bento-lead h3 { color: var(--soft-white); font-size: 1.4rem; }
.bento .bento-lead p { color: rgba(251, 251, 251, 0.84); font-size: 0.98rem; }
.bento .bento-lead .feature-card-icon-wrap { background: rgba(0, 164, 189, 0.22); }
.bento .bento-lead .feature-card-icon-wrap svg { color: var(--teal); }
.bento .bento-wide { grid-column: span 6; }

.bento h3 { margin: 0 0 8px; color: var(--brand); font-size: 1.05rem; }
.bento p { color: var(--muted); font-size: 0.9rem; margin: 0; line-height: 1.5; }

.feature-card-icon-wrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    border-radius: 12px;
    background: rgba(0, 164, 189, 0.12);
    margin-bottom: 16px;
}
.feature-card-icon-wrap svg { width: 24px; height: 24px; color: var(--teal-ink); }

/* Legacy equal-width feature grid — still used by a couple of secondary
   pages that genuinely are a flat list of peers. */
.feature-icon-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 18px; margin-bottom: 44px; }
.feature-icon-grid .card { margin-bottom: 0; }
.feature-icon-grid h3 { margin: 0 0 8px; color: var(--brand); font-size: 1.05rem; }
.feature-icon-grid p { color: var(--muted); font-size: 0.88rem; margin: 0; line-height: 1.45; }

/* --- Numbered steps --------------------------------------------------
   Three steps with a connecting rule, and each card offset a little
   further down than the last — the stagger is what makes it read as a
   sequence rather than three parallel options. */
.steps-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; margin-bottom: 52px; }
.step-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 26px 24px;
    position: relative;
}
.step-card:nth-child(2) { transform: translateY(18px); }
.step-card:nth-child(3) { transform: translateY(36px); }
.step-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--brand-dark);
    font-weight: 800;
    font-size: 0.95rem;
    margin-bottom: 16px;
}
.step-card h3 { margin: 0 0 8px; font-size: 1.05rem; color: var(--brand); }
.step-card p { color: var(--muted); font-size: 0.88rem; margin: 0; line-height: 1.5; }

/* Read-only banner shown to an accountant on every accounting page (see
   includes/accounting_nav.php). Sits directly under the workflow nav, so
   it needs to read as attached to it rather than as a page alert that
   arrived after an action. */
.accounting-readonly-banner {
    margin-top: -6px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: baseline;
    font-size: 0.9rem;
}
.accounting-readonly-banner strong { flex: 0 0 auto; }
/* A disabled control still has to look deliberate rather than broken. */
.accounting-readonly-banner ~ * button[disabled],
.accounting-readonly-banner ~ * input[type="submit"][disabled] { opacity: 0.45; cursor: not-allowed; }

/* The one-time-code box. Wide, spaced characters, because a six-digit
   code is read off a phone and typed back one digit at a time — a normal
   text input makes people lose their place. */
.otp-input {
    font-size: 1.6rem;
    letter-spacing: 0.5em;
    text-align: center;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    padding: 12px 8px;
}

/* --- Membership register (members.php) -------------------------------
   The list is the page, so it takes the major column and the
   add/import rail sits beside it. Reversed from the usual "form first,
   list below" arrangement on purpose: people open this page to find
   somebody far more often than to add somebody, and a stacked layout
   puts the search box below the fold on a laptop. */
/* A wider major column than the house 62/38. The register carries four
   columns of real data and was scrolling horizontally on a desktop with
   empty space to its right, while the rail beside it holds two short
   paragraphs and a file input. Still asymmetric — just at the ratio this
   particular content needs rather than the default one. */
.members-row { align-items: start; grid-template-columns: 72fr 28fr; }
.members-form-row { align-items: start; }
/* Grid items default to min-width:auto, which means "never shrink below
   your content" — so the register's table pushed its own card wider than
   the phone screen and took the whole page with it. Same fix as
   .report-layout > *; the table then scrolls inside its own container,
   which is what .report-table-scroll is for. */
.members-row > *,
.members-form-row > * { min-width: 0; }
/* The search row. align-items:stretch rather than flex-end: the input,
   the status select and the Search button are three controls doing one
   job, so they share a height as well as a left edge. Under flex-end they
   aligned on their text baselines instead, which left the input sitting
   visibly shorter than the button beside it. */
.members-filter { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; margin-bottom: 10px; }
.members-filter > div { display: flex; }
.members-filter-search { flex: 1; min-width: 0; }

/* The CSV picker in the Import aside. A file input isn't in the shared
   form-control rule above (its internal button can't be styled the same
   way), so it kept its intrinsic ~253px width — which at around 900px,
   where the aside is at its narrowest, pushed 30px past the right edge
   and made the whole page scroll sideways. Capping it at the column
   width is all it needs. */
.members-import input[type=file] { max-width: 100%; }
.members-filter input[type="search"] { width: 100%; margin: 0; }
.members-filter select { min-width: 150px; margin: 0; }
/* .btn carries a 20px top margin globally, for buttons that follow a
   field. Here the button IS a field in the row, and that margin was
   setting the row's height — stretching the input and select to 66px
   against the button's 46px. */
.members-filter .btn { white-space: nowrap; margin: 0; }

/* Narrowing the "missing details" list by which detail is missing
   (2026-08-29). A row of small links rather than a second <select>: there
   are exactly three, they are mutually exclusive, and each carries its own
   count — which is the number an admin is actually deciding on. The one
   you are on is not a link, so the row says where you are without needing
   a separate marker. */
.members-missing-kinds { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: 8px 0 12px; }
.members-missing-kind {
    display: inline-block;
    padding: 3px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.82rem;
    text-decoration: none;
    background: #fff;
}
.members-missing-kind:hover { border-color: var(--teal-deep); color: var(--teal-ink); text-decoration: none; }
.members-missing-kind.is-current {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
    font-weight: 600;
}
/* The result count reads as the answer to the search above it, so it sits
   with the search row rather than drifting into the table below. */
.members-filter-count { margin: 0 0 14px; }

.members-table td { vertical-align: top; }
.members-table .is-editing { background: rgba(0, 164, 189, 0.07); }
.members-table .is-editing td:first-child { box-shadow: inset 3px 0 0 var(--teal); }
/* Invite from the register (2026-09-11): the Invite/Edit pair stacks in
   the actions cell, and the invite-all bar sits under the filter kinds. */
.members-row-actions { white-space: nowrap; }
.members-row-invite { display: inline-block; margin: 0 6px 0 0; }
.members-row-invite .btn { margin-top: 0; }
.members-invited-on { font-size: 0.78rem; }
.members-invite-all { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 0 0 14px; padding: 12px 14px; background: var(--bg); border-radius: var(--radius); }
.members-invite-all form { margin: 0; }
.members-invite-all .btn { margin-top: 0; }
.members-invite-all .hint { margin: 0; flex: 1 1 260px; }

/* Age on its own line, always.
   As an inline span, whether it sat beside the name or wrapped below was
   decided by how long that particular name happened to be — "Johan Botha
   age 56" on one row, "Chantelle Adams" / "age 30" on the next. Nothing
   about the data differs between those two rows, so nothing about the
   layout should either. */
/* Date of birth, then the age beneath it — admin register only. Henk,
   2026-08-21: members found a displayed age personal, so the age now
   appears on this screen and nowhere a member can reach. The date is the
   record; the age is the convenience, so the date reads first and the age
   sits under it, quieter. */
.members-dob { display: block; color: var(--muted); font-size: 0.85rem; margin-top: 3px; white-space: nowrap; }
.members-age { display: block; color: var(--muted); font-size: 0.85rem; margin-top: 1px; white-space: nowrap; opacity: 0.85; }
.members-contact { font-size: 0.9rem; }

/* --- Website live-feed settings (accounting-company.php) --------------
   The settings form is the wide half: it carries six checkboxes and five
   controls, and squeezing that into the minor column would stack every
   one of them. */
.embed-row { align-items: start; }
.embed-toggle {
    background: var(--bg);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius);
    padding: 14px 16px;
    margin-bottom: 18px;
}
.embed-toggle label { font-weight: 400; margin: 0; }
.embed-fieldset { border: 0; padding: 0; margin: 0 0 18px; }
.embed-fieldset legend { padding: 0; font-weight: 700; font-size: 0.95rem; color: var(--brand); }
.embed-section-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; margin-top: 10px; }
.embed-section-option {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    font-weight: 400;
    margin: 0;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--card-bg);
}
.embed-section-option small { display: block; color: var(--muted); font-size: 0.8rem; line-height: 1.4; margin-top: 2px; }
.embed-section-option input { margin-top: 3px; flex: 0 0 auto; }

/* Snippet boxes. The code is a readonly <textarea> rather than a <pre>
   so it can be selected and copied by a company admin whose browser blocks
   the clipboard API — which is most of them on plain http. */
.embed-snippets { margin-top: 20px; }
.embed-snippet { margin-bottom: 16px; }
.embed-snippet-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 6px; }
.embed-snippet-head small { display: block; color: var(--muted); font-size: 0.82rem; line-height: 1.4; max-width: 60ch; }
.embed-snippet-code {
    width: 100%;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
    line-height: 1.5;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    resize: vertical;
    white-space: pre;
    overflow-x: auto;
}
.embed-snippet-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin: 6px 0 10px; }

/* --- Team page: role access matrix -----------------------------------
   A permissions table people read by scanning a column, so the cells
   carry a mark AND a word: the mark for the scan, the word because
   "what does the tick actually mean here" is the question a symbol-only
   matrix always leaves behind. */
/* The global `th` rule uppercases and greys headers, which is right for a
   column heading and wrong for a row label carrying a sentence of
   explanation underneath — "RUNS THE COMPANY SIDE DAY TO DAY" is a shout,
   not a description. Row headers here opt back out of it. */
.role-matrix th[scope="row"] {
    text-align: left;
    vertical-align: top;
    min-width: 190px;
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.95rem;
    color: var(--text);
}
.role-matrix-note {
    display: block;
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--muted);
    line-height: 1.4;
    margin-top: 4px;
    max-width: 34ch;
    text-transform: none;
    letter-spacing: 0;
}
.role-matrix-cell { white-space: nowrap; vertical-align: top; }
.role-matrix-mark { font-weight: 800; margin-right: 6px; }
.role-matrix-label { font-size: 0.86rem; }
.role-matrix-cell.is-full .role-matrix-mark { color: var(--success-text); }
.role-matrix-cell.is-view .role-matrix-mark { color: var(--warn-text); }
.role-matrix-cell.is-none { color: var(--muted); }
.role-matrix-cell.is-scoped .role-matrix-mark { color: var(--teal-ink); }

/* The add-member form beside its explanation. The form is the wide half:
   it holds four fields, and squeezing those into the minor column would
   wrap every one of them onto its own line. */
.team-add-row { align-items: start; }
.team-role-explainer:empty { display: none; }
/* The card for the login you're using right now, so a page full of
   near-identical cards still tells you where you are. Two classes on
   purpose: .content-card sets a full `border` further down this file, and
   a single-class rule up here would lose to it on source order. */
.content-card.content-card-you { border-left: 4px solid var(--teal); }

/* Four-step variant, for demo.php's 1-2-3-4 tour. The stagger carries on
   to a fourth card, so the row needs more clearance beneath it than the
   three-step version's 52px — otherwise the last card, pushed 54px down,
   collides with whatever follows it. */
.steps-grid-4 { margin-bottom: 96px; }
.steps-grid-4 .step-card:nth-child(4) { transform: translateY(54px); }
.step-card-note {
    display: block;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
    color: var(--teal-ink);
    font-size: 0.82rem;
    font-weight: 600;
    line-height: 1.45;
}

/* --- Pricing teaser --------------------------------------------------
   Copy left, the number right, on one line. The price is the thing being
   looked for, so it gets to be the largest object on the row. */
.pricing-teaser {
    display: grid;
    grid-template-columns: var(--split-major) var(--split-minor);
    gap: 36px;
    align-items: center;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 5px solid var(--accent);
    border-radius: 16px;
    padding: 36px 34px;
    margin-bottom: 52px;
}
.pricing-teaser-eyebrow { text-transform: uppercase; letter-spacing: 1px; font-size: 0.74rem; font-weight: 700; color: var(--teal-ink); margin-bottom: 10px; }
.pricing-teaser h2 { margin: 0 0 10px; font-size: 1.5rem; }
.pricing-teaser p { color: var(--muted); margin: 0; max-width: 52ch; }
.pricing-teaser-figure { text-align: right; }
.pricing-teaser-price { font-size: 0.95rem; color: var(--muted); margin-bottom: 14px; }
.pricing-teaser-price strong { display: block; font-size: 3rem; font-weight: 800; color: var(--brand); line-height: 1; letter-spacing: -2px; }
.accounting-teaser { border-left-color: var(--teal); }

/* billing.php's summary panel reuses .pricing-teaser (copy left, the
   number right) because the price is what a pastor opens this page to
   look at, and it should sit where prices sit everywhere else on the
   site. Two differences from the marketing version: the status badge is
   the heading, so it needs no heading weight of its own, and the action
   sits under the figure rather than beside the copy. */
.billing-summary h2 { margin: 0 0 12px; }
.billing-summary .pricing-teaser-figure form { display: flex; justify-content: flex-end; }
.billing-summary .pricing-teaser-figure .hint { display: block; }

/* The card for the plan a company is already on. It borrows
   .pricing-card-popular's emphasis — on this page "the one you're on" is
   the card that matters, not the one we'd most like to sell — and its
   button is a flat label, not a control, since there's nothing to switch
   to. Styled as a disabled-looking span rather than a disabled <button>
   so it never reads as an action that's temporarily unavailable. */
.pricing-card-current .btn.is-current-plan {
    cursor: default;
    opacity: 0.65;
    pointer-events: none;
}

@media (max-width: 860px) {
    .billing-summary .pricing-teaser-figure form { justify-content: flex-start; }
}

/* --- Closing CTA -----------------------------------------------------
   The ask on the left, the buttons on the right, rather than a centred
   stack — it mirrors the hero and closes the page the way it opened. */
.cta-split {
    display: grid;
    grid-template-columns: var(--split-major) var(--split-minor);
    gap: 36px;
    align-items: center;
    background: var(--brand-dark);
    color: var(--soft-white);
    border-radius: 20px;
    padding: 44px 40px;
    margin-bottom: 10px;
}
.cta-split h2 { color: var(--soft-white); margin: 0 0 10px; font-size: 1.7rem; letter-spacing: -0.3px; }
.cta-split p { color: rgba(251, 251, 251, 0.8); margin: 0; max-width: 52ch; }
.cta-split .hero-cta-row { margin: 0; justify-content: flex-end; }
.cta-split .btn-secondary { background: transparent; color: var(--soft-white); border-color: rgba(251, 251, 251, 0.5); }
.cta-split .btn-secondary:hover:not(:disabled):not([disabled]) { background: rgba(251, 251, 251, 0.14); border-color: var(--soft-white); }

@media (max-width: 860px) {
    /* One column, in reading order. On a phone there is no "beside" —
       the asymmetry becomes vertical hierarchy instead of columns. */
    .hero-split,
    .stats-strip,
    .split-row,
    .split-row.split-row-reverse,
    .pricing-teaser,
    .cta-split { grid-template-columns: 1fr; }
    .split-row.split-row-reverse .split-row-text,
    .split-row.split-row-reverse .split-row-aside { order: 0; }
    .hero-split { padding: 40px 26px; gap: 30px; }
    .hero-split h1 { font-size: 2rem; max-width: none; }
    .cta-split { padding: 34px 26px; }
    .cta-split .hero-cta-row { justify-content: flex-start; }
    .pricing-teaser-figure { text-align: left; }
    .members-row { grid-template-columns: 1fr; }
    .stat-lead .stat-number { font-size: 2.6rem; }
    .step-card:nth-child(2), .step-card:nth-child(3), .step-card:nth-child(4) { transform: none; }
    .steps-grid-4 { margin-bottom: 52px; }   /* nothing is offset any more, so the extra clearance is just a gap */
    .bento .card,
    .bento .bento-lead,
    .bento .bento-side,
    .bento .bento-wide { grid-column: span 12; grid-row: auto; }
}

@media (max-width: 1100px) and (min-width: 861px) {
    /* The bento's twelve columns get cramped before the phone breakpoint:
       drop the lead card to full width and let the rest pair up. */
    .bento .bento-lead { grid-column: span 12; grid-row: auto; }
    .bento .card, .bento .bento-side { grid-column: span 6; }
}

/* Dashboard stat widgets (dashboard.php) */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px;
    margin-bottom: 24px;
}
.stat-tile {
    display: block;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 20px;
    text-decoration: none;
    color: inherit;
    box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04);
    transition: box-shadow 0.15s, transform 0.15s;
}
a.stat-tile:hover { box-shadow: 0 3px 10px rgba(20, 30, 40, 0.1); transform: translateY(-1px); }
.stat-tile-value { font-size: 1.9rem; font-weight: 700; color: var(--brand-dark); line-height: 1.1; }
.stat-tile-label { color: var(--muted); font-size: 0.83rem; margin-top: 6px; }
.stat-tile-warn { border-color: var(--warn-text); }
.stat-tile-warn .stat-tile-value { color: var(--warn-text); }
.stat-tile-accent .stat-tile-value { color: var(--accent); }

/* Member profile module cards (member-profile.php) — large clickable
   tiles linking to News / Courses & training / Upcoming Activities /
   Volunteering / Suggestions / FAQ's. */
.module-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin: 16px 0 28px;
}

/* "More" drawer for inactive sections (Henk, 2026-08-24). Features with
   nothing in them collapse into this rather than showing empty cards. */
.module-more {
    margin: 0 0 28px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--card-bg);
}
.module-more > summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    cursor: pointer;
    list-style: none;
    font-weight: 600;
    color: var(--text-muted, #5b6770);
    user-select: none;
}
.module-more > summary::-webkit-details-marker { display: none; }
/* A chevron that rotates when the drawer opens. */
.module-more > summary::before {
    content: "";
    width: 8px;
    height: 8px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-45deg);
    transition: transform 0.15s ease;
    flex: 0 0 auto;
    margin-left: 2px;
}
.module-more[open] > summary::before { transform: rotate(45deg); }
.module-more-count {
    margin-left: auto;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 700;
    min-width: 22px;
    height: 22px;
    padding: 0 7px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--surface-alt, #eef2f5);
    color: var(--text-muted, #5b6770);
}
.module-more > .module-grid { padding: 0 16px 16px; margin: 0; }
@media (prefers-reduced-motion: reduce) {
    .module-more > summary::before { transition: none; }
}
.module-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 24px 22px;
    text-decoration: none;
    color: inherit;
    box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04);
    transition: box-shadow 0.15s, transform 0.15s, border-color 0.15s;
}
.module-card:hover {
    box-shadow: 0 4px 14px rgba(20, 30, 40, 0.1);
    transform: translateY(-2px);
    border-color: var(--brand);
}
.module-card-icon { width: 34px; height: 34px; color: var(--brand); margin-bottom: 14px; }
.module-card-title { font-size: 1.08rem; font-weight: 700; color: var(--brand-dark); }
.module-card-desc { color: var(--muted); font-size: 0.85rem; margin-top: 6px; line-height: 1.4; }
.module-card-count {
    display: inline-block;
    margin-top: 14px;
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--brand);
    background: rgba(46, 76, 109, 0.08);
    padding: 4px 10px;
    border-radius: 999px;
}
/* Grid items default to min-width:auto — "never narrower than my longest
   word" — so a single long word sets the column width. In Afrikaans
   "Vrywilligerswerk" and "Kursusse en Opleiding" did exactly that, pushing
   two 138px columns out to 167px each and the page 26px wider than a
   5-inch screen. English never showed it because its labels are shorter.
   min-width:0 lets the column win and the word wrap. */
.module-card { min-width: 0; }
.module-card-title,
.module-card-desc { overflow-wrap: anywhere; }

@media (max-width: 480px) {
    .module-grid { grid-template-columns: 1fr 1fr; gap: 12px; }
    .module-card { padding: 18px 16px; }
}
/* Below this, two tiles leave about 130px each — not enough for a title
   and a line of description in either language. One column reads better
   than two cramped ones. */
@media (max-width: 380px) {
    .module-grid { grid-template-columns: 1fr; }
}

/* Content cards (member-company-life.php: News / Courses / Activities /
   Volunteering) — a card-grid restyle of the plain stacked .content-item
   list, scoped to its own class so .content-item's plain bordered-box look
   keeps working everywhere else it's used (admin department pages, meeting
   slots, dependents, suggestions, and so on). */
.content-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 18px;
    margin-top: 4px;
}
.content-card {
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04);
    transition: box-shadow 0.15s, transform 0.15s, border-color 0.15s;
}
.content-card:hover {
    box-shadow: 0 4px 14px rgba(20, 30, 40, 0.1);
    transform: translateY(-2px);
    border-color: var(--brand);
}
.content-card-icon { width: 26px; height: 26px; color: var(--brand); margin-bottom: 12px; }
.content-card h3 { margin: 0 0 6px; color: var(--brand-dark); font-size: 1rem; }
.content-card-meta { color: var(--muted); font-size: 0.82rem; margin-bottom: 4px; }
.content-card-body { font-size: 0.9rem; white-space: pre-line; color: var(--text); flex-grow: 1; margin-top: 4px; }
/* The first meta line after the description needs the same air as the
   gap between two meta lines — without it "When: ..." crowded the end
   of the paragraph while "Location: ..." below it sat comfortably, so
   the block read as unevenly spaced. Visible on any card that has both
   a description and a date, which is most activities. */
.content-card-body + .content-card-meta { margin-top: 10px; }
.content-card-actions { margin-top: 14px; }
.content-card-actions form { margin: 0; }
.content-card .attachment-gallery { margin-top: 12px; }

/* FAQs stay a single-column accordion rather than a grid — an expanded
   answer sitting next to short collapsed cards looks broken side by side. */
.content-card-list { display: flex; flex-direction: column; gap: 12px; margin-top: 4px; }
.content-card-list .content-card { padding: 16px 18px; }
.content-card-list summary { cursor: pointer; font-weight: 700; color: var(--brand-dark); list-style: none; }
.content-card-list summary::-webkit-details-marker { display: none; }
@media (max-width: 480px) {
    .content-card-grid { grid-template-columns: 1fr; }
}

/* Widget row (two compact cards side by side on wider screens) */
.widget-row { display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 20px; align-items: stretch; }
.widget-row .card { flex: 1 1 320px; margin: 0; }

/* Footer */
.site-footer { border-top: 1px solid var(--border); padding: 24px 0; color: var(--muted); font-size: 0.85rem; margin-top: 40px; }

/* Utility */
.text-muted { color: var(--muted); }
.mt-0 { margin-top: 0; }
.empty-state { text-align: center; padding: 40px 20px; color: var(--muted); }
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Responsive tables — horizontal scroll on narrow screens instead of
   breaking the layout, so dashboard tables stay usable on a phone. */
.table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 12px; }
.table-responsive table { margin-top: 0; min-width: 560px; }

/* Member-facing pages (landing, login, register, profile) — a lighter,
   mobile-first chrome since these are opened by scanning a QR code on
   a phone, not by an admin at a desk. */
.member-header { padding: 2px 0; }
.member-header .header-inner { justify-content: flex-start; gap: 14px; padding: 14px 20px; }
.brand-small { display: inline-flex; align-items: center; font-weight: 700; color: #fff; font-size: 1rem; letter-spacing: 0.3px; }
.brand-small .brand-icon { height: 24px; margin-right: 6px; }
.company-tag { color: var(--accent); font-size: 0.9rem; }

/* Persistent "Main Menu / Log out" strip shown under the header on every
   logged-in member page (see includes/member-header.php) — a slightly
   darker sub-bar keeps it visually attached to the header above while
   staying legible against it, and it never scrolls out of reach the way a
   bottom-of-page link does on a long page. */
.member-quicknav {
    display: flex;
    align-items: center;
    /* 12, not the original 18: each link now carries 7px of its own side
       padding for its hover wash, which supplies the rest of the gap. */
    gap: 12px;
    padding: 9px 14px;
    background: rgba(0, 0, 0, 0.14);
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.member-quicknav-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: #fff;
    text-decoration: none;
    font-size: 0.83rem;
    font-weight: 600;
    opacity: 0.92;
}
/* Same rebuild as the admin header (2026-08-28): an underline alone on a
   dark band is not a hover state anybody sees. The label and its icon both
   take the bright teal — the icon uses currentColor, so it comes along on
   its own — and the item gets a wash so the whole tap/hit area answers. */
.member-quicknav-link {
    padding: 3px 7px;
    border-radius: 5px;
    transition: color 0.12s ease, background-color 0.12s ease;
}
.member-quicknav-link:hover,
.member-quicknav-link:focus-visible {
    opacity: 1;
    text-decoration: none;
    color: var(--teal-bright);
    background: rgba(0, 164, 189, 0.16);
}
.member-quicknav-link svg { width: 15px; height: 15px; flex-shrink: 0; }
.member-quicknav-logout { margin-left: auto; }
/* The quick-nav link for the page you are already on (2026-08-26, added
   with Company Life). Full opacity plus an underline rather than a
   different colour: this bar sits on a dark translucent band where a
   second accent colour reads as a second kind of thing, and the point is
   only to say "you are here". */
.member-quicknav-current { opacity: 1; text-decoration: underline; text-underline-offset: 3px; }
/* Hovering the page you are already on responds, but keeps its white
   "you are here" colour rather than repainting into the hover teal.
   Same rule as .site-header nav a.active:hover. */
.member-quicknav-current:hover { color: #fff; }

/* Three items now, and the member portal is phone-first. Below 420px the
   labels alone would push Log out off the edge, so the bar tightens up
   rather than wrapping to two rows — a wrapped nav band pushes the page
   content down on every single member page. */
/* Four items since the event link joined (2026-08-26), one of them named
   after the event itself and therefore variable-length. Scroll the bar
   sideways rather than let it wrap: a wrapped nav band pushes the content
   down on EVERY member page, and this one sits under the header on all of
   them. Log out keeps its margin-left:auto, so it stays at the far end of
   the scrollable strip. */
/* SIX items since Donations / Tithing and Volunteering joined
   (2026-08-27), and that changed the right answer here. Sideways scrolling
   was fine for four: the last item sat just past the edge and a thumb
   found it. At six, "Donations" — the one item the company most wants a
   member to notice — falls entirely off a 390px screen behind a scroll
   affordance phones do not draw. A hidden link may as well not exist, so
   the bar now WRAPS to two tidy rows below 560px and every item is visible
   without discovering anything. The cost is roughly 30px of height on
   member pages, bought back by tightening the padding. */
@media (max-width: 560px) {
    .member-quicknav {
        flex-wrap: wrap;
        gap: 6px 10px;
        padding: 6px 10px;
    }
    .member-quicknav-link { flex: 0 0 auto; white-space: nowrap; }
    /* margin-left:auto pins Log out to the right of the LAST row, which
       leaves a ragged gap mid-bar once the items wrap. In two rows it
       simply takes its place in the order. */
    .member-quicknav-logout { margin-left: 0; }
}
@media (max-width: 430px) {
    .member-quicknav { gap: 4px 6px; padding-left: 8px; padding-right: 8px; }
    .member-quicknav-link { font-size: 0.78rem; gap: 4px; padding: 3px 5px; }
    /* SEVEN items since Help joined (2026-08-31), and on a 390px screen
       that tipped the bar from two rows to three — with Log out stranded
       alone on the last one, costing height on every member page. The
       icons are the part that can go: each costs ~19px of width and they
       decorate labels that already say what they are. Below 430px the
       words stand on their own and the bar is two rows again. */
    .member-quicknav-link svg { display: none; }
}
main.container.narrow { max-width: 560px; padding-top: 24px; }

/* The QR landing page a member reaches on their phone. Left-aligned, not
   centred: on a 375px screen there is no "beside", so the asymmetry is
   vertical — a ranged-left heading with the brand rule above it reads
   faster than centred text, and the two big tap targets below carry the
   hierarchy. */
.landing-hero { text-align: left; padding: 20px 0 10px; }
.landing-hero h1 { font-size: 1.9rem; letter-spacing: -0.4px; }
.landing-hero::before {
    content: "";
    display: block;
    width: 44px;
    height: 3px;
    background: var(--teal);
    border-radius: 2px;
    margin-bottom: 14px;
}
.landing-menu { justify-content: flex-start !important; }
.landing-actions { display: flex; flex-direction: column; gap: 14px; margin-top: 28px; }

.landing-menu { display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; font-size: 0.88rem; }
.landing-menu a { color: var(--brand); text-decoration: none; font-weight: 600; }
.landing-menu a:hover { text-decoration: underline; }

.btn-tap {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 22px 20px;
    border-radius: 12px;
    text-decoration: none;
    min-height: 84px;
}
.btn-tap-title { font-size: 1.15rem; font-weight: 700; }
.btn-tap-sub { font-size: 0.88rem; margin-top: 4px; opacity: 0.9; }
.btn-tap-primary { background: var(--brand); color: #fff; }
.btn-tap-primary:hover { background: var(--brand-dark); }
.btn-tap-secondary { background: var(--accent); color: var(--brand-dark); }
.btn-tap-secondary:hover { background: var(--brand-dark); color: #fff; }
.btn-tap-primary:hover .btn-tap-sub,
.btn-tap-secondary:hover .btn-tap-sub { color: #fff; }

.profile-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 2px; }
.profile-top h1 { margin: 0; }
/* Member profile photos (2026-09-11, includes/member_photo.php). One round
   element in three sizes; the initials disc keeps lists aligned when a
   member has no picture. --mp-hue is set per member so the tint is stable. */
.member-photo { border-radius: 50%; object-fit: cover; flex: 0 0 auto; background: var(--bg); border: 1px solid var(--border); display: inline-block; vertical-align: middle; }
.member-photo-sm { width: 32px; height: 32px; }
.member-photo-md { width: 56px; height: 56px; }
.member-photo-lg { width: 120px; height: 120px; }
.member-photo-initials { display: inline-flex; align-items: center; justify-content: center; font-weight: 700; color: #fff; letter-spacing: 0.5px; border: none;
    background: hsl(var(--mp-hue, 205), 45%, 45%); }
.member-photo-sm.member-photo-initials { font-size: 0.72rem; }
.member-photo-md.member-photo-initials { font-size: 1.1rem; }
.member-photo-lg.member-photo-initials { font-size: 2.4rem; }
.member-photo-card { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
.member-photo-card form { margin: 0 0 8px; }
.member-photo-card input[type="file"] { margin: 0 0 8px; max-width: 100%; }
.member-photo-card .btn { margin-top: 0; }
.members-name-cell { display: flex; gap: 10px; align-items: flex-start; }
.members-list-photo { margin-top: 2px; }
/* Hospital & pastoral care (2026-09-11, pastoral-care.php / member-care.php). */
.care-toolbar { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.care-toolbar .tab-buttons { margin-bottom: 12px; }
.care-toolbar .btn { margin-top: 0; }
.care-tabs .tab-button { text-decoration: none; }
.care-table td { vertical-align: top; font-size: 0.9rem; }
.care-table .is-editing { background: rgba(0, 164, 189, 0.07); }
.care-overdue { color: var(--error-text); font-weight: 700; }
.care-detail { margin-top: 20px; align-items: start; }
.care-detail > * { min-width: 0; } /* let a wide table scroll inside its card instead of stretching the page (2026-09-11) */
.care-detail.split-row-reverse > .split-row-aside { order: 0; } /* capture form left, list right (2026-09-14) */
.care-aside-form { margin: 0 0 18px; }
.care-aside-form .btn { margin-top: 8px; }
.care-visit-form { margin: 0 0 14px; padding-bottom: 14px; border-bottom: 1px solid var(--border); }
.care-visit-log { list-style: none; margin: 0; padding: 0; }
.care-visit-log li { padding: 10px 0; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
.care-visit-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.care-visit-head .text-muted { font-size: 0.8rem; }
.care-visit-delete { margin: 0 0 0 auto; }
.care-visit-delete .link-button { background: none; border: none; cursor: pointer; font-size: 1rem; padding: 0 4px; min-height: 0; }
.care-visit-notes { margin-top: 4px; white-space: pre-line; }
.care-danger { margin-top: 18px; }
.care-stats .stat-tile { padding: 14px 16px; }
.care-stats .stat-tile-value { font-size: 1.6rem; }
/* =====================================================================
   GROUPED ADMIN NAVIGATION (2026-09-11). Henk: "Navigation menu are very
   busy. Maybe we can redesign." One row: Dashboard + four <details>
   groups on the left, user · language · log out on the right. Under
   900px a menu button reveals the bar and the groups stack as headed
   lists. The old flat-link rules above still style the logged-out bar. */
.site-nav-admin { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex: 1 1 auto; min-width: 0; }
.site-nav-admin .nav-primary { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.site-nav-admin .nav-secondary { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.site-header .site-nav-admin a { margin-left: 0; }
/* The admin bar needs more than the 980px content measure: let the header
   run to 1400px so five groups plus the user cluster sit on one line. */
.site-header .container { max-width: 1400px; }
.site-header .site-nav-admin .nav-primary > a { padding: 8px 12px; border-radius: 6px; border-bottom: none; font-weight: 600; white-space: nowrap; }
.site-header .site-nav-admin .nav-primary > a.active,
.site-nav-admin .nav-group-current > summary { background: rgba(0, 164, 189, 0.22); color: #fff; opacity: 1; box-shadow: inset 0 -2px 0 var(--teal); }
.nav-group { position: relative; }
.nav-group > summary {
    list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 5px;
    padding: 8px 10px 8px 12px; border-radius: 6px; color: #fff; font-size: 0.95rem; font-weight: 600; opacity: 0.92;
    user-select: none; transition: background-color 0.12s ease, color 0.12s ease;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary:hover, .nav-group[open] > summary { background: rgba(0, 164, 189, 0.14); color: var(--teal-bright); opacity: 1; }
.nav-group-current[open] > summary { color: #fff; }
.nav-caret { width: 14px; height: 14px; transition: transform 0.15s ease; }
.nav-group[open] .nav-caret { transform: rotate(180deg); }
.nav-dropdown {
    position: absolute; top: calc(100% + 6px); left: 0; min-width: 210px; z-index: 60;
    background: var(--card-bg); border: 1px solid var(--border); border-radius: 10px;
    box-shadow: 0 12px 30px rgba(0, 19, 59, 0.22); padding: 6px;
}
.site-header .nav-dropdown a {
    display: block; padding: 9px 12px; border-radius: 6px; color: var(--text); font-size: 0.93rem; opacity: 1;
    border-bottom: none; margin: 0; white-space: nowrap;
}
.site-header .nav-dropdown a:hover, .site-header .nav-dropdown a:focus-visible { background: rgba(0, 164, 189, 0.12); color: var(--teal-ink); border-bottom: none; }
.site-header .nav-dropdown a.active { background: var(--brand); color: #fff; }
.site-header .nav-dropdown a.active:hover { color: #fff; }
.site-nav-admin .nav-user { margin-left: 0; font-size: 0.86rem; white-space: nowrap; max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.site-nav-admin .nav-user-company { color: rgba(251, 251, 251, 0.75); }
.site-nav-admin .lang-switcher { margin-left: 0; }
.site-header .site-nav-admin .nav-logout { white-space: nowrap; padding: 6px 10px; border: 1px solid rgba(251, 251, 251, 0.35); border-radius: 6px; font-size: 0.86rem; border-bottom-width: 1px; }
.site-header .site-nav-admin .nav-logout:hover { border-color: var(--teal); background: rgba(0, 164, 189, 0.14); }
.nav-toggle {
    display: none; align-items: center; gap: 8px; margin-left: auto; padding: 8px 12px; border-radius: 6px;
    background: transparent; color: #fff; border: 1px solid rgba(251, 251, 251, 0.35); font: inherit; font-size: 0.9rem; cursor: pointer; min-height: 0;
}
.nav-toggle svg { width: 20px; height: 20px; }
.nav-toggle[aria-expanded="true"] { background: rgba(0, 164, 189, 0.2); border-color: var(--teal); }
@media (max-width: 1350px) {
    .site-nav-admin .nav-user-company { display: none; }
}
@media (max-width: 1150px) {
    .site-nav-admin .nav-user { display: none; }
}
@media (max-width: 900px) {
    .nav-toggle { display: inline-flex; }
    .site-nav-admin { display: none; flex-direction: column; align-items: stretch; flex-basis: 100%; gap: 6px; padding-top: 8px; border-top: 1px solid rgba(251, 251, 251, 0.15); margin-top: 4px; }
    .site-nav-admin.is-open { display: flex; }
    .site-nav-admin .nav-primary { flex-direction: column; align-items: stretch; gap: 2px; }
    .site-nav-admin .nav-primary > a { padding: 10px 12px; }
    .nav-group > summary { width: 100%; justify-content: space-between; padding: 10px 12px; }
    .nav-dropdown { position: static; box-shadow: none; border: none; background: rgba(251, 251, 251, 0.06); border-radius: 8px; margin: 2px 0 6px; padding: 4px; }
    .site-header .nav-dropdown a { color: #fff; padding: 9px 20px; white-space: normal; }
    .site-header .nav-dropdown a:hover { color: var(--teal-bright); background: rgba(0, 164, 189, 0.14); }
    .site-header .nav-dropdown a.active { background: rgba(0, 164, 189, 0.3); }
    .site-nav-admin .nav-secondary { margin-left: 0; justify-content: space-between; flex-wrap: wrap; padding: 8px 4px 2px; border-top: 1px solid rgba(251, 251, 251, 0.15); }
    .site-nav-admin .nav-user { display: inline; max-width: 100%; white-space: normal; }
    .site-nav-admin .nav-user-company { display: inline; }
}
/* Small groups (2026-09-11, groups.php / member-group.php). */
.groups-tier { margin-left: 6px; font-size: 0.66rem; }
.groups-level-1 td:first-child strong { font-size: 1.02rem; }
.groups-level-1, .groups-level-2 { background: rgba(0, 34, 82, 0.03); }
.groups-closed td { opacity: 0.6; }
.groups-roster td { padding: 6px 4px; vertical-align: middle; }
.groups-roster td:first-child { width: 36px; }
.groups-report { border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; margin: 0 0 8px; }
.groups-report > summary { cursor: pointer; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-size: 0.92rem; }
.groups-report-flagged { border-color: var(--warn-text); background: rgba(248, 180, 32, 0.06); }
.groups-report-body { margin-top: 8px; font-size: 0.92rem; }
.groups-report-body p { margin: 0 0 8px; }
.groups-report-meta { font-size: 0.8rem; }
.groups-att-list { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 8px; }
.groups-att { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 0.76rem; font-weight: 600; }
.groups-att.is-present { background: var(--success-bg); color: var(--success-text); }
.groups-att.is-absent { background: #eef0f3; color: #8a94a3; text-decoration: line-through; }
.groups-review-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 6px; }
.groups-review-form input[type="text"] { flex: 1 1 220px; margin: 0; }
.groups-review-form .btn { margin-top: 0; }
.groups-tick-list { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 8px 0 12px; }
.groups-tick { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; cursor: pointer; }
.groups-tick input { width: 18px; height: 18px; margin: 0; }
.groups-tick-big { flex-direction: column; gap: 0; }
.groups-tick-big .groups-tick { padding: 10px 6px; border-bottom: 1px solid var(--border); width: 100%; font-size: 1rem; }
.groups-tick-big .groups-tick input { width: 24px; height: 24px; }
.groups-tick-big .groups-tick:has(input:checked) { background: rgba(0, 164, 189, 0.08); }
.groups-held { display: flex; align-items: center; gap: 8px; margin: 12px 0 8px; font-weight: 600; }
.groups-held input { width: 20px; height: 20px; margin: 0; }
.groups-inline-form { display: inline-flex; gap: 6px; flex-wrap: wrap; align-items: center; justify-content: flex-end; }
.groups-inline-form input[type="text"] { width: 150px; margin: 0; padding: 6px 8px; font-size: 0.85rem; }
.groups-inline-form .btn { margin-top: 0; }
.groups-followup { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 10px 0; border-bottom: 1px solid var(--border); font-size: 0.92rem; }
.groups-capture textarea, .groups-capture input { margin-bottom: 6px; }
.groups-trend-up { color: var(--success-text); font-weight: 700; }
.groups-trend-down { color: var(--error-text); font-weight: 700; }
.dash-charts.groups-charts { margin-bottom: 20px; grid-template-columns: 1fr 1fr; } /* two same-shaped column charts side by side in equal halves; on a phone each keeps its 520px minimum and scrolls */
/* =====================================================================
   APP SHELL (2026-09-11). Henk: "Update i-company to use the following
   layout" — dark sidebar with the modules on the left, white top bar with
   quick actions, content beside it. Signed-in pages only; the marketing
   pages keep .site-header. Under 1000px the sidebar slides in over the
   page from the menu button. */
.app-shell { display: flex; min-height: 100vh; background: var(--bg); }
.app-sidebar {
    width: 236px; flex: 0 0 236px; background: var(--brand-dark); color: rgba(251, 251, 251, 0.86);
    display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; overflow-y: auto; z-index: 70;
    scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.18) transparent;
}
.app-brand { display: flex; align-items: center; gap: 10px; padding: 16px 18px 12px; color: #fff; font-weight: 700; font-size: 1rem; text-decoration: none; letter-spacing: 0.2px; }
.app-brand .brand-icon { height: 28px; margin: 0; }
.app-brand span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-nav { padding: 4px 10px 12px; flex: 1 1 auto; }
.app-nav-section { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 1px; color: rgba(251, 251, 251, 0.45); padding: 14px 10px 4px; font-weight: 700; }
.app-nav-link, .app-nav-group > summary {
    display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 7px; color: rgba(251, 251, 251, 0.86);
    text-decoration: none; font-size: 0.9rem; font-weight: 500; cursor: pointer; list-style: none; transition: background-color 0.12s ease, color 0.12s ease;
}
.app-nav-group > summary::-webkit-details-marker { display: none; }
.app-nav-link svg, .app-nav-group > summary svg:first-child { width: 17px; height: 17px; flex: 0 0 auto; opacity: 0.85; }
.app-nav-link:hover, .app-nav-group > summary:hover { background: rgba(255, 255, 255, 0.07); color: #fff; text-decoration: none; }
.app-nav-link.active, .app-nav-group.is-current > summary { background: rgba(0, 164, 189, 0.22); color: #fff; box-shadow: inset 3px 0 0 var(--teal); }
.app-nav-caret { margin-left: auto; width: 13px !important; height: 13px !important; opacity: 0.6; transition: transform 0.15s ease; }
.app-nav-group[open] .app-nav-caret { transform: rotate(90deg); }
.app-nav-children { padding: 2px 0 6px 18px; }
.app-nav-children a { display: block; padding: 6px 10px 6px 19px; border-left: 1px solid rgba(255, 255, 255, 0.14); color: rgba(251, 251, 251, 0.72); text-decoration: none; font-size: 0.85rem; }
.app-nav-children a:hover { color: #fff; text-decoration: none; }
.app-nav-children a.active { color: #fff; font-weight: 700; border-left-color: var(--teal); }
.app-sidebar-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 14px 16px; border-top: 1px solid rgba(255, 255, 255, 0.1); }
.app-sidebar-foot .lang-switcher { margin: 0; }
.app-sidebar-foot .lang-switcher select { font-size: 0.8rem; }
.app-logout { color: rgba(251, 251, 251, 0.8); font-size: 0.84rem; padding: 6px 10px; border: 1px solid rgba(251, 251, 251, 0.3); border-radius: 6px; text-decoration: none; white-space: nowrap; }
.app-logout:hover { border-color: var(--teal); color: #fff; text-decoration: none; }
.app-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.app-main > main.container { margin: 0; flex: 1 0 auto; padding-top: 24px; }
.app-main > main.container:not(.wide) { max-width: 1180px; }
.app-main .site-footer { margin-top: 24px; }
.app-topbar {
    display: flex; align-items: center; gap: 8px; padding: 8px 20px; background: var(--card-bg); border-bottom: 1px solid var(--border);
    position: sticky; top: 0; z-index: 60; min-height: 54px;
}
.app-menu-btn { display: none; align-items: center; justify-content: center; width: 38px; height: 38px; border: none; background: transparent; color: var(--text); border-radius: 8px; cursor: pointer; padding: 0; min-height: 0; }
.app-menu-btn svg { width: 22px; height: 22px; }
.app-menu-btn:hover { background: var(--bg); }
.app-quick { position: relative; }
.app-quick-btn {
    display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: 7px; color: var(--text); font-size: 0.86rem; font-weight: 600;
    text-decoration: none; cursor: pointer; list-style: none; background: transparent; border: 1px solid transparent; white-space: nowrap;
}
.app-quick-btn::-webkit-details-marker { display: none; }
.app-quick-btn svg { width: 16px; height: 16px; }
.app-quick-btn:hover, .app-quick[open] > .app-quick-btn { background: var(--bg); border-color: var(--border); text-decoration: none; color: var(--brand-dark); }
.app-quick-menu { position: absolute; top: calc(100% + 6px); left: 0; min-width: 220px; background: var(--card-bg); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 12px 30px rgba(0, 19, 59, 0.18); padding: 6px; z-index: 80; }
.app-quick-menu a { display: block; padding: 8px 12px; border-radius: 6px; color: var(--text); text-decoration: none; font-size: 0.9rem; }
.app-quick-menu a:hover { background: rgba(0, 164, 189, 0.12); color: var(--teal-ink); text-decoration: none; }
.app-search { display: flex; align-items: center; gap: 6px; margin-left: 6px; padding: 0 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg); height: 36px; width: 260px; }
.app-search svg { width: 16px; height: 16px; color: var(--muted); flex: 0 0 auto; }
.app-search input { border: none; background: transparent; margin: 0; padding: 0; height: 100%; width: 100%; font-size: 0.88rem; box-shadow: none; }
.app-search input:focus { outline: none; box-shadow: none; }
.app-topbar-right { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.app-icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 8px; color: var(--muted); }
.app-icon-btn svg { width: 19px; height: 19px; }
.app-icon-btn:hover { background: var(--bg); color: var(--brand-dark); }
.app-user { display: flex; align-items: center; gap: 9px; padding: 3px 6px 3px 4px; margin-left: 6px; }
.app-user-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--brand); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 0.78rem; font-weight: 700; }
.app-user-text { display: flex; flex-direction: column; line-height: 1.15; }
.app-user-text strong { font-size: 0.84rem; color: var(--text); }
.app-user-text small { font-size: 0.7rem; color: var(--muted); }
.app-sidebar-backdrop { display: none; position: fixed; inset: 0; background: rgba(0, 19, 59, 0.45); z-index: 65; }
@media (max-width: 1000px) {
    .app-sidebar { position: fixed; left: 0; top: 0; transform: translateX(-100%); transition: transform 0.18s ease; box-shadow: 0 0 40px rgba(0,0,0,0.3); }
    .app-sidebar.is-open { transform: translateX(0); }
    body.app-sidebar-open .app-sidebar-backdrop { display: block; }
    .app-menu-btn { display: inline-flex; }
    .app-search { width: 160px; }
    .app-quick-link span { display: none; }
    .app-user-text { display: none; }
    .app-topbar { padding: 8px 12px; }
}
@media (max-width: 600px) {
    .app-search { display: none; }
    .app-quick-link { display: none; }
}
/* The WhatsApp float sits bottom-right on the admin shell, clear of the sidebar. */
body:has(.app-shell) .whatsapp-float { left: auto !important; right: 22px !important; bottom: 22px; }
@media print {
    .app-sidebar, .app-topbar, .app-sidebar-backdrop { display: none !important; }
    .app-main > main.container { max-width: none; }
}
.care-inline { display: none; }
.care-table-member { font-size: 0.86rem; }
.care-table-member td, .care-table-member th { padding: 7px 8px; }
@media (max-width: 600px) {
    .care-table-member .care-fold-col { display: none; }
    .care-inline { display: block; font-size: 0.78rem; }
    .table-responsive .care-table-member { min-width: 0; width: 100%; }
}

.locked-field {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.92rem;
}
.locked-field:last-child { border-bottom: none; }
.locked-field span { color: var(--muted); }

/* "Verify on Google Maps" button under an address field */
.map-verify-btn { margin-top: 8px; }

/* Children / dependents (member-profile.php) */
.dependent-row {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    margin-top: 14px;
}
.dependent-row-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
}
.dependent-row-top form { margin: 0; }
/* The note a company keeps against one child — an allergy, who may collect
   them. Given its own tinted band rather than another line of grey meta,
   because on a Sunday morning it is the line somebody has to notice
   without looking for it. Added 2026-08-31, when it turned out the column
   had never been displayed anywhere. */
.dependent-note {
    margin: 10px 0 0;
    padding: 8px 12px;
    background: var(--warn-bg);
    color: var(--warn-text);
    border-radius: var(--radius);
    font-size: 0.9rem;
}
.dependent-training { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.dependent-training h3 { font-size: 0.95rem; margin: 0 0 6px; color: var(--brand-dark); }
.training-log-list { list-style: none; margin: 0 0 10px; padding: 0; }
.training-log-list li { padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
.training-log-list li:last-child { border-bottom: none; }
details > summary { cursor: pointer; }
details > summary.btn { list-style: none; }
details > summary.btn::-webkit-details-marker { display: none; }
.training-add-form { margin-top: 10px; }
.training-add-form .btn { margin-top: 12px; }

/* Printable QR code page */
.qr-print-card { text-align: center; max-width: 480px; margin: 0 auto; padding: 40px 30px; }
.qr-print-logo { height: 44px; width: auto; margin-bottom: 20px; }
.qr-print-header h2 { margin-bottom: 4px; }
.qr-print-header p { color: var(--muted); margin-top: 0; }
.qr-holder { margin: 24px auto; display: flex; justify-content: center; }
.qr-holder svg { width: 260px; height: 260px; }
.qr-url { font-family: monospace; font-size: 0.8rem; color: var(--muted); word-break: break-all; }

/* Printable Section 18A donation tax certificate, Customer Invoice, and
   Donation Receipt — all three share this same certificate-print-card /
   certificate-header structure, and the optional logo/notes branding set
   on accounting-invoice-design.php (see accounting_render_document_logo()
   / accounting_render_document_notes() in includes/accounting.php). */
.certificate-print-card { max-width: 640px; margin: 0 auto; padding: 40px; }
.certificate-header { text-align: center; border-bottom: 2px solid var(--border); padding-bottom: 16px; margin-bottom: 16px; }
.certificate-logo { max-height: 90px; max-width: 100%; margin: 0 auto 14px; display: block; }
.certificate-notes { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--border); }
.logo-preview { max-height: 90px; max-width: 260px; display: block; margin-bottom: 10px; border: 1px solid var(--border); border-radius: 6px; padding: 8px; background: #fff; }

@media print {
    .no-print, .site-header, .site-footer { display: none !important; }
    body { background: #fff; }
    .qr-print-card, .certificate-print-card { border: none; box-shadow: none; padding: 0; }
    .qr-holder svg { width: 320px; height: 320px; }
}

/* POPIA / encryption trust badge */
.popia-badge {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--muted);
    font-size: 0.8rem;
    line-height: 1.4;
}
.popia-badge-icon { flex-shrink: 0; color: #5a8a6b; }
.popia-badge-footer { justify-content: center; padding-top: 10px; }
.popia-badge-inline {
    background: var(--success-bg);
    color: #1f5c33;
    padding: 10px 12px;
    border-radius: 6px;
    margin: 10px 0 4px;
}
.popia-badge-inline .popia-badge-icon { color: #1f5c33; }

/* Language switcher */
.lang-switcher { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.lang-switcher select {
    background: rgba(255,255,255,0.12);
    color: #fff;
    border: 1px solid rgba(255,255,255,0.35);
    border-radius: 6px;
    padding: 5px 8px;
    font-size: 0.85rem;
}
.lang-switcher select option { color: var(--text); }

/* Tabbed sections (company-life.php / member-company-life.php) */
.tab-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.tab-button {
    flex: 1 1 auto;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: #fff;
    color: var(--brand);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    text-align: center;
}
.tab-button.active { background: var(--brand); color: #fff; border-color: var(--brand); }
.tab-panel { display: none; }
.tab-panel.active { display: block; }
.content-item {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    margin-top: 14px;
}
.content-item:first-child { margin-top: 0; }
.content-item h3 { margin: 0 0 4px; color: var(--brand-dark); font-size: 1rem; }
.content-item-meta { color: var(--muted); font-size: 0.83rem; margin-bottom: 6px; }
.content-item-body { font-size: 0.92rem; white-space: pre-line; }
.content-item-actions { margin-top: 10px; }

/* Company Life attachments (images/PDFs on news, courses, activities,
   volunteer openings) — a wrapping row of image thumbnails and/or small
   file chips (for PDFs), each with an optional delete button on the
   admin-facing pages. */
.attachment-gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}
.attachment-tile { position: relative; }
/* Lead picture on a news post (render_news_media(), 2026-09-08): the first
   image attached is the news item itself, so it runs the full width of
   the card instead of sitting as an 84px thumbnail. Height is capped so a
   tall poster doesn't push the next post off the screen; the click opens
   the full image. */
.news-lead { position: relative; margin: 10px 0 12px; }
.news-lead a { display: block; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--bg); }
.news-lead img { display: block; width: 100%; max-height: 380px; object-fit: contain; }
.content-card .news-lead img { max-height: 320px; }
.news-lead .news-lead-delete { top: 6px; right: 6px; }
/* "Your giving" on member-giving.php (2026-09-08): the member's own record
   of gifts, thank-you line, totals strip, dense table, receipt buttons. */
.giving-history-thanks { font-size: 1.05rem; font-weight: 600; color: var(--brand); margin: 0 0 6px; }
.giving-history-summary { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: flex-end; margin: 14px 0 12px; padding: 12px 14px; background: var(--bg); border-radius: var(--radius); }
.giving-history-total { display: flex; flex-direction: column; }
.giving-history-total-value { font-size: 1.4rem; font-weight: 700; color: var(--brand); }
.giving-history-total-label { font-size: 0.8rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.giving-history-year { display: flex; flex-direction: column; font-weight: 600; }
.giving-history-table td.num, .giving-history-table th.num { text-align: right; }
.giving-history-actions { margin: 14px 0 6px; }
.giving-history-subheading { margin: 22px 0 4px; font-size: 1.05rem; }
/* 2026-09-11 (Henk): "Move the View Receipt to the left and make the
   font / text smaller. Then the member don't have to browse to the right
   and left ... on mobile devices." The giving table is compact by design:
   smaller type, tighter cells, a slimmer button in the FIRST column, no
   forced 560px minimum, and below 600px the Document no. column folds
   into the description line — so a 390px phone shows every row whole. */
.giving-history .table-responsive table { min-width: 0; width: 100%; }
.giving-history-table { font-size: 0.82rem; }
.giving-history-table th, .giving-history-table td { padding: 7px 8px; vertical-align: top; }
.giving-history-table th { font-size: 0.74rem; }
.giving-history-table .text-muted { font-size: 0.76rem; }
.giving-history-table td.giving-action { width: 1%; padding-left: 4px; }
.giving-history-table .btn-small { padding: 4px 10px; min-height: 30px; font-size: 0.76rem; white-space: nowrap; }
.giving-doc-inline, .giving-date-inline { display: none; }
@media (max-width: 600px) {
    /* Three columns on a phone: button | date + description + numbers | amount. */
    .giving-history-table .giving-doc-col, .giving-history-table .giving-date-col { display: none; }
    .giving-doc-inline { display: block; }
    .giving-date-inline { display: block; font-weight: 600; font-size: 0.74rem; color: var(--muted); }
    .giving-history-table td.num { font-size: 0.8rem; }
    .giving-history-table { font-size: 0.78rem; }
    .giving-history-table th, .giving-history-table td { padding: 6px 5px; }
    .giving-history-table .btn-small { padding: 4px 8px; font-size: 0.72rem; }
}
.attachment-thumb {
    display: block;
    width: 84px;
    height: 84px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--bg);
}
.attachment-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.attachment-file-chip {
    display: flex;
    align-items: center;
    gap: 6px;
    max-width: 180px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--text);
    font-size: 0.8rem;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.attachment-file-chip svg { flex-shrink: 0; color: var(--muted); }
.attachment-file-chip span { overflow: hidden; text-overflow: ellipsis; }
.attachment-delete-form { position: absolute; top: -6px; right: -6px; margin: 0; }
.attachment-delete-btn {
    width: 20px;
    height: 20px;
    line-height: 18px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: #fff;
    color: var(--error-text);
    font-size: 0.9rem;
    font-weight: 700;
    cursor: pointer;
    text-align: center;
}
.attachment-delete-btn:hover { background: var(--error-bg); }

/* Pricing page (pricing.php) — tiered subscription cards, banded by
   estimated company member count. */
.pricing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 20px;
    margin: 10px 0 30px;
    align-items: stretch;
}
.pricing-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 28px 22px;
    text-align: center;
    box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04);
    transition: box-shadow 0.15s, transform 0.15s, border-color 0.15s;
}
.pricing-card:hover { box-shadow: 0 4px 14px rgba(20, 30, 40, 0.1); transform: translateY(-2px); }
.pricing-card h2 { margin: 6px 0 4px; font-size: 1.15rem; color: var(--brand-dark); }
.pricing-card-popular { border-color: var(--accent); border-width: 2px; padding-top: 26px; }
.pricing-card-badge {
    position: absolute;
    top: -13px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--accent);
    color: var(--brand-dark);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    padding: 4px 12px;
    border-radius: 999px;
    white-space: nowrap;
}
.pricing-card-range { color: var(--muted); font-size: 0.85rem; }
.pricing-card-price { margin: 16px 0; color: var(--brand-dark); font-size: 2.4rem; font-weight: 800; }
.pricing-card-price-currency { font-size: 1.2rem; font-weight: 700; vertical-align: top; position: relative; top: 6px; }
.pricing-card-price-suffix { font-size: 0.9rem; font-weight: 500; color: var(--muted); }
.pricing-card-tagline { color: var(--muted); font-size: 0.87rem; flex-grow: 1; margin: 0 0 20px; line-height: 1.4; }

.feature-check-list { list-style: none; margin: 10px 0 0; padding: 0; }
.feature-check-list li {
    position: relative;
    padding: 8px 0 8px 30px;
    border-bottom: 1px solid var(--border);
    font-size: 0.92rem;
}
.feature-check-list li:last-child { border-bottom: none; }
.feature-check-list li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 11px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--success-bg);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231f7a3f' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 10px 10px;
}
@media (max-width: 480px) {
    .pricing-grid { grid-template-columns: 1fr; }
}

/* Registration plan picker (register-company.php) — a compact version of
   the pricing cards above, selectable via a hidden radio input per card. */
.plan-picker { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-top: 6px; }
.plan-picker-option { position: relative; }
.plan-picker-option input[type=radio] { position: absolute; opacity: 0; width: 1px; height: 1px; }
.plan-picker-option label {
    display: block;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 14px;
    cursor: pointer;
    text-align: center;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.plan-picker-option label:hover { border-color: var(--brand); }
.plan-picker-option input[type=radio]:checked + label {
    border-color: var(--brand);
    border-width: 2px;
    box-shadow: 0 0 0 1px var(--brand);
    background: rgba(46, 76, 109, 0.04);
}
.plan-picker-option input[type=radio]:focus-visible + label { outline: 2px solid var(--brand); outline-offset: 2px; }
.plan-picker-label { font-weight: 700; color: var(--brand-dark); font-size: 0.95rem; }
.plan-picker-range { color: var(--muted); font-size: 0.78rem; margin-top: 2px; }
.plan-picker-price { font-weight: 700; color: var(--brand-dark); margin-top: 8px; font-size: 1.05rem; }

/* Floating WhatsApp contact button (includes/header.php) — fixed to the
   corner of the viewport, sits above the page content on every public/admin
   page. Not shown on the member portal (member-header.php uses its own
   header and deliberately doesn't include this — congregants have no reason
   to WhatsApp the platform operator about I-Transact itself). */
.whatsapp-float {
    position: fixed;
    bottom: 22px;
    right: 22px;
    width: 56px;
    height: 56px;
    background: #25d366;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
    z-index: 1000;
    transition: transform 0.15s, box-shadow 0.15s;
}
.whatsapp-float:hover { transform: scale(1.08); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.32); }
.whatsapp-float svg { width: 30px; height: 30px; fill: #fff; }
@media (max-width: 480px) {
    .whatsapp-float { bottom: 16px; right: 16px; width: 50px; height: 50px; }
    .whatsapp-float svg { width: 26px; height: 26px; }
}

/* Small-screen refinements */
@media (max-width: 600px) {
    .hero h1 { font-size: 1.7rem; }
    h1 { font-size: 1.5rem; }
    .card { padding: 18px; }
    main.container { padding: 22px 16px 50px; }
    .row { gap: 0; }
    .row > * { flex-basis: 100%; }
    table th, table td { font-size: 0.86rem; padding: 8px; }
    .header-inner { padding: 14px; }
    .site-header nav a { margin-left: 12px; font-size: 0.88rem; }
    .hero-panel { padding: 40px 20px; border-radius: 12px; }
    .hero-panel h1 { font-size: 1.8rem; }
    .cta-banner { padding: 34px 20px; border-radius: 12px; }
    .pricing-teaser { padding: 28px 20px; }
}

/* Welfare / Welsyn (welfare.php, member-welfare.php) */
.welfare-item-icon { width: 26px; height: 26px; color: var(--brand); }
.welfare-item-photo-wrap {
    width: 100%;
    aspect-ratio: 16 / 10;
    border-radius: 10px;
    background: var(--bg, var(--bg));
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    margin-bottom: 12px;
}
/* contain, not cover — most of these are tall, narrow product photos
   (bottles, standing packets) on a plain background dropped into a wide
   16:10 card frame. cover crops in to fill the frame, chopping off the
   top/bottom of the packaging; contain shrinks the whole photo to fit
   inside the frame instead, letterboxed on the wrap's own background
   color, so the full product is always visible. */
.welfare-item-photo-wrap img { width: 100%; height: 100%; object-fit: contain; display: block; }
.welfare-item-photo-wrap .welfare-item-icon { width: 40px; height: 40px; color: var(--muted); }
.welfare-price { color: var(--muted); font-size: 0.85rem; margin: 2px 0 10px; }
.welfare-price strong { color: var(--brand-dark); }

.welfare-progress {
    position: relative;
    height: 8px;
    border-radius: 999px;
    background: var(--bg, #eef1f4);
    overflow: hidden;
    margin: 4px 0 8px;
}
.welfare-progress-fill {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    background: var(--accent);
    opacity: 0.45;
    border-radius: 999px;
    transition: width 0.2s;
}
.welfare-progress-fill-received { background: var(--success-text); opacity: 1; }
.welfare-progress-label { display: flex; justify-content: space-between; font-size: 0.78rem; color: var(--muted); margin-bottom: 2px; }
.welfare-progress-label .welfare-still-needed { font-weight: 700; color: var(--brand-dark); }
.welfare-progress-label .welfare-fulfilled { color: var(--success-text); font-weight: 700; }

.welfare-qty-form { display: flex; gap: 8px; align-items: center; margin-top: 10px; }
.welfare-qty-form input[type="number"] { max-width: 80px; margin: 0; }
.welfare-qty-form button { white-space: nowrap; }

/* flex-wrap and min-width:0 added 2026-08-22. Flex items refuse to shrink
   below their content by default, so on a 5-inch screen the "Cancel"
   button was rendering 76px past the right edge of its own card — clipped,
   unreachable, and the action the row exists for. It now wraps onto a
   second line instead. */
.welfare-pledge-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 0.88rem; }
.welfare-pledge-row > * { min-width: 0; }
.welfare-pledge-row:last-child { border-bottom: none; }
.welfare-pledge-row .welfare-pledge-meta { color: var(--muted); }
.welfare-pledge-row form { margin: 0; display: inline-flex; gap: 6px; align-items: center; }
.welfare-pledge-row input[type="number"] { max-width: 64px; margin: 0; padding: 4px 6px; }

.welfare-pack-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; margin-top: 4px; }
.welfare-pack-card { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04); }
.welfare-pack-card h3 { margin: 0 0 4px; color: var(--brand-dark); font-size: 1rem; }
.welfare-pack-items { list-style: none; margin: 10px 0; padding: 0; font-size: 0.85rem; }
.welfare-pack-items li { display: flex; justify-content: space-between; padding: 4px 0; border-bottom: 1px dashed var(--border); }
.welfare-pack-items li:last-child { border-bottom: none; }

.welfare-stock-hint { font-size: 0.8rem; color: var(--muted); margin-top: 2px; }
@media (max-width: 480px) {
    .welfare-pack-grid { grid-template-columns: 1fr; }
}

/* member-welfare.php accordion — a collapsed row of thumb + name + status
   + chevron per item, expanding to the full description/progress/pledge
   form. Reuses .content-card-list/.content-card so it inherits the FAQ
   accordion's card chrome; everything below is layout specific to the
   summary row and the shrunk-down thumbnail. */
.welfare-accordion-item { padding: 0; overflow: hidden; }
.welfare-accordion-item:hover { transform: none; box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04); border-color: var(--border); }
.welfare-accordion-summary {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
}
.welfare-accordion-thumb {
    flex: 0 0 auto;
    width: 42px;
    height: 42px;
}
.welfare-accordion-thumb .welfare-item-photo-wrap {
    width: 42px;
    height: 42px;
    aspect-ratio: auto;
    border-radius: 8px;
    margin-bottom: 0;
}
.welfare-accordion-thumb .welfare-item-icon { width: 22px; height: 22px; }
.welfare-accordion-name {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 700;
    color: var(--brand-dark);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.welfare-accordion-status {
    flex: 0 0 auto;
    font-size: 0.78rem;
    font-weight: 700;
    white-space: nowrap;
    padding: 3px 9px;
    border-radius: 999px;
}
.welfare-accordion-status.status-pledged { background: var(--warn-bg); color: var(--warn-text); }
.welfare-accordion-status.status-needed { background: var(--bg, #eef1f4); color: var(--muted); }
.welfare-accordion-status.status-met { background: var(--success-bg); color: var(--success-text); }
.welfare-accordion-chevron {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    color: var(--muted);
    transition: transform 0.15s;
}
.welfare-accordion-item[open] .welfare-accordion-chevron { transform: rotate(180deg); }
.welfare-accordion-body {
    padding: 0 16px 16px;
    border-top: 1px solid var(--border);
    margin-top: 0;
    padding-top: 12px;
}
/* Bank Reconciliation grid (accounting-bank.php) — a Sage-style flat,
   inline-editable table: every unmatched bank statement line is one row
   with its own small <form>, and Date/Payee/Description/Reference/
   Selection(category)/VAT/Spent/Received are all editable directly in
   the cell rather than behind an expand/edit step. Kept deliberately
   plain (no JS framework, no AJAX) — same server-rendered-form
   convention as the rest of the app; the only JS is the tiny
   unallocated-select colouring and the split-row add/remove below. */
.bank-grid-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.bank-grid-table th { padding: 5px 6px; white-space: nowrap; text-align: left; border-bottom: 2px solid var(--border); }
.bank-grid-table td { padding: 2px 6px; vertical-align: middle; border-bottom: 1px solid var(--border); }
.bank-grid-table input[type="text"],
.bank-grid-table input[type="date"],
.bank-grid-table input[type="number"],
.bank-grid-table select {
    width: 100%;
    min-width: 80px;
    box-sizing: border-box;
    padding: 3px 5px;
    font-size: 0.82rem;
    line-height: 1.25;
    border: 1px solid var(--border);
    border-radius: 4px;
}
.bank-grid-table select.bank-selection-unallocated { color: var(--warn-text); font-weight: 600; }
.bank-grid-actions { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.bank-grid-icon-btn {
    width: 22px;
    height: 22px;
    line-height: 20px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
    text-align: center;
    background: #fff;
}
.bank-grid-confirm-btn { color: #1a7f37; }
.bank-grid-confirm-btn:hover { background: #e6f4ea; }
.bank-grid-ignore-btn { color: var(--error-text); }
.bank-grid-ignore-btn:hover { background: var(--error-bg); }
/* Staged import rows flagged as possible duplicates (2026-09-08). */
.tx-row-duplicate td { background: var(--warn-bg) !important; }
.tx-dup-badge { display: inline-block; margin-top: 4px; }
/* Move a captured line to the Reviewed tab (✓✓), or send it back (↩). */
.bank-grid-review-btn { color: #1a56db; font-size: 0.72rem; letter-spacing: -1px; }
.bank-grid-review-btn:hover { background: #e8effc; }
.bank-grid-unreview-btn { color: #64748b; }
.bank-grid-unreview-btn:hover { background: #eef1f5; }
/* Clickable Date column header (sort toggle) + the amount search bar. */
.tx-sort-link { color: inherit; text-decoration: none; white-space: nowrap; }
.tx-sort-link:hover { text-decoration: underline; }
.tx-sort-arrow { font-size: 0.72em; opacity: 0.75; }
.tx-amount-search { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 4px 0 14px; }
.tx-amount-search input[type="text"] { max-width: 220px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 6px; }
.tx-amount-clear { font-size: 0.85rem; }
/* From / To date pickers beside the transactions search (2026-09-08). */
.tx-date-range { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tx-date-range label { font-size: 0.85rem; color: var(--muted); margin: 0; }
.tx-date-range input[type="date"] { width: auto; margin: 0; padding: 6px 8px; font-size: 0.9rem; }
.bank-grid-split-row { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; flex-wrap: wrap; }
.bank-grid-split-row select { min-width: 130px; }
.bank-grid-split-row input[type="number"] { max-width: 110px; }

/* accounting-customer-invoice.php's ?edit=<id> line-items grid — same
   plain server-rendered-table + <template> clone-to-add-row idiom as
   .bank-grid-table's split-row feature above, but for full invoice lines
   (Type/Description/Unit/Qty/Price/VAT/Exclusive/VAT Amt/Total) and with
   both an Add Line button AND a per-row Remove button — the split-row
   feature only ever needed Add. The <template> here sits inside the
   <table> itself (a sibling of <tbody>) rather than beside it, since its
   content is a bare <tr> that needs table-context parsing to clone
   correctly into <tbody>. */
.li-grid-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.li-grid-table th { padding: 6px 6px; white-space: nowrap; text-align: left; border-bottom: 2px solid var(--border); }
.li-grid-table td { padding: 4px 6px; vertical-align: middle; border-bottom: 1px solid var(--border); }
.li-grid-table input[type="text"],
.li-grid-table input[type="number"],
.li-grid-table select {
    width: 100%;
    min-width: 80px;
    box-sizing: border-box;
    padding: 4px 5px;
    font-size: 0.82rem;
    border: 1px solid var(--border);
    border-radius: 4px;
}
.li-grid-table td.li-computed { white-space: nowrap; text-align: right; color: var(--muted); }
.li-grid-table td.li-total { color: var(--text); font-weight: 600; }
.li-remove-btn {
    width: 22px;
    height: 22px;
    line-height: 20px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
    text-align: center;
    background: #fff;
    color: var(--error-text);
}
.li-remove-btn:hover { background: var(--error-bg); }
.li-totals-summary { max-width: 320px; margin-left: auto; margin-top: 16px; font-size: 0.9rem; }
.li-totals-summary div { display: flex; justify-content: space-between; padding: 4px 0; }
.li-totals-summary .li-grand-total { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 8px; font-weight: 700; font-size: 1.05rem; }

@media (max-width: 480px) {
    .welfare-accordion-summary { padding: 12px; gap: 10px; }
    .welfare-accordion-thumb, .welfare-accordion-thumb .welfare-item-photo-wrap { width: 36px; height: 36px; }
    .welfare-accordion-status { font-size: 0.72rem; padding: 3px 7px; }
}

/* ---------------------------------------------------------------------
   Bank Reconciliation ("Reconcile Banks") — accounting-bank.php, rebuilt
   2026-08-20. Laid out to match Henk's reference screenshot: a two-column
   header panel (account + balances on the left, period + options on the
   right), a dense tick-off grid, then Select/Deselect All on the left of
   the footer with the four running totals stacked on the right.

   The grid is deliberately denser than the app's other tables — a
   treasurer works down a month of statement lines, so rows are compact
   and column widths are pinned so the numbers stay in a readable column
   instead of jumping about as descriptions change length.
--------------------------------------------------------------------- */
.reconcile-header { display: flex; flex-wrap: wrap; gap: 28px; align-items: flex-start; }
.reconcile-header-col { flex: 1 1 320px; min-width: 0; }

.reconcile-field { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.reconcile-field > label {
    flex: 0 0 150px;
    margin: 0;
    text-align: right;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--muted);
}
.reconcile-field > select,
.reconcile-field > input,
.reconcile-field > output { flex: 1 1 auto; margin: 0; min-width: 0; }

/* The read-only "Balance" box: same shape as the input beside it so the
   two read as a pair, but visibly not editable. */
.reconcile-readonly {
    display: block;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg);
    color: var(--text);
    font-variant-numeric: tabular-nums;
    text-align: right;
    font-weight: 600;
}
.reconcile-readonly.is-negative { color: var(--error-text); }

.reconcile-field-check { align-items: center; }
.reconcile-field-check > label {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    text-align: left;
    font-weight: 400;
    color: var(--text);
}
.reconcile-field-check input[type="checkbox"] { width: auto; flex: 0 0 auto; margin: 0; }

.reconcile-grid-card { padding: 0; overflow: hidden; }
/* Roughly 12 rows before it scrolls — enough to see a month at a glance
   without pushing the totals off the bottom of the screen, which is the
   one thing a treasurer needs permanently in view. */
.reconcile-grid-scroll { max-height: 460px; overflow: auto; }

.reconcile-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.reconcile-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--brand);
    color: #fff;
    font-weight: 600;
    text-align: left;
    padding: 9px 10px;
    white-space: nowrap;
}
.reconcile-table td { padding: 6px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.reconcile-table tbody tr:nth-child(even) { background: #fafbfc; }
.reconcile-table tbody tr:hover { background: var(--bg); }

.reconcile-table .col-doc { width: 34px; text-align: center; }
.reconcile-table .col-tick { width: 90px; text-align: center; }
.reconcile-table .col-tick input[type="checkbox"] { width: auto; margin: 0; }
.reconcile-table .col-amount {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
.reconcile-table .col-amount.is-negative { color: var(--error-text); }
.reconcile-nowrap { white-space: nowrap; }
/* Descriptions on a bank statement are long and repetitive; truncating
   keeps the amount column aligned, and the full text stays available as
   a title tooltip. */
.reconcile-truncate { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.reconcile-doc-link { text-decoration: none; font-size: 0.95rem; opacity: 0.75; }
.reconcile-doc-link:hover { opacity: 1; }

.reconcile-footer {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    align-items: flex-start;
    justify-content: space-between;
    margin-top: 18px;
}
.reconcile-footer-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.reconcile-totals { margin: 0; min-width: 320px; }
.reconcile-totals > div { display: flex; align-items: center; justify-content: flex-end; gap: 14px; margin-bottom: 8px; }
.reconcile-totals dt { font-size: 0.88rem; font-weight: 600; color: var(--muted); }
.reconcile-totals dd { margin: 0; }
.reconcile-totals output {
    display: block;
    min-width: 160px;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg);
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
/* The Difference box is the one number the whole screen is about, so it
   is emphasised and turns green only when it actually reaches zero. */
.reconcile-total-difference dt { color: var(--text); }
.reconcile-total-difference output { border-width: 2px; border-color: var(--brand); font-size: 1.02rem; }
.reconcile-total-difference output.is-balanced {
    border-color: var(--success-text);
    background: var(--success-bg);
    color: var(--success-text);
}

.reconcile-buttons { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 22px; }

@media (max-width: 700px) {
    .reconcile-field { flex-direction: column; align-items: stretch; gap: 4px; }
    .reconcile-field > label { flex: 0 0 auto; text-align: left; }
    .reconcile-footer { flex-direction: column; }
    .reconcile-totals { min-width: 0; width: 100%; }
    .reconcile-totals > div { justify-content: space-between; }
    .reconcile-truncate { max-width: 160px; }
}

/* Print: the Print button is a plain window.print(), so this stylesheet
   is what turns the working screen into the reconciliation report a
   treasurer files. Everything interactive goes; the grid prints in full
   (no scroll box, no row cap) with the ticks rendered as characters,
   since a printed checkbox widget doesn't reliably show its state. */
@media print {
    .site-header, .site-footer, .accounting-nav, .whatsapp-float,
    .reconcile-buttons, .reconcile-footer-actions, .demo-banner, .alert { display: none !important; }

    body { background: #fff; }
    .container, .container.wide { max-width: none; width: auto; padding: 0; }
    .card { border: none; box-shadow: none; padding: 0; margin-bottom: 12px; }

    .reconcile-grid-scroll { max-height: none; overflow: visible; }
    .reconcile-table { font-size: 0.72rem; }
    .reconcile-table thead th {
        position: static;
        background: #fff;
        color: #000;
        border-bottom: 2px solid #000;
    }
    .reconcile-table tbody tr { page-break-inside: avoid; }
    .reconcile-table tr.reconcile-opening-row td { position: static; }
    .reconcile-table tbody tr:nth-child(even) { background: #fff; }
    .reconcile-truncate { max-width: none; white-space: normal; }

    /* td, not the header cell — the <th> shares the .col-tick class and
       would otherwise print an empty box next to the column title. */
    .reconcile-table td.col-tick input[type="checkbox"] { display: none; }
    .reconcile-table td.col-tick::after { content: "\2610"; font-size: 1rem; }
    .reconcile-table td.col-tick:has(input:checked)::after { content: "\2611"; }

    /* The header fields print as plain values, not as form controls: a
       printed dropdown arrow and text-input border are noise on a filed
       reconciliation. */
    .reconcile-field select,
    .reconcile-field input[type="text"],
    .reconcile-field input[type="date"] {
        border: none;
        padding-left: 0;
        background: none;
        appearance: none;
        -webkit-appearance: none;
        font-weight: 600;
    }
    .reconcile-field-check { display: none; }
    .reconcile-field input[type="date"]::-webkit-calendar-picker-indicator { display: none; }
    .reconcile-readonly { border: none; padding-left: 0; text-align: left; }

    .reconcile-field > label { color: #000; }
    .reconcile-readonly, .reconcile-totals output { background: #fff; border-color: #000; }
    .reconcile-totals { break-inside: avoid; }
}

/* ---------------------------------------------------------------------
   Opening Balances (accounting-opening-balances.php) — a plain two-column
   entry table per section (bank accounts, funds). Amounts are right-
   aligned and tabular so a column of figures reads as a column.
--------------------------------------------------------------------- */
.opening-balance-table { width: 100%; border-collapse: collapse; }
.opening-balance-table th {
    text-align: left;
    font-size: 0.83rem;
    color: var(--muted);
    font-weight: 600;
    padding: 6px 10px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.opening-balance-table th.col-amount { text-align: right; }
.opening-balance-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.opening-balance-table td label { margin: 0; font-weight: 600; }
.opening-balance-table td input { margin: 0; }
.opening-balance-table td.col-amount input { text-align: right; font-variant-numeric: tabular-nums; }
.opening-balance-table .badge { margin-left: 8px; vertical-align: middle; }

@media (max-width: 600px) {
    .opening-balance-table th, .opening-balance-table td { padding: 6px 4px; }
}

/* The locked Opening Balance line at the foot of the reconciliation grid.
   Visually set apart from real transactions — it isn't one, and it can't
   be un-ticked. */
.reconcile-table tr.reconcile-opening-row td {
    /* Sticky to the bottom of the scroll box, mirroring the sticky header
       row at the top: the opening balance is context for every figure in
       the grid, so it should stay in view rather than being something you
       scroll past and forget. */
    position: sticky;
    bottom: 0;
    z-index: 1;
    background: var(--bg);
    font-style: italic;
    color: var(--muted);
    border-top: 2px solid var(--border);
}
.reconcile-table tr.reconcile-opening-row td.col-amount { font-style: normal; color: var(--text); }
.reconcile-table tr.reconcile-opening-row td.col-amount.is-negative { color: var(--error-text); }

/* =====================================================================
   Accounting workflow nav — the 1-2-3-4 stepper (2026-08-20 redesign).

   Henk asked for the Accounting section to be organised by the order a
   treasurer works in rather than by subject area, and for the layout to
   be ASYMMETRICAL. Both show up here: the four numbered steps take the
   left of the bar as connected chevrons (so it reads as a process, not a
   list of links), and the occasional destinations — Dashboard, Reports,
   Setup — sit right-aligned in the quieter original styling. Equal
   weighting would flatten the hierarchy this redesign exists to create.
   See includes/accounting_nav.php for what lives under each step.
===================================================================== */
.accounting-nav-workflow {
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 0;
    overflow: visible;
}

.accounting-steps { display: flex; align-items: stretch; min-width: 0; }

.accounting-step { position: relative; }

/* The chevron itself. clip-path cuts the arrow point on the right and the
   matching notch on the left, and the negative margin slides each step
   into the previous one's notch so they interlock. */
.accounting-step > summary {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 14px 26px 14px 30px;
    margin-left: -16px;
    background: var(--bg);
    color: var(--muted);
    font-weight: 700;
    font-size: 0.9rem;
    white-space: nowrap;
    cursor: pointer;
    list-style: none;
    clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 50%, calc(100% - 16px) 100%, 0 100%, 16px 50%);
    transition: background 0.15s ease, color 0.15s ease;
}
.accounting-step > summary::-webkit-details-marker { display: none; }

/* The first step has no previous chevron to sit in, so it gets a flat
   left edge and no overlap — otherwise the bar starts with a stray notch. */
.accounting-step:first-child > summary {
    margin-left: 0;
    padding-left: 20px;
    border-top-left-radius: var(--radius);
    border-bottom-left-radius: var(--radius);
    clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 50%, calc(100% - 16px) 100%, 0 100%);
}

/* Later steps overlap earlier ones, so paint order has to run backwards —
   otherwise step 2 would be drawn over step 1's arrow point. */
.accounting-step:nth-child(1) { z-index: 4; }
.accounting-step:nth-child(2) { z-index: 3; }
.accounting-step:nth-child(3) { z-index: 2; }
.accounting-step:nth-child(4) { z-index: 1; }

.accounting-step-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--border);
    color: var(--brand-dark);
    font-size: 0.78rem;
    font-weight: 800;
    flex: 0 0 auto;
}

.accounting-step > summary:hover { background: #e9edf1; color: var(--brand-dark); }

/* "Active" (this is the step you're working in) and "open" (you've just
   pulled its menu down) are different states and must not look identical —
   otherwise two chevrons go solid at once and neither means anything. Only
   active gets the solid brand fill; merely-open gets a light lift. */
.accounting-step.active > summary {
    background: var(--brand);
    color: #fff;
}
.accounting-step.active > summary .accounting-step-number {
    background: var(--accent);
    color: var(--brand-dark);
}
.accounting-step[open]:not(.active) > summary {
    background: #e3e8ee;
    color: var(--brand-dark);
}

/* The dropdown panel hangs below the chevron. Nudged right to clear the
   notch, so it lines up with the step's label rather than its point. */
.accounting-step > .accounting-nav-menu { left: 16px; }

.accounting-nav-aside { display: flex; align-items: center; gap: 2px; padding-right: 6px; }
.accounting-nav-menu-right { left: auto; right: 0; }

@media (max-width: 900px) {
    /* Below this the four chevrons stop fitting side by side. They stack as
       full-width numbered rows instead of scrolling sideways: a horizontal
       scroll container would have to be `overflow-x: auto`, and a box that
       scrolls on one axis is forced to clip on the other — which would cut
       the step's own dropdown off at the strip's edge. Stacking keeps the
       process order readable top-to-bottom and keeps every sub-item
       reachable, which matters more on a phone than the chevron shape does.
       The dropdowns become inline expansions here for the same reason:
       a floating panel on a 380px screen is worse than simply pushing the
       rows below it down. */
    .accounting-nav-workflow { flex-direction: column; align-items: stretch; gap: 0; padding: 0; }
    .accounting-steps { flex-direction: column; align-items: stretch; }
    .accounting-step > summary,
    .accounting-step:first-child > summary {
        clip-path: none;
        margin-left: 0;
        padding: 13px 16px;
        border-radius: 0;
        font-size: 0.86rem;
        border-bottom: 1px solid var(--border);
    }
    .accounting-step > .accounting-nav-menu {
        position: static;
        left: auto;
        box-shadow: none;
        border: none;
        border-bottom: 1px solid var(--border);
        border-radius: 0;
        min-width: 0;
        padding: 4px 0 8px 47px;
    }
    .accounting-nav-aside { padding: 0 6px; }
}

/* ---------------------------------------------------------------------
   Create Invoice (accounting-invoice-new.php) — the asymmetrical split.

   Wide left column for the line-item grid (where all the typing happens),
   narrow right rail for the framing decisions (customer, reference, due
   date, running total). Not 50/50: an even split would give the customer
   picker the same visual weight as ten line items, which isn't the shape
   of the task. On a phone the rail stacks ABOVE the grid — you choose who
   you're billing before you start typing what for.
--------------------------------------------------------------------- */
.invoice-build {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 20px;
    align-items: start;
}
.invoice-build-main { min-width: 0; }
.invoice-build-rail { display: flex; flex-direction: column; gap: 16px; }
.invoice-build-rail .card { padding: 18px; }
.invoice-build-rail label { font-size: 0.85rem; }

.invoice-build-totals div {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 5px 0;
    font-size: 0.9rem;
}
.invoice-build-totals output { font-variant-numeric: tabular-nums; font-weight: 600; }
.invoice-build-totals .li-grand-total {
    border-top: 1px solid var(--border);
    margin-top: 6px;
    padding-top: 10px;
    font-weight: 700;
    font-size: 1.05rem;
}

@media (max-width: 900px) {
    .invoice-build { grid-template-columns: 1fr; }
    /* Rail first on a phone: decide the customer before typing lines. */
    .invoice-build-rail { order: -1; }
}

/* One row picked out by ?highlight=<id> — used when the Create Invoice
   page hands off to the invoice list, and when the Reconcile Banks grid's
   document link opens a transaction. A gold left edge and a brief flash
   rather than a permanent background: it answers "which one?" on arrival
   and then gets out of the way. */
.row-highlight > td {
    background: var(--warn-bg) !important;
    box-shadow: inset 3px 0 0 var(--accent);
    animation: itransact-row-flash 2.4s ease-out 1;
}
@keyframes itransact-row-flash {
    0%, 30% { background: #fdf0cd; }
    100%    { background: var(--warn-bg); }
}
@media (prefers-reduced-motion: reduce) {
    .row-highlight > td { animation: none; }
}

/* The floating WhatsApp button is pinned to the bottom-right of the
   viewport, which is exactly where the Accounting screens put the numbers
   that matter — the reconciliation totals, the invoice total and its
   Create button, both in right-hand rails. On those pages it moves to the
   bottom-left instead. Accounting is a back-office area a treasurer works
   in for an hour at a time; the support button being on the other side
   costs nothing there, whereas covering the Difference figure costs a lot.
   Scoped with :has() so no page needs a body class, and a browser without
   :has() support simply keeps the original position rather than breaking. */
body:has(.accounting-nav) .whatsapp-float {
    left: 20px;
    right: auto;
}
@media (max-width: 600px) {
    /* The small-screen rule further up re-pins `right`, so restate the
       override at that width rather than letting it snap back. */
    body:has(.accounting-nav) .whatsapp-float { left: 16px; right: auto; }
}

/* ---------------------------------------------------------------------
   Deposit split panel (accounting-transactions.php).

   One banked amount broken into the gifts that made it up. Inline in the
   grid (Henk's choice over a dedicated screen), which means it has to
   stay usable for a deposit covering twenty members' tithes: the
   allocation list scrolls inside the panel instead of pushing the rest of
   the grid off the screen.
--------------------------------------------------------------------- */
.tx-split-row > td { background: var(--bg); padding: 0; }
.tx-split-panel {
    padding: 16px 18px;
    border-left: 4px solid var(--accent);
    background: var(--card-bg);
    margin: 6px 0;
    border-radius: var(--radius);
    box-shadow: inset 0 0 0 1px var(--border);
}
.tx-split-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}
.tx-split-deposit { text-align: right; }
.tx-split-deposit strong { display: block; font-size: 1.25rem; font-variant-numeric: tabular-nums; }

/* Roughly eight allocation rows before it scrolls — a long list stays in
   the panel rather than burying the running total below the fold, which
   is the one figure the treasurer is working towards. */
.tx-split-rows-scroll { max-height: 320px; overflow-y: auto; }

.tx-split-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.tx-split-table th {
    text-align: left;
    padding: 4px 6px;
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 600;
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    background: var(--card-bg);
}
.tx-split-table td { padding: 4px 6px; }
.tx-split-table input, .tx-split-table select { margin: 0; font-size: 0.85rem; padding: 6px 8px; }
.tx-split-table .tx-split-amount { text-align: right; font-variant-numeric: tabular-nums; max-width: 120px; }

.tx-split-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.tx-split-totals { display: flex; gap: 20px; flex-wrap: wrap; }
.tx-split-totals div { display: flex; align-items: baseline; gap: 8px; font-size: 0.88rem; }
.tx-split-totals output { font-weight: 700; font-variant-numeric: tabular-nums; }
/* "Still to allocate" is the number the treasurer is driving to zero, so
   it's the one that changes colour: amber while there's money left,
   green when it lands, red if they've over-allocated. */
.tx-split-remainder output { color: var(--warn-text); }
.tx-split-remainder output.is-balanced { color: var(--success-text); }
.tx-split-remainder output.is-over { color: var(--error-text); }

.tx-split-btn { color: var(--brand); font-weight: 700; }
.tx-split-btn:hover { background: var(--bg); }

@media (max-width: 700px) {
    .tx-split-panel { padding: 12px; }
    .tx-split-foot { flex-direction: column; align-items: stretch; }
}

/* A split deposit on the reconciliation grid: one line matching the bank
   statement, expandable to the allocations underneath. The allocations
   are visibly subordinate — indented, lighter, no checkbox of their own —
   so it's clear the deposit ticks as a unit. */
.reconcile-table tr.reconcile-group-row > td { font-weight: 600; }
.reconcile-expand-btn {
    border: none;
    background: none;
    cursor: pointer;
    font-size: 0.8rem;
    color: var(--muted);
    padding: 2px 4px;
    line-height: 1;
}
.reconcile-expand-btn:hover { color: var(--brand); }
.reconcile-table tr.reconcile-child-row > td {
    background: var(--bg);
    color: var(--muted);
    font-size: 0.8rem;
    font-weight: 400;
}
.reconcile-table tr.reconcile-child-row > td:nth-child(2) { padding-left: 24px; }
.reconcile-mismatch {
    display: inline-block;
    width: 16px;
    height: 16px;
    line-height: 16px;
    text-align: center;
    border-radius: 50%;
    background: var(--error-bg);
    color: var(--error-text);
    font-weight: 800;
    font-size: 0.72rem;
    margin-left: 6px;
    cursor: help;
}

/* A disabled button has to LOOK disabled. The split panel's Save is
   disabled until the allocations add up to the banked amount — without
   this it reads as clickable and the treasurer just wonders why nothing
   happens. */
.btn:disabled,
.btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
    box-shadow: none;
}
/* The hover rules above already exclude disabled buttons with
   :not(:disabled):not([disabled]), so nothing needs neutralising here.
   This used to force `background: var(--brand)`, which filled a disabled
   .btn-secondary navy the moment the cursor crossed it — the one button
   state that should never look more clickable. */

/* =====================================================================
   Brand colour application (2026-08-20)

   The palette at the top of this file defines the colours; this is where
   the rest of the app is brought onto them. Kept as one block rather than
   scattered edits so the brand rules are readable in one place.
===================================================================== */

/* Links carry the teal, but the accessible one: pure #00A4BD on white is
   2.98:1, which is not a link colour, it's a decoration. */
a { color: var(--teal-ink); }
a:hover { color: var(--brand); }

/* The header's active page gets a teal underline rather than the generic
   hover underline — the one place a visitor looks to know where they are.

   HOVER, rebuilt 2026-08-28. Henk: "Currently the mouse over colour is the
   same as the menu." It was: white stayed white and a 60%-alpha teal rule
   appeared under the word, which on a navy bar is very nearly nothing. A
   nav item is a target, so hovering now does what a target does — the
   label lights up in bright teal, the underline goes to full strength, and
   a faint teal wash marks the hit area so the whole item responds rather
   than just its text. The active page keeps the solid teal underline and
   stays white, so "where I am" and "what I am about to click" remain two
   visibly different things. */
.site-header nav a {
    border-bottom: 2px solid transparent;
    padding: 2px 6px;
    border-radius: 4px 4px 0 0;
    transition: color 0.12s ease, background-color 0.12s ease, border-color 0.12s ease;
}
.site-header nav a:hover,
.site-header nav a:focus-visible {
    text-decoration: none;
    opacity: 1;
    color: var(--teal-bright);
    border-bottom-color: var(--teal);
    background: rgba(0, 164, 189, 0.14);
}
.site-header nav a.active { border-bottom-color: var(--teal); opacity: 1; }
/* Hovering the page you are already on should still respond, but must not
   repaint the "you are here" mark into something else. */
.site-header nav a.active:hover { color: #fff; }

/* Focus rings in teal so they're visible against navy chrome as well as
   white cards — a navy ring on a navy header is an invisible focus ring. */
input:focus, select:focus, textarea:focus { border-color: var(--teal-deep); box-shadow: 0 0 0 3px rgba(0, 164, 189, 0.18); }
a:focus-visible, button:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
    outline: 2px solid var(--teal);
    outline-offset: 2px;
    border-radius: 3px;
}

/* Cards lift slightly on a navy-tinted shadow rather than a neutral grey
   one, so the whole page sits in the brand's colour temperature. */
.card { box-shadow: 0 1px 2px rgba(0, 34, 82, 0.05); }

/* A teal-filled button, for the one action on a screen that IS the
   screen's purpose. --teal-deep, not the raw brand teal: white on
   #00A4BD is 2.98:1, white on #007487 is 5.46:1. */
.btn-teal { background: var(--teal-deep); color: #fff; }
.btn-teal:hover:not(:disabled):not([disabled]) { background: #005F6E; color: #fff; }

.site-footer { border-top: 3px solid var(--teal); }


/* =====================================================================
   Reports (accounting-reports.php) + the SVG charts on it (2026-08-20)

   Layout is the site's 62/38 asymmetry with the NARROW side first: the
   controls are a compact rail you touch briefly, the report is what you
   actually read. Print drops the rail entirely — nobody files a copy of
   the date pickers.
===================================================================== */
.report-layout {
    display: grid;
    grid-template-columns: var(--split-minor) var(--split-major);
    gap: 24px;
    align-items: start;
}
.report-controls {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 4px solid var(--teal);
    border-radius: var(--radius);
    padding: 20px;
    position: sticky;
    top: 16px;   /* the controls stay reachable while a long report scrolls */
}
.report-controls label:first-of-type { margin-top: 0; }

.report-presets { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }
.report-presets-label {
    text-transform: uppercase;
    letter-spacing: 0.9px;
    font-size: 0.68rem;
    font-weight: 700;
    color: var(--muted);
    margin-bottom: 10px;
}
.report-preset {
    display: block;
    padding: 7px 10px;
    border-radius: 6px;
    font-size: 0.86rem;
    text-decoration: none;
    color: var(--text);
}
.report-preset:hover { background: var(--bg); }
.report-preset.active { background: var(--brand); color: var(--soft-white); font-weight: 600; }

.report-actions { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); display: grid; gap: 10px; }

/* min-width:0 — a grid item defaults to min-width:auto, so the chart's
   own min-width propagates out and makes the whole SHEET wide, which is
   what pushes the page sideways on a phone. This is the fix that lets the
   inner scroll containers actually do their job. */
.report-sheet { padding: 28px 30px; min-width: 0; }
.report-layout > * { min-width: 0; }
.report-sheet-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 24px;
    flex-wrap: wrap;
    padding-bottom: 18px;
    margin-bottom: 20px;
    border-bottom: 2px solid var(--brand);
}
.report-sheet-company { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); font-weight: 700; }
.report-sheet-head h2 { margin: 6px 0 4px; font-size: 1.5rem; }
.report-sheet-period { color: var(--muted); font-size: 0.9rem; }
/* The hero figure: one per view, proportional figures (tabular-nums makes
   a large standalone number look loose), same sans as everything else. */
.report-sheet-net { text-align: right; }
.report-sheet-net span { display: block; font-size: 0.8rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.9px; font-weight: 700; }
.report-sheet-net strong { font-size: 2.4rem; font-weight: 800; color: var(--success-text); line-height: 1.1; letter-spacing: -1px; }
.report-sheet-net.is-negative strong { color: var(--error-text); }

.report-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; margin-bottom: 8px; }
.report-table th, .report-table td { padding: 8px 10px; text-align: left; }
.report-table thead th { border-bottom: 1px solid var(--border); color: var(--muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.6px; }
.report-table tbody td { border-bottom: 1px solid var(--border); }
/* tabular-nums HERE, in columns that must align vertically — the opposite
   of the hero figure above. */
.report-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.report-table .num.is-negative, .report-table td.is-negative { color: var(--error-text); }
.report-table .report-section-row th { padding-top: 20px; color: var(--brand); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 1px; border-bottom: 1px solid var(--border); }
.report-table .report-subtotal-row th { border-top: 1px solid var(--border); border-bottom: none; }
.report-table .report-total-row th { border-top: 2px solid var(--brand); font-size: 1.05rem; padding-top: 12px; }
.report-section-heading { margin: 32px 0 10px; font-size: 1.1rem; color: var(--brand); }
.report-basis-note { color: var(--muted); font-size: 0.82rem; margin: 14px 0 0; line-height: 1.5; }

/* --- Charts ---------------------------------------------------------
   Recessive chrome, loud data. Text wears ink colours, never the series
   colour — identity comes from the coloured mark beside it. */
.chart-figure { margin: 0 0 26px; }
.chart-figure figcaption {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.9px;
    font-weight: 700;
    color: var(--muted);
    margin-bottom: 10px;
}
.chart { width: 100%; height: auto; display: block; overflow: visible; }
.chart-tick { font-size: 11px; fill: #5A6B7C; font-variant-numeric: tabular-nums; }
.chart-label { font-size: 12px; fill: #1E2C3F; }
.chart-value { font-size: 12px; fill: #5A6B7C; font-variant-numeric: tabular-nums; }
/* The hit target is the invisible full-band rect inside each group, so a
   small value is as easy to hover as a large one. */
.chart-mark { cursor: default; }
.chart-mark:hover path, .chart-mark:focus-visible path { opacity: 0.82; }
.chart-mark:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
/* Drillable columns on the accounting dashboard's Income vs Expense chart
   (2026-09-08): a click opens that month's category breakdown panel. The
   selected bar keeps a teal underline-style outline so it's clear which
   month the panel belongs to. */
.chart-mark-drill { cursor: pointer; }
.chart-mark-drill.is-selected path { opacity: 1; stroke: var(--brand); stroke-width: 2; }
/* The group's own focus ring would box the full-height invisible hit area;
   ring the bar itself instead. */
.chart-mark-drill:focus-visible { outline: none; }
.chart-mark-drill:focus-visible path { stroke: var(--teal); stroke-width: 2; }
.acct-drill-panel { margin-top: 16px; border-left: 4px solid var(--teal); }
.acct-drill-head { display: flex; align-items: flex-start; gap: 12px; }
.acct-drill-head .section-head { flex: 1; }
.acct-drill-head .acct-drill-close { flex: 0 0 auto; }
.chart-legend { display: flex; gap: 18px; flex-wrap: wrap; font-size: 0.85rem; color: var(--muted); margin-bottom: 12px; }
.chart-legend span { display: inline-flex; align-items: center; gap: 7px; }
.chart-legend i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.chart-note { font-size: 0.8rem; color: var(--muted); margin: 6px 0 0; }

@media (max-width: 1000px) {
    .report-layout { grid-template-columns: 1fr; }
    .report-controls { position: static; }
}

@media print {
    /* The report is the document; everything that helped you build it goes. */
    .site-header, .site-footer, .accounting-nav, .whatsapp-float,
    .report-controls, .demo-banner, .alert { display: none !important; }
    body { background: #fff; }
    .container, .container.wide { max-width: none; width: auto; padding: 0; }
    .report-layout { display: block; }
    .report-sheet { border: none; box-shadow: none; padding: 0; }
    .report-table { font-size: 0.8rem; }
    .report-table tbody tr, .chart-figure { page-break-inside: avoid; }
}

/* A wide report table or chart scrolls inside its own container rather
   than pushing the page sideways — on a phone the page must never move
   horizontally, but the report itself is allowed to. The chart keeps a
   min-width so its labels stay legible when it scrolls, instead of being
   squeezed to unreadable 6px text. */
.report-table-scroll { overflow-x: auto; }
.chart-figure { overflow-x: auto; }
.chart-figure .chart { min-width: 520px; }

@media print {
    /* Nothing scrolls on paper. */
    .report-table-scroll, .chart-figure { overflow: visible; }
    .chart-figure .chart { min-width: 0; }
}

/* The Reports page is the one accounting screen whose controls live in a
   LEFT rail, so the bottom-left float position set above lands right on
   top of its Print and Download buttons. Here it goes back to the right,
   where only body text sits. */
body:has(.report-controls) .whatsapp-float { left: auto; right: 20px; }
@media (max-width: 600px) {
    body:has(.report-controls) .whatsapp-float { left: auto; right: 16px; }
}

/* An Expenses report's hero figure is a total spent, not a surplus — it
   wears the expense pole's colour rather than the success green, so the
   number never reads as a good-news figure by accident. */
.report-sheet-net.is-expense strong { color: #C06A05; }

/* Dashboard charts (dashboard.php) — the growth chart takes the major
   column because change-over-time is the story stat tiles can't tell;
   departments sit in the minor column as meters rather than a second SVG,
   because a wide ranked-bar chart squeezed into a 38% column renders its
   labels at about 6px. */
.dash-charts {
    display: grid;
    grid-template-columns: var(--split-major) var(--split-minor);
    gap: 20px;
    align-items: start;
    margin-bottom: 24px;
}
.dash-charts > * { min-width: 0; margin: 0; }

.dash-meter-list { list-style: none; margin: 0; padding: 0; }
.dash-meter-list li { margin-bottom: 14px; }
.dash-meter-list li:last-child { margin-bottom: 0; }
.dash-meter-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 0.88rem; margin-bottom: 5px; }
.dash-meter-head strong { font-variant-numeric: tabular-nums; color: var(--brand); }
.dash-meter-track {
    height: 8px;
    border-radius: 999px;
    /* A lighter step of the fill's own hue, not neutral grey — the state
       then reads across the whole bar rather than only where it's filled. */
    background: rgba(0, 150, 174, 0.16);
    overflow: hidden;
}
.dash-meter-fill { display: block; height: 100%; border-radius: 999px; background: #0096AE; }

@media (max-width: 900px) {
    .dash-charts, .dash-charts.groups-charts, .dash-charts.install-console-grid { grid-template-columns: 1fr; }
}

/* --- Migration list (db-check.php) -----------------------------------
   A numbered to-do list of SQL files to run, not a data table: the
   filename is the thing being read, so it leads each row and the
   explanation sits under it in muted text.

   The monospace "missing:" line is deliberately quiet. It is evidence for
   why the file is on the list — useful when something goes wrong, noise
   the rest of the time — so it must not compete with the filename. */
.migration-list { margin: 16px 0 0; padding-left: 22px; }
.migration-list li { margin-bottom: 18px; line-height: 1.5; }
.migration-list li:last-child { margin-bottom: 0; }
.migration-list code { font-size: 0.88rem; word-break: break-all; }
.migration-list .hint { margin: 4px 0 0; }
.db-check-missing { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.8rem; }

/* <details> used as a card: the summary is the whole clickable target,
   so it needs to look like one. */
details.card > summary { cursor: pointer; list-style-position: outside; }
details.card > summary::marker { color: var(--muted); }

/* --- Membership register on a phone (members.php) --------------------
   Below 760px the register stops being a table and becomes a stack of
   cards, one per member.

   WHY, rather than letting it scroll sideways as .report-table-scroll
   allows. A financial report scrolls acceptably: you go to it to read one
   figure, and the row labels stay put on the left. The register is
   different — every row ends in an Open button, and at 390px that button
   sat entirely off-screen with the Status column cut in half before it.
   The action you came to perform was invisible, inside a scroll container
   nothing signals is scrollable. A member is four short facts; four short
   facts fit on a phone perfectly well stacked.

   Done in CSS off the existing <table> rather than by rendering different
   markup, so there is one register in the source and no chance of the two
   drifting apart. The header row is dropped because each card's own
   content already says what it is: a name is a name, a badge is a status.
--------------------------------------------------------------------- */
@media (max-width: 760px) {
    /* The scroll container has nothing left to scroll once the table is
       a stack, and leaving it would clip the card shadows. */
    .members-row .report-table-scroll { overflow-x: visible; }

    .members-table,
    .members-table tbody,
    .members-table td { display: block; width: auto; }

    .members-table thead { display: none; }

    /* The card is a small grid rather than a plain stack, so the status
       badge shares the name's line instead of spending a whole row on one
       short word. Twenty-four members is already a long scroll on a
       phone, and a line saved per card is twenty-four lines saved down
       the page. */
    /* One column, four rows. An earlier version put the status badges in
       a second "auto" column beside the name; a member with four badges
       (approved + no consent + cannot sign in + details needed) stacked
       them down the right, each badge wrapping onto three lines, and the
       auto column grew past the card so the badges and the Open button
       spilled off the right edge (2026-09-12 phone screenshot). Badges now
       sit under the name as a wrapping row of compact chips, and every
       grid child has min-width:0 so nothing can stretch the card. */
    .members-table tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "name"
            "status"
            "contact"
            "open";
        gap: 0;
        align-items: start;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        padding: 12px 14px;
        margin-bottom: 9px;
        background: var(--card-bg);
        max-width: 100%;
        overflow: hidden;
    }
    .members-table tr:last-child { margin-bottom: 0; }

    .members-table td { min-width: 0; max-width: 100%; }
    .members-table td:nth-child(1) { grid-area: name; }
    .members-table td:nth-child(2) { grid-area: contact; }
    .members-table td:nth-child(3) { grid-area: status; text-align: left; }
    .members-table td:nth-child(4) { grid-area: open; }

    /* The editing highlight was an inset shadow on the first cell, which
       in a stack is just the top line. On a card the whole left edge is
       the right place for it. */
    .members-table .is-editing { box-shadow: inset 3px 0 0 var(--teal); }
    .members-table .is-editing td:first-child { box-shadow: none; }

    .members-table td { border: 0; padding: 0; }

    /* The name leads the card, so it gets the size the column header used
       to give it. */
    .members-table td:first-child strong { font-size: 1.02rem; }
    .members-name-cell > div { min-width: 0; }
    .members-name-cell strong { display: block; overflow-wrap: anywhere; }
    .members-table .members-dob,
    .members-table .members-age { display: inline; margin: 0 6px 0 0; }

    /* Status chips: one wrapping row, each chip on a single line. */
    .members-table td:nth-child(3) {
        display: flex; flex-wrap: wrap; gap: 4px 5px; margin-top: 7px;
    }
    .members-table td:nth-child(3) .badge {
        white-space: nowrap; font-size: 0.66rem; padding: 2px 8px;
        letter-spacing: 0.2px;
    }
    .members-table td:nth-child(3) br { display: none; }
    .members-table td:nth-child(3) .members-invited-on { flex: 1 0 100%; order: 10; font-size: 0.76rem; margin-top: 2px; }

    /* Contact: phone and e-mail on one line each, long addresses break
       rather than widen the card. An empty contact ("—") is hidden so the
       card does not spend a line on a dash. */
    .members-table td.members-contact { margin-top: 7px; overflow-wrap: anywhere; font-size: 0.86rem; }
    .members-table td.members-contact .members-contact-none { display: none; }

    /* Open goes full width: it is the only action on the card, and a
       full-width target is the one that never gets mis-tapped. .num
       right-aligns it for the table layout, which is wrong here. Invite
       (when shown) sits above it, also full width. */
    .members-table td.num { text-align: left; margin-top: 10px; white-space: normal; }
    .members-table td.num .btn { display: block; width: 100%; text-align: center; box-sizing: border-box; }
    .members-table td.num .members-row-invite { display: block; margin: 0 0 6px; }

    /* The search box was collapsing to about 70px — wide enough to show
       "Nam" — because it shared a flex line with a 150px-minimum select
       and the button, and it was the only one of the three allowed to
       shrink. Giving it the whole first line pushes the other two onto
       their own row, where they fit. */
    .members-filter-search { flex: 1 0 100%; }
    .members-filter select { flex: 1; }
}

/* The aside (Add a member / Import) is short and the register beside it
   is long, so past the aside's own height the right-hand column was
   simply empty for another thousand-odd pixels. Sticking it keeps the two
   actions it holds reachable from anywhere in the list, instead of only
   from the top of the page.

   Only above 900px, where the two really are side by side — below that
   .members-row is a single column and a sticky aside would pin itself
   over the list. */
@media (min-width: 901px) {
    .members-row > .split-row-aside {
        position: sticky;
        top: 20px;
    }
}

/* --- Celebrations + What's coming up (member-company-life.php) ---------
   The two time-bound blocks at the top of Company Life. Everything below
   them is in tabs; these two are not, because a birthday or a dated
   activity stops being useful once its date passes and a member should
   not have to go looking for it.
--------------------------------------------------------------------- */
/* Stacked, full width. The member portal runs in a 560px column
   (main.container.narrow), so there is no room here for the two-up split
   the admin side uses — at that width every date wrapped onto a second
   line. */
/* .companylife-top lived here from 2026-08-22 to 2026-08-29: the
   Celebrations + Activities block that sat above the tab bar and so
   rendered under every tab. Activities is a tab again and Celebrations
   was already on the member profile, so the section — and these rules —
   have no markup left to style. */

.celebration-list { list-style: none; margin: 14px 0 0; padding: 0; }
.celebration-row {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}
.celebration-row:last-child { border-bottom: 0; padding-bottom: 0; }

/* The day of the month as the anchor, so the column reads as a calendar
   running down the page rather than as a list of names you have to parse
   a date out of. Fixed width so the names line up whatever the date. */
.celebration-day {
    flex: 0 0 2.2em;
    text-align: center;
    font-weight: 800;
    font-size: 1.15rem;
    color: var(--brand);
    font-variant-numeric: tabular-nums;
}
/* Anniversaries get the accent, birthdays the brand colour — enough to
   tell the two apart while scanning without needing to read the label. */
.celebration-row-anniversary .celebration-day { color: var(--accent, #E8A33D); }

.celebration-body { display: block; min-width: 0; }
.celebration-meta { display: block; color: var(--muted); font-size: 0.84rem; margin-top: 1px; }

/* The Activities heading, which used to be a tab label and is now a
   section heading between the Celebrations card and the activity cards. */


/* --- Latest news teaser (member-profile.php) --------------------------
   One article under Celebrations, with a link through to Company Life for
   the rest. Sized down from the news cards on Company Life itself: this is
   a pointer to the news, not the news page. */
.profile-news-title { font-size: 1.05rem; margin: 10px 0 2px; }
.profile-news-body { font-size: 0.9rem; white-space: pre-line; margin-top: 10px; }
.profile-news-more { margin-bottom: 0; }

/* --- Key/value tables (accounting-company.php) ------------------------
   A two-column "label: value" table. table-layout:fixed makes the columns
   share the space available instead of being sized by their content, and
   anywhere-wrapping lets a long address or email break rather than push
   the column — and with it the page — wider than the screen.

   Deliberately NOT .table-responsive: that carries a 560px min-width for
   wide data grids, which on a 462px desktop column clipped the values
   ("Non-c…", "1 Company Street, S…") behind a scrollbar nobody could see.
   These tables have no minimum useful width; they should just wrap. */
.kv-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.kv-table th, .kv-table td { overflow-wrap: anywhere; }

/* A scroller with no minimum: scrolls only when the content genuinely
   doesn't fit, rather than forcing a scrollbar at every width the way a
   min-width floor does. */
.table-scroll-soft { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* --- Prayer requests --------------------------------------------------
   member-prayer.php (the form) and prayer-requests.php (the pastoral
   list). */

/* The anonymous toggle. Its explanation is long — it has to say what
   anonymity does and does not buy you — so the two sit as a block under
   the textarea rather than inline with it. */
.prayer-anon { display: flex; align-items: flex-start; gap: 8px; margin-top: 18px; font-weight: 600; }
.prayer-anon input { margin: 2px 0 0; width: auto; }
.prayer-anon-hint { margin: 6px 0 18px; }

/* An anonymous request on the pastoral list gets a quiet left edge, so it
   is obvious at a glance which entries have a name attached and which
   don't — before an admin starts reading and forms a guess. */
.prayer-anon-item { border-left: 3px solid var(--border); padding-left: 14px; }
.prayer-anon-badge { margin-left: 8px; vertical-align: middle; font-size: 0.7rem; }
.prayer-revealed-note { margin: 10px 0 0; }

/* --- Event planning checklist ----------------------------------------
   event-plan.php (the committee ticks) and member-profile.php (members
   read). One stylesheet for both, because it is one renderer.

   Everything here is a size down from the app's usual scale. The plan is
   fifteen steps and about two hundred items, and Henk's brief was
   explicit: it has to be usable on a 5-inch phone. At the normal body
   size a single step filled the screen twice over.
--------------------------------------------------------------------- */
.event-plan { font-size: 0.86rem; line-height: 1.45; }
.event-plan-card { padding-bottom: 8px; }

.event-plan-head { margin-bottom: 14px; }
.event-plan-title { font-size: 1.15rem; margin: 0 0 4px; letter-spacing: -0.2px; }
.event-plan-meta { color: var(--muted); font-size: 0.82rem; margin: 0 0 6px; }
.event-plan-summary { margin: 0 0 10px; }

/* One bar, because "how ready are we" is the only number most people
   want from a 200-item checklist. */
.event-plan-progress {
    height: 8px;
    border-radius: 999px;
    background: var(--border);
    overflow: hidden;
    margin-top: 10px;
}
.event-plan-progress-bar { height: 100%; background: var(--accent, #E8A33D); border-radius: 999px; }
.event-plan-progress-text { color: var(--muted); font-size: 0.78rem; margin: 6px 0 0; }

/* Each step is a <details>, closed by default: fifteen headings you can
   thumb through, instead of a page you scroll for a minute. */
.event-step { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 8px; background: var(--card-bg); }
.event-step[open] { border-color: var(--brand); }
.event-step.is-done { border-left: 3px solid var(--teal, #00A4BD); }

.event-step-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    cursor: pointer;
    list-style: none;             /* the default triangle sits badly next to the number */
}
.event-step-summary::-webkit-details-marker { display: none; }
.event-step-summary::marker { content: ''; }

.event-step-no {
    flex: 0 0 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--brand);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}
.event-step.is-done .event-step-no { background: var(--teal, #00A4BD); }

.event-step-titles { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.event-step-title { font-weight: 700; color: var(--brand-dark); }
.event-step-count { color: var(--muted); font-size: 0.74rem; font-variant-numeric: tabular-nums; }
.event-step-badge { flex: 0 0 auto; font-size: 0.65rem; }

.event-step-body { padding: 0 12px 12px; border-top: 1px solid var(--border); }
.event-step-tools { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; margin: 10px 0; }
.event-step-tick { margin: 0; }
.event-step-intro { color: var(--muted); margin: 10px 0; font-style: italic; }

.event-item-list { list-style: none; margin: 8px 0 0; padding: 0; }
.event-item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
}
.event-item:last-child { border-bottom: 0; }
.event-item.is-done .event-item-label,
.event-item.is-done .event-tick span { color: var(--muted); text-decoration: line-through; }

/* A sub-heading inside a step ("Information required from every company"). */
.event-item-group {
    font-weight: 700;
    color: var(--brand-dark);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    margin: 14px 0 4px;
}
/* A line to read, not to do: the programme times, the prayer principles.
   Indented and quiet so it never reads as an untickable task. */
.event-item-info {
    color: var(--muted);
    padding: 3px 0 3px 12px;
    border-left: 2px solid var(--border);
    margin: 2px 0;
}

/* The tick itself. A generous target — this gets used one-handed, at a
   venue, probably in the sun. */
.event-tick { display: flex; align-items: flex-start; gap: 8px; margin: 0; font-weight: 400; cursor: pointer; }
.event-tick input { margin: 2px 0 0; width: auto; flex: 0 0 auto; min-width: 16px; min-height: 16px; }
.event-item-form { margin: 0; flex: 1; min-width: 0; }
.event-item-edit { flex: 0 0 auto; font-size: 0.74rem; }

/* The member's read-only view: a drawn tick rather than a disabled
   checkbox, which people try to click. */
.event-item-mark {
    flex: 0 0 16px;
    color: var(--teal, #00A4BD);
    font-weight: 700;
    line-height: 1.4;
}
.event-item-label { flex: 1; min-width: 0; }

@media (max-width: 420px) {
    /* 5-inch territory. Another notch down, and the step number and
       counts tighten up so a long Afrikaans heading still gets the width. */
    .event-plan { font-size: 0.82rem; }
    .event-plan-title { font-size: 1.05rem; }
    .event-step-summary { padding: 9px 10px; gap: 8px; }
    .event-step-body { padding: 0 10px 10px; }
    .event-step-no { flex-basis: 20px; height: 20px; font-size: 0.68rem; }
}

/* The event switcher and the publish banner (event-plan.php). */
.event-plan-switch { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.event-plan-switch .hint { margin: 0 4px 0 0; }
.event-plan-publish { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; justify-content: space-between; }
.event-plan-publish form { margin: 0; }
.event-plan-live { margin: 0 0 14px; }

/* ---------------------------------------------------------------------
   The organising committee (event-plan.php, member-profile.php).

   Same 0.86rem as the checklist it sits with, and stacked rather than
   tabled: ten roles each with a responsibility sentence, a name and a
   phone number is four columns no 5-inch screen can hold. At 620px and
   up it splits into the house 62/38 — the role and what it covers on the
   left, who is doing it on the right — which is the shape of the table
   Henk supplied, without a table's minimum width.
   --------------------------------------------------------------------- */
.event-committee { font-size: 0.86rem; margin-top: 18px; }
.event-committee-heading { font-size: 1rem; margin: 0 0 10px; }
.event-committee-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }

.event-committee-row {
    display: grid;
    gap: 2px 16px;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--teal, #00A4BD);
    border-radius: 4px;
    background: var(--surface, #fff);
}

/* An unfilled role is the point of the list, not an error — a quiet
   dashed edge says "this one still needs somebody" without shouting. */
.event-committee-row.is-unfilled { border-left-style: dashed; }

.event-committee-role { font-weight: 600; }
.event-committee-resp { color: var(--muted, #5b6770); line-height: 1.45; }
.event-committee-who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.event-committee-contact { color: var(--muted, #5b6770); font-size: 0.8rem; word-break: break-word; }
.event-committee-vacant { color: var(--muted, #5b6770); font-style: italic; }
.event-committee-note {
    grid-column: 1 / -1;
    margin-top: 4px;
    padding-top: 4px;
    border-top: 1px dashed var(--border);
    color: var(--muted, #5b6770);
    font-size: 0.78rem;
}
.event-committee-add { margin-top: 16px; }

@media (min-width: 620px) {
    .event-committee-row {
        grid-template-columns: var(--split-major, 62fr) var(--split-minor, 38fr);
    }
    .event-committee-role { grid-column: 1; }
    .event-committee-resp { grid-column: 1; }
    /* Spans both rows on the right so it stays level with the role name
       however long the responsibility sentence runs. */
    .event-committee-who { grid-column: 2; grid-row: 1 / span 2; align-content: start; }
}

@media (max-width: 420px) {
    .event-committee { font-size: 0.82rem; }
    .event-committee-row { padding: 8px 10px; }
}

/* ---------------------------------------------------------------------
   People in a role (2026-08-24). A role holds a list now, so the right
   column is a stack rather than one name.
   --------------------------------------------------------------------- */
.event-people { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
.event-person { line-height: 1.45; }

/* Where somebody is from, when they are not from here. Deliberately
   quiet — it is context, not a warning. */
.event-person-tag {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 10px;
    background: var(--surface-alt, #eef2f5);
    color: var(--muted, #5b6770);
    font-size: 0.72rem;
    white-space: nowrap;
}
.event-person.is-external .event-person-tag { background: #e6f4f7; color: #0a6a7c; }

.event-person-state { font-size: 0.72rem; white-space: nowrap; }
.event-person-state.is-pending { color: #8a6100; }
.event-person-state.is-declined { color: var(--muted, #5b6770); text-decoration: line-through; }
.event-person-state.is-accepted { color: #1c7c47; }

/* The admin's editable list: name on the left, buttons on the right,
   stacking on a phone rather than squeezing three columns into 320px. */
.event-people-admin { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 8px; }
.event-person-admin {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
    align-items: baseline;
    justify-content: space-between;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 4px;
}
.event-person-admin-who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; min-width: 0; }
.event-person-admin-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.event-person-admin-actions form { margin: 0; }

.event-people-sub { font-size: 0.95rem; margin: 20px 0 6px; }
.event-people-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; margin: 0; }
.event-people-form select,
.event-people-form input[type="text"] { flex: 1 1 200px; min-width: 0; margin: 0; }
.event-people-form .btn { flex: 0 0 auto; }
.event-people-invite { margin-top: 16px; }

.event-lookup-hit {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    justify-content: space-between;
    margin: 6px 0 0;
}

/* The invitation card on a member's home screen, and the "whose event is
   this?" line on an event they accepted a role at another company. */
.event-invite-card { border-left: 3px solid var(--teal, #00A4BD); }
.event-invite-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 10px; }
.event-invite-actions form { margin: 0; }
.event-host-tag {
    margin: 0 0 8px;
    font-size: 0.78rem;
    color: var(--muted, #5b6770);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.event-guest-window { margin-bottom: 14px; }

/* The "add the standard items back" prompt on welfare.php?tab=items.
   Added 2026-08-24, when the automatic re-seeding that used to do this by
   itself was removed for undoing people's deletions. */
.welfare-restore {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 16px;
    align-items: center;
    justify-content: space-between;
}
.welfare-restore form { margin: 0; }
.welfare-restore p { margin-top: 4px; }

/* =====================================================================
   Customer statements (accounting-statements.php). Added 2026-08-24.
   ===================================================================== */

/* The 1-2-3-4 progress header, echoing the wizard in the brief. */
.statement-stepper {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 26px;
    list-style: none;
    margin: 0 0 26px;
    padding: 0;
    counter-reset: none;
}
.statement-step { display: flex; align-items: center; gap: 10px; color: var(--muted, #5b6770); }
.statement-step-no {
    flex: 0 0 30px; width: 30px; height: 30px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 0.95rem;
    background: var(--surface-alt, #e6eaf0); color: var(--muted, #5b6770);
}
.statement-step-label { font-weight: 600; font-size: 0.98rem; }
.statement-step.is-current .statement-step-no { background: var(--brand-dark, #1f3550); color: #fff; }
.statement-step.is-current .statement-step-label { color: var(--text, #161b24); }
.statement-step.is-done .statement-step-no { background: var(--teal, #0c7c8e); color: #fff; }

/* Step 1 form. The screenshot's right-aligned label column on wide
   screens, stacking on a phone. */
.statement-form h2 { font-size: 1.15rem; margin: 26px 0 12px; }
.statement-form h2.mt-0 { margin-top: 0; }
.statement-field { display: grid; grid-template-columns: 190px minmax(0, 360px); gap: 10px 16px; align-items: center; margin: 10px 0; }
.statement-field > label { text-align: right; color: var(--muted, #5b6770); font-weight: 600; }
.statement-field input, .statement-field select { margin: 0; }
.statement-daterange { display: flex; gap: 10px; flex-wrap: wrap; }
.statement-daterange select { flex: 1 1 150px; }
.statement-custom-dates { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.statement-range-preview { margin: 6px 0 0; }
.statement-category-note { grid-column: 1 / -1; margin: 2px 0 8px; }

.statement-check { display: flex; gap: 12px; align-items: flex-start; margin: 12px 0; font-weight: 400; cursor: pointer; }
.statement-check input[type="checkbox"] { margin-top: 3px; width: auto; flex: 0 0 auto; min-width: 16px; min-height: 16px; }
.statement-check .hint { font-weight: 400; }
.statement-less-input { width: 130px; margin: 6px 0 0; display: block; }

.statement-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; justify-content: flex-end; }

/* Step 2 customer list. */
.statement-list th, .statement-list td { vertical-align: middle; }
.statement-list-check { width: 34px; text-align: center; }
.statement-list-check input { width: auto; margin: 0; }
.chip-small { font-size: 0.7rem; padding: 1px 7px; }

/* Step 3 / 4 summary + finish. */
.statement-summary { list-style: none; margin: 14px 0; padding: 0; max-width: 380px; }
.statement-summary li { display: flex; justify-content: space-between; gap: 16px; padding: 9px 0; border-bottom: 1px solid var(--border, #e0e4ea); }
.statement-summary li span { color: var(--muted, #5b6770); }
.statement-summary li strong { font-variant-numeric: tabular-nums; }
.statement-summary-warn strong { color: #a25a04; }
.statement-finish-tick {
    width: 54px; height: 54px; border-radius: 50%;
    background: var(--ok-soft, #dcefe1); color: var(--ok, #157a3c);
    display: flex; align-items: center; justify-content: center; margin-bottom: 6px;
}
.statement-finish-tick svg { width: 28px; height: 28px; }

.customer-category-edit > summary { display: inline-block; list-style: none; }
.customer-category-edit > summary::-webkit-details-marker { display: none; }
.customer-category-form { display: flex; gap: 8px; margin-top: 8px; }
.customer-category-form input { margin: 0; }

/* ---- The statement document itself (print + on-screen preview) ---- */
.statement-doc { max-width: 720px; margin: 0 auto; color: #000; }
.statement-head { text-align: center; margin-bottom: 6px; }
.statement-head h2 { margin: 6px 0 2px; }
.statement-title { text-align: center; margin: 14px 0 18px; letter-spacing: 0.02em; }
.statement-meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.statement-meta-right { text-align: right; }
.statement-meta-label { display: block; color: var(--muted, #5b6770); font-size: 0.82rem; }
.statement-table { width: 100%; border-collapse: collapse; margin-top: 6px; font-size: 0.92rem; }
.statement-table th, .statement-table td { padding: 7px 8px; border-bottom: 1px solid #e0e4ea; text-align: left; }
.statement-table th.num, .statement-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.statement-table thead th { border-bottom: 2px solid #c3cad4; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted, #5b6770); }
.statement-bbf td { font-style: italic; color: var(--muted, #5b6770); }
.statement-detail td { font-size: 0.84rem; color: var(--muted, #5b6770); border-bottom: 1px dashed #e8ebf0; padding-top: 3px; padding-bottom: 3px; }
.statement-closing td { border-top: 2px solid #c3cad4; border-bottom: none; font-weight: 700; font-size: 1.05rem; padding-top: 12px; }

/* The chrome-free printable batch: one statement per page. */
.statement-print-body { background: #fff; margin: 0; padding: 24px; }
.statement-print-bar { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.statement-page { max-width: 760px; margin: 0 auto 30px; }
@media print {
    .no-print { display: none !important; }
    .statement-page { margin: 0; max-width: none; page-break-after: always; }
    .statement-page:last-child { page-break-after: auto; }
    .statement-print-body { padding: 0; }
}

@media (max-width: 640px) {
    .statement-field { grid-template-columns: 1fr; }
    .statement-field > label { text-align: left; }
    .statement-actions { justify-content: stretch; }
    .statement-actions .btn { flex: 1; }
}

/* =====================================================================
   Dashboard "start here" — getting-started checklist + needs-attention.
   Added 2026-08-24. Both lead the dashboard and both self-hide when
   there's nothing to show, so an established company sees neither.
   ===================================================================== */
.dash-panel-title { font-size: 1.15rem; margin: 0 0 12px; }

.dash-attention {
    margin: 0 0 22px;
    padding: 18px 20px;
    border: 1px solid var(--border);
    border-left: 4px solid var(--teal, #0c7c8e);
    border-radius: var(--radius);
    background: var(--card-bg);
}
.dash-attention-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.dash-attention-list li { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; }
.dash-attention-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--teal, #0c7c8e); }
.dash-attention-text { flex: 1; min-width: 0; }
.dash-attention-cta { flex: 0 0 auto; font-weight: 600; text-decoration: none; color: var(--teal-dark, #075463); white-space: nowrap; }
.dash-attention-cta:hover { text-decoration: underline; }

.dash-setup {
    margin: 0 0 26px;
    padding: 20px 22px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--card-bg);
    box-shadow: 0 1px 2px rgba(20, 30, 40, 0.04);
}
.dash-setup-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.dash-setup-progress { font-size: 0.85rem; color: var(--muted, #5b6770); font-weight: 600; font-variant-numeric: tabular-nums; }
.dash-setup-bar { height: 6px; border-radius: 3px; background: var(--surface-alt, #e6eaf0); overflow: hidden; margin: 4px 0 16px; }
.dash-setup-bar > span { display: block; height: 100%; background: var(--teal, #0c7c8e); border-radius: 3px; transition: width 0.3s ease; }
.dash-setup-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.dash-setup-step { display: flex; align-items: center; gap: 13px; padding: 11px 8px; border-radius: 8px; }
.dash-setup-step + .dash-setup-step { border-top: 1px solid var(--border); }
.dash-setup-tick {
    flex: 0 0 24px; width: 24px; height: 24px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    border: 2px solid var(--border-strong, #c3cad4); color: #fff;
}
.dash-setup-step.is-done .dash-setup-tick { background: var(--teal, #0c7c8e); border-color: var(--teal, #0c7c8e); }
.dash-setup-tick svg { width: 14px; height: 14px; }
.dash-setup-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.dash-setup-label { font-weight: 600; }
.dash-setup-step.is-done .dash-setup-label { color: var(--muted, #5b6770); }
.dash-setup-hint { font-size: 0.84rem; color: var(--muted, #5b6770); }
.dash-setup-cta { flex: 0 0 auto; white-space: nowrap; }
.dash-setup-donetag { flex: 0 0 auto; font-size: 0.78rem; font-weight: 600; color: var(--teal-dark, #075463); }

@media (max-width: 560px) {
    .dash-setup-step { flex-wrap: wrap; }
    .dash-setup-body { flex-basis: calc(100% - 37px); }
    .dash-setup-cta, .dash-setup-donetag { margin-left: 37px; }
    .dash-attention-cta { margin-left: 19px; }
}

/* Danger zone — the accounting reset card (accounting-company.php, 2026-08-24).
   Set apart so a destructive action never reads like a routine panel. */
.danger-zone {
    border: 1px solid var(--error-text, #b3261e);
    border-left: 4px solid var(--error-text, #b3261e);
    margin-top: 26px;
    background: var(--card-bg);
}
.danger-zone-title { font-size: 1.1rem; margin: 0 0 10px; color: var(--error-text, #b3261e); }
.danger-zone label { margin-top: 12px; }

/* ---- Accounting dashboard (2026-08-24 visual rebuild) ---- */
.acct-stat-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 14px; }
.acct-stat { background: var(--card, #fff); border: 1px solid var(--border, #e3e8ef); border-radius: 12px; padding: 15px 18px; }
.acct-stat-lead { background: linear-gradient(135deg, rgba(0,150,174,0.10), rgba(0,150,174,0.02)); border-color: rgba(0,150,174,0.35); }
.acct-stat-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted, #64748b); }
.acct-stat-value { font-size: 1.6rem; font-weight: 700; margin-top: 6px; line-height: 1.1; color: var(--text, #1a2b4a); }
.acct-stat-lead .acct-stat-value { font-size: 1.9rem; }
.acct-stat-value.is-income { color: #1a7f37; }
.acct-stat-value.is-expense { color: #b3261e; }
.acct-stat-value.is-negative { color: #b3261e; }
.acct-chart-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; margin-top: 16px; }
.acct-chart-pair > .card, .acct-chart-card { min-width: 0; max-width: 100%; }
.acct-chart-card .chart-figure { margin: 0; overflow-x: auto; }
@media (max-width: 860px) {
    .acct-stat-grid { grid-template-columns: 1fr 1fr; }
    .acct-chart-pair { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 480px) {
    .acct-stat-grid { grid-template-columns: 1fr; gap: 10px; }
    .acct-stat { padding: 12px 14px; }
    .acct-stat-value { font-size: 1.35rem; }
    .acct-stat-lead .acct-stat-value { font-size: 1.6rem; }
}

/* Wide / compact chart pairs (chart_pair() in includes/charts.php,
   2026-09-12). Each chart is in the page twice; the compact one is drawn
   for a ~360-unit viewBox so its type is full size on a phone, and it
   never scrolls. Above 600px the wide one shows, as before. */
.chart-figure-compact { display: none; }
@media (max-width: 600px) {
    .chart-figure-wide { display: none; }
    .chart-figure-compact { display: block; overflow: visible; }
    .chart-figure-compact .chart { min-width: 0; }
    .acct-chart-card { padding: 14px 12px; }
    .acct-chart-card .section-head { margin-bottom: 8px; }
    .acct-drill-head { flex-wrap: wrap; }
    .acct-drill-head .acct-drill-close { order: -1; margin-left: auto; }
    .acct-drill-head .section-head { flex: 1 0 100%; }
    .acct-recent-table th, .acct-recent-table td { padding: 6px 4px !important; font-size: 0.84rem; }
    .acct-recent-table td:first-child, .acct-recent-table th:first-child { white-space: nowrap; }
}

/* ---- Customer receipts, dense list (2026-08-26 rebuild) ----------------
   The Receipts page used one large card per gift. On a real company's data
   that is 100 cards at roughly 140px — around fourteen thousand pixels of
   scrolling for one Sunday's giving, with the bulk control stranded at the
   very top. These rules turn it into a table of ~44px rows and pin the
   controls, so a page's worth fits on one screen without scrolling.
   Everything here is layout for that page only; the table itself reuses
   the shared .report-table / .tx-pagination styles so paging and grids
   look identical across Accounting. */

.receipts-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    /* Sticky against the card's own top padding, with a matching negative
       margin so the bar's background covers the full card width as rows
       scroll under it rather than showing a strip of them at the edges. */
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--card-bg);
    margin: -24px -24px 0;
    padding: 16px 24px 12px;
    border-bottom: 1px solid var(--border);
}
.receipts-tabs { margin-bottom: 0; gap: 6px; }
.receipts-toolbar .tab-button { padding: 6px 12px; font-size: 0.85rem; }
.receipts-toolbar-action { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0; }
.receipts-toolbar-action .hint { margin: 0; white-space: nowrap; }

.receipts-inline-note { margin: 12px 0 0; }

/* Dense rows: the shared .report-table already sets 8px padding; this
   tightens the vertical rhythm further and stops any single cell wrapping
   into a second line, which is what actually drives row height. */
.receipts-table td, .receipts-table th { padding: 6px 10px; vertical-align: middle; }
.receipts-table tbody tr:hover { background: rgba(0, 0, 0, 0.015); }
.receipts-col-date { white-space: nowrap; }
.receipts-number { white-space: nowrap; font-variant-numeric: tabular-nums; }
.receipts-amount { font-weight: 600; color: #1a7f37; }
.receipts-col-action { text-align: right; white-space: nowrap; width: 1%; }
.receipts-col-action form { margin: 0; display: inline-block; }
.receipts-row-actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
/* Smaller than .btn-small: a 38px control in a 44px row defeats the point. */
.receipts-table .btn-small { min-height: 30px; padding: 4px 10px; font-size: 0.8rem; }
.receipts-badge { margin-left: 6px; font-size: 0.68rem; padding: 2px 8px; }
.receipts-range { margin: 12px 0 0; }

@media (max-width: 700px) {
    /* Stacking the toolbar is fine; un-sticking it is deliberate — a
       two-row sticky bar on a phone eats most of the viewport it was
       meant to save. */
    .receipts-toolbar { position: static; margin: -24px -24px 0; }
    .receipts-toolbar-action { width: 100%; }
    .receipts-table { min-width: 620px; }
}

/* ---- Member profile tabs (2026-08-26) ---------------------------------
   The member portal is phone-first, and five tabs is more than the Company
   Life page's four. These rules stop the row wrapping into an unreadable
   stack on a narrow screen: below 620px the tabs scroll sideways as one
   line instead, which keeps them one thumb-swipe apart and keeps the
   panel below starting at a predictable place. Everything else is
   inherited from the shared .tab-buttons / .tab-button component. */

.profile-tabs { margin-top: 18px; }

@media (max-width: 620px) {
    .profile-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        /* Room for the scrollbar on desktops that show one, and enough
           bottom margin that the panel doesn't crowd it. */
        padding-bottom: 6px;
        /* Bleed to the screen edges so the last tab isn't cut off flush
           against the container padding, which reads as "that's all". */
        margin-left: -16px;
        margin-right: -16px;
        padding-left: 16px;
        padding-right: 16px;
    }
    .profile-tabs .tab-button { flex: 0 0 auto; }
}

/* ---- Delete a member (2026-08-26) -------------------------------------
   Folded away behind a <details> in the member edit rail. "Mark inactive"
   and "Delete permanently" read almost identically at a glance and only
   one of them can be undone, so this one asks to be opened first, states
   what the cascade will take, and only then shows a button. Muted until
   opened — it should be findable, not inviting. */

.members-delete {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}
.members-delete > summary {
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--muted);
    list-style: none;
}
.members-delete > summary::-webkit-details-marker { display: none; }
.members-delete > summary::before { content: '▸ '; }
.members-delete[open] > summary::before { content: '▾ '; }
.members-delete > summary:hover { color: var(--error-text); }
.members-delete[open] > summary { color: var(--error-text); margin-bottom: 10px; }
.members-delete-also { margin-bottom: 4px; font-weight: 600; }
.members-delete-list {
    margin: 0 0 14px;
    padding-left: 20px;
    font-size: 0.85rem;
    color: var(--muted);
    line-height: 1.7;
}

/* The "use Mark inactive instead" steer at the top of the delete panel
   (2026-08-26). Henk's own conclusion — "I think de-activate... because we
   might loose information" — written into the screen so the judgement is
   made once here rather than re-made by every admin at every record.
   Informational blue rather than the panel's red: it is the calm advice
   before the warning, not another alarm. */
.members-delete-advice {
    background: rgba(0, 150, 174, 0.08);
    border-left: 3px solid rgba(0, 150, 174, 0.55);
    border-radius: 4px;
    padding: 10px 12px;
    margin: 0 0 12px;
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--text);
}

/* ---- Company welcome page (landing.php, 2026-08-26) ---------------------
   What somebody meets after scanning the QR code on a company notice
   board: almost always a phone, held by a person standing up, who has
   never seen this app. So it reads top to bottom as one warm column —
   who we are, when we meet, where we are, who to talk to — with the
   sign-in / register actions last rather than first. */

.welcome-page { max-width: 560px; margin: 0 auto; }

.welcome-hero { text-align: center; padding: 4px 0 8px; }
.welcome-logo {
    display: block;
    margin: 0 auto 14px;
    max-width: 110px;
    max-height: 110px;
    height: auto;
}
.welcome-eyebrow {
    margin: 0 0 4px;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--muted);
}
.welcome-heading { margin: 0 0 12px; font-size: 1.75rem; line-height: 1.25; }
.welcome-message {
    font-size: 1.02rem;
    line-height: 1.7;
    color: var(--text);
    text-align: left;
}

/* Facts sit side by side where there is room and stack on a phone. Two
   short blocks, so a grid rather than cards — a card each would make
   "Sundays 09:00" look like a section of its own. */
/* Since "Where to find us" was removed (2026-08-26) this holds one block,
   the service times. auto-fit rather than a fixed 1fr 1fr so a single
   block fills the width instead of sitting stranded in a half column —
   and so a second fact could be added back later without touching this. */
.welcome-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-top: 26px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
}
.welcome-fact h2 {
    margin: 0 0 6px;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--muted);
}
.welcome-fact p { margin: 0; line-height: 1.6; }

.welcome-leaders { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--border); }
.welcome-leaders h2, .welcome-contact h2 { margin: 0 0 4px; font-size: 1.05rem; }
.welcome-leader-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 14px;
}
.welcome-leader {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px;
}
.welcome-leader-name { margin: 0; font-weight: 700; line-height: 1.3; }
.welcome-leader-role {
    margin: 2px 0 8px;
    font-size: 0.82rem;
    color: var(--muted);
}
.welcome-leader-contact { margin: 2px 0 0; font-size: 0.88rem; word-break: break-word; }

.welcome-contact { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--border); }
.welcome-contact-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 12px 0 0;
}
/* Contact details can be long (a full email address); let them wrap
   inside the button rather than pushing the page sideways. */
.welcome-contact-row .btn { word-break: break-word; }

.welcome-actions { margin-top: 28px; }
.welcome-admin-link { text-align: center; margin-top: 22px; font-size: 0.85rem; }
.welcome-admin-link a { color: var(--muted); }

@media (max-width: 520px) {
    .welcome-leader-grid { grid-template-columns: 1fr; }
    .welcome-heading { font-size: 1.5rem; }
}

/* ---- The admin editor behind it (company-welcome.php) ---- */
.welcome-preview-link { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.welcome-af { margin: 18px 0; padding-top: 14px; border-top: 1px solid var(--border); }
.welcome-af > summary { cursor: pointer; font-size: 0.88rem; font-weight: 600; color: var(--brand); }
.welcome-leader-form { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.welcome-leader-form h3 { margin-top: 0; font-size: 1rem; }
.welcome-leader-table td, .welcome-leader-table th { padding: 8px 10px; vertical-align: middle; }

/* ---- Company details + logo (company-details.php, 2026-08-27) ------------
   Two narrow cards rather than the full page width: this is a contact
   card and a picture, and a name field stretched across a desktop screen
   reads as a form somebody has to fill in rather than a detail they came
   to correct. */
.company-details-card { max-width: 640px; }
.company-details-remove { font-weight: 500; display: flex; align-items: center; gap: 6px; }
.company-details-remove input { width: auto; margin: 0; }
.company-details-links { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 22px; }
.mt-20 { margin-top: 20px; }

/* ---- Donations / Tithing (member-giving.php, 2026-08-27) ---------------
   Henk: "members should feel welcome to donated ... Should be a friendly
   page". So the type leads and the boxes recede: the company's own words
   get real line-height and no card around them, and the banking details —
   the part that would otherwise dominate and make the page read like an
   invoice — sit in an ordinary card BELOW them. The account number is the
   one thing somebody has to copy accurately onto a phone keypad, so it is
   the only element given a monospace face and letter-spacing. */
.giving-hero { padding: 6px 0 4px; }
.giving-hero h1 { font-size: 1.75rem; letter-spacing: -0.3px; margin-bottom: 10px; }
.giving-intro { font-size: 1.02rem; line-height: 1.65; color: var(--text); margin: 0 0 22px; }

.giving-online-button { display: inline-block; margin-top: 4px; }

.giving-details { margin: 14px 0 0; display: grid; grid-template-columns: auto 1fr; gap: 8px 18px; }
.giving-details dt { color: var(--muted); font-size: 0.88rem; }
.giving-details dd { margin: 0; font-weight: 600; text-align: right; overflow-wrap: anywhere; }
/* Tabular figures and a little tracking: an account number is copied digit
   by digit, and proportional numerals in a bold face are exactly where a 1
   and a 7 get confused. */
.giving-number {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.98rem;
}
.giving-reference-hint { margin-top: 14px; }

.giving-closing { margin: 24px 0 8px; color: var(--muted); font-size: 0.92rem; line-height: 1.6; }
.giving-contact { margin-top: 18px; }
.giving-contact-links { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0 0; }
.giving-preview-band { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

@media (max-width: 420px) {
    /* Label above value rather than a two-column grid: at this width the
       account name and the longer labels wrap to two lines each and the
       right-aligned column stops lining up with anything. */
    .giving-details { grid-template-columns: 1fr; gap: 2px; }
    .giving-details dd { text-align: left; margin-bottom: 10px; }
}

/* The admin side (company-giving.php). The status list is the answer to the
   question an admin opened the page with — can my members actually give
   yet — so it is stated in words, with the colour only reinforcing it. */
.giving-status-list { list-style: none; padding: 0; margin: 10px 0 14px; }
.giving-status-list li { padding: 4px 0 4px 22px; position: relative; font-size: 0.92rem; }
.giving-status-list li::before { position: absolute; left: 0; font-weight: 700; }
.giving-status-ok::before { content: '✓'; color: var(--success-text); }
.giving-status-missing::before { content: '!'; color: var(--warn-text); }
/* The Section 18A switch. A real checkbox with the label beside it rather
   than a styled toggle: this is a legal declaration about the
   organisation, and a control that looks like a preference invites being
   flipped like one. */
.giving-s18a-toggle { display: flex; align-items: flex-start; gap: 9px; font-weight: 500; margin-top: 12px; }
.giving-s18a-toggle input { width: auto; margin: 3px 0 0; flex-shrink: 0; }

/* ---- Verse of the Day (2026-08-26) -------------------------------------
   The first thing on a member's Overview tab, and deliberately the only
   thing there that is not a task, a count or a piece of admin. Styled as
   a quiet quotation rather than a card with a heading and a border: a
   verse should read like something offered, not like another panel
   competing for attention. */

.verse-card {
    margin: 0 0 22px;
    padding: 20px 22px;
    background: linear-gradient(135deg, rgba(0, 150, 174, 0.10), rgba(0, 150, 174, 0.02));
    border-left: 3px solid rgba(0, 150, 174, 0.55);
    border-radius: 10px;
}
.verse-eyebrow {
    margin: 0 0 8px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--muted);
}
.verse-text {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 1.08rem;
    line-height: 1.7;
    color: var(--text);
}
.verse-reference {
    margin: 10px 0 0;
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--brand-dark, var(--brand));
}
.verse-translation {
    margin-left: 6px;
    font-weight: 600;
    font-size: 0.78rem;
    color: var(--muted);
}
/* The publisher's copyright notice. Small, but never display:none —
   Lockman's permission for the Amplified Bible is conditional on it
   being shown with a working link. */
.verse-credit {
    margin: 10px 0 0;
    font-size: 0.68rem;
    line-height: 1.5;
    color: var(--muted);
}
.verse-credit a { color: inherit; text-decoration: underline; }

/* ---- The admin editor (company-verses.php) ---- */
.verses-today .verse-text { font-size: 1.02rem; }
.verses-form { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.verses-form h3 { margin-top: 0; font-size: 1rem; }
.verses-table td, .verses-table th { padding: 8px 10px; vertical-align: middle; }
.verses-excerpt { max-width: 420px; }
.verses-rights-list { margin: 0; padding-left: 20px; font-size: 0.85rem; line-height: 1.7; color: var(--muted); }
.checkbox-line { display: flex; align-items: center; gap: 8px; margin: 14px 0; font-weight: 600; }
.checkbox-line input { width: auto; margin: 0; }

/* The company's own website, under the contact buttons on the welcome page
   (2026-08-26). A link rather than another button: everything above it
   reaches a person, this reaches a page, and making it look identical to
   "phone the pastor" would overstate it. */
.welcome-website { margin: 10px 0 0; font-size: 0.9rem; }
.welcome-logo-hint { margin: -8px 0 18px; }

/* ---- Install help page (install-app.php, 2026-08-31) -------------------
   Read on a phone, usually by somebody who is stuck — so the steps are
   large, numbered and unmissable, and the video is below them rather than
   above. Anyone who can already guess the answer gets it without waiting
   for a download; anyone whose video will not play still has the whole
   instruction. */
.install-heading { margin-bottom: 6px; }
.install-steps { list-style: none; padding: 0; margin: 24px 0 0; counter-reset: none; }
.install-steps li {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 0;
    border-bottom: 1px solid var(--border);
    font-size: 1.02rem;
    line-height: 1.5;
}
.install-steps li:last-child { border-bottom: none; }
.install-step-n {
    flex: 0 0 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--brand);
    color: #fff;
    font-weight: 700;
    font-size: 0.95rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.install-done {
    margin: 18px 0 4px;
    padding: 12px 16px;
    background: var(--success-bg);
    color: var(--success-text);
    border-radius: var(--radius);
    font-weight: 600;
}
.install-video { margin-top: 30px; }
.install-video h2 { font-size: 1.1rem; margin-bottom: 10px; }
/* The source is 1080x1920. Capping the height stops a 9:16 video from
   running past the fold on a desktop, where the column is wide. */
.install-video video {
    width: 100%;
    max-width: 340px;
    max-height: 70vh;
    height: auto;
    display: block;
    border-radius: 12px;
    background: #000;
}
.install-share { margin-top: 10px; }
.install-share-url { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.82rem; }
.install-other { margin-top: 18px; }
.install-ios { margin-top: 26px; }
/* Console install guide (install-app.php?console=1, 2026-09-11): two platform cards side by side, compact steps. */
.dash-charts.install-console-grid { grid-template-columns: 1fr 1fr; margin-bottom: 20px; }
.install-steps-compact { margin-top: 8px; }
.install-steps-compact li { padding: 10px 0; }
.install-next { margin-top: 26px; }
.install-back { margin-top: 18px; }

.welcome-install-link { margin-top: 18px; text-align: center; font-size: 0.92rem; }
.footer-install-link { margin-top: 10px; }
.footer-install-link a { color: var(--soft-white); text-decoration: underline; font-size: 0.88rem; }
.footer-install-link a:hover { color: var(--teal-bright); }

/* =====================================================================
   COURSES AS A WIZARD (2026-08-31)

   Henk: "The course layout should be like a wizard layout. 1. The
   Heading of the course 2. how long the course is 3. Intro 4. day 1".

   Everything below is shared by member-course.php (a member walking the
   course) and company-course.php's preview (an admin checking their own
   work), because both render through includes/course_wizard.php. The
   measurements are set for a phone held one-handed in a company foyer,
   which is where a devotional course actually gets read.
   ===================================================================== */

.course-wizard { max-width: 720px; margin: 0 auto; }
.course-breadcrumb { margin: 0 0 14px; font-size: 0.9rem; }

/* ---- the progress rail ---------------------------------------------
   Numbered dots rather than a bar: a bar says "78% done", which is not
   a thing anybody wants to know about a six-day devotional, whereas a
   row of days says which one you are on and lets you jump back to any
   of them. Scrolls sideways rather than wrapping, so a twelve-day
   course does not push the actual content below the fold. */
.course-progress { margin-bottom: 18px; }
.course-progress-steps {
    list-style: none;
    margin: 0;
    padding: 0 0 6px;
    display: flex;
    gap: 6px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}
.course-progress-step { flex: 0 0 auto; }
.course-progress-step > a,
.course-progress-step > span {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px 6px 7px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--card-bg);
    color: var(--muted);
    text-decoration: none;
    font-size: 0.85rem;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.course-progress-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    color: var(--muted);
    font-size: 0.75rem;
    font-weight: 700;
    flex: 0 0 auto;
}
.course-progress-step > a:hover,
.course-progress-step > a:focus-visible {
    border-color: var(--brand-mid);
    color: var(--brand);
    background: #EEF4FA;
}
.course-progress-step > a:hover .course-progress-dot,
.course-progress-step > a:focus-visible .course-progress-dot {
    background: var(--brand-mid);
    color: #fff;
}
.course-progress-step.is-done > a,
.course-progress-step.is-done > span { color: var(--teal-ink); border-color: #BFE3EA; }
.course-progress-step.is-done .course-progress-dot { background: var(--teal-deep); color: #fff; }
.course-progress-step.is-current > a,
.course-progress-step.is-current > span {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
    font-weight: 600;
}
.course-progress-step.is-current .course-progress-dot { background: var(--accent); color: var(--brand-dark); }
.course-progress-count { margin: 0; font-size: 0.82rem; color: var(--muted); }

/* ---- the step itself ----------------------------------------------- */
.course-card { padding: 26px 24px 30px; }
.course-eyebrow {
    margin: 0 0 4px;
    font-size: 0.76rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--teal-ink);
}
.course-title { margin: 0 0 6px; font-size: 1.6rem; line-height: 1.25; color: var(--brand); }
.course-subtitle { margin: 0 0 14px; font-size: 1.02rem; color: var(--muted); font-style: italic; }

/* "How long the course is" — a chip, not a sentence, because it is the
   one fact somebody checks before deciding whether to start, and a chip
   is findable without reading. */
.course-meta-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.course-chip {
    display: inline-block;
    padding: 4px 11px;
    border-radius: 999px;
    background: var(--bg);
    border: 1px solid var(--border);
    font-size: 0.82rem;
    color: var(--text);
}
.course-chip-duration { background: #EAF6F9; border-color: #BFE3EA; color: var(--teal-ink); font-weight: 600; }
.course-chip-empty { color: var(--muted); font-style: italic; }

.course-scripture {
    margin: 0 0 16px;
    padding: 9px 13px;
    background: var(--bg);
    border-left: 3px solid var(--teal);
    border-radius: 0 var(--radius) var(--radius) 0;
    font-size: 0.95rem;
}
.course-scripture-label { font-weight: 700; color: var(--brand); }

/* Prose set for reading a screenful at a time, not for scanning. */
.course-prose p { margin: 0 0 14px; line-height: 1.7; font-size: 1rem; }
.course-prose p:last-child { margin-bottom: 0; }
.course-prose-tight p { margin-bottom: 8px; font-size: 0.97rem; }
.course-subheading {
    margin: 20px 0 8px;
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--brand);
}
.course-list { margin: 0 0 14px; padding-left: 22px; }
.course-list li { margin-bottom: 7px; line-height: 1.6; }

/* KEY TRUTH / CENTRAL TRUTH / FINAL TRUTH. Gold on navy: it is the line
   the author wants remembered after everything else is forgotten, and
   it has to survive being skim-read. Navy text on gold rather than the
   reverse — white on #F8B420 is 1.82:1 and unreadable. */
.course-callout {
    margin: 18px 0;
    padding: 14px 16px;
    background: var(--accent);
    color: var(--brand-dark);
    border-radius: var(--radius);
}
.course-callout-label {
    display: block;
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-weight: 800;
    margin-bottom: 4px;
    opacity: 0.85;
}
.course-callout-text { display: block; font-size: 1.04rem; font-weight: 600; line-height: 1.5; }

.course-panel {
    margin: 18px 0;
    padding: 15px 17px;
    background: var(--bg);
    border-radius: var(--radius);
    border: 1px solid var(--border);
}
.course-panel h3 { margin: 0 0 10px; font-size: 0.95rem; color: var(--brand); }
.course-panel .course-list { margin-bottom: 0; }
.course-panel-questions { background: #EEF4FA; border-color: #CFE0EF; }
.course-panel-action { border-left: 3px solid var(--teal); }
.course-panel-prayer { background: #FBF6EC; border-color: #EFE0C2; font-style: italic; }

/* "My notes" — ruled lines, deliberately not a form field. Nothing a
   member writes about their own prayer life is stored anywhere. */
.course-notes { margin-top: 26px; padding-top: 18px; border-top: 1px dashed var(--border); }
.course-notes h3 { margin: 0 0 4px; font-size: 0.95rem; color: var(--brand); }
.course-notes-lines { margin-top: 12px; }
.course-notes-lines span { display: block; height: 30px; border-bottom: 1px solid var(--border); }
/* The saved notes box (2026-09-07); the ruled lines above remain the fallback. */
.course-notes-form label h3 { cursor: text; }
.course-notes-form textarea { width: 100%; box-sizing: border-box; margin-top: 10px; min-height: 150px; resize: vertical; font: inherit; line-height: 1.55; }
.course-notes-actions { display: flex; align-items: center; gap: 12px; margin-top: 10px; flex-wrap: wrap; }
.course-notes-status { font-size: 0.85rem; color: var(--muted, #6b7280); }
@media print { .course-notes-form button, .course-notes-status, .course-notes-form .hint { display: none; } .course-notes-form textarea { border: none; padding: 0; } }

/* ---- back / next ---------------------------------------------------
   Thumb-sized and pinned to opposite ends, so neither is hit by
   accident on a phone. */
.course-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin-top: 20px;
}
.course-nav .btn { min-height: 44px; display: inline-flex; align-items: center; }
.course-nav-spacer { flex: 1 1 auto; }
.course-nav-next { margin-left: auto; }
.course-booking { margin-top: 18px; text-align: center; }

/* ---- the admin side ------------------------------------------------ */
.course-admin-subtitle { margin: 2px 0 10px; color: var(--muted); font-style: italic; font-size: 0.94rem; }
.course-admin-summary { color: var(--muted); }
.course-admin-days { margin: 12px 0 0; padding-left: 20px; }
.course-admin-days li { margin-bottom: 5px; font-size: 0.92rem; }

.course-fieldset {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px 18px;
    margin: 0 0 20px;
}
.course-fieldset legend {
    padding: 0 8px;
    font-weight: 700;
    color: var(--brand);
    font-size: 0.95rem;
}

.course-day-list { list-style: none; margin: 0; padding: 0; }
.course-day-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 0;
    border-bottom: 1px solid var(--border);
}
.course-day-row:last-child { border-bottom: 0; }
.course-day-row.is-editing { background: #FFF9EC; border-radius: var(--radius); padding-left: 10px; padding-right: 10px; }
.course-day-main { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }
.course-day-badge {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    background: var(--brand);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    white-space: nowrap;
}
.course-day-title { font-weight: 600; }
.course-day-ref { color: var(--muted); font-size: 0.86rem; }
.course-day-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* The preview stacks every step, which is the one way an admin reads a
   course differently from a member. Each step is boxed so it is obvious
   where one ends and the next begins. */
.course-preview-step {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px 18px;
    margin-bottom: 16px;
    background: var(--card-bg);
}
.course-preview-step:last-child { margin-bottom: 0; }

@media (max-width: 560px) {
    .course-card { padding: 20px 16px 24px; }
    .course-title { font-size: 1.35rem; }
    .course-progress-label { display: none; }   /* dots only — the rail stays one row */
    .course-progress-step > a,
    .course-progress-step > span { padding: 5px; }
    .course-nav { gap: 8px; }
    .course-nav .btn { padding-left: 12px; padding-right: 12px; font-size: 0.9rem; }
    .course-day-row { align-items: flex-start; }
}

/* The wizard opened inside the admin's courses tab (2026-08-31). Same
   renderer as the member's page, sitting in an admin card — so it gets a
   little more room and a strip along the top saying whose view it is. */
.course-wizard-admin { max-width: none; padding: 22px 22px 26px; }
.course-wizard-admin .course-title { font-size: 1.45rem; }
.course-wizard-admin-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin: 18px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}
.course-wizard-admin-actions .hint { margin: 0; }

/* The days in the admin list are links into their own step. Kept looking
   like list text rather than a row of blue — the badge already signals
   that each one is a thing you can open. */
.course-admin-days a { color: inherit; text-decoration: none; }
.course-admin-days a:hover .course-day-badge,
.course-admin-days a:focus-visible .course-day-badge { background: var(--teal-deep); }
.course-admin-days a:hover, .course-admin-days a:focus-visible { text-decoration: underline; }

.course-example-card { border-left: 3px solid var(--teal); }

/* The company's own app icon, previewed on company-details.php (2026-08-31).
   The preview is the point of that card: an admin cannot otherwise find
   out what their app looks like on a phone without installing it on one,
   and a wide logo's problem is invisible until you see it in a square. */
.app-icon-preview { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 26px; margin: 4px 0 18px; }
.app-icon-preview figure { margin: 0; text-align: center; }
.app-icon-preview figcaption { margin-top: 8px; font-size: 0.8rem; color: var(--muted); max-width: 130px; }
/* Drawn at 96px — near enough to what a launcher gives an icon that a
   logo too small to read here is too small to read there. */
.app-icon-preview img { width: 96px; height: 96px; display: block; background: var(--bg); }
.app-icon-square { border-radius: 20px; box-shadow: 0 2px 8px rgba(0, 34, 82, 0.18); }
.app-icon-round  { border-radius: 50%;  box-shadow: 0 2px 8px rgba(0, 34, 82, 0.18); }
.app-icon-preview-note { flex: 1 1 240px; margin: 0; min-width: 220px; }

/* Family tab (2026-09-09): the Registered / Not on I-Transact badge sits
   inline after the birthday, and the "linked to you by" list gets a
   sub-heading of its own so it doesn't read as one more child. */
.dependent-row-top .badge { margin-left: 6px; vertical-align: middle; }
.family-reverse-heading { margin: 22px 0 0; font-size: 1rem; }

/* =====================================================================
   BIBLE BATTLE (2026-09-09) — member-bible-battle.php + admin bible-battle.php
   Henk: "provided it feels like a real game, not a school test." So this
   is the one member page that is allowed a dark, saturated look: a navy
   hero with gold, big answer buttons, a ring timer. It still uses the
   brand tokens — navy, gold, teal — so it is recognisably I-Transact, and
   everything below the hero is ordinary cards, tabs and .report-table so
   nothing has to be learned twice. Phone-first: four full-width answer
   buttons under the thumb, 44px+ tap targets, no horizontal scroll at 390px.
   ===================================================================== */
.bb-hero {
    background: linear-gradient(135deg, var(--brand-dark) 0%, var(--brand) 55%, #1f3f7a 100%);
    color: var(--soft-white);
    border-radius: var(--radius);
    padding: 22px 20px 18px;
    margin-bottom: 18px;
    position: relative;
    overflow: hidden;
}
.bb-hero::after {
    content: "";
    position: absolute; right: -40px; top: -40px; width: 180px; height: 180px; border-radius: 50%;
    background: radial-gradient(circle, rgba(248,180,32,0.35) 0%, rgba(248,180,32,0) 70%);
    pointer-events: none;
}
.bb-hero-eyebrow { margin: 0; font-size: 0.8rem; letter-spacing: 0.4px; text-transform: uppercase; opacity: 0.8; }
.bb-hero-title { margin: 2px 0 0; font-size: 2rem; line-height: 1.1; color: var(--accent); text-shadow: 0 2px 0 rgba(0,0,0,0.25); }
.bb-hero-tagline { margin: 6px 0 14px; opacity: 0.9; font-size: 0.95rem; }
.bb-hero-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.bb-hero-stats > div { background: rgba(255,255,255,0.08); border-radius: 10px; padding: 10px 6px; text-align: center; }
.bb-stat-num { display: block; font-size: 1.25rem; font-weight: 800; color: #fff; }
.bb-stat-label { display: block; font-size: 0.7rem; opacity: 0.85; line-height: 1.2; margin-top: 2px; }
.bb-xp-bar { height: 10px; background: rgba(0,0,0,0.25); border-radius: 999px; overflow: hidden; }
.bb-xp-bar > span { display: block; height: 100%; background: linear-gradient(90deg, var(--teal) 0%, #7fe37f 100%); border-radius: 999px; }
.bb-xp-bar-hero { margin-top: 14px; }
.bb-hero .bb-xp-text { margin: 6px 0 0; font-size: 0.8rem; opacity: 0.9; }
.bb-eyebrow { margin: 0 0 4px; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.4px; color: var(--teal-ink); font-weight: 700; }
.bb-challenge-card { border: 2px solid var(--accent); }
.bb-play-btn { font-size: 1.15rem; padding: 14px; }
.bb-done-line { background: var(--success-bg); color: var(--success-text); padding: 10px 12px; border-radius: 8px; font-size: 0.93rem; }
.bb-done-line a { color: inherit; margin-left: 6px; }
.bb-inline-form { display: flex; gap: 8px; align-items: center; }
.bb-inline-form input[type=text] { flex: 1 1 auto; margin: 0; min-width: 0; }
.bb-inline-form .btn { flex: 0 0 auto; }
.bb-badge-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.bb-badge { display: flex; gap: 10px; align-items: flex-start; border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; font-size: 0.9rem; }
.bb-badge small { color: var(--muted); }
.bb-badge-icon { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.1rem; background: var(--bg); color: var(--muted); }
.bb-badge-earned { border-color: var(--accent); background: #fffaf0; }
.bb-badge-earned .bb-badge-icon { background: var(--accent); color: var(--brand-dark); }
.bb-badge-locked { opacity: 0.7; }
.bb-league-switch { display: flex; gap: 8px; margin-bottom: 12px; }
.bb-podium { display: grid; grid-template-columns: 1fr 1.2fr 1fr; gap: 8px; align-items: end; margin: 6px 0 14px; }
.bb-podium-slot { text-align: center; border-radius: 10px 10px 0 0; padding: 12px 6px 10px; color: #fff; background: var(--brand-mid); }
.bb-podium-1 { background: linear-gradient(180deg, var(--accent) 0%, var(--accent-deep) 100%); color: var(--brand-dark); padding-top: 22px; }
.bb-podium-2 { background: #6f8194; }
.bb-podium-3 { background: #9a6a3c; }
.bb-podium-rank { display: block; font-size: 1.3rem; font-weight: 800; }
.bb-podium-name { display: block; font-weight: 700; font-size: 0.95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bb-podium-pts { display: block; font-size: 0.8rem; opacity: 0.9; }
.bb-board-table td.num, .bb-board-table th.num { text-align: right; white-space: nowrap; }
.bb-board-me td { background: #fffaf0; font-weight: 600; }
.bb-my-team { border: 2px solid var(--teal); border-radius: 10px; padding: 12px 14px; }
.bb-my-team h3 { margin: 0 0 4px; }
.bb-my-team form { margin-top: 8px; }
.bb-prize-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.bb-prize { border: 1px solid var(--border); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; gap: 3px; background: #fffdf7; }
.bb-prize strong { color: var(--brand); }
.bb-prize small { color: var(--muted); }
.bb-prize-tbc { background: var(--card-bg); }
.bb-prize-tbc span { color: var(--muted); font-style: italic; }
.bb-awards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.bb-award { display: flex; gap: 10px; align-items: center; border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; }
.bb-award-icon { font-size: 1.4rem; }
.bb-award small { color: var(--muted); }

/* ---- Play screen ---- */
.bb-play { max-width: 560px; margin: 0 auto; }
.bb-play-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; font-size: 0.9rem; }
.bb-quit { color: var(--muted); text-decoration: none; }
.bb-play-title { font-weight: 700; color: var(--brand); }
.bb-play-progress { color: var(--muted); white-space: nowrap; }
.bb-card { background: var(--card-bg); border-radius: 14px; padding: 18px; box-shadow: 0 6px 24px rgba(0,34,82,0.10); }
.bb-timer-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.bb-type-chip { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; color: var(--teal-ink); background: #e6f6f9; padding: 4px 10px; border-radius: 999px; }
.bb-timer { position: relative; width: 64px; height: 64px; }
.bb-timer svg { width: 64px; height: 64px; transform: rotate(-90deg); }
.bb-timer circle { fill: none; stroke-width: 3.5; }
.bb-timer-track { stroke: var(--border); }
.bb-timer-arc { stroke: var(--teal); stroke-linecap: round; transition: stroke 0.2s; }
.bb-timer-low .bb-timer-arc { stroke: #e0402f; }
.bb-timer-low #bb-timer-num { color: #e0402f; }
.bb-timer span { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 1.25rem; color: var(--brand); }
.bb-prompt { font-size: 1.2rem; line-height: 1.4; font-weight: 600; color: var(--text); margin: 8px 0 16px; word-break: break-word; }
.bb-options { display: grid; gap: 10px; }
.bb-option {
    display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
    border: 0; border-radius: 12px; padding: 14px 14px; min-height: 56px;
    color: #fff; font-size: 1rem; font-weight: 600; cursor: pointer; line-height: 1.3;
    box-shadow: 0 3px 0 rgba(0,0,0,0.22); font-family: inherit;
}
.bb-option:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(0,0,0,0.22); }
.bb-option:disabled { opacity: 0.6; cursor: default; }
.bb-option-0 { background: #1d9a4f; }
.bb-option-1 { background: #2563c9; }
.bb-option-2 { background: #d64545; }
.bb-option-3 { background: #7c3aed; }
.bb-option-letter { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; background: rgba(255,255,255,0.22); display: flex; align-items: center; justify-content: center; font-weight: 800; }
.bb-option-text { flex: 1 1 auto; }
.bb-question-hint { margin: 12px 0 0; font-size: 0.8rem; color: var(--muted); text-align: center; }
.bb-feedback-headline { font-size: 1.5rem; font-weight: 800; margin-bottom: 8px; }
.bb-feedback-right { border-top: 6px solid #1d9a4f; }
.bb-feedback-right .bb-feedback-headline { color: #1d9a4f; }
.bb-feedback-wrong { border-top: 6px solid #d64545; }
.bb-feedback-wrong .bb-feedback-headline { color: #d64545; }
.bb-points-pop { display: inline-block; background: var(--accent); color: var(--brand-dark); border-radius: 999px; padding: 2px 12px; font-size: 1rem; margin-left: 6px; vertical-align: middle; }
.bb-feedback-prompt { color: var(--muted); margin: 0 0 8px; font-size: 0.95rem; }
.bb-feedback-answer { margin: 0 0 8px; font-size: 1.05rem; }
.bb-feedback-explain { margin: 0 0 8px; }
.bb-feedback-ref { margin: 0 0 4px; color: var(--teal-ink); font-weight: 600; }
.bb-feedback-time { margin: 0; color: var(--muted); font-size: 0.85rem; }
.bb-next-btn { margin-top: 16px; font-size: 1.05rem; padding: 14px; }
.bb-results { text-align: center; }
.bb-results-eyebrow { margin: 0; text-transform: uppercase; letter-spacing: 0.4px; font-size: 0.8rem; color: var(--muted); font-weight: 700; }
.bb-results-score { margin: 6px 0 4px; }
.bb-results-big { font-size: 3rem; font-weight: 900; color: var(--brand); line-height: 1; }
.bb-results-unit { color: var(--muted); }
.bb-results-line { margin: 4px 0; color: var(--text); }
.bb-level-row { margin: 14px 0; text-align: left; }
.bb-level-name { display: block; font-weight: 700; margin-bottom: 4px; color: var(--brand); }
.bb-results .bb-xp-text { display: block; font-size: 0.8rem; color: var(--muted); margin-top: 4px; }
.bb-new-badges { margin: 12px 0; text-align: left; }
.bb-new-badges-title { margin: 0 0 6px; font-weight: 800; color: var(--accent-deep); }
.bb-review { text-align: left; margin: 12px 0; }
.bb-review summary { cursor: pointer; color: var(--teal-ink); font-weight: 600; }
.bb-review-list { padding-left: 20px; margin: 8px 0 0; font-size: 0.9rem; }
.bb-review-list li { margin-bottom: 6px; }
.bb-review-right { color: var(--success-text); }
.bb-review-wrong { color: var(--error-text); }
.bb-review-meta { display: block; font-size: 0.8rem; color: var(--muted); }
.bb-next-action { display: block; text-align: left; text-decoration: none; color: var(--text); border: 2px dashed var(--teal); border-radius: 12px; padding: 12px 14px; margin: 14px 0; }
.bb-next-action:hover { background: #e6f6f9; }
.bb-next-action-label { display: block; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.4px; color: var(--teal-ink); font-weight: 700; }
.bb-next-action strong { display: block; color: var(--brand); margin: 2px 0; }
.bb-next-action span:last-child { display: block; font-size: 0.9rem; color: var(--muted); }
/* Admin */
.bb-admin-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 16px; }
.bb-admin-stat { background: var(--card-bg); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.bb-admin-stat strong { display: block; font-size: 1.5rem; color: var(--brand); }
.bb-admin-stat span { font-size: 0.85rem; color: var(--muted); }
.bb-q-prompt { max-width: 520px; }
.bb-q-options-list { margin: 0; padding-left: 18px; font-size: 0.85rem; color: var(--muted); }
.bb-q-options-list .bb-q-correct { color: var(--success-text); font-weight: 700; }
.bb-row-actions { display: flex; gap: 6px; flex-wrap: nowrap; }
.bb-row-actions form { margin: 0; }
@media (max-width: 620px) {
    .bb-hero-title { font-size: 1.6rem; }
    .bb-hero-stats { grid-template-columns: repeat(2, 1fr); }
    .bb-podium-name { font-size: 0.85rem; }
    .bb-prompt { font-size: 1.1rem; }
}

/* Bible Battle avatars (2026-09-10): an emoji on a coloured disc. */
.bb-avatar { --bb-av-size: 32px; display: inline-flex; align-items: center; justify-content: center; width: var(--bb-av-size); height: var(--bb-av-size); border-radius: 50%; font-size: calc(var(--bb-av-size) * 0.58); line-height: 1; vertical-align: middle; box-shadow: inset 0 -2px 0 rgba(0,0,0,0.15); flex: 0 0 auto; }
.bb-hero-me { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.bb-avatar-hero { box-shadow: 0 0 0 3px rgba(255,255,255,0.35); }
.bb-hero-nick { font-weight: 800; font-size: 1.1rem; color: #fff; }
.bb-cell-player { white-space: nowrap; }
.bb-cell-player .bb-avatar { margin-right: 4px; }
.bb-podium-slot .bb-avatar-podium { display: flex; margin: 4px auto 6px; box-shadow: 0 0 0 3px rgba(255,255,255,0.5); }
.bb-team-members { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.bb-team-members span { display: inline-flex; align-items: center; gap: 4px; }
.bb-avatar-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; }
.bb-avatar-choice { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 4px; border: 2px solid var(--border); border-radius: 12px; cursor: pointer; font-size: 0.75rem; color: var(--muted); text-align: center; }
.bb-avatar-choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.bb-avatar-choice:hover { border-color: var(--teal); }
.bb-avatar-choice:focus-within { outline: 2px solid var(--teal); outline-offset: 2px; }
.bb-avatar-current { border-color: var(--accent); background: #fffaf0; color: var(--brand); font-weight: 700; }

/* Data Guard (2026-09-10): data-backup.php + platform-health.php */
.dg-check-row { display: flex; flex-wrap: wrap; gap: 0 22px; }
.dg-check-row .checkbox-row { margin: 8px 0; }
.dg-status-line { margin: 0 0 12px; }
.dg-danger-card { border: 2px solid var(--error-text); }
.dg-steps { margin: 0 0 14px; padding-left: 20px; font-size: 0.93rem; }
.dg-steps li { margin-bottom: 4px; }
.dg-table-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 4px 12px; margin: 8px 0 14px; font-size: 0.85rem; max-height: 320px; overflow: auto; border: 1px solid var(--border); border-radius: 8px; padding: 10px; }
.dg-table-pick label { display: flex; gap: 6px; align-items: center; }
.dg-table-pick input { width: auto; margin: 0; }
.dg-dest-form summary { display: inline-block; }
.dg-status-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; padding: 12px 16px; border-radius: var(--radius); margin-bottom: 16px; border-left: 6px solid; }
.dg-status-ok { background: var(--success-bg); color: var(--success-text); border-color: var(--success-text); }
.dg-status-warn { background: var(--warn-bg); color: var(--warn-text); border-color: var(--accent-deep); }
.dg-status-crit { background: var(--error-bg); color: var(--error-text); border-color: var(--error-text); }
.dg-status-banner strong { font-size: 1.05rem; }
.dg-status-banner form { margin-left: auto; }
.dg-check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 10px; }
.dg-check { display: flex; gap: 10px; align-items: flex-start; border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; }
.dg-check-dot { flex: 0 0 auto; width: 12px; height: 12px; border-radius: 50%; margin-top: 5px; background: var(--muted); }
.dg-check-ok .dg-check-dot { background: var(--success-text); }
.dg-check-warn .dg-check-dot { background: var(--accent); }
.dg-check-crit .dg-check-dot { background: var(--error-text); box-shadow: 0 0 0 4px rgba(179,38,30,0.18); }
.dg-check-crit { border-color: var(--error-text); }
.dg-check-warn { border-color: var(--accent); }
.dg-check-value { color: var(--muted); font-size: 0.9rem; margin-left: 4px; }
.dg-check-detail { font-size: 0.82rem; color: var(--muted); margin-top: 2px; word-break: break-word; }
.dg-pre { background: var(--brand-dark); color: var(--soft-white); padding: 12px 14px; border-radius: 8px; font-size: 0.82rem; overflow-x: auto; white-space: pre-wrap; word-break: break-all; }

/* =====================================================================
   REPORTS HUB (reports.php, 2026-09-11). Henk: "all types of reports the
   system can give... very fancy and visual with print options."
   The catalogue is a card grid per group; a report is the accounting
   report-layout (rail + sheet) with tiles, charts, meters and tables.
   ===================================================================== */
.reports-group { margin-top: 26px; }
.reports-group-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; }
.reports-group-head h2 { margin: 0; font-size: 1.15rem; text-transform: uppercase; letter-spacing: 1px; color: var(--brand); }
.reports-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.report-card {
    display: grid; grid-template-columns: 48px 1fr; grid-template-rows: auto auto; column-gap: 14px; row-gap: 6px;
    background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px;
    text-decoration: none; color: var(--text); position: relative; overflow: hidden;
    transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.report-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--teal); }
.report-card:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(0, 19, 59, 0.12); border-color: var(--teal); }
.report-card-icon { grid-row: 1 / 3; width: 48px; height: 48px; border-radius: 14px; display: flex; align-items: center; justify-content: center; background: rgba(0, 150, 174, 0.12); color: var(--teal-ink); }
.report-card-icon svg { width: 24px; height: 24px; }
.report-card-body { display: flex; flex-direction: column; gap: 4px; }
.report-card-body strong { font-size: 1.02rem; }
.report-card-body span { color: var(--muted); font-size: 0.86rem; line-height: 1.45; }
.report-card-meta { grid-column: 2; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.8px; color: var(--muted); font-weight: 700; }
.reports-group-people .report-card::before, .reports-group-people .report-card:hover { border-color: #0096AE; background-color: var(--card-bg); }
.reports-group-people .report-card::before { background: #0096AE; }
.reports-group-people .report-card-icon { background: rgba(0, 150, 174, 0.12); color: #007A8E; }
.reports-group-ministry .report-card::before { background: #6b3fa0; }
.reports-group-ministry .report-card-icon { background: rgba(107, 63, 160, 0.12); color: #5a2f8f; }
.reports-group-ministry .report-card:hover { border-color: #6b3fa0; }
.reports-group-care .report-card::before { background: #c8102e; }
.reports-group-care .report-card-icon { background: rgba(200, 16, 46, 0.1); color: #a30d25; }
.reports-group-care .report-card:hover { border-color: #c8102e; }
.reports-group-giving .report-card::before { background: #d19a00; }
.reports-group-giving .report-card-icon { background: rgba(209, 154, 0, 0.14); color: #8a6500; }
.reports-group-giving .report-card:hover { border-color: #d19a00; }

.report-crumbs { margin-bottom: 8px; font-size: 0.9rem; }
.reports-sheet-layout { margin-top: 12px; grid-template-columns: 250px 1fr; }
/* Paired charts scale to their half on a desktop; a phone goes back to the 520px minimum and scrolls. */
.reports-blocks .chart-figure { overflow: visible; }
.reports-blocks .chart-figure .chart { min-width: 0; }
.report-custom { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.report-custom label { font-size: 0.8rem; margin-top: 8px; }
.reports-sheet-id { display: flex; gap: 16px; align-items: flex-start; }
.reports-sheet-logo { width: 56px; height: 56px; object-fit: contain; border-radius: 10px; }
.reports-headline { margin-left: auto; }
.reports-headline strong { color: var(--brand); }
.reports-tiles { margin-bottom: 8px; }
.reports-tiles .stat-tile-value { font-size: 1.6rem; white-space: nowrap; }
.reports-blocks { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 26px; margin-top: 18px; }
.reports-block { min-width: 0; }
.reports-block.is-full { grid-column: 1 / -1; }
.reports-block h3 { margin: 0 0 4px; font-size: 1.02rem; color: var(--brand); }
.reports-block .hint { margin-bottom: 8px; }
.reports-block-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.reports-csv-link { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.6px; text-decoration: none; border: 1px solid var(--border); border-radius: 6px; padding: 3px 9px; color: var(--teal-ink); }
.reports-csv-link:hover { background: var(--bg); }
.reports-meters { margin-top: 10px; }
.reports-meters .dash-meter-head small { color: var(--muted); font-weight: 500; margin-left: 6px; }
.reports-empty { padding: 18px 0; }
.reports-rowcount { margin: 4px 0 0; font-size: 0.78rem; }
.reports-note { margin: 0; }
.reports-print-foot { display: none; }
@media (max-width: 1000px) {
    .reports-sheet-layout { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
    .reports-blocks { grid-template-columns: 1fr; }
    .reports-blocks .chart-figure { overflow-x: auto; }
    .reports-blocks .chart-figure .chart { min-width: 520px; }
    .reports-sheet-id { flex-direction: column; }
}
@media print {
    @page { margin: 12mm; }
    .app-shell .app-main > main.container { padding: 0; }
    .report-crumbs, .reports-csv-link, .no-print, .whatsapp-float, .demo-banner, .site-footer { display: none !important; }
    .reports-sheet-layout { display: block; }
    .reports-sheet { border: none; box-shadow: none; padding: 0; }
    .reports-blocks { grid-template-columns: 1fr 1fr; gap: 16px 22px; }
    .reports-block, .stat-tile, .chart-figure, .reports-meters li { page-break-inside: avoid; break-inside: avoid; }
    .reports-block.is-full { grid-column: 1 / -1; }
    .reports-tiles { grid-template-columns: repeat(5, 1fr) !important; gap: 10px; }
    .stat-tile { border: 1px solid #ccc; box-shadow: none; }
    .dash-meter-fill, .report-card::before { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .reports-print-foot { display: block; margin-top: 24px; padding-top: 10px; border-top: 1px solid #ccc; font-size: 0.72rem; color: #666; }
    .report-table { font-size: 0.78rem; }
    .report-table-scroll { overflow: visible; }
    .chart-figure { overflow: visible; }
    .chart-figure .chart { min-width: 0; }
}

/* =====================================================================
   MEMBER PROFILE DEPTH (2026-09-11): tags, "More about this member",
   households, member fields settings, "About you".
   ===================================================================== */
.member-tag { display: inline-block; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.3px; padding: 2px 8px; border-radius: 999px; color: #fff; background: var(--tag, #0096AE); margin: 2px 4px 0 0; white-space: nowrap; }
.member-tags { display: inline; }
.member-tag-picker { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.member-tag-option { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border); border-radius: 999px; padding: 4px 10px 4px 6px; font-size: 0.86rem; cursor: pointer; background: var(--card-bg); }
.member-tag-option input { width: auto; margin: 0; accent-color: var(--tag, #0096AE); }
.member-tag-option:has(input:checked) { background: var(--tag, #0096AE); color: #fff; border-color: var(--tag, #0096AE); }
.member-depth { margin-top: 24px; }
.member-depth-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px 28px; }
.member-depth-grid h3 { margin: 6px 0 4px; font-size: 1rem; color: var(--brand); }
.member-depth-grid label { margin-top: 10px; }
.member-depth-custom { grid-column: 1 / -1; }
.member-depth-grid-inner { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0 28px; }
.about-you-facts { margin-bottom: 12px; }
.fields-inline { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.fields-inline input[type="color"] { width: 38px; height: 34px; padding: 2px; border: 1px solid var(--border); border-radius: 6px; flex: 0 0 auto; }
.fields-inline input[type="text"] { flex: 1 1 160px; min-width: 0; }
.fields-actions { white-space: nowrap; }
.fields-actions .link-button[disabled] { opacity: 0.3; cursor: default; }
.households-add-row { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border); }
.households-add-row .row { display: flex; gap: 8px; align-items: center; }
.households-add-row select { flex: 1 1 auto; min-width: 0; }
.households-actions { white-space: nowrap; }
.households-actions .groups-inline-form { display: inline-block; margin-left: 6px; }
#about-you { margin-top: 22px; }

/* =====================================================================
   NOTES TIMELINE (includes/notes_panel.php, notes.php, 2026-09-11)
   ===================================================================== */
.notes-panel { margin-top: 24px; }
.notes-count { display: inline-block; font-size: 0.75rem; font-weight: 700; background: var(--bg); border: 1px solid var(--border); border-radius: 999px; padding: 1px 9px; vertical-align: middle; margin-left: 6px; color: var(--muted); }
.notes-add textarea { width: 100%; }
.notes-add-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.notes-add-row select, .notes-add-row input[type="date"] { width: auto; flex: 0 1 auto; margin: 0; }
.notes-timeline { list-style: none; margin: 18px 0 0; padding: 0 0 0 18px; border-left: 2px solid var(--border); }
.notes-item { position: relative; padding: 0 0 18px 18px; }
.notes-item::before { content: ""; position: absolute; left: -24px; top: 5px; width: 10px; height: 10px; border-radius: 50%; background: var(--teal); border: 2px solid var(--card-bg); box-shadow: 0 0 0 2px var(--border); }
.notes-item.is-call::before { background: #6b3fa0; }
.notes-item.is-visit::before { background: #2e7d32; }
.notes-item.is-meeting::before { background: #d19a00; }
.notes-item.is-pastoral::before { background: #c8102e; }
.notes-item.is-admin::before { background: #555e6d; }
.notes-item.is-pinned { background: rgba(209, 154, 0, 0.07); border-radius: 8px; margin-left: -8px; padding-left: 26px; padding-top: 8px; }
.notes-item.is-pinned::before { left: -16px; top: 13px; }
.notes-item-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: 0.82rem; color: var(--muted); margin-bottom: 4px; }
.notes-item-head time { font-weight: 700; color: var(--text); }
.notes-kind { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.7px; padding: 2px 8px; border-radius: 999px; background: rgba(0, 150, 174, 0.12); color: #007A8E; }
.notes-kind-call { background: rgba(107, 63, 160, 0.12); color: #5a2f8f; }
.notes-kind-visit { background: rgba(46, 125, 50, 0.12); color: #2e7d32; }
.notes-kind-meeting { background: rgba(209, 154, 0, 0.16); color: #8a6500; }
.notes-kind-pastoral { background: rgba(200, 16, 46, 0.1); color: #a30d25; }
.notes-kind-admin { background: rgba(85, 94, 109, 0.14); color: #444c5a; }
.notes-pin { color: #d19a00; }
.notes-actions { margin-left: auto; display: inline-flex; gap: 6px; }
.notes-actions form { display: inline; }
.notes-actions .link-button { font-size: 1rem; line-height: 1; }
.notes-body { white-space: normal; line-height: 1.5; max-width: 80ch; }
.notes-body mark { background: rgba(209, 154, 0, 0.35); padding: 0 2px; border-radius: 2px; }
.notes-empty { padding: 14px 0 0; }
.notes-search-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.notes-search-q { flex: 1 1 260px; min-width: 0; }
.notes-search-q input { width: 100%; }
.notes-search-row select, .notes-search-row input[type="date"] { width: auto; margin: 0; }
.notes-result-count { margin: 10px 0 0; }
.notes-subject-link { font-weight: 700; text-decoration: none; color: var(--brand); }
.notes-subject-type { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.7px; color: var(--muted); margin-right: 4px; }
@media (max-width: 600px) {
    .notes-timeline { padding-left: 12px; }
    .notes-item { padding-left: 12px; }
    .notes-item::before { left: -18px; }
}

/* --- Departments list on a phone (departments.php) --------------------
   Same treatment as the membership register above: below 760px the
   five-column table (name / description / translated / members / Manage)
   sat in .table-responsive at min-width 560px, so a 390px phone scrolled
   sideways and the Manage button was the part off-screen. Each row
   becomes a card: name, description, then a line with the translated
   badge and member count, then a full-width Manage button. The paged
   rows keep their hidden attribute working (display:block would
   otherwise override it). 2026-09-12. */
.dept-count-label { display: none; }
@media (max-width: 760px) {
    .table-responsive.departments-scroll { overflow-x: visible; }
    .table-responsive table.departments-table { min-width: 0; margin-top: 12px; }
    .departments-table,
    .departments-table tbody,
    .departments-table tr,
    .departments-table td { display: block; width: auto; min-width: 0; max-width: 100%; }
    .departments-table thead { display: none; }
    .departments-table tr[hidden] { display: none; }
    .departments-table tr {
        border: 1px solid var(--border);
        border-radius: var(--radius);
        padding: 12px 14px;
        margin-bottom: 9px;
        background: var(--card-bg);
        overflow: hidden;
    }
    .departments-table tr:last-child { margin-bottom: 0; }
    .departments-table td { border: 0; padding: 0; overflow-wrap: anywhere; }
    .departments-table td.dept-name { font-weight: 700; font-size: 1.02rem; color: var(--brand); }
    .departments-table td.dept-desc { font-size: 0.86rem; margin-top: 3px; }
    .departments-table .dept-desc-none { display: none; }
    .departments-table td.dept-translated,
    .departments-table td.dept-count { display: inline-block; font-size: 0.82rem; margin-top: 8px; margin-right: 12px; vertical-align: middle; }
    .departments-table td.dept-translated .badge { font-size: 0.66rem; padding: 2px 8px; white-space: nowrap; }
    .departments-table .dept-count-label { display: inline; color: var(--muted); }
    .departments-table td.dept-open { margin-top: 10px; }
    .departments-table td.dept-open .btn { display: block; width: 100%; text-align: center; box-sizing: border-box; }
}

/* --- Transactions grid, compact (accounting-transactions.php, 2026-09-12)
   Ten columns used to pin their own widths inline (130/120/24ch/150/170/
   110/90/100/100 + actions ≈ 1 300px), so beside the 236px sidebar the
   New / Reviewed grids and the capture rows scrolled sideways on any
   laptop narrower than ~1 550px and the amount + action columns were the
   part off-screen. Henk: "make the font smaller to fit all the
   information". Widths now live here as tx-c-* classes, type is a step
   smaller, and the description column takes whatever is left. */
.tx-grid-scroll { overflow-x: auto; }
.bank-grid-table.tx-grid { font-size: 0.76rem; table-layout: auto; }
.bank-grid-table.tx-grid th { padding: 4px 3px; font-size: 0.7rem; }
.bank-grid-table.tx-grid td { padding: 2px 3px; }
.bank-grid-table.tx-grid input[type="text"],
.bank-grid-table.tx-grid input[type="date"],
.bank-grid-table.tx-grid input[type="number"],
.bank-grid-table.tx-grid select { min-width: 0; padding: 2px 4px; font-size: 0.74rem; }
.bank-grid-table.tx-grid input[type="date"] { padding-right: 2px; }
.bank-grid-table.tx-grid .tx-c-date  { width: 118px; }
.bank-grid-table.tx-grid .tx-c-payee { width: 108px; }
.bank-grid-table.tx-grid .tx-c-desc  { width: auto; min-width: 120px; }
.bank-grid-table.tx-grid .tx-c-cat   { width: 132px; }
.bank-grid-table.tx-grid .tx-c-giver { width: 140px; }
.bank-grid-table.tx-grid .tx-c-ref   { width: 88px; }
.bank-grid-table.tx-grid .tx-c-vat   { width: 60px; }
.bank-grid-table.tx-grid .tx-c-amt   { width: 82px; text-align: right; white-space: nowrap; }
.bank-grid-table.tx-grid .tx-c-spent    { color: #900; }
.bank-grid-table.tx-grid .tx-c-received { color: #1a7f37; }
.bank-grid-table.tx-grid .tx-c-giver .text-muted { font-size: 0.68rem; }
.bank-grid-table.tx-grid .bank-grid-actions { gap: 2px; display: inline-flex; vertical-align: middle; flex-wrap: nowrap; }
.bank-grid-table.tx-grid .tx-split-btn { vertical-align: middle; margin-left: 2px; }
.bank-grid-table.tx-grid td:last-child { white-space: nowrap; }
.bank-grid-table.tx-grid td:last-child .btn { display: block; width: max-content; }
.bank-grid-table.tx-grid .btn.btn-small { padding: 2px 6px; font-size: 0.7rem; }
/* Roomy screens get the old type size back — the columns still fit. */
@media (min-width: 1700px) {
    .bank-grid-table.tx-grid { font-size: 0.85rem; }
    .bank-grid-table.tx-grid th { font-size: 0.78rem; }
    .bank-grid-table.tx-grid input[type="text"],
    .bank-grid-table.tx-grid input[type="date"],
    .bank-grid-table.tx-grid input[type="number"],
    .bank-grid-table.tx-grid select { font-size: 0.82rem; }
}

/* --- Payroll employee form (payroll-employee.php, 2026-09-12) ------------
   Number fields (salary, hourly rate, hours, overtime) were never in the
   global input rule above, so the Employment and pay section showed raw
   browser inputs beside styled ones. They are in it now; the rules here
   just keep the pay row tidy: the fixed-width pickers stay narrow, the
   short rows still line up at the bottom, and hints do not push the row. */
.payroll-emp-form .row { align-items: flex-start; }
.payroll-emp-form .row-col { min-width: 0; flex-basis: 150px; }
.payroll-emp-form input[type=number] { -moz-appearance: textfield; }
.payroll-emp-form .hint { line-height: 1.35; }
@media (max-width: 600px) {
    .payroll-emp-form .row-col { max-width: none !important; }
}

/* --- Payslips page: per-run calculation breakdown (payroll-runs.php,
   2026-09-12). A nested table under each finalised run showing how every
   employee's net pay was reached, so the figures can be checked before
   the bank file is paid. Newest run opens expanded; older ones toggle. */
.pr-calc-row > td { background: var(--bg); padding: 0 0 14px !important; }
.pr-calc { border-left: 3px solid var(--teal); margin: 0 0 0 10px; padding: 10px 12px 4px; }
.pr-calc-head { font-weight: 700; font-size: 0.9rem; color: var(--brand); margin-bottom: 4px; }
.pr-calc-table { font-size: 0.8rem; margin-bottom: 4px; }
.pr-calc-table th, .pr-calc-table td { padding: 5px 7px; }
.pr-calc-table thead th { font-size: 0.68rem; letter-spacing: 0.4px; }
.pr-calc-table tfoot th { border-top: 2px solid var(--border); font-size: 0.8rem; }
.pr-calc-table td .hint, .pr-calc-table th .hint { font-size: 0.72rem; }
.pr-calc-toggle[aria-expanded="true"] { background: var(--teal); color: #fff; border-color: var(--teal); }

/* --- In-app notice banner in the member app (member-header.php, 2026-09-14).
   Sits right under the nav, one per undismissed notice (max 3). Teal edge
   ties it to the company's notifications; Open + Dismiss stay tappable at
   phone width by wrapping under the text. */
.member-notice { display: flex; gap: 12px; align-items: flex-start; background: #e6f6f8; border: 1px solid rgba(0,150,174,0.35); border-left: 4px solid var(--teal); border-radius: var(--radius); padding: 12px 14px; margin-bottom: 14px; flex-wrap: wrap; }
.member-notice-icon { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; background: var(--teal); color: #fff; display: flex; align-items: center; justify-content: center; }
.member-notice-icon svg { width: 18px; height: 18px; }
.member-notice-text { flex: 1 1 200px; min-width: 0; }
.member-notice-text strong { display: block; color: var(--brand); font-size: 0.98rem; }
.member-notice-text p { margin: 3px 0 4px; font-size: 0.9rem; overflow-wrap: anywhere; }
.member-notice-when { font-size: 0.74rem; color: var(--muted); }
.member-notice-actions { display: flex; gap: 6px; flex: 0 0 auto; margin: 0; align-self: center; }
@media (max-width: 480px) {
    .member-notice-actions { flex-basis: 100%; justify-content: flex-end; }
}
.member-push-prompt { background: #fff8e6; border-color: rgba(212,140,0,0.35); border-left-color: var(--accent, #f5a623); }
.member-push-prompt .member-notice-icon { background: var(--accent, #f5a623); color: #1a2b4a; }

.groups-visitor-boxes { display: grid; gap: 6px; }
.groups-visitor-boxes input { margin: 0; }
.groups-visitor { display: grid; grid-template-columns: 1.3fr 1fr 1.3fr; gap: 6px; }
.groups-visitor input { margin: 0; }
.groups-visitor-list { margin: 0 0 10px 18px; padding: 0; font-size: 0.9rem; }
@media (max-width: 600px) { .groups-visitor { grid-template-columns: 1fr; } }
.groups-report-switch { margin: 0 0 14px; }
.groups-report-switch .tab-button { font-size: 0.85rem; padding: 5px 12px; }
/* Absent Member Check-in tab (2026-09-14): compact capture grid above a full-width list. */
.groups-fu-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 4px 14px; align-items: start; }
.groups-fu-form label { margin-top: 6px; }
.groups-fu-form select, .groups-fu-form input, .groups-fu-form textarea { margin-bottom: 0; }
.groups-fu-form textarea { min-height: 42px; }
.groups-fu-submit { grid-column: 1 / -1; margin-top: 10px; }
.groups-fu-submit .btn { margin-top: 0; }
input[type=time] { height: 41px; line-height: 1.2; -webkit-appearance: none; appearance: none; }

/* =====================================================================
   SUNDAY CHECK-IN (2026-09-15) — checkin.php door screen, register and
   member-checkin.php. Built for a tablet or phone in an usher's hand:
   48px+ touch targets, one column on phones, no hover-only affordances.
   ===================================================================== */
.checkin-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 24px; margin-bottom: 16px; }
.checkin-head .subtitle { margin-bottom: 0; }
.checkin-tabs { margin-bottom: 0; }
.checkin-tabs .tab-button { text-decoration: none; }
.checkin-door .card { margin: 0 0 14px; }
.checkin-service { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 14px 24px; }
.checkin-service-fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; flex: 1 1 420px; }
.checkin-service-fields label { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; font-weight: 600; color: var(--muted); margin: 0; flex: 1 1 150px; }
.checkin-service-fields input { margin: 0; height: 44px; }
.checkin-service-fields .btn { height: 44px; margin: 0; white-space: nowrap; }
.checkin-count { display: flex; align-items: center; gap: 12px; min-width: 190px; }
.checkin-count-num { font-size: 2.8rem; font-weight: 800; line-height: 1; color: var(--brand); font-variant-numeric: tabular-nums; }
.checkin-count-label { font-weight: 700; color: var(--brand); line-height: 1.2; }
.checkin-count-label small { font-weight: 400; color: var(--muted); }
.checkin-search-row { display: flex; gap: 8px; align-items: stretch; }
.checkin-search { flex: 1 1 auto; height: 56px; font-size: 1.25rem; padding: 0 16px; margin: 0; border-radius: 12px; }
.checkin-clear { height: 56px; width: 56px; padding: 0; margin: 0; font-size: 1.6rem; line-height: 1; flex: 0 0 56px; }
.checkin-results, .checkin-family-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; margin-top: 12px; }
.checkin-none { grid-column: 1 / -1; margin: 10px 0 0; }
.checkin-person {
    display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; column-gap: 12px; align-items: center; text-align: left;
    min-height: 64px; padding: 8px 12px; border: 2px solid var(--border, #d9e0ea); border-radius: 12px; background: #fff; color: var(--text);
    font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background .15s, border-color .15s, transform .1s;
}
.checkin-person .checkin-photo { grid-row: 1 / span 2; }
.checkin-person-name { font-weight: 700; font-size: 1.02rem; line-height: 1.2; }
.checkin-person-name .badge { vertical-align: middle; margin-left: 4px; }
.checkin-state { font-size: 0.78rem; color: var(--muted); }
.checkin-person:active { transform: scale(0.98); }
.checkin-person.is-in { background: var(--success-bg); border-color: var(--success-text); }
.checkin-person.is-in .checkin-state { color: var(--success-text); font-weight: 700; }
.checkin-person.is-in .checkin-state::before { content: '✓ '; }
.checkin-person.is-pending { border-style: dashed; }
.checkin-person.is-busy { opacity: 0.6; pointer-events: none; }
.checkin-person.just-in { animation: checkin-pop .5s ease; }
@keyframes checkin-pop { 0% { transform: scale(1); } 40% { transform: scale(1.04); } 100% { transform: scale(1); } }
.checkin-family { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--border, #d9e0ea); }
.checkin-family-title { margin: 0; font-weight: 700; color: var(--brand); }
.checkin-family-row { margin-top: 8px; }
.checkin-visitor { margin-top: 14px; }
.checkin-visitor summary { display: inline-flex; list-style: none; cursor: pointer; }
.checkin-visitor summary::-webkit-details-marker { display: none; }
.checkin-visitor-form { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.checkin-visitor-form input { flex: 1 1 220px; margin: 0; height: 48px; }
.checkin-visitor-form .btn { height: 48px; margin: 0; }
.checkin-letters { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.checkin-letter { min-width: 40px; height: 40px; padding: 0 10px; border: 1px solid var(--border, #d9e0ea); border-radius: 999px; background: #fff; color: var(--brand); font: inherit; font-weight: 700; cursor: pointer; }
.checkin-letter.active { background: var(--brand); color: #fff; border-color: var(--brand); }
.checkin-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.checkin-tile { grid-template-columns: 1fr; grid-template-rows: auto auto auto; justify-items: center; text-align: center; min-height: 128px; padding: 12px 8px 10px; }
.checkin-tile .checkin-photo { grid-row: auto; }
.checkin-tile .checkin-person-name { font-size: 0.92rem; margin-top: 6px; }
.checkin-list-card summary { cursor: pointer; font-weight: 700; color: var(--brand); }
.checkin-list-card summary .badge { background: var(--bg); color: var(--brand); margin-left: 6px; }
.checkin-list { margin-top: 10px; }
.checkin-list-row { display: grid; grid-template-columns: auto 1fr auto auto; gap: 10px; align-items: center; padding: 8px 0; border-top: 1px solid var(--border, #e6ebf2); }
.checkin-list-row:first-child { border-top: 0; }
.checkin-list-name { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.checkin-list-meta { font-size: 0.8rem; color: var(--muted); white-space: nowrap; }
.checkin-undo { font-size: 0.82rem; }
.checkin-offline { margin-bottom: 14px; }
.checkin-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.checkin-actions .btn { margin: 0; }
.checkin-absent-form { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.checkin-absent-form label, .checkin-absent-form select { margin: 0; }
.checkin-absent-form .hint { flex-basis: 100%; margin: 0; }
.table-responsive table.checkin-table { min-width: 0; }
.member-checkin { max-width: 520px; margin: 0 auto; text-align: center; }
.member-checkin-service { font-size: 1.1rem; }
.member-checkin-yes { height: 60px; font-size: 1.15rem; margin: 14px 0 8px; }
@media (max-width: 600px) {
    .checkin-head { align-items: flex-start; }
    .checkin-count { width: 100%; justify-content: center; }
    .checkin-results, .checkin-family-row { grid-template-columns: 1fr; }
    .checkin-tiles { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
    .checkin-tile { min-height: 112px; }
    .checkin-tile .member-photo-md { width: 44px; height: 44px; }
    .checkin-list-row { grid-template-columns: auto 1fr auto; }
    .checkin-list-meta { grid-column: 2; font-size: 0.74rem; white-space: normal; }
    .checkin-undo { grid-column: 3; grid-row: 1 / span 2; }
}

/* AUDIT TRAIL (2026-09-15) — audit-trail.php */
.audit-filters { margin-bottom: 14px; }
.audit-filter-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px 14px; }
.audit-filter-row > div { margin: 0; }
.audit-filter-row label { font-size: 0.8rem; font-weight: 600; color: var(--muted); }
.audit-filter-row input, .audit-filter-row select { margin-bottom: 0; }
.audit-filter-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px; }
.audit-filter-actions .btn { margin: 0; }
.audit-filter-actions .hint { margin: 0 0 0 auto; }
.audit-table { font-size: 0.86rem; }
.audit-table td { vertical-align: top; }
.audit-details { word-break: break-word; max-width: 420px; }
.audit-pager { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 14px; }
.audit-pager .btn { margin: 0; }
@media (max-width: 600px) {
    .table-responsive table.audit-table { min-width: 0; }
    .audit-table thead { display: none; }
    .audit-table tr { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 10px; padding: 10px 0; border-top: 1px solid var(--border, #e6ebf2); }
    .audit-table td { padding: 0; border: 0; }
    .audit-table .audit-details { grid-column: 1 / -1; }
    .audit-table .audit-ip { grid-column: 1 / -1; font-size: 0.74rem; }
    .audit-table .audit-when br { display: none; }
    .audit-table .audit-when small::before { content: ' '; }
}

/* DEPARTMENT DUTIES (2026-09-16) — department.php + member-departments.php */
.dept-duties-card summary { cursor: pointer; font-weight: 700; color: var(--brand); font-size: 1.05rem; }
.dept-duties { margin: 10px 0 0; padding-left: 22px; columns: 2; column-gap: 32px; }
.dept-duties li { margin: 0 0 6px; break-inside: avoid; font-size: 0.92rem; }
.dept-duties-details { margin-top: 8px; font-size: 0.88rem; }
.dept-duties-details summary { cursor: pointer; color: var(--teal-ink); font-weight: 600; }
.dept-duties-details .dept-duties { columns: 1; padding-left: 18px; }
@media (max-width: 700px) { .dept-duties { columns: 1; } }

/* CAMPUSES (2026-09-16) — campuses.php */
.campus-table td { vertical-align: top; }
.campus-inactive td { color: var(--muted); }
.campus-actions form { margin: 0; }
.campus-actions .btn, .campus-actions .link-button { margin: 2px 0; }
@media (max-width: 700px) {
    .table-responsive table.campus-table { min-width: 0; }
    .campus-table thead { display: none; }
    .campus-table tr { display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; padding: 10px 0; border-top: 1px solid var(--border, #e6ebf2); }
    .campus-table td { padding: 0; border: 0; text-align: left; }
    .campus-table td.campus-actions { grid-column: 1 / -1; white-space: normal; }
}

/* =====================================================================
   PRINTABLE MEMBER LIST (2026-09-17): members-print.php — cards (photo +
   every field) or a compact table, with the register's filters in the
   250px rail. Reuses the reports sheet chrome; only the card grid and
   its print rules are new.
   ===================================================================== */
.members-print-form input[type="search"], .members-print-form select { width: 100%; }
.members-print-form label { display: block; font-size: 0.8rem; margin-top: 10px; }
.members-print-form .members-print-check { display: flex; align-items: center; gap: 8px; font-size: 0.88rem; margin-top: 10px; cursor: pointer; }
.members-print-form .members-print-check input { width: auto; margin: 0; }
.members-print-check-warn { color: var(--warn-text, #8a5300); }
.members-print-sensitive-hint { font-size: 0.74rem; margin-top: 2px; }
.members-print-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 18px; }
.members-print-card { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; min-width: 0; background: var(--card-bg); }
.members-print-card-head { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 10px; }
.members-print-card-head .member-photo-lg { width: 84px; height: 84px; border-radius: 12px; }
.members-print-card-head .member-photo-lg.member-photo-initials { font-size: 1.8rem; }
.members-print-card-title { min-width: 0; }
.members-print-card-title h3 { margin: 2px 0 6px; font-size: 1.08rem; color: var(--brand); overflow-wrap: anywhere; }
.members-print-card-sub { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 4px; }
.members-print-campus { font-size: 0.76rem; font-weight: 700; color: var(--teal-ink, #007a8c); }
.members-print-fields { display: grid; grid-template-columns: max-content 1fr; gap: 3px 12px; margin: 0; font-size: 0.84rem; }
.members-print-fields dt { color: var(--muted); font-weight: 600; white-space: nowrap; }
.members-print-fields dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.members-print-fields dd small { color: var(--muted); }
.members-print-table { font-size: 0.84rem; }
.members-print-table td, .members-print-table th { vertical-align: top; }
.members-print-table .mp-col-address { min-width: 160px; }
.mp-mono { font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 900px) {
    .members-print-cards { grid-template-columns: 1fr; }
}
@media print {
    .members-print-sheet .report-sheet-head { margin-bottom: 8px; }
    .members-print-cards { grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
    .members-print-card { page-break-inside: avoid; break-inside: avoid; padding: 8px 10px; border-color: #bbb; }
    .members-print-card-head { margin-bottom: 6px; gap: 10px; }
    .members-print-card-head .member-photo-lg { width: 64px; height: 64px; }
    .members-print-card-title h3 { font-size: 0.98rem; margin: 0 0 4px; }
    .members-print-fields { font-size: 0.7rem; line-height: 1.3; gap: 1px 8px; }
    .members-print-table { font-size: 0.72rem; }
    .members-print-table td, .members-print-table th { padding: 4px 6px; }
    .members-print-table tr { page-break-inside: avoid; break-inside: avoid; }
    .member-photo, .member-photo-initials, .member-tag, .badge { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .members-print-sheet .report-sheet-net { display: none; }
}

/* DISCOUNT CODES (2026-09-17): discount-codes.php + the code box on register-company.php */
.discount-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: 1px; }
.discount-input { text-transform: uppercase; letter-spacing: 1.5px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; max-width: 320px; }
.discount-table td { vertical-align: top; }
.discount-code-row { display: flex; gap: 8px; align-items: center; }
.discount-code-row input { flex: 1 1 auto; max-width: none; }
.discount-code-row .btn { margin: 0; white-space: nowrap; }
.discount-view { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }
.discount-view code { background: var(--bg); padding: 2px 6px; border-radius: 4px; }

/* ==========================================================================
   VISITORS (visitors.php, visitor-card.php) — 2026-09-21
   One table per tab; on a phone the secondary columns fold into the name
   cell so nothing scrolls sideways (project UI rule, 2026-09-11).
   ========================================================================== */
.visitors-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.visitors-badge { font-size: 0.66rem; padding: 2px 8px; white-space: nowrap; vertical-align: middle; }
.visitors-badge-open { background: rgba(0, 164, 189, 0.14); color: var(--teal-ink); }
.visitors-contact-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 16px; }
.visitors-contact-row .btn { margin-top: 0; }
.visitors-message { margin: 0 0 16px; }
.visitors-filter { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 0 0 12px; }
.visitors-filter input[type="search"] { flex: 1 1 220px; min-width: 0; margin: 0; }
.visitors-filter select { flex: 0 1 190px; width: auto; min-width: 0; margin: 0; }
.visitors-filter .btn { margin-top: 0; }
.table-responsive table.visitors-table, .table-responsive table.visitors-visits-table { min-width: 0; }
.visitors-table td { font-size: 0.88rem; }
.visitors-cell-name a { text-decoration: none; }
.visitors-fold { display: none; }
.visitors-pager { display: flex; gap: 10px; align-items: center; margin: 12px 0 0; }
.visitors-pager .btn { margin-top: 0; }
.visitors-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
.visitors-grid > div { min-width: 0; }
.visitors-form h3 { margin: 22px 0 4px; font-size: 1rem; }
.visitors-steps { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 16px; padding: 0; counter-reset: vstep; }
.visitors-steps li { counter-increment: vstep; font-size: 0.78rem; font-weight: 700; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); background: #fff; white-space: nowrap; }
.visitors-steps li::before { content: counter(vstep) ". "; }
.visitors-steps li.is-done { background: var(--success-bg); color: var(--success-text); border-color: transparent; }
.visitors-steps li.is-current { background: var(--brand-dark); color: #fff; border-color: var(--brand-dark); }
.visitors-inline-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 10px; }
.visitors-inline-form input { margin: 0; width: auto; flex: 1 1 150px; min-width: 0; }
.visitors-inline-form input[type="date"] { flex: 0 1 160px; }
.visitors-inline-form .btn { margin-top: 0; }
.visitors-accept { padding-bottom: 14px; margin-bottom: 4px; border-bottom: 1px solid var(--border); }
.visitors-accept .btn { margin-top: 0; }
.visitors-break { word-break: break-all; }
.visitor-card-page .card { max-width: 560px; margin-left: auto; margin-right: auto; }
.checkin-visitor-form input[type="tel"] { min-width: 0; }
@media (max-width: 760px) {
    .visitors-col-source, .visitors-col-visits, .visitors-col-last, .visitors-col-assigned { display: none; }
    .visitors-fold { display: block; margin-top: 2px; }
    .visitors-table td, .visitors-table th { padding-left: 8px; padding-right: 8px; }
    .visitors-cell-next { white-space: nowrap; font-size: 0.8rem; }
    .visitors-grid { grid-template-columns: minmax(0, 1fr); }
    .visitors-filter select { flex: 1 1 140px; }
}
.visitors-datetime { display: flex; gap: 8px; }
.visitors-datetime input { min-width: 0; margin: 0; }
.visitors-datetime input[type="time"] { flex: 0 0 120px; }

/* ==========================================================================
   COMMUNICATION (communication.php, platform-sms-credits.php) — 2026-09-21
   ========================================================================== */
.comm-ico { width: 20px; height: 20px; vertical-align: -4px; flex: 0 0 auto; }
.comm-balance { font-weight: 700; font-size: 0.85rem; color: var(--brand-dark); background: #fff; border: 1px solid var(--border); border-radius: 999px; padding: 7px 14px; white-space: nowrap; }
.comm-balance-big { font-size: 2.2rem; font-weight: 700; color: var(--brand-dark); margin: 0 0 4px; line-height: 1.1; }
.comm-channels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 8px 0 4px; }
.comm-channel { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: #fff; border: 2px solid var(--border); border-radius: 12px; text-decoration: none; color: var(--brand-dark); min-width: 0; }
.comm-channel .comm-ico { width: 26px; height: 26px; }
.comm-channel span { display: flex; flex-direction: column; min-width: 0; }
.comm-channel small { color: var(--muted); font-size: 0.78rem; }
.comm-channel.active { border-color: var(--teal-ink); background: rgba(0, 164, 189, 0.06); }
.comm-to { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-start; }
.comm-to > select, .comm-to > div { flex: 1 1 220px; min-width: 0; margin: 0; }
.comm-to select, .comm-to input, .comm-to textarea { margin: 0; }
.comm-member-pick { position: relative; }
.comm-member-pick input { margin: 0; }
.comm-member-results { position: absolute; z-index: 20; left: 0; right: 0; top: 100%; background: #fff; border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(0, 19, 59, 0.12); padding: 4px; max-height: 260px; overflow: auto; }
.comm-member-results button { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 9px 10px; border-radius: 8px; cursor: pointer; font: inherit; min-height: 0; }
.comm-member-results button:hover, .comm-member-results button:focus { background: rgba(0, 164, 189, 0.1); }
.comm-member-results small { color: var(--muted); }
.comm-tokens { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; font-size: 0.82rem; color: var(--muted); margin: 8px 0 0; }
.comm-token { font: inherit; font-size: 0.78rem; font-weight: 700; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--border); background: #fff; color: var(--teal-ink); cursor: pointer; min-height: 0; }
.comm-bubble { white-space: normal; overflow-wrap: anywhere; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--border); background: #f6f8fb; margin: 8px 0; max-width: 520px; font-size: 0.93rem; }
.comm-bubble-whatsapp { background: #e7f8e9; border-color: #c9ebcd; border-top-right-radius: 3px; }
.comm-bubble-in { background: #fff; border-top-left-radius: 3px; }
.comm-bubble mark { background: #fff3c4; padding: 0 3px; border-radius: 3px; }
.comm-vars { display: grid; gap: 8px; margin-top: 8px; }
.comm-var { display: grid; grid-template-columns: minmax(0, 190px) minmax(0, 1fr) minmax(0, 1fr); gap: 8px; align-items: center; }
.comm-var label, .comm-var select, .comm-var input { margin: 0; }
.comm-preview-stats { margin: 12px 0; }
.comm-confirm { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.comm-confirm .btn { margin-top: 0; }
.comm-first { list-style: none; margin: 0 0 12px; padding: 0; font-size: 0.9rem; }
.comm-first li { padding: 7px 0; border-bottom: 1px solid var(--border); overflow-wrap: anywhere; }
.comm-first .link-button { background: none; border: 0; color: var(--teal-ink); cursor: pointer; padding: 0 0 0 6px; font-size: 0.8rem; min-height: 0; }
.table-responsive table.comm-table { min-width: 0; }
.comm-table td { font-size: 0.88rem; overflow-wrap: anywhere; }
.comm-row-link { text-decoration: none; }
.comm-badge { font-size: 0.66rem; padding: 2px 8px; white-space: nowrap; }
.comm-badge-sent { background: rgba(0, 164, 189, 0.14); color: var(--teal-ink); }
.comm-fold { display: none; }
.comm-error { font-weight: 400; }
.comm-unread td { background: rgba(0, 164, 189, 0.06); }
.comm-plus { color: var(--success-text); font-weight: 700; }
.comm-ledger td { font-size: 0.85rem; padding: 7px 6px; }
.comm-progress { margin-top: 14px; }
.comm-progress .btn { margin-top: 0; }
.comm-progress-bar { height: 10px; border-radius: 999px; background: #e3e8ef; overflow: hidden; }
.comm-progress-bar span { display: block; height: 100%; background: var(--teal-ink); transition: width 0.3s; }
.comm-thread { display: flex; flex-direction: column; gap: 10px; max-height: 60vh; overflow: auto; padding: 8px 2px; margin-bottom: 12px; }
.comm-msg { display: flex; flex-direction: column; max-width: 85%; }
.comm-msg .comm-bubble { margin: 0 0 2px; }
.comm-msg-out { align-self: flex-end; align-items: flex-end; }
.comm-reply textarea { margin: 0 0 8px; }
.comm-reply .btn { margin-top: 0; }
.comm-inline-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 12px 0; }
.comm-inline-actions .btn { margin-top: 0; }
.comm-inline-actions .link-button { background: none; border: 0; cursor: pointer; text-decoration: underline; font-size: 0.85rem; min-height: 0; }
.comm-steps { margin-top: 18px; font-size: 0.9rem; }
.comm-steps summary { cursor: pointer; font-weight: 700; color: var(--teal-ink); }
.comm-steps li { margin: 8px 0; overflow-wrap: anywhere; }
@media (max-width: 760px) {
    .comm-channels { grid-template-columns: minmax(0, 1fr); gap: 8px; }
    .comm-channel { padding: 10px 12px; }
    .comm-col-hide { display: none; }
    .comm-fold { display: block; margin-top: 2px; }
    .comm-var { grid-template-columns: minmax(0, 1fr); gap: 4px; }
    .comm-table td, .comm-table th { padding-left: 8px; padding-right: 8px; }
    .comm-msg { max-width: 94%; }
}

/* Help hub + WhatsApp set-up guide (help.php, help-whatsapp.php) 2026-09-21 */
.table-responsive table.help-table, .help-table { min-width: 0; }
.help-need { margin: 0 0 8px; padding-left: 20px; }
.help-need li { margin: 8px 0; }
.help-video video { width: 100%; max-width: 360px; height: auto; display: block; margin: 0 auto; border-radius: 12px; background: #00133B; }
.install-step-text { overflow-wrap: anywhere; }

/* ==========================================================================
   HOME CELLS > GEOGRAPHICAL AREAS (groups-map.php) — 2026-09-21
   ========================================================================== */
.geo-map { height: 560px; border-radius: 12px; border: 1px solid var(--border); background: #e8eef5; z-index: 0; }
.geo-map.is-placing { cursor: crosshair; outline: 3px solid var(--accent); }
.geo-map.is-placing .leaflet-interactive { cursor: crosshair; }
.geo-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 320px); }
.geo-layout > * { min-width: 0; }
.geo-campus select { margin: 0; width: auto; }
.geo-locate { margin: 0 0 16px; }
.geo-locate .btn { margin-top: 8px; }
.geo-locate .comm-progress-bar { margin: 10px 0 6px; }
.geo-plan-actions { display: flex; gap: 8px; }
.geo-plan-actions .btn { margin-top: 0; }
.geo-divide label { display: block; margin: 10px 0 4px; font-weight: 600; }
.geo-divide input[type="radio"], .geo-divide input[type="checkbox"], .geo-inline-check input { width: auto; min-height: 0; margin: 0 6px 0 0; vertical-align: middle; }
.geo-divide input[type="number"] { margin: 0; }
.geo-current { font-weight: 700; }
.geo-swatch { display: inline-block; width: 14px; height: 14px; border-radius: 4px; margin-right: 8px; vertical-align: -2px; border: 1px solid rgba(0, 0, 0, 0.15); }
.geo-area-link { text-decoration: none; }
.geo-area-open > td { background: #f8fafc; padding: 14px; }
.geo-area-tools { display: flex; gap: 10px 24px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.geo-area-tools .visitors-inline-form { margin-top: 0; }
.geo-area-tools select { width: auto; margin: 0; flex: 0 1 200px; }
.geo-inline-check { font-size: 0.85rem; white-space: normal; margin: 0; font-weight: 400; }
.geo-move select { margin: 0; width: auto; max-width: 150px; padding: 6px 8px; font-size: 0.82rem; min-height: 0; }
.geo-members td { background: transparent; }
@media (max-width: 1000px) { .geo-layout { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 760px) {
    .geo-map { height: 380px; }
    .geo-area-open > td { padding: 10px 6px; }
    .geo-move select { max-width: 110px; }
}

/* MEMBERS > HOME ADDRESS WITH UNIT (2026-09-23) — the unit / flat / complex
   field sits beside the street address on wide screens and stacks on phones. */
.address-row .address-unit-col { flex: 1 1 200px; max-width: 260px; }
.address-row .address-street-col { flex: 3 1 260px; }
@media (max-width: 600px) { .address-row .address-unit-col { max-width: none; } }

/* Home page — "New in I-Transact" (index.php, 2026-09-24). Four themed cards,
   each a short titled list; reuses .feature-icon-grid for the columns. */
.home-new-grid { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); align-items: start; }
.home-new-grid .card.home-new-card { margin: 0; }
.home-new-card h3 { margin-bottom: 4px; }
.home-new-list { list-style: none; margin: 8px 0 0; padding: 0; }
.home-new-list li { padding: 10px 0; border-top: 1px solid var(--border); }
.home-new-list li:first-child { border-top: 0; padding-top: 4px; }
.home-new-list strong { display: block; color: var(--brand-dark); font-size: 0.92rem; margin-bottom: 2px; }
.home-new-list span { display: block; color: var(--muted); font-size: 0.85rem; line-height: 1.45; }

/* =====================================================================
   SUPER USER (2026-09-25) — public "Super user" link top right of the
   logged-out header, the top-bar button, and platform-companies.php.
   ===================================================================== */
.site-header nav a.nav-super {
    display: inline-flex; align-items: center; gap: 6px; vertical-align: middle;
    padding: 5px 11px; border: 1px solid rgba(251, 251, 251, 0.4); border-radius: 999px;
    font-size: 0.84rem; font-weight: 600; opacity: 0.95;
}
.site-header nav a.nav-super svg { width: 15px; height: 15px; }
.site-header nav a.nav-super:hover, .site-header nav a.nav-super.active { text-decoration: none; border-color: var(--teal); background: rgba(0, 164, 189, 0.18); }
.app-super-btn { border-color: var(--border); color: var(--brand-dark); }
.app-super-btn.is-current { background: rgba(0, 164, 189, 0.12); border-color: var(--teal); }
@media (max-width: 600px) { .app-super-btn span { display: none; } }

.super-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; justify-content: space-between; margin-bottom: 14px; }
.super-filter .tab-buttons { margin-bottom: 0; }
.super-filter .tab-button { text-decoration: none; }
.super-search { display: flex; gap: 6px; align-items: center; }
.super-search input[type="search"] { margin: 0; width: 240px; max-width: 100%; }
.super-search .btn { margin: 0; }
.table-responsive table.super-table { min-width: 860px; }
.super-table td { vertical-align: top; }
.super-table .num { text-align: right; white-space: nowrap; }
.super-table .super-open { white-space: nowrap; }
.super-table tr.is-selected td { background: rgba(0, 164, 189, 0.08); }
.super-table .super-was { color: var(--muted); text-decoration: line-through; font-size: 0.82rem; margin-right: 4px; }
.super-tag { display: inline-block; font-size: 0.7rem; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: rgba(0, 164, 189, 0.14); color: var(--teal-ink); white-space: nowrap; }
.super-tag-code { background: var(--warn-bg); color: var(--warn-text); }
.super-detail { scroll-margin-top: 70px; }
.super-detail dl { display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin: 0 0 14px; font-size: 0.9rem; }
.super-detail dt { color: var(--muted); }
.super-detail dd { margin: 0; overflow-wrap: anywhere; }
.super-price { font-size: 1.9rem; font-weight: 700; color: var(--brand-dark); line-height: 1.1; }
.super-price small { font-size: 0.85rem; color: var(--muted); font-weight: 400; }
.super-preview { margin: 10px 0 0; padding: 10px 12px; border-radius: 8px; background: var(--bg); font-size: 0.9rem; }
.super-preview strong { color: var(--brand-dark); }
.super-table .badge { white-space: nowrap; }
@media (max-width: 760px) {
    .table-responsive table.super-table { min-width: 520px; }
    .super-table .super-col-opt { display: none; }
}
@media (max-width: 600px) {
    .super-search { width: 100%; }
    .super-search input[type="search"] { flex: 1 1 auto; width: auto; min-width: 0; }
}
/* Super user e-mail to companies (2026-09-25) */
.super-bulk { margin: 0 0 14px; }
.super-bulk > summary { list-style: none; display: inline-flex; cursor: pointer; }
.super-bulk > summary::-webkit-details-marker { display: none; }
.super-bulk-body { margin-top: 12px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); max-width: 720px; }
.super-mail-form textarea { width: 100%; }
.super-mail-to { border: 0; padding: 0; margin: 6px 0 0; }
.super-mail-to .checkbox-line { margin: 6px 0; font-weight: 400; }
.super-mail-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.super-mail-actions .btn { margin: 0; }

/* =====================================================================
   RECONCILE BANKS (2026-09-26) — line filter + a print layout that fits
   every column on A4 portrait. Henk: "Fix layout and design of bank
   statement print out. Make font smaller to fit all the information."
   ===================================================================== */
.reconcile-print-meta { display: none; }
.reconcile-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 12px; border-bottom: 1px solid var(--border); background: var(--bg); font-size: 0.85rem; }
.reconcile-filter-title { color: var(--brand-dark); }
.reconcile-filter label { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-weight: 600; color: var(--muted); }
.reconcile-filter input, .reconcile-filter select { margin: 0; width: auto; padding: 5px 8px; font-size: 0.85rem; min-height: 0; }
.reconcile-filter input[type="search"] { width: 230px; max-width: 100%; }
.reconcile-filter .btn { margin: 0; }
.reconcile-filter-count { color: var(--muted); font-weight: 600; }
.reconcile-table tr.is-filtered-out { display: none !important; }
@media (max-width: 600px) { .reconcile-filter input[type="search"] { width: 100%; } }

@media print {
    @page { size: A4 portrait; margin: 10mm 9mm 12mm; }
    html, body { font-size: 9pt; }
    .app-shell { display: block !important; }
    .app-main { margin: 0 !important; width: auto !important; }
    .app-main > main.container, .container, .container.wide { max-width: none !important; padding: 0 !important; margin: 0 !important; }

    /* Title block */
    .accounting-nav, .reconcile-history, .reconcile-filter, .reconcile-field-check { display: none !important; }
    main h1 { font-size: 14pt; margin: 0 0 1mm; }
    .reconcile-print-meta { display: block; margin: 0 0 3mm; font-size: 8pt; color: #444; }

    /* Account / period / balances: one compact band, two columns */
    .reconcile-header.card { display: grid !important; grid-template-columns: 1fr 1fr; gap: 0 8mm; padding: 2mm 0 !important; margin: 0 0 3mm !important; border-top: 1px solid #000 !important; border-bottom: 1px solid #000 !important; border-radius: 0; }
    .reconcile-header-col { flex: none; }
    .reconcile-field { flex-direction: row !important; align-items: center !important; gap: 3mm !important; margin: 0 0 1mm !important; }
    .reconcile-field > label { flex: 0 0 34mm !important; text-align: left !important; font-size: 8pt; font-weight: 600; }
    .reconcile-field select, .reconcile-field input[type="text"], .reconcile-field input[type="date"], .reconcile-readonly {
        font-size: 8.5pt !important; padding: 0 !important; min-height: 0 !important; height: auto !important; line-height: 1.3; }

    /* The grid: every column on the page, small type, text wraps */
    .reconcile-grid-card { overflow: visible !important; padding: 0 !important; }
    .reconcile-grid-scroll { max-height: none !important; overflow: visible !important; }
    .reconcile-table { table-layout: fixed; width: 100% !important; font-size: 7pt !important; line-height: 1.25; }
    .reconcile-table thead { display: table-header-group; } /* repeat on every page */
    .reconcile-table thead th { font-size: 6.5pt; padding: 1.2mm 1mm !important; text-transform: uppercase; letter-spacing: 0; white-space: normal; }
    .reconcile-table td { padding: 0.7mm 1mm !important; vertical-align: top !important; border-bottom: 0.5px solid #bbb !important; overflow-wrap: anywhere; }
    .reconcile-table .col-doc { display: none; }
    .reconcile-table th:nth-child(2), .reconcile-table td:nth-child(2) { width: 14%; }  /* reference */
    .reconcile-table th:nth-child(3), .reconcile-table td:nth-child(3) { width: 9%; }   /* date */
    .reconcile-table th:nth-child(4), .reconcile-table td:nth-child(4) { width: 15%; }  /* selection */
    .reconcile-table th:nth-child(5), .reconcile-table td:nth-child(5) { width: 12.5%; }  /* document type */
    .reconcile-table th:nth-child(6), .reconcile-table td:nth-child(6) { width: 5%; }   /* reconciled */
    .reconcile-table th:nth-child(7), .reconcile-table td:nth-child(7) { width: 11%; }  /* total */
    .reconcile-table th:nth-child(8), .reconcile-table td:nth-child(8) { width: 21.5%; }  /* description */
    .reconcile-table th:nth-child(9), .reconcile-table td:nth-child(9) { width: 12%; }  /* cust/supp ref */
    .reconcile-table th.col-tick { font-size: 0; }                /* "Reconciled" → a ✓ header, saves a column's width */
    .reconcile-table th.col-tick::after { content: "\2713"; font-size: 8pt; }
    .reconcile-table td.col-tick::after { font-size: 8pt !important; }
    .reconcile-nowrap { white-space: normal !important; }
    .reconcile-table td:nth-child(3), .reconcile-table .col-amount { white-space: nowrap !important; }
    .reconcile-truncate { max-width: none !important; white-space: normal !important; overflow: visible !important; text-overflow: clip !important; }
    .reconcile-table tr.reconcile-child-row > td:nth-child(2) { padding-left: 3mm !important; }
    .reconcile-table .col-amount { font-weight: 600; }
    .reconcile-table .col-amount.is-negative { color: #b00020 !important; }

    /* Totals: a tight box on the right, kept with the table's end */
    .reconcile-footer { display: block !important; margin-top: 3mm !important; break-inside: avoid; }
    .reconcile-totals { min-width: 0 !important; width: 80mm; margin-left: auto !important; font-size: 8pt; }
    .reconcile-totals > div { margin: 0 0 1mm !important; gap: 3mm !important; }
    .reconcile-totals dt { font-size: 8pt !important; }
    .reconcile-totals output { font-size: 8.5pt !important; padding: 0.8mm 2mm !important; min-width: 30mm; }
}

/* =====================================================================
   CAPTURE GRID — "Add a transaction" (2026-09-26 redesign). Henk:
   "banking import screen looks very untidy". Scoped to .tx-add-grid so
   the New / Reviewed grids above keep their compact layout.
   ===================================================================== */
.tx-add-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px 20px; margin: 26px 0 10px; }
.tx-add-head h3 { margin: 0 0 2px; }
.tx-add-head .hint { margin-bottom: 0; }
.tx-add-summary { display: flex; flex-wrap: wrap; gap: 6px; font-size: 0.8rem; }
.tx-add-summary > span { padding: 4px 10px; border-radius: 999px; background: var(--bg); border: 1px solid var(--border); color: var(--text); white-space: nowrap; }
.tx-add-summary .tx-add-sum-in strong { color: #1a7f37; }
.tx-add-summary .tx-add-sum-out strong { color: #b42318; }
.tx-add-summary .tx-add-sum-dup { background: var(--warn-bg); border-color: #f0d58a; color: var(--warn-text); font-weight: 600; }

.tx-add-scroll { border: 1px solid var(--border); border-radius: 10px; background: #fff; }
.bank-grid-table.tx-add-grid { table-layout: fixed; min-width: 1060px; font-size: 0.78rem; }
.bank-grid-table.tx-add-grid th {
    position: sticky; top: 0; z-index: 1;
    background: #f5f7fa; color: var(--muted); font-size: 0.68rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
    padding: 8px 6px; border-bottom: 1px solid var(--border);
}
.bank-grid-table.tx-add-grid th:first-child { padding-left: 10px; }
.bank-grid-table.tx-add-grid th:nth-child(8), .bank-grid-table.tx-add-grid th:nth-child(9) { text-align: right; }
.bank-grid-table.tx-add-grid td { padding: 5px 6px; border-bottom: 1px solid #eef1f5; background: #fff; vertical-align: middle; }
.bank-grid-table.tx-add-grid td:first-child { padding-left: 10px; box-shadow: inset 3px 0 0 transparent; }
.bank-grid-table.tx-add-grid tr.tx-add-row:hover td { background: #f8fafc; }
.bank-grid-table.tx-add-grid tr.tx-add-row:focus-within td { background: #f2f9fb; }

/* Column widths. Description takes what's left; below ~1350px of table the
   grid scrolls sideways a little rather than squeezing the description away. */
.bank-grid-table.tx-add-grid { min-width: 1180px; }
.bank-grid-table.tx-add-grid th:nth-child(1), .bank-grid-table.tx-add-grid .tx-c-date  { width: 122px; }
.bank-grid-table.tx-add-grid th:nth-child(2), .bank-grid-table.tx-add-grid .tx-c-payee { width: 108px; }
.bank-grid-table.tx-add-grid th:nth-child(3), .bank-grid-table.tx-add-grid .tx-c-desc  { width: auto; }
.bank-grid-table.tx-add-grid th:nth-child(4), .bank-grid-table.tx-add-grid .tx-c-cat   { width: 128px; }
.bank-grid-table.tx-add-grid th:nth-child(5), .bank-grid-table.tx-add-grid .tx-c-giver { width: 166px; }
.bank-grid-table.tx-add-grid th:nth-child(6), .bank-grid-table.tx-add-grid .tx-c-ref   { width: 88px; }
.bank-grid-table.tx-add-grid th:nth-child(7), .bank-grid-table.tx-add-grid .tx-c-vat   { width: 86px; }
.bank-grid-table.tx-add-grid th:nth-child(8), .bank-grid-table.tx-add-grid th:nth-child(9),
.bank-grid-table.tx-add-grid .tx-c-amt { width: 88px; }
.bank-grid-table.tx-add-grid th:nth-child(10), .bank-grid-table.tx-add-grid .tx-c-act { width: 100px; }
.bank-grid-table.tx-add-grid td, .bank-grid-table.tx-add-grid th { padding-left: 4px; padding-right: 4px; }

/* Inputs: one height, quiet borders, clear focus */
.bank-grid-table.tx-add-grid input[type="text"],
.bank-grid-table.tx-add-grid input[type="date"],
.bank-grid-table.tx-add-grid input[type="number"],
.bank-grid-table.tx-add-grid select {
    width: 100%; height: 30px; margin: 0; padding: 3px 7px; font-size: 0.78rem;
    border: 1px solid #d9dfe7; border-radius: 6px; background-color: #fff; box-shadow: none;
}
.bank-grid-table.tx-add-grid select { padding-right: 18px; text-overflow: ellipsis; }
.bank-grid-table.tx-add-grid input::placeholder { color: #a3adba; }
.bank-grid-table.tx-add-grid input:focus, .bank-grid-table.tx-add-grid select:focus { border-color: var(--teal); outline: none; box-shadow: 0 0 0 3px rgba(0, 164, 189, 0.15); }
.bank-grid-table.tx-add-grid .tx-c-desc input { font-weight: 500; }
.bank-grid-table.tx-add-grid .giver-with-add { display: flex !important; align-items: center; gap: 4px; width: 100%; }
.bank-grid-table.tx-add-grid .giver-with-add select { flex: 1 1 auto; min-width: 0; width: auto; }
.bank-grid-table.tx-add-grid .giver-with-add .js-add-giver { flex: 0 0 26px; width: 26px; height: 30px; padding: 0; margin: 0; border-radius: 6px; border: 1px solid #d9dfe7; background: #f5f7fa; color: var(--brand); font-weight: 700; cursor: pointer; }
.bank-grid-table.tx-add-grid .giver-with-add .js-add-giver:hover { background: #e8f6f9; border-color: var(--teal); }
.bank-grid-table.tx-add-grid .tx-c-vat select { padding-left: 5px; padding-right: 14px; font-size: 0.72rem; background-position: right 3px center; }
.bank-grid-table.tx-add-grid .tx-c-amt input { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.bank-grid-table.tx-add-grid .tx-c-spent input:not(:placeholder-shown) { color: #b42318; }
.bank-grid-table.tx-add-grid .tx-c-received input:not(:placeholder-shown) { color: #1a7f37; }
.bank-grid-table.tx-add-grid .tx-c-amt input[type="number"]::-webkit-inner-spin-button { display: none; }
.bank-grid-table.tx-add-grid .tx-c-amt input[type="number"] { -moz-appearance: textfield; }

/* Actions: three fixed slots so +, ÷ and × line up on every row */
.bank-grid-table.tx-add-grid .tx-add-actions { display: grid; grid-template-columns: repeat(3, 26px); gap: 4px; justify-content: start; }
.bank-grid-table.tx-add-grid .tx-add-actions .bank-grid-icon-btn { width: 26px; height: 26px; margin: 0; }
.tx-act-slot { display: block; width: 26px; height: 26px; }

/* Possible duplicate: amber edge + a small chip, row height unchanged */
.bank-grid-table.tx-add-grid tr.tx-row-duplicate td { background: #fffaf0 !important; }
.bank-grid-table.tx-add-grid tr.tx-row-duplicate td:first-child { box-shadow: inset 3px 0 0 #e0a100; }
.bank-grid-table.tx-add-grid .tx-c-desc { position: relative; }
.bank-grid-table.tx-add-grid .tx-dup-badge {
    position: absolute; right: 9px; white-space: nowrap; top: 50%; transform: translateY(-50%); margin: 0;
    font-size: 0.6rem; padding: 2px 6px; border-radius: 999px; letter-spacing: .02em; pointer-events: auto;
    background: #fdecc8; color: #8a5a00; border: 1px solid #f0d58a;
}
.bank-grid-table.tx-add-grid tr.tx-row-duplicate .tx-c-desc input { padding-right: 112px; }

/* Rows typed by hand (not imported) read as "new" */
.bank-grid-table.tx-add-grid tr.is-blank td { background: #fcfdfe; }
.bank-grid-table.tx-add-grid .field-error { font-size: 0.68rem; margin-top: 2px; }

/* Split panel inside the capture grid keeps the fixed layout from squeezing it */
.bank-grid-table.tx-add-grid tr.tx-split-row td { background: #f7fbfc; white-space: normal; }

.tx-add-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-top: 12px; }
.tx-add-foot .btn { margin: 0; }
.tx-add-range { margin: 0 0 0 auto; }
.tx-add-pager { margin: 0; }
.tx-add-pager > * { margin: 0 !important; }
@media (max-width: 760px) { .tx-add-range { margin-left: 0; } }
/* Capture grid selects: a slim drawn arrow instead of the wide native one,
   so "No VAT", category and member names get the room. */
.bank-grid-table.tx-add-grid select {
    -webkit-appearance: none; appearance: none;
    padding-right: 20px !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b7785' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 7px center; background-size: 10px 6px;
}
/* Member notices: "Clear all" (2026-09-26) */
.member-notice-clearall { display: flex; justify-content: flex-end; margin: 0 0 6px; }
.member-notice-clearall .link-button { font-size: 0.85rem; font-weight: 600; color: var(--brand); }

/* Address look-up while typing (2026-09-26) — assets/js/maps.js */
.addr-lookup { position: relative; }
.addr-lookup textarea { width: 100%; }
.addr-lookup-list {
    position: absolute; z-index: 90; left: 0; right: 0; top: 100%; margin: 0; padding: 4px; list-style: none;
    background: #fff; border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 12px 30px rgba(0, 19, 59, 0.16); max-height: 300px; overflow: auto;
}
.addr-lookup-list li { padding: 8px 10px; border-radius: 7px; cursor: pointer; line-height: 1.3; }
.addr-lookup-list li strong { display: block; font-size: 0.92rem; color: var(--text); }
.addr-lookup-list li span { display: block; font-size: 0.8rem; color: var(--muted); }
.addr-lookup-list li.is-active, .addr-lookup-list li:hover { background: rgba(0, 164, 189, 0.10); }
.addr-lookup-list li.addr-lookup-empty { cursor: default; color: var(--muted); font-size: 0.85rem; }
.addr-lookup-list li.addr-lookup-empty:hover { background: none; }
.addr-lookup-note { font-size: 0.78rem; color: var(--muted); margin: 3px 0 0; min-height: 1em; }
.addr-lookup.is-confirmed textarea { border-color: #1a7f37; }
.addr-lookup.is-confirmed .addr-lookup-note { color: #1a7f37; font-weight: 600; }

/* ---- Course registration link (course-register.php / course-link.php, 2026-09-27) ---- */
.course-register-card { max-width: 560px; }
/* Course registrations card on the admin dashboard (replaces Getting started, 2026-09-27) */
.dash-courses { margin-bottom: 22px; }
.dash-courses-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.dash-courses-head .dash-panel-title { margin: 0; }
.dash-courses-subhead { font-size: 0.95rem; margin: 18px 0 8px; }
.dash-courses-table td, .dash-courses-table th { font-size: 0.9rem; }
.dash-courses-table .dash-num { text-align: right; white-space: nowrap; }
.dash-courses-actions { white-space: nowrap; font-size: 0.85rem; }
/* Active course on the member home page, under the Verse of the Day (2026-09-27) */
.member-course-card { margin: -8px 0 22px; padding: 16px 22px; background: linear-gradient(135deg, rgba(245, 180, 0, 0.12), rgba(245, 180, 0, 0.02)); border-left: 3px solid rgba(214, 150, 0, 0.6); border-radius: 10px; }
.member-course-title { margin: 0 0 2px; font-size: 1.2rem; }
.member-course-subtitle { margin: 0 0 8px; color: var(--muted); font-size: 0.92rem; }
.member-course-card .course-meta-chips { margin: 6px 0; }
.member-course-meta { margin: 0 0 10px; font-size: 0.88rem; color: var(--muted); }
.member-course-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.member-course-actions form { margin: 0; }
.member-course-more { font-size: 0.88rem; }
.member-course-card + .member-course-card { margin-top: 0; }
.course-register-hero { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.course-register-logo { width: auto; max-width: 150px; height: 64px; object-fit: contain; border-radius: 12px; background: #fff; border: 1px solid var(--border, #e5e7eb); padding: 4px; flex: 0 0 auto; }
.course-link-head { display: flex; align-items: center; gap: 12px; }
.course-link-head-logo { width: 44px; height: 44px; object-fit: contain; }
.course-link-poster-logo { display: block; margin: 0 auto 12px; max-width: 160px; max-height: 120px; width: auto; height: auto; }
.course-register-company { margin: 0 0 4px; font-size: 0.85rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted, #6b7280); }
.course-register-title { margin-top: 0; }
.course-register-description { margin-top: 14px; }
.course-register-description p { margin: 0 0 10px; line-height: 1.55; }
.course-register-action { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border, #e5e7eb); }
.course-register-new { margin-top: 12px; }
.course-link-row { display: flex; gap: 8px; align-items: stretch; flex-wrap: wrap; }
.course-link-row input { flex: 1 1 260px; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.85rem; }
.course-link-actions { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 8px; }
.course-link-poster-title { font-size: 1.6rem; font-weight: 700; margin: 6px 0; }
@media print { .course-link-poster-title { font-size: 2.4rem; } }

/* 2026-09-27 — Company Life tabs moved into the sidebar (Company Life ▸ News /
   Courses & training / …). The page now shows one section with its counts
   as a heading instead of the old .tab-buttons row. */
.cl-section-title { margin: 4px 0 16px; padding-bottom: 8px; border-bottom: 2px solid var(--teal); font-size: 1.15rem; }

/* 2026-09-27 — course start / end date chips (member course cover page,
   member home "active course" card). Warm tint so they read as dates,
   not as the duration (teal) or the weekly schedule (plain). */
.course-chip-date { background: #FFF8E6; border-color: #F2DC9C; color: var(--brand-dark); font-weight: 600; }

/* 2026-09-27 — date + time pickers on company-course.php (edit a course). */
.course-fieldset .row { margin-top: 4px; }
.course-fieldset input[type="datetime-local"] { width: 100%; max-width: 260px; }

/* 2026-09-27 — "Paid" tick on each course booking (company-life.php ▸ Courses ▸ Booked members). */
.course-booking-row { display: flex; align-items: flex-start; gap: 12px; }
.course-booking-who { flex: 1 1 auto; min-width: 0; }
.course-paid-form { margin: 0; flex: 0 0 auto; display: flex; align-items: center; }
.course-paid-tick { display: inline-flex; align-items: center; gap: 6px; margin: 0; padding: 3px 10px; border: 1px solid var(--border); border-radius: 999px; font-size: 0.82rem; font-weight: 600; cursor: pointer; background: #fff; white-space: nowrap; }
.course-paid-tick input { margin: 0; width: auto; }
.course-booking-row.is-paid .course-paid-tick { background: #E8F6EE; border-color: #A9DCBD; color: #1D6B3A; }
.course-paid-on { display: inline-block; margin-left: 6px; font-size: 0.8rem; color: #1D6B3A; font-weight: 600; }
.course-paid-amount { width: 110px; max-width: 110px; margin: 0 0 0 6px; padding: 3px 8px; font-size: 0.82rem; }

/* 2026-09-27 — non-members added to a course by hand (Booked members list). */
.course-guest-badge { margin-left: 6px; background: #EEF1F7; color: var(--brand-dark); font-size: 0.72rem; }
.course-guest-remove { margin: 0; flex: 0 0 auto; }
.course-guest-form { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); }
.course-guest-heading { margin: 0 0 8px; font-size: 0.9rem; }
.course-guest-fields { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 6px; }
.course-guest-fields input { flex: 1 1 180px; min-width: 0; margin: 0; }
.course-guest-fields .btn { flex: 0 0 auto; }

/* 2026-09-27 — "+ Add people" panel per course (members search + public guest). */
.course-add-panel { margin-top: 14px; padding: 14px 16px; border: 1px solid var(--border); border-left: 3px solid var(--teal); border-radius: var(--radius); background: #F7FBFC; }
.course-add-panel-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 10px; }
.course-add-close { font-size: 0.85rem; }
.course-add-section + .course-add-section { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--border); }
.course-add-panel .course-guest-form { margin-top: 14px; }
.course-add-results { margin-top: 8px; background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 0 10px; }
.course-add-results li { align-items: center; }

/* ---------------------------------------------------------------------
   Demo interest list pop-up (demo.php, 2026-09-29). No info, no access:
   the overlay has no close button — the only ways out are submitting or
   "Back to home". Navy head band so the gold eyebrow has contrast.
   --------------------------------------------------------------------- */
.demo-lead-overlay {
    position: fixed; inset: 0; z-index: 1100;   /* above .whatsapp-float (1000) */
    display: none; align-items: center; justify-content: center;
    padding: 16px;
    background: rgba(0, 19, 59, 0.62);
    backdrop-filter: blur(3px);
    overflow-y: auto;
}
.demo-lead-overlay.is-open { display: flex; }
.demo-lead-overlay[hidden] { display: none; }
body.demo-lead-locked { overflow: hidden; }
.demo-lead-box {
    width: 100%; max-width: 460px; margin: auto;
    background: var(--card-bg); border-radius: 12px;
    box-shadow: 0 24px 60px rgba(0, 19, 59, 0.35);
    overflow: hidden;
}
.demo-lead-head { background: var(--brand); color: var(--soft-white); padding: 22px 24px 18px; }
.demo-lead-head .hero-eyebrow { margin-bottom: 8px; }
.demo-lead-head h2 { color: var(--soft-white); margin: 0 0 6px; font-size: 1.45rem; line-height: 1.2; }
.demo-lead-head p { margin: 0; color: rgba(251, 251, 251, 0.86); font-size: 0.92rem; line-height: 1.45; }
.demo-lead-box > .alert { margin: 16px 24px 0; }
.demo-lead-form { padding: 4px 24px 20px; }
.demo-lead-form label { margin-top: 12px; }
.demo-lead-form input[type=text], .demo-lead-form input[type=email], .demo-lead-form select { width: 100%; }
.demo-lead-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.demo-lead-row > div { min-width: 0; }
.demo-lead-form .demo-lead-consent {
    display: flex; gap: 10px; align-items: flex-start;
    font-weight: 500; font-size: 0.86rem; line-height: 1.4; color: var(--muted);
    margin-top: 16px; cursor: pointer;
}
.demo-lead-consent input { margin-top: 3px; flex: 0 0 auto; width: 18px; height: 18px; }
.demo-lead-submit { width: 100%; margin-top: 18px; padding-top: 12px; padding-bottom: 12px; font-size: 1rem; }
.demo-lead-foot { margin: 12px 0 0; font-size: 0.78rem; color: var(--muted); line-height: 1.45; text-align: center; }
.demo-lead-back { display: block; margin-top: 8px; font-weight: 600; color: var(--teal-ink); }
.demo-lead-hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
/* Coming back (2026-10-06): the one-field "Registered before?" box above the form. */
.demo-lead-return { margin: 0; padding: 14px 24px 16px; background: var(--bg); border-bottom: 1px solid var(--border); }
.demo-lead-return label { margin: 0 0 8px; font-size: 0.88rem; line-height: 1.35; }
.demo-lead-return-row { display: flex; gap: 8px; align-items: stretch; }
.demo-lead-return-row input[type=email] { flex: 1 1 auto; min-width: 0; width: auto; }
.demo-lead-return-row .btn { flex: 0 0 auto; margin: 0; min-height: 0; padding: 0 16px; white-space: nowrap; }
.demo-lead-return .field-error { margin-top: 8px; }
.demo-lead-new-heading { margin: 16px 24px 0; font-weight: 700; color: var(--brand); font-size: 0.95rem; }
.demo-lead-box > .alert + .demo-lead-return { margin-top: 14px; border-top: 1px solid var(--border); }
@media (max-width: 480px) {
    .demo-lead-row { grid-template-columns: 1fr; gap: 0; }
    .demo-lead-head { padding: 18px 18px 14px; }
    .demo-lead-form { padding: 0 18px 18px; }
    .demo-lead-box > .alert { margin: 14px 18px 0; }
    .demo-lead-return { padding: 12px 18px 14px; }
    .demo-lead-new-heading { margin: 14px 18px 0; }
}
/* Locked persona cards (not registered yet) */
.demo-locked-note { margin: 14px 0 0; font-size: 0.86rem; color: var(--muted); }

/* demo-leads.php (super user) */
.demo-leads-table { width: 100%; font-size: 0.86rem; }
.demo-leads-table td, .demo-leads-table th { vertical-align: top; }
.demo-leads-table .dl-email { overflow-wrap: anywhere; }
.super-search select { width: auto; max-width: 220px; margin: 0; }
.demo-leads-table .dl-delete { background: none; border: none; cursor: pointer; padding: 0; margin-left: 8px; font-size: 0.78rem; color: var(--muted); text-decoration: underline; min-height: 0; }
@media (max-width: 760px) { .super-search { flex-wrap: wrap; } }
.demo-leads-table .dl-followup { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.demo-leads-table .dl-followup select { width: auto; min-width: 130px; padding: 4px 6px; font-size: 0.84rem; }
.demo-leads-table .dl-followup input[type=text] { width: 100%; min-width: 160px; padding: 4px 6px; font-size: 0.84rem; flex: 1 1 160px; }
.demo-leads-table .dl-followup .btn { padding: 4px 10px; font-size: 0.8rem; }

/* ---- Bible School on Wheels curriculum (includes/course_bsow.php, 2026-09-30) ----
   Ported from Henk's bsow-section.html (soteriabedieninge.org.za). Same layout,
   on the I-Transact brand tokens. Shown on course-register.php under any course
   titled "Bible School on Wheels" / "Bybelskool op Wiele" / BSOW. */
.bsow { margin: 22px 0 8px; color: var(--brand); line-height: 1.65; }
.bsow *, .bsow *::before, .bsow *::after { box-sizing: border-box; }
.bsow-wrap { padding: 32px; border-radius: 20px; background: #FAF7F1; border: 1px solid var(--border); }
.bsow-eyebrow { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 12px; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: #8A6400; }
.bsow-eyebrow::before { content: ''; width: 26px; height: 1.5px; background: currentColor; }
.bsow-head { display: grid; grid-template-columns: 1.2fr 0.8fr; gap: 32px; align-items: start; }
.bsow-head > * { min-width: 0; }
.bsow-title { font-family: Georgia, 'Times New Roman', serif; font-weight: 600; font-size: 2rem; line-height: 1.15; color: var(--brand); margin: 0 0 12px; }
.bsow-lead { font-size: 1.02rem; color: var(--muted); margin: 0; }
.bsow-ticks { list-style: none; padding: 0; display: grid; gap: 10px; margin: 20px 0 0; }
.bsow-ticks li { display: flex; gap: 12px; align-items: flex-start; color: var(--muted); }
.bsow-ticks li::before { content: ''; width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; margin-top: 2px; background: #F7F0DC url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237d621a' stroke-width='3'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center/12px no-repeat; }
.bsow-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.bsow-fact { min-width: 0; background: #fff; border: 1px solid var(--border); border-radius: 14px; padding: 12px 14px; }
.bsow-fact b { display: block; font-family: Georgia, 'Times New Roman', serif; font-size: 1.25rem; color: var(--brand); line-height: 1.2; overflow-wrap: anywhere; }
.bsow-fact small { color: var(--muted); font-size: 0.84rem; }
.bsow-tabs { display: none; flex-wrap: wrap; padding: 5px; border-radius: 999px; background: #fff; border: 1px solid var(--border); margin-top: 30px; }
.bsow-tabs button { border: 0; background: transparent; padding: 9px 20px; border-radius: 999px; font-family: inherit; font-weight: 600; font-size: 0.92rem; color: var(--muted); cursor: pointer; }
.bsow-tabs button.is-active { background: var(--brand); color: #fff; }
.bsow-pane { margin-top: 26px; }
.bsow-pane-title { margin: 0; font-size: 1.1rem; color: var(--brand); }
/* With JavaScript the years become tabs; without it they stack. */
.bsow.bsow-js .bsow-tabs { display: inline-flex; }
.bsow.bsow-js .bsow-pane { display: none; margin-top: 0; }
.bsow.bsow-js .bsow-pane.is-active { display: block; }
.bsow.bsow-js .bsow-pane-title { display: none; }
.bsow-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 18px; }
.bsow-card { min-width: 0; background: #fff; border: 1px solid var(--border); border-radius: 16px; padding: 22px; }
.bsow-card h4 { font-size: 1.08rem; color: var(--brand); margin: 0 0 4px; }
.bsow-card > small { color: var(--muted); font-size: 0.86rem; }
.bsow-card ol { margin: 14px 0 0; padding: 0; list-style: none; counter-reset: bsowm; display: grid; gap: 10px; }
.bsow-card li { display: flex; gap: 12px; align-items: center; font-weight: 500; }
.bsow-card li > span { min-width: 0; overflow-wrap: anywhere; }
.bsow-card li::before { counter-increment: bsowm; content: counter(bsowm); width: 28px; height: 28px; border-radius: 50%; background: #F7F0DC; color: #7D621A; font-weight: 700; font-size: 0.85rem; display: grid; place-items: center; flex-shrink: 0; }
.bsow-elect li::before { background: #E9EEF8; color: var(--brand-mid); }
.bsow-vid { display: inline-flex; align-items: center; gap: 10px; margin-top: 16px; color: var(--brand); font-weight: 600; text-decoration: none; }
.bsow-vid svg { width: 26px; height: 26px; color: var(--accent-deep); flex-shrink: 0; }
.bsow-vid:hover span { text-decoration: underline; }
.bsow-note { margin: 18px 0 0; font-size: 0.85rem; color: var(--muted); }
.bsow-btn { display: inline-flex; align-items: center; gap: 9px; margin-top: 22px; padding: 13px 24px; border-radius: 999px; font-weight: 600; font-size: 0.95rem; text-decoration: none; background: var(--accent); color: var(--brand-dark); box-shadow: 0 8px 24px -8px rgba(216,148,0,0.7); transition: background 0.2s; }
.bsow-btn:hover { background: var(--accent-deep); color: var(--brand-dark); text-decoration: none; }
.bsow-btn svg { width: 18px; height: 18px; }
@media (max-width: 860px) {
    .bsow-wrap { padding: 22px 16px; }
    .bsow-head, .bsow-cols { grid-template-columns: 1fr; gap: 18px; }
    .bsow-title { font-size: 1.7rem; }
    .bsow-tabs button { padding: 8px 14px; }
}

/* ==========================================================================
   POWER SEARCH, ALERTS BELL, TASKS (2026-10-03)
   Henk: "add power search option on the top to assist with function search"
   + the three workflow gaps a new client asked about (a task list, alerts
   to the person something is assigned to, scheduled messages).
   .app-psearch wraps the existing .app-search box and owns its dropdown.
   ========================================================================== */
.app-psearch { position: relative; flex: 1 1 240px; max-width: 460px; min-width: 0; margin-left: 6px; }
.app-psearch .app-search { width: auto; margin-left: 0; transition: border-color .12s, background .12s, box-shadow .12s; }
.app-psearch .app-search:focus-within { background: var(--card-bg); border-color: var(--teal); box-shadow: 0 0 0 3px rgba(0, 164, 189, 0.16); }
.app-psearch .app-search input::-webkit-search-cancel-button { cursor: pointer; }
.app-psearch-kbd { flex: 0 0 auto; font: 600 0.68rem/1 inherit; color: var(--muted); border: 1px solid var(--border); border-radius: 5px; padding: 3px 5px; background: var(--card-bg); white-space: nowrap; }
.app-psearch .app-search:focus-within .app-psearch-kbd { display: none; }
.app-psearch-panel {
    position: absolute; top: calc(100% + 6px); left: 0; right: 0; min-width: 320px; max-height: min(70vh, 520px); overflow-y: auto;
    background: var(--card-bg); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 14px 34px rgba(0, 19, 59, 0.18); padding: 6px; z-index: 80;
}
.app-psearch-panel[hidden] { display: none; }
.app-psearch-section { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.8px; color: var(--muted); font-weight: 700; padding: 8px 10px 4px; }
.app-psearch-item { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 8px 10px; border-radius: 7px; color: var(--text); text-decoration: none; }
.app-psearch-item:hover, .app-psearch-item.is-active { background: rgba(0, 164, 189, 0.12); text-decoration: none; }
.app-psearch-item.is-active { box-shadow: inset 3px 0 0 var(--teal); }
.app-psearch-title { font-weight: 600; font-size: 0.9rem; min-width: 0; overflow-wrap: anywhere; }
.app-psearch-sub { flex: 0 0 auto; max-width: 46%; font-size: 0.76rem; color: var(--muted); text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-psearch-badge { display: inline-block; margin-left: 7px; padding: 1px 6px; border-radius: 999px; background: var(--warn-bg); color: var(--warn-text); font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px; vertical-align: 1px; }
.app-psearch-none { padding: 14px 10px; color: var(--muted); font-size: 0.88rem; }
.app-psearch-all { display: block; margin-top: 4px; padding: 9px 10px; border-top: 1px solid var(--border); font-size: 0.82rem; font-weight: 600; color: var(--teal-ink); text-decoration: none; }
.app-psearch-all:hover { text-decoration: underline; }
.app-psearch-open { display: none; border: none; background: transparent; cursor: pointer; }

/* The results page (search.php) */
.psearch-page-form { display: flex; gap: 10px; align-items: center; }
.psearch-page-form input { margin: 0; flex: 1 1 auto; min-width: 0; }
.psearch-page-form .btn { margin: 0; flex: 0 0 auto; }
.psearch-results { padding-bottom: 12px; }
.psearch-result { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; padding: 10px 8px; border-top: 1px solid var(--border); color: var(--text); text-decoration: none; }
.psearch-result:hover { background: rgba(0, 164, 189, 0.08); text-decoration: none; }
.psearch-result-title { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.psearch-result-sub { flex: 0 0 auto; color: var(--muted); font-size: 0.84rem; text-align: right; }

/* Alerts bell */
.app-alerts > summary { position: relative; list-style: none; cursor: pointer; }
.app-alerts > summary::-webkit-details-marker { display: none; }
.app-alerts-count { position: absolute; top: 1px; right: 0; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 999px; background: var(--error-text); color: #fff; font-size: 0.64rem; font-weight: 700; line-height: 17px; text-align: center; box-shadow: 0 0 0 2px var(--card-bg); }
.app-alerts-menu { left: auto; right: 0; width: 340px; max-width: calc(100vw - 24px); padding: 6px; }
.app-alerts-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 8px 8px; font-size: 0.9rem; }
.app-alerts-head form { margin: 0; }
.app-alerts-head .link-button { background: none; border: 0; padding: 0; min-height: 0; margin: 0; color: var(--teal-ink); font-size: 0.78rem; font-weight: 600; cursor: pointer; }
.app-alerts-head .link-button:hover { text-decoration: underline; }
.app-quick-menu a.app-alert { display: grid; gap: 1px; padding: 8px 10px 8px 14px; border-radius: 7px; position: relative; }
.app-alert.is-unread::before { content: ""; position: absolute; left: 4px; top: 14px; width: 6px; height: 6px; border-radius: 50%; background: var(--teal); }
.app-alert-title { font-size: 0.86rem; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.app-alert:not(.is-unread) .app-alert-title { font-weight: 500; color: var(--muted); }
.app-alert-body { font-size: 0.78rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-alert-when { font-size: 0.7rem; color: var(--muted); }
.app-alerts-empty { margin: 0; padding: 10px; color: var(--muted); font-size: 0.84rem; }
.app-quick-menu a.app-alerts-all { margin-top: 4px; border-top: 1px solid var(--border); border-radius: 0 0 7px 7px; text-align: center; font-size: 0.82rem; font-weight: 600; color: var(--teal-ink); }

/* Alerts page */
.alerts-list { padding-top: 6px; padding-bottom: 10px; }
.alerts-row { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; padding: 11px 8px 11px 18px; border-bottom: 1px solid var(--border); color: var(--text); text-decoration: none; position: relative; }
.alerts-row:last-of-type { border-bottom: none; }
.alerts-row:hover { background: rgba(0, 164, 189, 0.08); text-decoration: none; }
.alerts-row.is-unread::before { content: ""; position: absolute; left: 5px; top: 18px; width: 7px; height: 7px; border-radius: 50%; background: var(--teal); }
.alerts-row:not(.is-unread) strong { font-weight: 500; }
.alerts-row-main { display: grid; gap: 2px; min-width: 0; }
.alerts-row-body { font-size: 0.86rem; color: var(--muted); overflow-wrap: anywhere; }
.alerts-row-meta { flex: 0 0 auto; font-size: 0.78rem; color: var(--muted); text-align: right; }

/* Tasks */
.task-elsewhere { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin: 0 0 16px; padding: 10px 14px; background: var(--warn-bg); border: 1px solid rgba(138, 97, 0, 0.25); border-radius: var(--radius); font-size: 0.88rem; color: var(--warn-text); }
.task-elsewhere a { color: var(--warn-text); font-weight: 700; }
.task-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.task-filters input[type="search"], .task-filters select { margin: 0; width: auto; flex: 0 1 190px; min-width: 0; height: 38px; padding-top: 0; padding-bottom: 0; }
.task-filters input[type="search"] { flex: 1 1 200px; max-width: 320px; }
.task-filters .btn { margin: 0; }
.task-filter-check { margin: 0; font-size: 0.86rem; white-space: nowrap; }
.task-filter-clear { font-size: 0.84rem; }
.table-responsive table.task-table { min-width: 0; width: 100%; }
.task-table .task-col-do { width: 44px; padding-right: 0; }
.task-table .task-col-do form { margin: 0; }
.task-done-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; min-height: 0; margin: 0; padding: 0; border: 2px solid var(--border); border-radius: 50%; background: var(--card-bg); color: transparent; cursor: pointer; transition: border-color .12s, color .12s, background .12s; }
.task-done-btn svg, .task-done-mark svg { width: 15px; height: 15px; }
.task-done-btn:hover, .task-done-btn:focus-visible { border-color: var(--success-text); color: var(--success-text); background: var(--success-bg); }
.task-done-mark { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; background: var(--success-bg); color: var(--success-text); }
.task-cell-title a { color: var(--brand-dark); text-decoration: none; }
.task-cell-title a:hover { text-decoration: underline; }
.task-comments { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 999px; background: var(--bg); border: 1px solid var(--border); color: var(--muted); font-size: 0.7rem; font-weight: 700; text-align: center; }
.task-fold { display: none; }
.task-form-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.task-form-actions .btn { margin: 0; }
.task-about { margin: 14px 0 0; padding: 9px 12px; background: var(--bg); border-radius: var(--radius); font-size: 0.9rem; }
.task-read-title { font-size: 1.1rem; margin: 0 0 8px; }
.task-read-details { margin: 0 0 14px; overflow-wrap: anywhere; }
.task-meta { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; margin: 0 0 12px; font-size: 0.92rem; }
.task-meta dt { color: var(--muted); }
.task-meta dd { margin: 0; font-weight: 600; }
.task-status-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 0 0 10px; }
.task-status-actions form { margin: 0; }
.task-status-actions .btn { margin: 0; }
.task-status-actions .link-button, .task-strip .link-button { background: none; border: 0; padding: 0; min-height: 0; margin: 0; cursor: pointer; text-decoration: underline; font-size: 0.84rem; }
.task-created { margin: 0 0 4px; }
.task-comment-form { display: grid; gap: 8px; margin: 0 0 12px; }
.task-comment-form textarea { margin: 0; }
.task-comment-form .btn { margin: 0; justify-self: start; }
.task-updates { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.task-update { display: grid; gap: 2px; padding-left: 12px; border-left: 2px solid var(--border); }
.task-update-comment { border-left-color: var(--teal); }
.task-update-who { font-size: 0.74rem; color: var(--muted); }
.task-update-body { font-size: 0.9rem; overflow-wrap: anywhere; }
.task-update:not(.task-update-comment) .task-update-body { color: var(--muted); font-size: 0.84rem; }
.task-danger { margin-top: 18px; font-size: 0.86rem; }
.task-danger summary { cursor: pointer; color: var(--muted); }
.task-danger form { margin: 10px 0 0; }
/* "Open tasks" strip on a member / visitor / care case / home cell page */
.task-strip { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border); }
.task-strip h3 { margin: 0 0 8px; display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.task-strip h3 .btn { margin: 0; }
.task-strip ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: 0.9rem; }
.task-strip li small { color: var(--muted); }

@media (max-width: 1100px) {
    .app-psearch-kbd { display: none; }
}
@media (max-width: 760px) {
    /* Phones: the box lives behind the magnifier button and drops in under the top bar. */
    .app-psearch-open { display: inline-flex; }
    .app-psearch { display: none; position: fixed; left: 0; right: 0; top: 54px; max-width: none; margin: 0; padding: 8px 12px 10px; background: var(--card-bg); border-bottom: 1px solid var(--border); box-shadow: 0 10px 24px rgba(0, 19, 59, 0.16); z-index: 70; }
    .app-psearch.is-open { display: block; }
    .app-psearch .app-search { display: flex; width: auto; height: 42px; }
    .app-psearch .app-search input { font-size: 1rem; }
    .app-psearch-panel { position: static; min-width: 0; max-height: calc(100vh - 140px); margin-top: 8px; box-shadow: none; border: none; padding: 0; }
    .app-alerts-menu { position: fixed; top: 58px; right: 8px; left: 8px; width: auto; max-width: none; }
    .psearch-result, .alerts-row { flex-direction: column; gap: 2px; }
    .psearch-result-sub, .alerts-row-meta { text-align: left; }
    .task-table .task-col-who, .task-table .task-col-due, .task-table .task-col-status { display: none; }
    .task-fold { display: block; margin-top: 2px; }
    .task-filters input[type="search"] { flex-basis: 100%; max-width: none; }
    .task-filters select { flex: 1 1 130px; }
}
.app-user-text strong, .app-user-text small { white-space: nowrap; max-width: 170px; overflow: hidden; text-overflow: ellipsis; }

/* Scheduled messages (2026-10-03): "Send now / Send later" on the confirm step. */
.comm-when { flex: 1 1 100%; border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px 12px; margin: 0; min-width: 0; }
.comm-when legend { font-weight: 600; font-size: 0.85rem; padding: 0 6px; }
.comm-when .checkbox-row { display: inline-flex; margin: 0 18px 0 0; }
.comm-when-fields { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.comm-when-fields[hidden] { display: none; }
.comm-when-fields input { width: auto; flex: 0 1 180px; min-width: 0; margin: 0; }
.comm-when .hint { margin: 8px 0 0; }
.comm-scheduled { display: flex; flex-direction: column; gap: 4px; }
.comm-scheduled .comm-inline-actions { margin: 8px 0 0; }
.comm-scheduled form { margin: 0; }
@media (max-width: 1500px) { .app-psearch-kbd { display: none; } }
/* The company name in the sidebar turned navy-on-navy under the pointer (a:hover outranks .app-brand). */
.app-brand:hover { color: #fff; text-decoration: none; }

/* Families and Member fields & tags (2026-10-03): three tables that did not fit
   their column — children's names wrapped a word a line, the delete × was cut
   off, and all three scrolled sideways on a phone. */
.table-responsive table.households-table, .table-responsive table.fields-table { min-width: 0; width: 100%; }
.households-table th, .households-table td, .fields-table th, .fields-table td { padding-left: 8px; padding-right: 8px; }
.households-table .members-name-cell strong { overflow-wrap: anywhere; }
.households-table tr.households-has-dependents > td { border-bottom: 0; padding-bottom: 2px; }
.households-dependents > td { padding-top: 0; padding-left: 54px; color: var(--muted); font-size: 0.85rem; }
.households-dependent { display: inline-block; margin-right: 16px; }
.households-fold, .fields-fold { display: none; }
.households-actions .groups-inline-form { vertical-align: middle; }
.households-actions .link-button, .fields-table .link-button { min-width: 26px; }
.fields-name-cell { display: flex; gap: 8px; align-items: flex-start; }
.fields-name-cell > div { min-width: 0; }
.fields-order { display: flex; flex-direction: column; gap: 2px; flex: 0 0 auto; margin: 0; }
.fields-order .link-button { padding: 0 5px; min-height: 0; line-height: 1.35; font-size: 0.8rem; }
.fields-order .link-button[disabled] { opacity: 0.3; cursor: default; }
.fields-sees { font-size: 0.82rem; }
.fields-table th.num.fields-fold-col, .fields-table td.num.fields-fold-col { width: 1%; white-space: nowrap; }
.fields-table .fields-inline input[type="text"] { flex-basis: 110px; }
@media (max-width: 760px) {
    .households-fold-col, .fields-fold-col { display: none; }
    .households-fold, .fields-fold { display: block; color: var(--muted); font-size: 0.82rem; margin-top: 2px; }
    .households-dependents > td { padding-left: 8px; }
    .households-table th, .households-table td { padding-left: 6px; padding-right: 6px; }
    .households-dependents > td { padding-left: 6px; }
    .fields-actions { white-space: normal; }
    .fields-actions .btn, .fields-actions .groups-inline-form { margin: 2px 0; }
}

/* Backups: "Sign in with Microsoft / Google" (2026-10-03) */
.dg-cloud-connect, .dg-cloud-edit { margin: 16px 0; padding: 14px 16px; border: 1px solid var(--border); border-radius: 10px; }
.dg-cloud-connect h3, .dg-cloud-edit h3 { margin: 0 0 10px; font-size: 1rem; }
.dg-cloud-buttons { display: flex; gap: 10px; flex-wrap: wrap; }
.dg-cloud-buttons .btn { margin-top: 0; }
.dg-cloud-connect .hint { margin: 10px 0 0; }
.dg-cloud-edit .btn { margin-top: 12px; }
.dg-cloud-keyset { border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px 14px; margin: 14px 0 0; min-width: 0; }
.dg-cloud-keyset legend { font-weight: 700; padding: 0 6px; }
.dg-cloud-keyset legend .badge { margin-left: 6px; }
.dg-cloud-keys code { overflow-wrap: anywhere; }
.dg-cloud-secret { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.dg-cloud-secret-saved { font-weight: 600; }
.dg-cloud-keys form > .btn { margin-top: 16px; }
.dg-fold { display: none; }
.dg-dest-table .bb-row-actions { flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 760px) {
    .dg-dest-table .dg-fold-col { display: none; }
    .dg-dest-table .dg-fold { display: block; color: var(--muted); font-size: 0.82rem; margin-top: 3px; }
    .dg-dest-table th, .dg-dest-table td { padding-left: 6px; padding-right: 6px; }
    .dg-dest-table td:first-child { overflow-wrap: anywhere; }
}

/* ==========================================================================
   MEMBER APP: MENU + POWER SEARCH (2026-10-04)
   Henk: "It is very hard to find the section on the user app. Can we update
   the members app with the power search option, including reworking of the
   menu."

   Markup: includes/member-header.php (the bar, the search box, the drawer),
   includes/member_navigation.php (the tree), member-menu.php (the menu as a
   page). The search dropdown reuses the console's .app-psearch-* rows.

   Phone first, because that is where members are: one Menu button, the
   company name, a Home button, and a full-width search box underneath — two
   rows, the same height the old link strip took. The menu is a drawer from
   the left. From 1024px it is a column that stays on screen.
   ========================================================================== */
.member-has-menu .member-header .header-inner { flex-wrap: wrap; align-items: center; gap: 10px 12px; padding: 10px 14px 12px; }
.member-header a.brand-small { color: #fff; text-decoration: none; flex: 0 0 auto; }
.member-header a.brand-small:hover { color: #fff; text-decoration: none; }
.member-has-menu .member-header .company-tag { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mnav-open {
    display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto; height: 40px; padding: 0 12px 0 10px;
    border: 1px solid rgba(251, 251, 251, 0.4); border-radius: 8px; background: rgba(255, 255, 255, 0.07);
    color: #fff; font-weight: 700; font-size: 0.9rem; text-decoration: none; cursor: pointer;
}
.mnav-open svg { width: 20px; height: 20px; flex: 0 0 auto; }
.mnav-open:hover, .mnav-open:focus-visible { color: #fff; text-decoration: none; background: rgba(0, 164, 189, 0.22); border-color: var(--teal); }
.mnav-home { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 40px; height: 40px; margin-left: auto; border-radius: 8px; color: #fff; }
.mnav-home svg { width: 21px; height: 21px; }
.mnav-home:hover, .mnav-home:focus-visible { color: var(--teal-bright); background: rgba(0, 164, 189, 0.18); }
.mnav-home.is-current { background: rgba(255, 255, 255, 0.12); }

/* The search box. A white field on the navy bar: it has to read as "type
   here" to somebody who has never used the app. 16px text, or iOS zooms. */
.member-psearch { position: relative; order: 10; flex: 1 1 100%; min-width: 0; }
.member-search { display: flex; align-items: center; gap: 8px; height: 44px; margin: 0; padding: 0 12px; background: #fff; border: 2px solid transparent; border-radius: 10px; }
.member-search svg { width: 18px; height: 18px; flex: 0 0 auto; color: var(--muted); }
.member-search input { flex: 1 1 auto; min-width: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: none; border-radius: 0; background: transparent; box-shadow: none; color: var(--text); font-size: 1rem; }
.member-search input:focus { outline: none; box-shadow: none; border: none; }
.member-search:focus-within { border-color: var(--teal); box-shadow: 0 0 0 3px rgba(0, 164, 189, 0.3); }
.member-psearch .app-psearch-panel {
    position: absolute; top: calc(100% + 6px); left: 0; right: 0; min-width: 0; max-height: min(62vh, 480px); margin-top: 0; overflow-y: auto;
    padding: 6px; background: var(--card-bg); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 14px 34px rgba(0, 19, 59, 0.24); z-index: 80;
}
.member-psearch .app-psearch-item { padding: 11px 10px; }
.member-psearch .app-psearch-all { padding: 12px 10px; }

/* The drawer. Off-screen to the LEFT, which never widens the page. */
.mnav-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: rgba(0, 19, 59, 0.5); z-index: 90; }
.mnav-backdrop[hidden] { display: none; }
.member-shell-main { min-width: 0; }
.mnav-drawer {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 100; width: min(86vw, 320px);
    display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain;
    background: var(--card-bg); box-shadow: 0 0 40px rgba(0, 19, 59, 0.3);
    transform: translateX(-104%); visibility: hidden; transition: transform 0.2s ease, visibility 0s linear 0.2s;
}
body.mnav-is-open { overflow: hidden; }
body.mnav-is-open .mnav-drawer { transform: none; visibility: visible; transition: transform 0.2s ease, visibility 0s; }
.mnav-drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex: 0 0 auto; padding: 12px 10px 12px 18px; background: var(--brand); color: #fff; }
.mnav-drawer-title { display: flex; flex-direction: column; min-width: 0; }
.mnav-drawer-title strong { font-size: 1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mnav-drawer-title span { font-size: 0.8rem; opacity: 0.85; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mnav-close { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 40px; height: 40px; margin: 0; padding: 0; border: none; border-radius: 8px; background: transparent; color: #fff; cursor: pointer; }
.mnav-close svg { width: 20px; height: 20px; }
.mnav-close:hover, .mnav-close:focus-visible { background: rgba(255, 255, 255, 0.14); }

.mnav { flex: 1 0 auto; padding: 8px; }
.mnav-top {
    display: flex; align-items: center; gap: 12px; width: 100%; min-height: 46px; margin: 0; padding: 8px 12px;
    border: none; border-radius: 8px; background: transparent; box-shadow: none;
    color: var(--brand); font: inherit; font-size: 0.96rem; font-weight: 700; line-height: 1.25; text-align: left; text-decoration: none; cursor: pointer;
}
.mnav-top > svg { width: 20px; height: 20px; flex: 0 0 auto; color: var(--teal-ink); }
.mnav-top > span:first-of-type { flex: 1 1 auto; min-width: 0; }
.mnav-top:hover, .mnav-top:focus-visible { background: rgba(0, 164, 189, 0.1); color: var(--brand); text-decoration: none; }
.mnav-chevron { display: inline-flex; flex: 0 0 auto; color: var(--muted); transition: transform 0.15s ease; }
.mnav-chevron svg { width: 16px; height: 16px; }
.mnav-group.is-open > .mnav-group-btn .mnav-chevron { transform: rotate(90deg); }
.mnav-sub { display: none; margin: 0 0 6px 21px; border-left: 2px solid var(--border); }
.mnav-group.is-open > .mnav-sub, .mnav-nojs .mnav-sub { display: block; }
.mnav-link { display: block; margin-left: -2px; padding: 10px 12px 10px 21px; border-left: 2px solid transparent; border-radius: 0 8px 8px 0; color: var(--text); font-size: 0.93rem; line-height: 1.3; text-decoration: none; }
.mnav-link:hover, .mnav-link:focus-visible { background: rgba(0, 164, 189, 0.1); color: var(--brand); text-decoration: none; }
/* "You are here": a wash and the teal rule, the same mark the console's
   sidebar uses, so somebody who uses both learns it once. */
.mnav-link.is-current { border-left-color: var(--teal); background: rgba(0, 164, 189, 0.14); color: var(--brand); font-weight: 700; }
a.mnav-top.is-current { background: rgba(0, 164, 189, 0.14); }
.mnav-foot { flex: 0 0 auto; margin-top: auto; padding: 8px 8px 14px; border-top: 1px solid var(--border); }
.mnav-lang { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 46px; padding: 4px 12px; }
.mnav-lang label { display: inline-flex; align-items: center; gap: 12px; margin: 0; color: var(--brand); font-size: 0.96rem; font-weight: 700; }
.mnav-lang label svg { width: 20px; height: 20px; flex: 0 0 auto; color: var(--teal-ink); }
.mnav-lang select { width: auto; max-width: 150px; margin: 0; padding: 6px 10px; font-size: 0.9rem; }
.mnav-logout, .mnav-logout:hover { color: var(--error-text); }
.mnav-logout > svg { color: var(--error-text); }

/* A search result that points INTO a page (an FAQ, a news item, the
   notifications card) is ringed for a moment, so the eye lands on it. */
.mnav-found { animation: mnav-found 2.4s ease-out 1; border-radius: 8px; }
@keyframes mnav-found { 0%, 60% { box-shadow: 0 0 0 3px rgba(248, 180, 32, 0.75); } 100% { box-shadow: 0 0 0 3px rgba(248, 180, 32, 0); } }

/* member-menu.php — the whole menu as a page, and the search results. */
.mnav-page-card { padding-bottom: 8px; }
.mnav-page-card + .mnav-page-card { margin-top: 14px; }
.mnav-list { list-style: none; margin: 0; padding: 0; }
.mnav-list li + li { border-top: 1px solid var(--border); }
.mnav-list a { display: block; padding: 11px 2px; color: var(--text); text-decoration: none; }
.mnav-list a > strong { display: block; color: var(--brand); font-size: 0.98rem; }
.mnav-list a > span { display: block; margin-top: 2px; color: var(--muted); font-size: 0.85rem; overflow-wrap: anywhere; }
.mnav-list a:hover > strong, .mnav-list a:focus-visible > strong { color: var(--teal-ink); text-decoration: underline; }
.mnav-list-lead { display: flex; align-items: center; gap: 10px; }
.mnav-list a > strong.mnav-list-lead { display: flex; }
.mnav-list-lead svg { width: 20px; height: 20px; flex: 0 0 auto; color: var(--teal-ink); }
.mnav-list-heading { margin: 16px 0 2px; color: var(--muted); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase; }

/* Wide screens: the menu is a column that stays put, the search sits in the
   bar, and the Menu button has nothing left to open. */
@media (min-width: 1024px) {
    .member-has-menu .member-header .header-inner { flex-wrap: nowrap; padding: 12px 20px; }
    .member-has-menu .member-header .company-tag { flex: 0 1 auto; }
    .mnav-open, .mnav-close, .mnav-backdrop { display: none; }
    .member-psearch { order: 0; flex: 0 1 440px; margin-left: auto; }
    .mnav-home { margin-left: 0; }
    .member-shell { display: flex; align-items: flex-start; max-width: 1400px; margin: 0 auto; }
    .member-shell-main { flex: 1 1 auto; }
    .mnav-drawer {
        position: sticky; top: 16px; z-index: 1; flex: 0 0 272px; width: 272px; max-height: calc(100vh - 32px); margin: 24px 0 24px 20px;
        border: 1px solid var(--border); border-radius: 12px; box-shadow: none;
        transform: none; visibility: visible; transition: none;
    }
    .mnav-drawer-head { border-radius: 11px 11px 0 0; padding: 14px 18px; }
    .mnav-foot { margin-top: 0; }
    .mnav-top { min-height: 42px; }
    .mnav-link { padding-top: 8px; padding-bottom: 8px; }
}
@media (max-width: 380px) {
    .member-has-menu .member-header .header-inner { padding-left: 10px; padding-right: 10px; gap: 10px 8px; }
    .member-header .brand-small .brand-icon { margin-right: 4px; }
}
/* Receipts and certificates are printed from the member app: paper gets the
   document, not the menu. */
@media print {
    .mnav-drawer, .mnav-backdrop, .mnav-open, .mnav-home, .member-psearch { display: none !important; }
    .member-shell { display: block; }
}

/* ==========================================================================
   CHILDREN'S MINISTRY: CARE DETAILS + CHECK-IN / CHECK-OUT (2026-10-04)
   Markup: kids-checkin.php (the door, the pickup panel, the register),
   children.php and member-profile.php (the care form per child). Data and
   rules: includes/kids.php.
   ========================================================================== */
/* What the team must know about a child: one small line each, the allergy
   first and in the error colour so it cannot be missed on a busy morning. */
.kids-flags { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; margin: 6px 0 0; }
.kids-flag { display: inline-block; padding: 3px 9px; border-radius: 6px; font-size: 0.82rem; line-height: 1.35; overflow-wrap: anywhere; }
.kids-flag-alert { background: var(--error-bg); color: var(--error-text); font-weight: 600; }
.kids-flag-stop { background: var(--warn-bg); color: var(--warn-text); font-weight: 600; }
.kids-flag-pickup { background: rgba(0, 164, 189, 0.12); color: var(--brand); }
.kids-flag-note { background: var(--warn-bg); color: var(--warn-text); }
.kids-care-edit { margin-top: 8px; }
.kids-care-edit > summary { cursor: pointer; font-size: 0.88rem; }
.kids-care-edit form { margin-top: 10px; }
.kids-care-edit textarea, .kids-care-edit select { margin-bottom: 10px; }
.alert-info { background: rgba(0, 164, 189, 0.12); color: var(--brand); }
.kids-active-banner strong, .kids-active strong { display: inline-block; margin-left: 4px; white-space: nowrap; }
.kids-active { margin: 8px 0 0; padding: 8px 12px; border-radius: var(--radius); background: rgba(0, 164, 189, 0.12); color: var(--brand); font-size: 0.9rem; }

/* The door. Three columns on a wide screen; on a phone the parent folds
   under the child's name so the row is two columns and never scrolls. */
.kids-stats { margin: 16px 0 0; }
.kids-filter { margin: 0 0 6px; height: 46px; font-size: 1rem; }
.kids-table, .kids-register { width: 100%; margin-top: 8px; }
.kids-table td, .kids-register td { vertical-align: top; }
.kids-table tr[hidden] { display: none; }
.kids-fold { display: none; font-size: 0.82rem; }
.kids-status { width: 1%; white-space: nowrap; }
.kids-status form { display: inline; margin: 0; }
.kids-status .btn { margin: 0; }
.kids-state, .kids-code { display: block; font-size: 0.85rem; }
.kids-state-in { color: var(--success-text); font-weight: 700; }
.kids-state-out { color: var(--muted); font-weight: 700; }
.kids-code { margin: 2px 0 6px; color: var(--muted); }
.kids-code strong { color: var(--brand-dark); font-size: 1.05rem; letter-spacing: 1.5px; }
.kids-status .text-muted, .kids-status .badge { display: block; width: fit-content; margin-top: 3px; font-size: 0.8rem; white-space: normal; }
.kids-undo { display: block !important; margin-top: 4px !important; }
.kids-undo .link-button { font-size: 0.78rem; color: var(--muted); }
.kids-row-in > td:first-child { box-shadow: inset 3px 0 0 var(--success-text); }
.kids-row-out { opacity: 0.72; }

/* The pickup panel: the code box is the biggest thing on it. */
.kids-out { border: 2px solid var(--teal); }
.kids-out-meta { margin: 0 0 6px; color: var(--muted); }
.kids-out-form { margin-top: 14px; }
.kids-out-fields { display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 12px 16px; }
.kids-out-fields input { margin: 0; height: 52px; }
.kids-code-input { font-size: 1.7rem; font-weight: 700; letter-spacing: 8px; text-align: center; }
.kids-nocode { display: flex; align-items: flex-start; gap: 8px; margin: 14px 0 6px; font-weight: 600; }
.kids-nocode input { width: auto; margin: 3px 0 0; flex: 0 0 auto; }
.kids-visitor-form .btn { margin-top: 4px; }

@media (max-width: 700px) {
    .kids-fold { display: block; margin-top: 2px; }
    .kids-fold-col { display: none; }
    .kids-table th, .kids-table td, .kids-register th, .kids-register td { padding-left: 8px; padding-right: 8px; }
    .kids-status { white-space: normal; width: 104px; }
    .kids-status .btn { width: 100%; padding-left: 6px; padding-right: 6px; }
    .kids-out-fields { grid-template-columns: minmax(0, 1fr); }
}

/* Team page: the "children's ministry access" switch on a login's card. */
.team-kids-access { margin-top: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); }
.team-kids-access-line { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.team-kids-access-line .badge { margin-left: 6px; }
.team-kids-access .hint { margin: 6px 0 0; }
.team-kids-access .btn { margin: 0; }
/* =====================================================================
   STUDENT MANAGEMENT FOR COURSES (course-students.php, 2026-10-06).
   Henk: "Add a management section under courses to manage students
   attendance, and add marks, including 1st year, 2nd year, 3rd year and
   4th year registration levels. Also add remarks section for each
   student." The two grids (.cs-grid) are his name list: students down
   the side, subject codes across the top, the first column pinned so a
   name never scrolls out of sight on a narrow screen.
   ===================================================================== */
.cs-levels { margin-bottom: 10px; }
.cs-levels .tab-button { font-size: 0.85rem; padding: 5px 12px; text-decoration: none; }
.cs-count { display: inline-block; min-width: 1.6em; padding: 0 6px; margin-left: 2px; border-radius: 999px; background: rgba(0, 34, 82, 0.08); color: var(--brand); font-size: 0.76rem; font-weight: 700; text-align: center; text-transform: none; letter-spacing: 0; }
.tab-button.active .cs-count { background: rgba(255, 255, 255, 0.22); color: #fff; }
h2 .cs-count { vertical-align: middle; font-weight: 600; }
.cs-course-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 0 0 16px; }
.cs-course-pick label { margin: 0; }
.cs-course-pick select { width: auto; min-width: 240px; max-width: 100%; }
.cs-group-line { margin: 0 0 12px; font-weight: 600; color: var(--brand); }
.cs-link-button { background: none; border: 0; padding: 0; min-height: 0; margin: 0; font: inherit; font-size: 0.82rem; color: var(--teal-ink); text-decoration: underline; cursor: pointer; }
.cs-link-button:hover, .cs-link-button:focus-visible { color: var(--brand-dark); }
.cs-inline-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 0; }
.cs-inline-form label { margin: 0; }
.cs-inline-form input[type=search], .cs-inline-form input[type=text], .cs-inline-form select { width: auto; flex: 1 1 180px; max-width: 320px; margin: 0; }
.cs-inline-form select { flex: 0 1 150px; }
.cs-inline-form .btn { margin: 0; }

/* Tables */
.table-responsive table.cs-table { min-width: 0; width: 100%; }
.cs-table .cs-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cs-table .cs-name { font-weight: 600; }
.cs-table .cs-sub { display: block; font-size: 0.8rem; }
.cs-table .cs-nowrap { white-space: nowrap; }
.cs-table tr.cs-row-off > * { opacity: 0.62; }
.cs-table .cs-actions { text-align: right; white-space: nowrap; }
.cs-table .cs-actions form { display: inline; margin: 0 0 0 8px; }
.cs-table .cs-actions .btn { margin: 0; }
.cs-code { display: inline-block; padding: 1px 7px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg); color: var(--brand-dark); font-size: 0.76rem; font-weight: 700; letter-spacing: 0.3px; white-space: nowrap; }
.cs-col-code { width: 1%; white-space: nowrap; }
.cs-col-tick { width: 1%; text-align: center; white-space: nowrap; }
.cs-col-tick input, .cs-grid input[type=checkbox] { width: 20px; height: 20px; margin: 0; vertical-align: middle; accent-color: var(--brand); }
.cs-col-mark { width: 1%; white-space: nowrap; }
.cs-subject-label { display: inline; margin: 0; font-weight: 400; font-size: inherit; cursor: pointer; }
.cs-group-row th { background: var(--bg); color: var(--brand); font-size: 0.82rem; }
input[type=text].cs-mark-input { width: 4.6em; padding: 6px 6px; margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
input[type=text].cs-mark-untaken { background: var(--bg); border-style: dashed; }
.cs-grid-marks th, .cs-grid-marks td { padding: 8px 5px; }
.cs-grid-marks .cs-grid-col { min-width: 0; }
.cs-grid-marks input[type=text].cs-mark-input { width: 3.7em; padding: 6px 5px; }
.cs-grid-marks .cs-grid-name { padding-left: 10px; }

/* The name-list grids: subject registration, marks, attendance overview */
.cs-grid-wrap { border: 1px solid var(--border); border-radius: var(--radius); }
.table-responsive table.cs-grid { width: auto; min-width: 100%; border-collapse: separate; border-spacing: 0; }
.cs-grid th, .cs-grid td { padding: 8px 10px; vertical-align: middle; }
.cs-grid .cs-grid-col { text-align: center; min-width: 64px; white-space: nowrap; }
.cs-grid thead th { background: var(--bg); }
.cs-grid thead th.cs-grid-col { text-transform: none; letter-spacing: 0; color: var(--brand-dark); font-size: 0.78rem; }
.cs-grid thead th.cs-grid-col small { display: block; font-weight: 400; color: var(--muted); }
.cs-grid .cs-grid-kinds th { text-align: center; }
.cs-grid .cs-grid-kinds .cs-kind-core { border-bottom: 3px solid var(--brand); color: var(--brand); }
.cs-grid .cs-grid-kinds .cs-kind-elective { border-bottom: 3px solid var(--teal); color: var(--teal-ink); }
.cs-grid .cs-grid-name { position: sticky; left: 0; z-index: 1; min-width: 170px; max-width: 240px; text-align: left; background: #fff; border-right: 1px solid var(--border); font-size: 0.92rem; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--text); }
.cs-grid thead .cs-grid-name, .cs-grid tfoot .cs-grid-name { background: var(--bg); color: var(--muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.4px; }
.cs-grid tfoot td, .cs-grid tfoot th { background: var(--bg); font-weight: 700; border-bottom: 0; border-top: 1px solid var(--border); }
.cs-grid tbody tr:last-child > * { border-bottom: 0; }
.cs-cell-mark { display: block; font-size: 0.72rem; color: var(--muted); line-height: 1.1; }
.cs-grid-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.cs-grid-actions .btn { margin: 0; }
.cs-legend { list-style: none; margin: 18px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 6px 20px; font-size: 0.86rem; color: var(--muted); }

/* Attendance */
.checkin-service-fields select { margin: 0; height: 44px; }
.cs-att { font-weight: 700; }
.cs-att-present { color: var(--success-text); }
.cs-att-absent { color: var(--error-text); }
.cs-att-excused { color: var(--warn-text); }
.cs-att-choice { display: flex; flex-wrap: wrap; gap: 6px; }
.cs-att-opt { display: inline-flex; align-items: center; margin: 0; cursor: pointer; }
.cs-att-opt input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.cs-att-opt span { display: inline-block; padding: 7px 14px; border: 1px solid var(--border); border-radius: 999px; background: #fff; font-size: 0.86rem; font-weight: 600; color: var(--muted); }
.cs-att-opt input:focus-visible + span { outline: 2px solid var(--brand); outline-offset: 2px; }
.cs-att-opt-present input:checked + span { background: var(--success-bg); border-color: var(--success-text); color: var(--success-text); }
.cs-att-opt-absent input:checked + span { background: var(--error-bg); border-color: var(--error-text); color: var(--error-text); }
.cs-att-opt-excused input:checked + span { background: var(--warn-bg); border-color: var(--warn-text); color: var(--warn-text); }

/* One student */
.cs-student-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 28px; }
.cs-student-head h2 .badge { vertical-align: middle; margin-left: 6px; }
.cs-student-meta { margin: 4px 0 0; color: var(--muted); }
.cs-student-stats { flex: 1 1 420px; max-width: 640px; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin: 0; }
.cs-student-stats .stat-tile { padding: 12px 14px; }
.cs-student-stats .stat-tile-value { font-size: 1.5rem; }
.cs-remark-form label { margin-top: 0; }
.cs-remark-form .btn { margin-top: 10px; }
.cs-remarks { list-style: none; margin: 18px 0 0; padding: 0; }
.cs-remarks li { padding: 12px 0; border-top: 1px solid var(--border); }
.cs-remark-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-size: 0.86rem; }
.cs-remark-meta form { margin: 0 0 0 auto; }
.cs-remark-text { margin-top: 4px; overflow-wrap: anywhere; }
.cs-member-link { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.cs-member-link form { margin: 0; }
.cs-member-link .training-log-list { flex: 1 1 100%; }
.cs-remove { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.cs-remove .btn { margin: 0; }
.cs-remove .hint { flex: 1 1 260px; margin: 0; }

/* Adding students, subjects, year groups */
.cs-add-block { padding: 14px 0; border-top: 1px solid var(--border); }
.cs-add-block:first-of-type { border-top: 0; padding-top: 0; }
.cs-add-block h3, .cs-add-block summary { margin: 0 0 8px; font-size: 1rem; font-weight: 700; color: var(--brand); }
.cs-add-block .row label { margin-top: 0; }
.cs-add-block .btn { margin-top: 12px; }
.cs-add-block .cs-inline-form .btn { margin-top: 0; }
.cs-add-block .training-log-list { margin-top: 10px; }
.cs-add-block .course-booking-row { align-items: center; }
.cs-subject-row > .cs-field-narrow { flex: 0 1 150px; }
.cs-subject-row > .cs-field-wide { flex: 3 1 280px; }
.cs-subject-row label { margin-top: 0; }
.cs-group-form { margin: 0 0 6px; padding: 10px 12px; background: var(--bg); border-radius: var(--radius); }
.cs-group-form label { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; flex: 1 1 220px; }
.cs-group-form label input { flex: 1 1 auto; max-width: none; }
.cs-bsow-load .cs-inline-form { justify-content: space-between; }

@media (max-width: 760px) {
    .cs-student-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .cs-grid .cs-grid-name { min-width: 120px; max-width: 150px; font-size: 0.86rem; }
    .cs-grid th, .cs-grid td { padding: 7px 6px; }
    .cs-register th:nth-child(6), .cs-register td:nth-child(6),
    .cs-register th:nth-child(3), .cs-register td:nth-child(3) { display: none; }
    .cs-att-opt span { padding: 7px 10px; font-size: 0.82rem; }
    .cs-own-subjects th:nth-child(3), .cs-own-subjects td:nth-child(3) { display: none; }
    .cs-own-subjects th, .cs-own-subjects td { padding: 8px 6px; }
    .cs-table .cs-actions form { display: block; margin: 6px 0 0; }
}
@media print {
    .cs-course-pick, .cs-levels, .cs-grid-actions, #cs-add, .cs-remove, .cs-member-link, .cs-remark-form { display: none !important; }
    .cs-grid .cs-grid-name { position: static; }
}
